chiark / gitweb /
*** empty log message ***
authorjames <james>
Wed, 20 Feb 2008 17:18:33 +0000 (17:18 +0000)
committerjames <james>
Wed, 20 Feb 2008 17:18:33 +0000 (17:18 +0000)
apps/mainloop.c
apps/sympathy.c
apps/usage.c

index f515478810cf824ca0fb9ce251c025019ac41a5e..851f2966af00ba191a1e60022b894aadedbb30c5 100644 (file)
@@ -10,6 +10,9 @@ static char rcsid[] = "$Id$";
 
 /*
  * $Log$
+ * Revision 1.4  2008/02/20 17:18:33  james
+ * *** empty log message ***
+ *
  * Revision 1.3  2008/02/20 02:11:35  james
  * *** empty log message ***
  *
@@ -333,13 +336,13 @@ mainloop (TTY * tty, Socket * server_socket, Socket * client_socket, Ansi * a,
           Log * log)
 {
   fd_set rfds, wfds;
-  Context c;
+  Context c={0};
   Clients *clients;
 
 
   c.v = vt102_new ();
   c.h = history_new (200);
-  c.l = log
+  c.l = log;
     /* are we being fed by a tty or a socket */
     if (client_socket)
     {
index e90b8d231376b13662600393a648b4c35e184c48..964d84cf769009770a6b22802ab9b76a0f5fed07 100644 (file)
@@ -10,6 +10,9 @@ static char rcsid[] = "$Id$";
 
 /*
  * $Log$
+ * Revision 1.6  2008/02/20 17:18:33  james
+ * *** empty log message ***
+ *
  * Revision 1.5  2008/02/20 15:50:14  james
  * *** empty log message ***
  *
@@ -27,9 +30,76 @@ static char rcsid[] = "$Id$";
  *
  */
 
+#include <stdarg.h>
 #include <sympathy.h>
 #include "mainloop.h"
 
+char *fatal_moan(char *fmt,...)
+{
+va_list ap;
+
+
+va_start(ap, fmt);
+n = vfprintf (stderr,fmt,ap);
+va_end(ap);
+
+putc('\n',stderr);
+exit(1);
+}
+
+
+
+/*make the path in fmt from home (hence the name) */
+
+char *mome(char *fmt,...)
+{
+
+                 int n;
+               int homelen;
+                 char *buf,*home;
+                 va_list ap;
+
+
+               home=getenv("HOME");
+               if (!home) return NULL;
+
+               homelen=strlen(home)+1;
+
+               size=1024+homelen;
+
+               buf = malloc (size);
+
+               if (!buf) 
+                       fatal_moan("malloc failed");
+
+               strcpy(buf,home);
+               strcat(buf,"/");
+
+                 while (1) {
+
+
+                    va_start(ap, fmt);
+                    n = vsnprintf (buf+homelen, size-homelen, fmt, ap);
+                    va_end(ap);
+
+                    if (n > -1 && n < len)
+                       return buf;
+
+                    if (n > -1)    /* glibc 2.1 */
+                       size = homelen+n+1; 
+                    else           /* glibc 2.0 */
+                       size *= 2;  /* twice the old size */
+               
+                 buf=realloc(buf,size);
+
+               if (!buf) 
+                       fatal_moan("malloc failed");
+                 }
+              }
+}
+
+
+
 int
 main (int argc, char *argv[])
 {
@@ -37,52 +107,214 @@ main (int argc, char *argv[])
   extern char *optarg;
   extern int optind, opterr, optopt;
 
-  int tflag = 0, cflag = 0, sflag = 0, rflag = 0;
-  int lflag = 0, dflag = 0, bflag = 0, pflag = 0;
-  int kflag = 0;
+  int oflags[128];
+  char *oargs[128];
 
-  int nhistory = 200;
-  int baud = -1;
-  char *rid, *device_path;
-  char *socket_path;
+  Socket *server_socket = NULL, *client_socket = NULL;
+  ANSI *ansi = NULL;
+  TTY *tty = NULL;
 
-  Log *log=NULL;
+  memset (oflags[128], 0, sizeof (oflags));
+  memset (oargs[128], 0, sizeof (oargs));
 
   while ((c = getopt (argc, argv, "tscr:d:pb:fL:Fk:n:")) != EOF)
     {
       switch (c)
         {
-        case 't':
-          tflag++;
-          break;
-        case 's':
-          sflag++;
-          break;
-        case 'c':
-          cflag++;
-       break;
-        case 'r':
-          rflag++;
-         rid=optarg;
-       break;
-       case 'L':
-               if (log) moan("only one -L argument is allowed");
-               log=file_log_new(optarg);
-               if (!log) moan("couldn't open %s as a log file",optarg);
-        default:
+        case ':':
+        case 'h':
+        case '?':
           usage ();
+        default:
+          if ((c > 64) && (c < 91))
+            {
+              oflags[c]++;
+              oargs[c] = optarg;
+            }
+          else if ((c > 96) && (c < 123))
+            {
+              oflags[c]++;
+              oargs[c] = optarg;
+            }
+          else
+            {
+              moan ("unknown option %c", c);
+              usage ();
+            }
         }
+
+    }
+
+  if (!oflags['s'] && !oflags['c'] && !oflags['t'] && !oflags['r'])
+    {
+      /*If no mode is specified behave like screen */
+      oflags['s']++;
+      oflags['c']++;
     }
 
+  if ((oflags['t'] && ((oflags['s'] || oflags['c']) || oflags['r'])) ||
+      (oflags['r'] && ((oflags['s'] || oflags['c']) || oflags['t'])) ||
+      ((oflags['s'] || oflags['c']) && (oflags['r'] || oflags['t'])))
+    fatal_moan ("specifiy exactly one of ( -c and or -s ), -t and -r");
+
+  if (oflags['r'] && oflags['k'])
+    fatal_moan ("-k is incompatible with -r");
 
 
+  /*Fold -r into -c */
+  if (oflags['r'])
+    {
+      int id = safe_atoi (oargs['r']);
+      if (id < 0)
+        fatal_moan ("cannot parse -r %s as an integer", oargs['r']);
+
+      oflags['k']++;
+      oargs['k'] = mome ("/.sympathy/%d", id);
+      oflags['r'] = 0;
+      oflags['c']++;
+    }
+
+  if (oflags['c'] && !oflags['k'])
+    fatal_moan ("-c requires a socket to be specified with -s or -k");
+
+  if (oflags['p'] && oflags['d'])
+    fatal_moan ("-p incompatible with -d");
+
+  /*implement server and client by opening the server socket to prevent */
+  /*a race condition, and then forking and munging the cmd line options */
+  /*in the parent and child so that the child is the server and the */
+  /*parent becomes its client */
+
+  if (oflags['c'] && oflags['s'] && oflags['F'])
+    fatal_moan ("-F is incompatible with -c -s");
+
+  if (oflags['s'] && !oflags['k'])
+    {
+      char *path;
+      path = mome ("/.sympathy");
+      mkdir (path, 0700);
+      free (path);
+
+      oargs['k'] = mome ("/.sympathy/%d", getpid ());
+      oflags['k']++;
+    }
+
+  if (oflags['s'])
+    {
+      server_socket = socket_listen (oargs['k']);
+      if (!server_socket)
+        fatal_moan ("failed to create socket %s for listening", oargs['k']);
+    }
+
+  switch (fork ())
+    {
+    case 0:                    /*child becomes the server */
+      oflags['c'] = 0;
+      oflags['H'] = 0;
+      break;
+    case -1:
+      fatal_moan ("fork failed");
+    default:
+      oflags['s'] = 0;
+      oflags['K'] = 0;
+      oflags['d'] = 0;
+      oflags['p'] = 0;
+      oflags['b'] = 0;
+      oflags['f'] = 0;
+      oflags['L'] = 0;
+      oflags['n'] = 0;
+    }
+
+
+  if ((oflags['p'] || oflags['d'] || oflags['K'] || oflags['b'] || oflags['f']
+       || oflags['L']) && oflags['c'])
+    fatal_moan ("-c or -r are incompatible with -p, -d, -K, -b, -f or -L");
+
+  if (oflags['t'] || oflags['s'])
+    {
+      if (!oflags['p'] && !oflags['d'])
+        oflags['p']++;
+    }
+
+
+  if (oflags['s'] || oflags['t'])
+    {
+
+      if (oflags['L'])
+        {
+          log = file_log_new (oargs['L']);
+          if (!log)
+            fatal_moan ("unable to access log file %s", oargs['L']);
+        }
+
+      if (oflags['p'])
+        {
+          tty = ptty_open (NULL, NULL);
+        }
+      else
+        {
+          tty =
+            serial_open (oargs['d'],
+                         oflags['K'] ? SERIAL_LOCK_ACTIVE :
+                         SERIAL_LOCK_PASSIVE);
+          if (tty)
+            fatal_moan ("unable to open serial port %s", oargs['d']);
+        }
+
+      if (oflags['b'])
+        {
+          int baud = safe_atoi (oargs['b']);
+
+          if (baud < 0)
+            fatal_maon ("Unable to parse baudrate %s", oargs['b']);
+
+          tty_set_baud (tty, baud);
+
+        }
+
+      tty_set_flow (tty, oflags['f'] ? 1 : 0);
+
+    }
+
+  if (oflags['c'])
+    {
+
+      client_socket = socket_connect (oargs['k']);
+      if (!client_socket)
+        fatal_moan ("failed to connect to socket %s", oargs['k']);
+
+
+    }
+
+  if (oflags['c'] || oflags['t'])
+    {
+
+      if (oflags['H'])
+        {
+          fatal_moan ("fix a bug in HTML dispatcher before this works");
+        }
+      else
+        {
+          ansi = (ANSI *) malloc (sizeof (ANSI));
+          memset (ansi, 0, sizeof (ANSI));
+
+          terminal_register_handlers ();
+          ansi->terminal = terminal_open (0, 1);
+          ansi_reset (ansi, NULL);
+        }
+    }
+
+  if (oflags['s'] && !oflags['F']) {
+               /*FIXME become a daemon*/
+  }
+
+  mainloop (tty, server_socket, client_socket, ansi, log);
+
+  if (ansi)
+    {
+      ansi_terminal_reset (ansi);
+      terminal_atexit ();
+    }
 
-#if 0
-  "sympathy -t      [-l] [-d serialdev|-p] [-b baud] [-f] [-L log]\n"
-    "sympathy -s      [-l] [-d serialdev|-p] [-b baud] [-f] [-L log] [-F] [-k skt]\n"
-    "                      [-n hlines]\n"
-    "sympathy [-s -c] [-l] [-d serialdev|-p] [-b baud] [-f] [-L log] [-k skt]\n"
-    "                      [-n hlines]\n"
-    "sympathy -c      [-H] -k skt\n" "sympathy -r id   [-H]\n" "\n" client ();
-#endif
+  return 0;
 }
