aboutsummaryrefslogtreecommitdiffstats
path: root/xenscreen.c
diff options
context:
space:
mode:
authorkraxel <kraxel>2006-07-04 08:40:34 +0000
committerkraxel <kraxel>2006-07-04 08:40:34 +0000
commit95dea4f9392a676d9149c141cd96b62d23ae50bf (patch)
tree8fdabe3e621882aefcd5f46d0d7e825a93632d93 /xenscreen.c
parenta93557e0070da8486852907cd17dc25b956beef6 (diff)
downloadxenwatch-95dea4f9392a676d9149c141cd96b62d23ae50bf.tar.gz
cmd line options, ...
Diffstat (limited to 'xenscreen.c')
-rw-r--r--xenscreen.c250
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;
}