From f2203b40cf372462e5277b1b530561e929636ee1 Mon Sep 17 00:00:00 2001 From: chatty Date: Mon, 15 Feb 1999 09:17:36 +0000 Subject: Initial revision --- src/inivyd.c | 221 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100644 src/inivyd.c (limited to 'src/inivyd.c') diff --git a/src/inivyd.c b/src/inivyd.c new file mode 100644 index 0000000..56d7106 --- /dev/null +++ b/src/inivyd.c @@ -0,0 +1,221 @@ +/* + * IvyDaemon, an Ivy gateway for short-lived agents + * + * Copyright (C) 1999 + * Centre d'Études de la Navigation Aérienne + * + * Main file for the super-daemon + * + * Author(s): Stephane Chatty + * from code by Patrick Amar + * + * $Id$ + * + * Please refer to file version.h for the + * copyright notice regarding this software + * + */ + +/* + * Le super-demon wixd. + * + * Il est normalement lance par inetd, avec la chaussette SOCK_DGRAM + * sur le descripteur 0, ou alors, si le symbole FROMBOOT est defini, il est + * lance depuis /etc/rc.local. + * + * Le serveur wixd: + * Il envoie un paquet connmsg de type MSG_SERVER contenant le numero + * de port sur lequel il a connecte sa chaussette. + * + * Les clients wix (wx, wxcat, etc ...): + * Ils envoient un paquet connmsg de type MSG_CLIENT ou ils demandent + * le port. + * + * L'identification de l'emetteur du paquet est le numero d'utilisateur. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ivyd.h" + + +const char* const dumpfilename = "/usr/tmp/wixd.db"; +const int dumpfilemode = 0644; +const char* const servicename = "ivyd"; +const char* const port_env_variable = "INIVYD_PORT"; +const int default_port = 3006; + +/* + * Definition de la table geree par le super-demon + */ + +typedef struct { + short s_port; /* le port sur lequel le client communique avec son serveur */ + short s_uid; /* le numero de processus du serveur wixd */ +} serverinfo; + +#define TABSIZ 64 /* 64 connections simultanees, ca devrait aller */ +serverinfo si_table [TABSIZ]; + +/* + * GetInfo (name) + * + * Rend l'information concernant l'utilisateur uid. + */ + +serverinfo* +GetInfo (int uid) +{ + register serverinfo *si; + register serverinfo *res = 0; + + for (si = si_table; si - si_table < TABSIZ; ++si) { + if (si->s_port == 0) { + if (! res) + res = si; + continue; + } + if (si->s_uid != uid) + continue; + res = si; + break; + } + return res; +} + +/* + * DumpInfo () + * + * Dumps to a file the contents of the table + */ + +int +DumpInfo () +{ + register serverinfo *si; + register int fd = creat (dumpfilename, dumpfilemode); + char buf [512]; + + if (fd == -1) + return 0; + + for (si = si_table; si - si_table < TABSIZ; ++si) { + if (! si->s_port) + continue; + (void) sprintf (buf, "user %5d, port %d\n", si->s_uid, ntohs (si->s_port)); + (void) write (fd, buf, strlen (buf)); + } + (void) close (fd); + return 1; +} + + +void +SigHup (int sig) +{ + DumpInfo (); +} + +void +main (int argc, const char **argv) +{ + struct servent *serv; + u_short serv_port = 0; + struct sockaddr_in from; + int fromlen; + struct connmsg msg; + register serverinfo *si; + int boot = 0; + int debug = 0; + + (void) signal (SIGHUP, SigHup); + + serv = getservbyname (servicename, 0); + + if (! serv) { + char *pp = getenv (port_env_variable); + serv_port = htons (pp ? atoi (pp) : default_port); + if (serv_port <= 0) + exit (0); + } else + serv_port = serv -> s_port; + + ++argv; + while (argc > 1) { + if (strcmp (*argv, "-boot") == 0 || strcmp (*argv, "-b") == 0) + boot = 1; + else if (strcmp (*argv, "-debug") == 0 || strcmp (*argv, "-d") == 0) + debug = 1; + else + fprintf (stderr, "bad option %s\n", *argv); + ++argv; + --argc; + } + + if (boot) { + if (!debug) { + int s; + + if (fork ()) + exit (0); + + /* on ferme tous les descripteurs */ + for (s = getdtablesize (); --s >= 0;) + close (s); + + /* et on se debarrasse du terminal de controle */ + if (-1 != open ("/dev/tty", 2)) { + (void) ioctl (0, TIOCNOTTY, 0); + close (0); + } + } else + close (0); + + /* + * Ouvre la chaussette et l'attache a bon port + */ + if (-1 == socket (AF_INET, SOCK_DGRAM, 0)) + exit (1); + memset (&from, 0, sizeof from); + from.sin_family = AF_INET; + from.sin_port = serv_port; + from.sin_addr.s_addr = INADDR_ANY; + if (-1 == bind (0, &from, sizeof from)) + exit (1); + } + + for (;;) { + fromlen = sizeof from; + if (recvfrom (0, (char *)&msg, sizeof msg, 0, (struct sockaddr *)&from, &fromlen) <= 0) { + if (errno == EINTR) + continue; + exit (1); + } + si = GetInfo (msg.msg_uid); + switch (msg.msg_type) { + case MSG_SERVER: + si->s_port = msg.msg_port; + si->s_uid = msg.msg_uid; + break; + + case MSG_CLIENT: + msg.msg_port = si->s_port; + msg.msg_type = MSG_REPLY; + (void) sendto (0, (char *)&msg, sizeof msg, 0, (struct sockaddr *)&from, fromlen); + break; + } + + } +} + -- cgit v1.1