index f86fa20906148e97e56880e83e0515dfa39e872d..0ef2667e76a12aec27af5143d9773da040e0be32 100644 (file)
@@ -10,6 +10,9 @@ static char rcsid[] = "$Id$";
 
 /*
  * $Log$
+ * Revision 1.4  2008/02/20 17:18:33  james
+ * *** empty log message ***
+ *
  * Revision 1.3  2008/02/20 02:11:35  james
  * *** empty log message ***
  *
@@ -27,13 +30,14 @@ usage (void)
 {
 
   fprintf (stderr, "Usage:\n"
-           "sympathy -t      [-l] [-d serialdev|-p] [-b baud] [-f] [-L log]\n"
-           "sympathy -s      [-l] [-d serialdev|-p] [-b baud] [-f] [-L log] [-F] [-k skt]\n"
+           "sympathy -t      [-K] [-d serialdev|-p] [-b baud] [-f] [-L log]\n"
+           "sympathy -s      [-K] [-d serialdev|-p] [-b baud] [-f] [-L log] [-F] [-k skt]\n"
           "                      [-n hlines]\n"
-           "sympathy [-s -c] [-l] [-d serialdev|-p] [-b baud] [-f] [-L log] [-k skt]\n"
+           "sympathy [-s -c] [-K] [-d serialdev|-p] [-b baud] [-f] [-L log] [-k skt]\n"
           "                      [-n hlines]\n"
            "sympathy -c      [-H] -k skt\n"
            "sympathy -r id   [-H]\n"
+           "sympathy {-l|-ls}\n"
            "sympathy -h\n"
            "\n"
            "Main mode:\n"
@@ -47,9 +51,10 @@ usage (void)
            "   -c     client mode: connect to server mode process\n"
            "   -r id  client mode: connect to server mode process on socket\n"
            "             ~/.sympathy/id\n"
+           "   -l or -ls  list active sockets in ~/.sympathy\n"
            "\n"
            "Options:\n"
-           "   -l  lock the serial device. By default sympathy checks that no\n"
+           "   -K  lock the serial device. By default sympathy checks that no\n"
            "          other process has create a lock file, and temporarily ceases\n"
            "          to access the serial port if it spots one. With this option\n"
            "          sympathy creates a lock file and prevents other programs\n"