diff options
author | kraxel <kraxel> | 2006-07-04 08:40:34 +0000 |
---|---|---|
committer | kraxel <kraxel> | 2006-07-04 08:40:34 +0000 |
commit | 95dea4f9392a676d9149c141cd96b62d23ae50bf (patch) | |
tree | 8fdabe3e621882aefcd5f46d0d7e825a93632d93 /xenscreen.c | |
parent | a93557e0070da8486852907cd17dc25b956beef6 (diff) | |
download | xenwatch-95dea4f9392a676d9149c141cd96b62d23ae50bf.tar.gz |
cmd line options, ...
Diffstat (limited to 'xenscreen.c')
-rw-r--r-- | xenscreen.c | 250 |
1 files changed, 189 insertions, 61 deletions
diff --git a/xenscreen.c b/xenscreen.c index dab818d..76e7893 100644 --- a/xenscreen.c +++ b/xenscreen.c @@ -1,5 +1,6 @@ #include <stdio.h> #include <stdlib.h> +#include <stdarg.h> #include <string.h> #include <unistd.h> #include <signal.h> @@ -27,9 +28,38 @@ struct dom { static LIST_HEAD(doms); static int domcnt; -static char *screenrc = "/etc/xen/xenscreenrc"; +static char *screen_rc = "/etc/xen/xenscreenrc"; +static char *screen_unlink = NULL; static char *screen_session = "xencon"; -static char *screen_title = "watch"; +static char *screen_title = "mon"; +static char *screen_window = NULL; +static int screen_detached; +static int screen_logging; + +static char builtin_screen_rc[] = +"multiuser on\n" +"\n" +"# status line\n" +"sorendition =s wb\n" +"hardstatus lastline \"%{=b bw} xen |%{-} %-w%{= yb} %50>%n* %t %{-}%+w%<\"\n" +"\n" +"# logging\n" +"logfile /var/log/xenscreen.%t\n" +"logtstamp on\n" +"\n" +"# disable killing windows\n" +"bind k\n" +"bind K\n" +"bind ^K\n" +"\n" +"# misc other useful settings\n" +"shell /bin/bash\n" +"defscrollback 5000\n" +"compacthist on\n" +"defutf8 on\n" +"termcapinfo xterm hs@\n" +"\n" +; /* ------------------------------------------------------------- */ @@ -69,6 +99,32 @@ static void catchsig(int sig) termsig = sig; } +/* ------------------------------------------------------------- */ + +static int screen_command(char *arg0, ...) +{ + va_list args; + char *argv[64]; + int i = 0; + + argv[i++] = "screen"; + argv[i++] = "-X"; + argv[i++] = "-S"; + argv[i++] = screen_session; + + argv[i++] = arg0; + va_start(args, arg0); + while (i < array_size(argv)) { + argv[i] = va_arg(args, char*); + if (NULL == argv[i]) + break; + i++; + } + va_end(args); + + return run_application_va(1, "screen", argv); +} + static void try_attach_screen(struct dom *dom, int boot) { int rc; @@ -95,10 +151,13 @@ static void try_attach_screen(struct dom *dom, int boot) return; } - rc = run_application(1, "screen", "screen", - "-X", "-S", screen_session, - "screen", "-L", "-t", dom->name, dom->tty, - NULL); + if (screen_logging) + rc = screen_command("screen", "-L", "-t", dom->name, dom->tty, + NULL); + else + rc = screen_command("screen", "-t", dom->name, dom->tty, + NULL); + #if 0 /* * Hmm, not exactly the most elegant way to do this, has @@ -109,10 +168,7 @@ static void try_attach_screen(struct dom *dom, int boot) * seems screen can't do that though :-( */ if (!boot) - rc = run_application(1, "screen", "screen", - "-X", "-S", screen_session, - "other", - NULL); + rc = screen_command("other", NULL); #endif dom->connected = 1; @@ -133,34 +189,45 @@ static void try_release_domain(struct dom *dom) static void builtin_screen_setup(void) { - static char *config[] = { - "sorendition =s wb", - "hardstatus lastline \"%{=b bw} xen |%{-} %-w%{= yb} %50>%n* %t %{-}%+w%<\"", - "logfile /var/log/xenscreen.%t", - NULL /* EOF */, - }; - char cmdline[256]; - int line,try,rc; - -#if 1 - /* FIXME: Hmm, doesn't work reliable without that one ... */ - sleep(1); -#endif + char *rc = strdup("/tmp/xenscreen-XXXXXX"); + int fd; - for (line = 0; config[line] != NULL; line++) { - for (try = 0; try < 5; try++) { - snprintf(cmdline, sizeof(cmdline), "screen -X -S %s %s", - screen_session, config[line]); - rc = run_cmdline(1,cmdline); - if (0 == rc) - break; - sleep(1); - } + fd = mkstemp(rc); + if (-1 == fd) { + fprintf(stderr,"mkstmp(%s): %s\n", rc, strerror(errno)); + return; } + write(fd, builtin_screen_rc, sizeof(builtin_screen_rc)); + close(fd); + + fprintf(stderr, "Config file \"%s\" doesn't exist, using builtin config (%s).\n", + screen_rc, rc); + screen_rc = rc; + screen_unlink = rc; + return; } /* ------------------------------------------------------------- */ +static void usage(FILE *fp) +{ + fprintf(fp, + "I'm managing xen consoles using screen.\n" + "\n" + "usage: xenscreen [options]\n" + "options:\n" + " -h print this text\n" + " -b print builtin screen config file\n" + " -L enable console output logging\n" + " -c screenrc screen config file [%s]\n" + " -S session screen session name [%s]\n" + " -p window preselect screen window\n" + "\n" + "-- \n" + "(c) 2006 Gerd Hoffmann <kraxel@suse.de>\n", + screen_rc, screen_session); +} + int main(int argc, char *argv[]) { struct sigaction act,old; @@ -168,40 +235,99 @@ int main(int argc, char *argv[]) struct xs_handle *xenstore = NULL; xs_transaction_t xst; char **vec = NULL; - int domid; + int domid, nac, c; char path[BUFSIZE], value[BUFSIZE]; unsigned int count, i, rc; struct dom *dom; time_t last_ctrl_c = 0; + char **nav; + + for (;;) { + if (-1 == (c = getopt(argc, argv, "hdbLc:S:u:p:"))) + break; + switch (c) { + case 'c': + screen_rc = optarg; + break; + case 'S': + screen_session = optarg; + break; + case 'u': + screen_unlink = optarg; + break; + case 'p': + screen_window = optarg; + break; + case 'L': + screen_logging = 1; + break; + case 'd': + screen_detached = 1; + break; + case 'b': + printf("%s", builtin_screen_rc); + exit(0); + case 'h': + usage(stdout); + exit(0); + default: + usage(stderr); + exit(1); + } + } if (!have_application("screen")) { - fprintf(stderr, "screen not installed, exiting\n"); + fprintf(stderr, "screen not found in $PATH (not installed?), exiting.\n"); exit(1); } if (NULL == getenv("STY") || NULL == strstr(getenv("STY"),screen_session)) { - /* not running inside screen, try to attach */ - rc = run_application(1, "screen", "screen", - "-S", screen_session, - "-r", "-p", "=", - NULL); - if (0 == rc) - exit(0); + /* not running inside screen */ + if (!screen_detached) { + /* try to attach */ + rc = run_application(1, "screen", "screen", + "-S", screen_session, + "-r", "-p", "=", + NULL); + if (0 == rc) + exit(0); + } else { + /* This is a nop: just check if screen is running */ + rc = screen_command("select", ".", NULL); + if (0 == rc) { + fprintf(stderr,"Screen session \"%s\" already active, exiting.\n", + screen_session); + exit(0); + } + } /* failing that, start a new screen session */ - if (0 != access(screenrc, R_OK)) - screenrc = "/dev/null"; - execlp("screen", "screen", - "-S", screen_session, - "-c", screenrc, - "-t", screen_title, argv[0], - NULL); - perror("execlp(screen)"); + fprintf(stderr,"Starting new screen session \"%s\".\n", screen_session); + if (0 != access(screen_rc, R_OK)) + builtin_screen_setup(); + nav = malloc(sizeof(char*) * (argc + 16)); + nac = 0; + nav[nac++] = "screen"; + if (screen_detached) { + nav[nac++] = "-d"; + nav[nac++] = "-m"; + } + nav[nac++] = "-S"; + nav[nac++] = screen_session; + nav[nac++] = "-c"; + nav[nac++] = screen_rc; + nav[nac++] = "-t"; + nav[nac++] = screen_title; + for (i = 0; argv[i] != NULL;) + nav[nac++] = argv[i++]; + if (screen_unlink) { + nav[nac++] = "-u"; + nav[nac++] = screen_unlink; + } + nav[nac++] = NULL; + execvp(nav[0], nav); + perror("execvp(screen)"); exit(1); - - } else if (0 != access(screenrc, R_OK)) { - /* no screenrc: do mini setup */ - builtin_screen_setup(); } /* setup signal handler */ @@ -244,14 +370,13 @@ int main(int argc, char *argv[]) xenstore_read(xenstore, path, dom->tty, sizeof(dom->tty)); try_attach_screen(dom, 1); } - rc = run_application(1, "screen", "screen", - "-X", "-S", screen_session, - "select", "0", - NULL); - rc = run_application(1, "screen", "screen", - "-X", "-S", screen_session, - "windowlist", "-b", - NULL); + + if (screen_window) + rc = screen_command("select", screen_window, NULL); + if (!screen_window || 0 != rc) { + rc = screen_command("select", "0", NULL); + rc = screen_command("windowlist", "-b", NULL); + } /* main loop */ fprintf(stderr,"ok, watching out for changes now\n"); @@ -332,5 +457,8 @@ int main(int argc, char *argv[]) try_attach_screen(dom, 0); try_release_domain(dom); } + + if (screen_unlink) + unlink(screen_unlink); return 0; } |