From f2203b40cf372462e5277b1b530561e929636ee1 Mon Sep 17 00:00:00 2001 From: chatty Date: Mon, 15 Feb 1999 09:17:36 +0000 Subject: Initial revision --- src/ivyecho.c | 313 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 src/ivyecho.c (limited to 'src/ivyecho.c') diff --git a/src/ivyecho.c b/src/ivyecho.c new file mode 100644 index 0000000..2b8227e --- /dev/null +++ b/src/ivyecho.c @@ -0,0 +1,313 @@ +/* + * IvyDaemon, an Ivy gateway for short-lived agents + * + * Copyright (C) 1999 + * Centre d'Études de la Navigation Aérienne + * + * Main file for the client ivyecho + * + * 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 "ivyd.h" + +const char* const servicename = "ivyd"; +const char* const port_env_variable = "INIVYD_PORT"; +const int default_port = DEFAULT_INIVYD_PORT; + +int debug = 0; + +void +Usage (const char* progname) { + fprintf (stderr, "Usage: %s [-b bus (ignored)][-s server] text\n", progname); + exit (1); +} + +/* Get in touch with super-server and retrieve server's port number */ +int +GetPort (long addr) +{ + struct servent *serv; + u_short serv_port; + struct sockaddr_in sin; + struct connmsg msg; + int sock; + int len; + + /* get service port number */ + 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; + + /* create and bind socket */ + sock = socket (AF_INET, SOCK_DGRAM, 0); + if (sock == -1) { + perror ("Can't create socket: "); + return 0; + } + memset (&sin, 0, sizeof sin); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + if (-1 == bind (sock, &sin, sizeof sin)) { + perror ("Can't bind socket: "); + goto failed; + } + sin.sin_port = serv_port; + sin.sin_addr.s_addr = addr; + + /* build request */ + msg.msg_uid = getuid (); + msg.msg_port = 0; + msg.msg_type = MSG_CLIENT; + + /* send it */ + if (-1 == sendto (sock, (char *)&msg, sizeof msg, 0, (struct sockaddr *)&sin, sizeof sin)) { + perror ("Can't send on socket: "); + goto failed; + } + + /* wait for reply */ + len = sizeof sin; + if (-1 == recvfrom (sock, (char *)&msg, sizeof msg, 0, (struct sockaddr *)&sin, &len)) { + perror ("Can't receive on socket: "); + goto failed; + } + + /* OK, we're done, return reply */ + (void) close (sock); + return (int) msg.msg_port; + +failed: + (void) close (sock); + return 0; +} + +int +ServerOpen (const char *host) +{ + int sock; + static struct sockaddr_in addr; + struct hostent *hp; + + /* determine host name and address */ + if (!host) + host = getenv ("IVYD"); + + if (!host) + host = "localhost"; + + hp = gethostbyname (host); + if (hp == 0) { + fprintf (stderr, "Unknown host %s\n", host); + return 0; + } + + /* create socket */ + sock = socket (AF_INET, SOCK_STREAM, 0); + if (sock < 0) { + perror ("Can't create socket: "); + return 0; + } + + + /* build address from host addr, asking port number to super-server */ + memcpy (&addr.sin_addr, hp->h_addr, hp->h_length); + addr.sin_family = AF_INET; + addr.sin_port = GetPort (addr.sin_addr.s_addr); + if (! addr.sin_port) + return 0; + + /* connect socket on address */ + if (connect (sock, &addr, sizeof (addr)) < 0) { + perror ("Can't connect socket: "); + return 0; + } + + return sock; +} + + +int +SendMsg (int sock, const char* s) +{ + request req; + + /* build request */ + strcpy (req.buffer, s); + + /* send request */ + /* we should handle return value more finely */ + if (write (sock, &req, sizeof (request)) != sizeof (request)) { + fprintf (stderr, "Unable to write %d bytes: ", sizeof (request)); + perror (""); + } + +#if 0 + answer ans; + register char *p = (char *) &ans; + register int n, l; + + /* retrieve answer (useless) */ + for (n = sizeof (answer); n > 0; p += l) { + n -= (l = read (sock, p, n)); + if (l <= 0) { + perror ("Error retrieving answer from server: "); + return 0; + } + } + return ans.ok; +#endif + return 1; +} + +void +HandleArgs (int sock, int index, int argc, char** argv) +{ + char buf [BUFSIZE]; + int space = 0; + int nbchars = 0; + + /* slice arguments into buffer */ + buf [0] = '\0'; + while (index < argc) { + const char* p = argv[index++]; + int l = strlen (p); + /* while we have pending chars for this arg... */ + while (l + space > 0) { + /* first try and fit space if needed */ + if (space) { + if (nbchars + space <= BUFSIZE - 1) { + strcat (buf, " "); + nbchars += space; + space = 0; + } else { + goto bufferfull; + } + } + + /* then look if we can fit all the chars we have */ + if (nbchars + l <= BUFSIZE - 1) { + /* if yes, go ahead */ + strcat (buf, p); + nbchars += l; + /* we'll need to insert space if there are other args */ + space = 1; + /* but let's make sure we don't keep looping */ + l = -1; + /* if buffer is full, handle it */ + if (nbchars == BUFSIZE - 1) + goto bufferfull; + /* otherwise, we're done anyway */ + else + continue; + + /* if not enough room, first fit what we can */ + } else { + int fitting = (BUFSIZE - 1) - nbchars; + if (fitting > 0) { + strncat (buf, p, fitting); + nbchars += fitting; + l -= fitting; + p += fitting; + } + } + + +bufferfull: /* now we have a full buffer */ + /* send it */ + if (debug) + printf ("Sending [%s]\n", buf); + SendMsg (sock, buf); + /* and prepare for next round */ + nbchars = 0; + buf [0] = '\0'; + } + } + if (nbchars > 0) { + if (debug) + printf ("Sending [%s]\n", buf); + SendMsg (sock, buf); + } +} + + +/* + * Demande un numero de port au super-serveur de la machine addr + */ + + +int +main (int argc, char** argv) +{ + char busbuf [128]; + const char* bus = 0; + char serverhostbuf [128]; + const char* serverhost = 0; + const struct option options [] = { + {"bus", required_argument, 0, 'b'}, + {"debug", no_argument, 0, 'd'}, + {"server", required_argument, 0, 's'}, + {0, 0, 0, 0} + }; + char c; + int servfd; + +#if 0 + if (strlen (argv0) >= 4 && !strcmp (argv0+strlen (argv0)-4, "wait")) + wflag = 1; +#endif + + /* handle options */ + while ((c = getopt_long (argc, argv, "+b:s:d", options, 0)) != EOF) { + switch (c) { + case 'b': + strcpy (busbuf, optarg) ; + bus = busbuf; + break; + case 's': + strcpy (serverhostbuf, optarg) ; + serverhost = serverhostbuf; + break; + case 'd': + debug = 1; + break; + } + } + + + /* Se connecter au serveur. */ + servfd = ServerOpen (serverhost); + if (!servfd) { + fprintf (stderr, "No server.\n"); + return 0; + } + + HandleArgs (servfd, optind, argc, argv); + + return 1; +} + -- cgit v1.1