diff options
Diffstat (limited to 'apps/sympathy.c')
-rw-r--r-- | apps/sympathy.c | 300 |
1 files changed, 266 insertions, 34 deletions
diff --git a/apps/sympathy.c b/apps/sympathy.c index e90b8d2..964d84c 100644 --- a/apps/sympathy.c +++ b/apps/sympathy.c @@ -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; } |