X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=apps%2Fsympathy.c;h=41d0bbb6961841d740a9e7f8cf52c37715ac141a;hb=ef427cbe3bc216800179b66b889b71fec843387c;hp=b24e6d001ad9c5b27312cfcaa27670f35bde5707;hpb=5cded6a34ead3205baf1a45ed5adbee24ebec685;p=sympathy.git diff --git a/apps/sympathy.c b/apps/sympathy.c index b24e6d0..41d0bbb 100644 --- a/apps/sympathy.c +++ b/apps/sympathy.c @@ -11,6 +11,51 @@ static char rcsid[] = /* * $Log$ + * Revision 1.27 2008/03/02 09:55:37 james + * *** empty log message *** + * + * 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 *** + * + * Revision 1.15 2008/02/27 01:31:14 james + * *** empty log message *** + * + * Revision 1.14 2008/02/24 00:43:55 james + * *** empty log message *** + * + * Revision 1.13 2008/02/24 00:42:53 james + * *** empty log message *** + * * Revision 1.12 2008/02/23 11:48:52 james * *** empty log message *** * @@ -59,13 +104,16 @@ static char rcsid[] = #include #include #include +#include #include "mainloop.h" extern void usage (void); - static char hostname[1024]; +char *socket_dirs[] = + { ".sympathy", "sympathy", "/etc/sympathy", "/var/sympathy", NULL }; + int safe_atoi (char *a) { @@ -128,6 +176,9 @@ mome (char *fmt, ...) strcpy (buf, home); strcat (buf, "/"); + if (!fmt) + return buf; + while (1) { @@ -151,15 +202,32 @@ mome (char *fmt, ...) } } +char * +gloo_paths (char *dir, char *leaf) +{ + int i; + char *ret, *ptr; + ret = ptr = malloc (strlen (dir) + strlen (leaf) + 2); + + while (*dir) + *(ptr++) = *(dir++); + *(ptr++) = '/'; + while (*leaf) + *(ptr++) = *(leaf++); + *ptr = 0; + + return ret; +} + + int -list_sockets (void) +list_sockets_in_dir (char *sockdir) { struct dirent *ent; struct stat buf; char *sn = NULL; Socket *s; - char *sockdir = mome ("/.sympathy/"); DIR *dir = opendir (sockdir); @@ -174,7 +242,7 @@ list_sockets (void) while ((ent = readdir (dir))) { - sn = mome (".sympathy/%s", ent->d_name); + sn = gloo_paths (sockdir, ent->d_name); if (stat (sn, &buf) || (!S_ISSOCK (buf.st_mode))) { free (sn); @@ -185,18 +253,18 @@ list_sockets (void) if (s) { - printf ("\t%s (Active)\n", ent->d_name); + printf ("\t%s (Active)\n", sn); socket_free (s); } else { if (strncmp (ent->d_name, hostname, hostname_len)) { - printf ("\t%s (Unknown - not this host)\n", ent->d_name); + printf ("\t%s (Unknown - not this host)\n", sn); } else { - printf ("\t%s (Dead, wiped)\n", ent->d_name); + printf ("\t%s (Dead, wiped)\n", sn); unlink (sn); } } @@ -209,6 +277,27 @@ list_sockets (void) return 0; } +int +list_sockets (void) +{ + char **ptr, *h; + + + for (ptr = socket_dirs; *ptr; ptr++) + { + h = mome (*ptr); + + if (h) + { + list_sockets_in_dir (h); + free (h); + } + + } + + return 0; +} + void get_hostname (void) @@ -233,6 +322,10 @@ main (int argc, char *argv[]) int c; extern char *optarg; extern int optind, opterr, optopt; + CRT_Pos size = { VT102_COLS_80, VT102_ROWS_24 }; + + int csnok_pipe[2] = { 0 }; + int csnok = 0; int oflags[128]; char *oargs[128]; @@ -243,22 +336,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)); -#if 0 - "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] [-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" -#endif - while ((c = getopt (argc, argv, "tscr:lKHd:pb:fL:Fk:n:")) != EOF) + while ((c = getopt (argc, argv, "vw:utscr:lKHd:pb:fL:Fk:n:")) != EOF) { switch (c) { @@ -291,26 +375,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 (); @@ -330,59 +421,42 @@ main (int argc, char *argv[]) fatal_moan ("agrument to -n must be greater than zero"); } - /*Fold -r into -c */ + /*Fold -r implies -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/%s%d", hostname, id); - oflags['r'] = 0; - oflags['c']++; - } + oflags['c']++; 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; @@ -391,16 +465,34 @@ main (int argc, char *argv[]) oflags['f'] = 0; oflags['L'] = 0; oflags['n'] = 0; - if (server_socket) + oflags['w'] = 0; + + /*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']++; } } } - if (oflags['c'] && !oflags['k']) - fatal_moan ("-c requires a socket to be specified with -s or -k"); + + if (oflags['c'] && !oflags['k'] && !oflags['r']) + fatal_moan ("-c requires a socket to be specified with -s or -k or -r"); if ((oflags['p'] || oflags['d'] || oflags['K'] || oflags['b'] || oflags['f'] || oflags['L']) && oflags['c']) @@ -412,12 +504,68 @@ main (int argc, char *argv[]) oflags['p']++; } + if (oflags['w']) + { + 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']) { @@ -430,12 +578,38 @@ main (int argc, char *argv[]) if (oflags['p']) { - tty = ptty_open (NULL, NULL); + 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 : @@ -459,6 +633,26 @@ main (int argc, char *argv[]) } + + FISH + { + char *id = oargs['r']; + if (id < 0) + fatal_moan ("cannot parse -r %s as an integer", oargs['r']); + + oflags['k']++; + if (safe_atoi (id) > 0) + { + oargs['k'] = find_socket ("%s%d", hostname, safe_atoi (id)); + } + else + { + oargs['k'] = find_socket ("%s", id); + } + oflags['r'] = 0; + oflags['c']++; + } + if (oflags['c']) { @@ -480,12 +674,14 @@ main (int argc, char *argv[]) else { terminal_register_handlers (); - ansi = ansi_new_from_terminal (terminal_open (0, 1)); + ansi = + ansi_new_from_terminal (terminal_open (0, 1), + oflags['u'] ? 0 : 1); ansi->reset (ansi, NULL); } } - mainloop (tty, server_socket, client_socket, ansi, log, history); + mainloop (tty, server_socket, client_socket, ansi, log, history, &size); if (ansi) {