summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchatty1999-02-15 09:17:36 +0000
committerchatty1999-02-15 09:17:36 +0000
commitf2203b40cf372462e5277b1b530561e929636ee1 (patch)
tree3a4ce7fc284972c0967113ba7444ff44c75775c6
parent23abb4b87c7e40ed259dd02f653516f60e55ade4 (diff)
downloadivyd-f2203b40cf372462e5277b1b530561e929636ee1.zip
ivyd-f2203b40cf372462e5277b1b530561e929636ee1.tar.gz
ivyd-f2203b40cf372462e5277b1b530561e929636ee1.tar.bz2
ivyd-f2203b40cf372462e5277b1b530561e929636ee1.tar.xz
Initial revision
-rw-r--r--src/Makefile55
-rw-r--r--src/inivyd.c221
-rw-r--r--src/ivyd.c271
-rw-r--r--src/ivyd.h62
-rw-r--r--src/ivyecho.c313
5 files changed, 922 insertions, 0 deletions
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..b2e6a8b
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,55 @@
+#
+# IvyDaemon, an Ivy gateway for short-lived agents
+#
+# Copyright (C) 1999
+# Centre d'Études de la Navigation Aérienne
+#
+# Makefile
+#
+# Author(s): Stephane Chatty <chatty@cenatoulouse.dgac.fr>
+#
+# $Id$
+#
+# Please refer to file version.h for the
+# copyright notice regarding this software
+#
+#
+
+INCDIRS =
+CFLAGS = -g -Wall $(INCDIRS)
+
+PROGS = in.ivyd ivyd ivyecho #ivycat
+OBJ =
+
+all: $(PROGS)
+
+
+in.ivyd: inivyd.c ivyd.h
+ $(CC) $(CFLAGS) -o in.ivyd inivyd.c
+
+ivy: ivy.c ivyd.h
+ $(CC) $(CFLAGS) -o ivy ivy.c
+
+ivyd: ivyd.c ivyd.h
+ $(CC) $(CFLAGS) -o ivyd ivyd.c -livy
+
+ivycat: ivycat.c ivyd.h
+ $(CC) $(CFLAGS) -o ivycat ivycat.c
+
+ivyecho: ivyecho.c ivyd.h
+ $(CC) $(CFLAGS) -o ivyecho ivyecho.c
+
+clean:
+ -rm -f *.o *~ $(PROGS)
+
+install: all
+ test -d $(PREFIX)/usr/bin || mkdirhier $(PREFIX)/usr/bin
+ install -m 755 in.ivyd $(PREFIX)/usr/bin/in.ivyd
+ install -m 755 ivyd $(PREFIX)/usr/bin/ivyd
+ install -m 755 inecho $(PREFIX)/usr/bin/ivyecho
+ install -m 755 ivycat $(PREFIX)/usr/bin/ivycat
+
+rpm::
+ /usr/bin/rpmize
+
+
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 <chatty@cenatoulouse.dgac.fr>
+ * from code by Patrick Amar <pa@lri.fr>
+ *
+ * $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 <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <memory.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/signal.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <errno.h>
+
+#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;
+ }
+
+ }
+}
+
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 <chatty@cenatoulouse.dgac.fr>
+ * from code by Patrick Amar <pa@lri.fr>
+ *
+ * $Id$
+ *
+ * Please refer to file version.h for the
+ * copyright notice regarding this software
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <fcntl.h>
+#include <memory.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#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);
+}
+
diff --git a/src/ivyd.h b/src/ivyd.h
new file mode 100644
index 0000000..39f2691
--- /dev/null
+++ b/src/ivyd.h
@@ -0,0 +1,62 @@
+/*
+ * IvyDaemon, an Ivy gateway for short-lived agents
+ *
+ * Copyright (C) 1999
+ * Centre d'Études de la Navigation Aérienne
+ *
+ * Header shared by server, superserver and clients
+ *
+ * Author(s): Stephane Chatty <chatty@cenatoulouse.dgac.fr>
+ * from code by Patrick Amar <pa@lri.fr>
+ *
+ * $Id$
+ *
+ * Please refer to file version.h for the
+ * copyright notice regarding this software
+ *
+ */
+
+/* exchanges with super-server (port registration) */
+
+#ifndef DEFAULT_INIVYD_PORT
+#define DEFAULT_INIVYD_PORT 3006
+#endif
+
+#define MSG_REPLY ((char) 0)
+#define MSG_CLIENT ((char) 1)
+#define MSG_SERVER ((char) 2)
+
+struct connmsg {
+ short msg_uid; /* identification de l'expediteur */
+ short msg_port; /* le port a utiliser pour l'uid ci-dessus */
+ char msg_type; /* type de messages */
+ char msg_fill1, /* fillers */
+ msg_fill2,
+ msg_fill3;
+
+};
+
+/* exchanges between clients and server */
+
+#define BUFSIZE 512
+
+typedef struct {
+ char buffer [BUFSIZE];
+} request;
+
+typedef struct {
+ int ok;
+} answer;
+
+
+/*
+ * L'adresse de la machine locale
+ */
+#ifndef LOCALHOST
+#ifdef INADDR_LOOPBACK
+#define LOCALHOST htonl (INADDR_LOOPBACK)
+#else
+#define LOCALHOST htonl (0x7f000001)
+#endif
+#endif
+
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 <chatty@cenatoulouse.dgac.fr>
+ * from code by Patrick Amar <pa@lri.fr>
+ *
+ * $Id$
+ *
+ * Please refer to file version.h for the
+ * copyright notice regarding this software
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <string.h>
+#include <memory.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#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;
+}
+