summaryrefslogtreecommitdiff
path: root/src/ivyecho.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ivyecho.c')
-rw-r--r--src/ivyecho.c313
1 files changed, 313 insertions, 0 deletions
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;
+}
+