From f2203b40cf372462e5277b1b530561e929636ee1 Mon Sep 17 00:00:00 2001 From: chatty Date: Mon, 15 Feb 1999 09:17:36 +0000 Subject: Initial revision --- src/ivyd.c | 271 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 src/ivyd.c (limited to 'src/ivyd.c') diff --git a/src/ivyd.c b/src/ivyd.c new file mode 100644 index 0000000..5a4f3d0 --- /dev/null +++ b/src/ivyd.c @@ -0,0 +1,271 @@ +/* + * IvyDaemon, an Ivy gateway for short-lived agents + * + * Copyright (C) 1999 + * Centre d'Études de la Navigation Aérienne + * + * Main file for the server + * + * Author(s): Stephane Chatty + * from code by Patrick Amar + * + * $Id$ + * + * Please refer to file version.h for the + * copyright notice regarding this software + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ivy.h" +#include "ivyd.h" + +const char* const servicename = "ivyd"; +const char* const port_env_variable = "INIVYD_PORT"; +const int default_port = DEFAULT_INIVYD_PORT; + +static char * HomeDir; +int debug = 0; + +static void +Usage (const char* progname) +{ + fprintf (stderr, "Usage: %s [-b bus][-d]\n", progname); + fprintf (stderr, " -d: does not fork so as to facilitate debugging\n"); + fprintf (stderr, " -b bus: selects Ivy bus on which to relay messages\n"); + exit (1); +} + + +/* + * Envoie un numero de port au super-serveur de la machine locale + */ +int +SendPort (int port) +{ + struct servent *serv; + u_short serv_port; + struct sockaddr_in sin; + struct connmsg msg; + int sock; + int res; + + 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; + + sock = socket (AF_INET, SOCK_DGRAM, 0); + if (sock == -1) + return 0; + + memset (&sin, 0, sizeof sin); + sin.sin_family = AF_INET; + sin.sin_port = serv_port; + sin.sin_addr.s_addr = LOCALHOST; + + msg.msg_uid = getuid (); + msg.msg_port = port; + msg.msg_type = MSG_SERVER; + + + res = sendto (sock, (char *)&msg, sizeof msg, 0, (struct sockaddr *)&sin, sizeof sin); + + /* We only detect local errors, but we have no guarantee that there is someone + at the other end. We should fix that someday (by going connected?) */ + + if (res == -1) + goto failed; + + (void) close (sock); + return 1; + +failed: + (void) close (sock); + return 0; +} + + +int +InitSocket () +{ + int s, i; + struct sockaddr_in addr; + + s = socket (AF_INET, SOCK_STREAM, 0); + if (s < 0) { + perror ("socket"); + return 0; + } + + memset (&addr, 0, sizeof addr); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + + if (bind (s, &addr, sizeof (addr)) == -1) { + perror ("bind"); + return 0; + } + + i = sizeof addr; + if (getsockname (s, &addr, &i) == -1) { + perror ("bind"); + return 0; + } + + + if (debug) + printf ("Ivyd listens on port %d\n", ntohs (addr.sin_port)); + + if (! SendPort (addr.sin_port)) { + fprintf (stderr, "No Ivyd port server. Continuing with port = %d\n", + ntohs (addr.sin_port)); + } + + /* je me debarrasse du terminal de controle */ + +/* freopen ("/dev/tty", "r+", stderr); */ + for (i = 0; i < 32; i++) + if (i != fileno (stderr) && i != s) + close (i); + +#ifndef SYSV + i = open ("/dev/tty", 0); + if (i != -1) { + (void) ioctl (i, TIOCNOTTY, 0); + close (i); + } +#endif SYSV + open ("/dev/null", 2); dup (0); + + + if (listen (s, 5) == -1) { + perror ("listen"); + return 0; + } + return s; +} + + +void +HandleRequests (void* ch, int fd, void* data) +{ + request req; + char* p = (char*) &req; + int n = sizeof (request); + struct sockaddr_in addr; + int len = sizeof (addr); + + fprintf (stderr, "REQUEST on %d\n", fd); + + /* retrieve request */ + while (n > 0) { +#if 1 + int l = read (fd, p, n); +#else + int l = recvfrom (fd, p, n, 0, (struct sockaddr*) &addr, &len); +#endif + if (l < 0) { + perror ("Error retrieving request from client"); + exit (0); + return; + } else if (l == 0) { + if (debug) + fprintf (stderr, "closing connection for %d\n", fd); + IvyChannelClose (ch); + close (fd); + return; + } + n -= l; + p += l; + } + +#if 0 + answer ans; + ans.ok = 1; + write ( +#endif + fprintf (stderr, "REQUEST [%s]\n", req.buffer); + IvySendMsg (req.buffer); +} + +void +HandleConnections (void* ch, int fd, void* data) +{ + static struct sockaddr sa; + static int acc; + int newfd = accept (fd, &sa, &acc); + fprintf (stderr, "CONNECTION %d\n", newfd); + IvyChannelSetUp (newfd, 0, 0, HandleRequests); +} + + +void +main (int argc, char **argv) +{ + int sock; + char busbuf [128]; + const char* bus = 0; + int c; + + /* handle args */ + while ((c = getopt (argc, argv, "b:d")) != EOF) { + switch (c) { + case 'b': + strcpy (busbuf, optarg) ; + bus = busbuf; + break; + case 'd': + debug = 1; + break; + default: + Usage (argv[0]); + } + } + + /* detach from tty */ + if (! debug) + if (fork ()) + exit (0); + + /* create server port */ + sock = InitSocket (); + + signal (SIGTERM, exit); /* pour flinguer le serveur */ + +#if 0 + /* + * Charger le fichier de personnalisation. + */ + HomeDir = getenv ("HOME"); + + if (!HomeDir || !*HomeDir) + fprintf (stderr, "%s: No HOME environment variable.\n", argv0); + else + StartUp (HomeDir); +#endif + + /* Ivy initialization and main loop */ + IvyInit ("IVYD", 0, 0, 0, 0, 0, 0); + IvyChannelSetUp (sock, 0, 0, HandleConnections); + IvyStart (bus); + IvyMainLoop (0); +} + -- cgit v1.1