X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=apps%2Fsympathy.c;h=5e52062442c4be7864ed8bac9b9400dccd464e47;hb=cdf3dc2606c558700fcb7432ba8d0b2c9d47a364;hp=a8dba28e16512e46bbe93e69b680bc8d95a6a852;hpb=8a3aac5f5287422699c9c7c5ee8969561da7317f;p=sympathy.git diff --git a/apps/sympathy.c b/apps/sympathy.c index a8dba28..5e52062 100644 --- a/apps/sympathy.c +++ b/apps/sympathy.c @@ -11,6 +11,36 @@ static char rcsid[] = /* * $Log$ + * Revision 1.26 2008/02/29 14:55:09 james + * *** empty log message *** + * + * Revision 1.25 2008/02/28 22:43:25 james + * *** empty log message *** + * + * Revision 1.24 2008/02/28 22:00:42 james + * *** empty log message *** + * + * Revision 1.23 2008/02/28 16:57:51 james + * *** empty log message *** + * + * Revision 1.22 2008/02/28 01:47:44 james + * *** empty log message *** + * + * Revision 1.21 2008/02/27 16:01:24 james + * *** empty log message *** + * + * Revision 1.20 2008/02/27 10:00:34 james + * *** empty log message *** + * + * Revision 1.19 2008/02/27 09:47:05 james + * *** empty log message *** + * + * Revision 1.18 2008/02/27 09:42:53 james + * *** empty log message *** + * + * Revision 1.17 2008/02/27 09:42:21 james + * *** empty log message *** + * * Revision 1.16 2008/02/27 01:31:38 james * *** empty log message *** * @@ -71,6 +101,7 @@ static char rcsid[] = #include #include #include +#include #include "mainloop.h" @@ -245,7 +276,10 @@ main (int argc, char *argv[]) int c; extern char *optarg; extern int optind, opterr, optopt; - int width = VT102_COLS_80; + CRT_Pos size = { VT102_COLS_80, VT102_ROWS_24 }; + + int csnok_pipe[2] = { 0 }; + int csnok = 0; int oflags[128]; char *oargs[128]; @@ -256,13 +290,13 @@ main (int argc, char *argv[]) Log *log = NULL; int history = 200; - + int pid; get_hostname (); memset (oflags, 0, sizeof (oflags)); memset (oargs, 0, sizeof (oargs)); - while ((c = getopt (argc, argv, "w:utscr:lKHd:pb:fL:Fk:n:")) != EOF) + while ((c = getopt (argc, argv, "vw:utscr:lKHd:pb:fL:Fk:n:")) != EOF) { switch (c) { @@ -295,26 +329,33 @@ main (int argc, char *argv[]) oflags['s'] = 0; - if (!oflags['s'] && !oflags['c'] && !oflags['t'] && !oflags['r'] - && !oflags['l']) - { - /*If no mode is specified behave like screen */ - oflags['s']++; - oflags['c']++; - } - - { int sum = 0; sum += oflags['t']; sum += (oflags['s'] || oflags['c']) ? 1 : 0; sum += oflags['r']; sum += oflags['l']; + sum += oflags['v']; + + if (!sum) + { + /*If no mode is specified behave like screen */ + oflags['s']++; + oflags['c']++; + sum++; + } if (sum != 1) - fatal_moan ("specifiy exactly one of ( -c and or -s ), -t, -r and -l"); + fatal_moan + ("specifiy exactly one of ( -c and or -s ), -t, -r, -l and -v"); } + if (oflags['v']) + { + fprintf (stderr, "Version: %s\n", libsympathy_version ()); + fprintf (stderr, "Version: %s\n", rcsid); + return 0; + } if (oflags['l']) return list_sockets (); @@ -337,12 +378,19 @@ main (int argc, char *argv[]) /*Fold -r into -c */ if (oflags['r']) { - int id = safe_atoi (oargs['r']); + char *id = oargs['r']; if (id < 0) fatal_moan ("cannot parse -r %s as an integer", oargs['r']); oflags['k']++; - oargs['k'] = mome ("/.sympathy/%s%d", hostname, id); + if (safe_atoi (id) > 0) + { + oargs['k'] = mome ("/.sympathy/%s%d", hostname, safe_atoi (id)); + } + else + { + oargs['k'] = mome ("/.sympathy/%s", id); + } oflags['r'] = 0; oflags['c']++; } @@ -350,43 +398,35 @@ main (int argc, char *argv[]) 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/%s%d", hostname, 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']); - } + /*implement server and client: this process forks. The parent */ + /*becomes the client and the child forks again to become the */ + /*server. If there's no -k argument the client (parent) needs */ + /*to find out the pid of the server, we use a pipe */ if (oflags['s'] && oflags['c']) { - switch (fork ()) + if (!oflags['k']) + { + csnok++; + pipe (csnok_pipe); + } + + switch (pid = fork ()) { case 0: /*child becomes the server */ oflags['c'] = 0; oflags['H'] = 0; + + if (csnok) + close (csnok_pipe[0]); break; case -1: fatal_moan ("fork failed"); - default: + default: /*parent becomes client*/ oflags['s'] = 0; oflags['K'] = 0; oflags['d'] = 0; @@ -396,10 +436,26 @@ main (int argc, char *argv[]) oflags['L'] = 0; oflags['n'] = 0; oflags['w'] = 0; - if (server_socket) + + /*Collect the child*/ + waitpid (pid, NULL, 0); + + /*if there was no k argument we need to find the*/ + /*pid of the server process so that we can work out*/ + /*what the socket is called. The server tells us on*/ + /*a pipe*/ + + if (csnok) { - socket_free_parent (server_socket); - server_socket = NULL; + close (csnok_pipe[1]); + + if (read (csnok_pipe[0], &pid, sizeof (pid)) != sizeof (pid)) + fatal_moan ("Failed to receive pid of server process"); + + close (csnok_pipe[0]); + + oargs['k'] = mome ("/.sympathy/%s%d", hostname, pid); + oflags['k']++; } } } @@ -420,17 +476,65 @@ main (int argc, char *argv[]) if (oflags['w']) { - width = safe_atoi (oargs['w']); - if ((width > VT102_MAX_COLS) || (width < 1)) + char buf[128], *ptr; + strcpy (buf, oargs['w']); + ptr = index (buf, 'x'); + if (ptr) + { + *ptr = 0; + ptr++; + size.y = safe_atoi (ptr); + } + size.x = safe_atoi (buf); + + if ((size.x > VT102_MAX_COLS) || (size.x < 1)) fatal_moan ("-w requires a width between 1 and %d\n", VT102_MAX_COLS); + + if ((size.y > VT102_MAX_ROWS) || (size.y < 1)) + fatal_moan ("-w requires a height between 1 and %d\n", + VT102_MAX_ROWS); + } if (oflags['s'] && !oflags['F']) { - daemon (1, 0); /*incase socket is relative path, unlink then will fail */ + /*nochdir incase socket is relative path, unlink then will fail */ + daemon (1, 0); + } + if (oflags['s'] ) + { + char *path; + path = mome ("/.sympathy"); + mkdir (path, 0700); + free (path); + + + if (!oflags['k']) { + pid = getpid (); + + oargs['k'] = mome ("/.sympathy/%s%d", hostname, pid); + oflags['k']++; + } + + server_socket = socket_listen (oargs['k']); + + /*Tell our parent's parent what our pid is */ + if (csnok) + { + pid = getpid (); + + write (csnok_pipe[1], &pid, sizeof (pid)); + close (csnok_pipe[1]); + } + + if (!server_socket) + fatal_moan ("failed to create socket %s for listening", oargs['k']); + + } + if (oflags['s'] || oflags['t']) { @@ -443,12 +547,38 @@ main (int argc, char *argv[]) if (oflags['p']) { - tty = ptty_open (NULL, NULL, width); + tty = ptty_open (NULL, NULL, &size); if (!tty) fatal_moan ("unable to open a ptty"); } else { + /*HACK-- check that console=device does not occur in */ + /*/proc/cmdline */ + if (!oargs['d']) + fatal_moan ("no argument to -d"); + + { + char kernel_cmdline[4096] = { 0 }; + char search_string[1024] = "console="; + char *ptr = oargs['d']; + int fd; + + if (!strncmp ("/dev/", ptr, 5)) + ptr += 5; + + strcat (search_string, ptr); + + fd = open ("/proc/cmdline", O_RDONLY); + read (fd, kernel_cmdline, sizeof (kernel_cmdline)); + close (fd); + + kernel_cmdline[sizeof (kernel_cmdline) - 1] = 0; + + if (strstr (kernel_cmdline, search_string)) + fatal_moan ("/proc/cmdline contains %s", search_string); + } + tty = serial_open (oargs['d'], oflags['K'] ? SERIAL_LOCK_ACTIVE : @@ -500,7 +630,7 @@ main (int argc, char *argv[]) } } - mainloop (tty, server_socket, client_socket, ansi, log, history, width); + mainloop (tty, server_socket, client_socket, ansi, log, history, &size); if (ansi) {