diff options
author | kraxel <kraxel> | 2005-12-12 12:36:17 +0000 |
---|---|---|
committer | kraxel <kraxel> | 2005-12-12 12:36:17 +0000 |
commit | 773bcf34b9ec8720822d36d07516fb861bc695f5 (patch) | |
tree | b6004f9f7ee13f1323c93ac0759669b948126e1a /xd_view.c | |
parent | 7e6f3f2478ddb5194dc842a016658319dad1099d (diff) | |
download | xenwatch-773bcf34b9ec8720822d36d07516fb861bc695f5.tar.gz |
- console handling.
Diffstat (limited to 'xd_view.c')
-rw-r--r-- | xd_view.c | 315 |
1 files changed, 210 insertions, 105 deletions
@@ -25,6 +25,47 @@ static GtkWidget *status; static XenDoms *store; static GtkWidget *view; +static int have_screen; +static int have_xenconsole; +static int have_krdc; +static int have_vncviewer; + +static int debug = 0; + +/* ------------------------------------------------------------------ */ + +static char *gtk_msg_type_name[] = { + [ GTK_MESSAGE_INFO ] = "INFO", + [ GTK_MESSAGE_WARNING ] = "WARNING", + [ GTK_MESSAGE_QUESTION ] = "QUESTION", + [ GTK_MESSAGE_ERROR ] = "ERROR", +}; + +static int __attribute__ ((format (printf, 2, 0))) +gtk_message(GtkMessageType type, char *fmt, ...) +{ + va_list args; + GtkWidget *dialog; + char msgbuf[1024]; + int rc; + + va_start(args, fmt); + rc = vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); + va_end(args); + + if (debug) + fprintf(stderr, "%s: %s", gtk_msg_type_name[type], msgbuf); + dialog = gtk_message_dialog_new(GTK_WINDOW(xd_toplevel), + GTK_DIALOG_DESTROY_WITH_PARENT, + type, GTK_BUTTONS_CLOSE, + "%s", msgbuf); + g_signal_connect_swapped(dialog, "response", + G_CALLBACK (gtk_widget_destroy), + dialog); + gtk_widget_show_all(dialog); + return rc; +} + /* ------------------------------------------------------------------ */ static gboolean have_binary(char *name) @@ -67,14 +108,16 @@ static gboolean have_binary(char *name) return false; } -static int run_and_wait(const char *app, ...) +static int run_application(int do_wait, const char *app, ...) { - static int debug = 0; va_list args; char *argv[64]; int status, rc, i; pid_t pid; + while (waitpid(-1, &status, WNOHANG) > 0) + /* collect zombies */; + if (debug) fprintf(stderr,"%s: %s |", __FUNCTION__, app); va_start(args, app); @@ -101,7 +144,10 @@ static int run_and_wait(const char *app, ...) app, strerror(errno)); exit(1); } - + + if (!do_wait) + return 0; + rc = waitpid(pid, &status, 0); if (rc != pid) { /* Huh? */ @@ -114,103 +160,127 @@ static int run_and_wait(const char *app, ...) return WEXITSTATUS(status); } -static void open_screen(gint id, char *name, char *tty) +static int attach_to_screen(gint id, char *name, char *tty) { int rc; /* try attaching to a running screen ... */ - rc = run_and_wait("screen", "screen", - "-X", "-S", "xenconsole", - "screen", "-t", name, tty, - NULL); + rc = run_application(1, "screen", "screen", + "-X", "-S", "xenconsole", + "screen", "-t", name, tty, + NULL); if (0 == rc) - return; + return 0; /* ... failing that start a new one ... */ - rc = run_and_wait("screen", "screen", - "-d", "-m", "-S", "xenconsole", "-t", name, tty, - NULL); + rc = run_application(1, "screen", "screen", + "-d", "-m", "-S", "xenconsole", "-t", name, tty, + NULL); if (0 != rc) { - fprintf(stderr, "ERROR: creating screen session failed\n"); - return; + gtk_message(GTK_MESSAGE_ERROR, "creating screen session failed\n"); + return -1; } /* ... configure ... */ - rc = run_and_wait("screen", "screen", - "-X", "-S", "xenconsole", - "hardstatus", "lastline", - " xen | %-w%{wR} %n %t* %{-}%+w", - NULL); + rc = run_application(1, "screen", "screen", + "-X", "-S", "xenconsole", + "hardstatus", "lastline", + "%{=b bw} xen | %-w%{yb} %n %t* %{-}%+w", + NULL); if (0 != rc) { - fprintf(stderr, "ERROR: configuring screen session failed\n"); - return; + gtk_message(GTK_MESSAGE_ERROR, "configuring screen session failed\n"); + return -1; } - /* ... and start xterm and attach to new screen */ - if (0 == fork()) { - execlp("xterm", "xterm", - "-name", "xenconsole", - "-title", "xen consoles via screen", - "-e", "screen", "-R", "xenconsole", - NULL); - exit(1); - } + /* new screen session created */ + return 1; +} + +static void display_screen_xterm(void) +{ + run_application(0, "xterm", "xterm", + "-name", "xenconsole", + "-title", "xen consoles via screen", + "-e", "screen", "-d", "-r", "xenconsole", + NULL); } static void open_xenconsole(gint id, char *name, char *tty) { char title[64], ids[8]; - pid_t pid; snprintf(title, sizeof(title), "xen console: %s (%d)", name, id); snprintf(ids, sizeof(ids), "%d", id); - if (0 == (pid = fork())) { - execlp("xterm", "xterm", - "-name", "xenconsole", - "-title", title, - "-e", XENCONSOLE, ids, - NULL); - exit(1); - } + + run_application(0, "xterm", "xterm", + "-name", "xenconsole", + "-title", title, + "-e", XENCONSOLE, ids, + NULL); } -static void open_tty(gint id, char *name, char *tty) +static void open_tty(gint id, char *name, char *tty, int screen) { - static int first = 1; - static int have_screen; - static int have_xenconsole; - int rc; - /* first-time init */ - if (first) { - fprintf(stderr, "first\n"); - first = 0; - have_screen = have_binary("screen"); - have_xenconsole = have_binary(XENCONSOLE); - } - /* sanity checks */ if (0 != access(tty, R_OK)) { - fprintf(stderr,"ERROR: no access to tty %s\n", tty); + gtk_message(GTK_MESSAGE_ERROR, "no access to tty %s\n", tty); return; } - rc = run_and_wait("fuser", "fuser", "-s", tty, NULL); + rc = run_application(1, "fuser", "fuser", "-s", tty, NULL); if (0 == rc) { - fprintf(stderr,"ERROR: tty %s already in use\n", tty); + gtk_message(GTK_MESSAGE_ERROR, "tty %s already in use\n", tty); return; } /* open terminal */ - if (have_screen) { - open_screen(id, name, tty); - return; + if (screen) { + if (have_screen) { + if (1 == attach_to_screen(id, name, tty)) + display_screen_xterm(); + } else { + gtk_message(GTK_MESSAGE_ERROR, "need screen, please install\n"); + } + } else { + if (have_xenconsole) { + open_xenconsole(id, name, tty); + } else { + gtk_message(GTK_MESSAGE_ERROR, "need xen-tools, please install\n"); + } } - if (have_xenconsole) { - open_xenconsole(id, name, tty); +} + +static void open_vnc(gint id, char *name, char *ostype) +{ + char *app = NULL; + char display[32]; + + if (have_vncviewer) { + app = "vncviewer"; + } else if (have_krdc) { + app = "krdc"; + } else { + gtk_message(GTK_MESSAGE_ERROR, "need vncviewer or krdc, please install\n"); return; } + + if (0 == strcmp(ostype, "vmx")) { + /* works for vmx ... */ + snprintf(display, sizeof(display), "localhost:%d", id); + run_application(0, app, app, display, NULL); + } else { + gtk_message(GTK_MESSAGE_ERROR, "VNC works for vmx domains only.\n"); + } +} + +static void detect_apps(void) +{ + have_screen = have_binary("screen"); + have_xenconsole = have_binary(XENCONSOLE); + have_krdc = have_binary("krdc"); + have_vncviewer = have_binary("vncviewer"); } /* ------------------------------------------------------------------ */ @@ -227,45 +297,69 @@ static void menu_cb_xenstore(void) gtk_widget_show_all(xs_toplevel); } -static void menu_cb_open_tty(void) +static gboolean get_domain(gint *id, char **name, char **tty, char **os) { GtkTreeSelection *sel; GtkTreeModel *model; GtkTreeIter iter; - char *name, *tty; - gint id = -1; sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); - if (!gtk_tree_selection_get_selected(sel, &model, &iter)) - return; + if (!gtk_tree_selection_get_selected(sel, &model, &iter)) { + gtk_message(GTK_MESSAGE_ERROR, "No domain selected\n"); + return false; + } gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, - XEN_DOMS_COL_I_ID, &id, - XEN_DOMS_COL_S_NAME, &name, - XEN_DOMS_COL_S_TERMINAL, &tty, + XEN_DOMS_COL_I_ID, id, + XEN_DOMS_COL_S_NAME, name, + XEN_DOMS_COL_S_TERMINAL, tty, + XEN_DOMS_COL_S_OSTYPE, os, -1); - - fprintf(stderr, "%s: %d\n", __FUNCTION__, id); - open_tty(id, name, tty); + if (0 == *id) { + gtk_message(GTK_MESSAGE_ERROR, "You can't do that for Domain-0\n"); + return false; + } + return true; } static void menu_cb_open_vnc(void) { - GtkTreeSelection *sel; - GtkTreeModel *model; - GtkTreeIter iter; - char *name, *tty; + char *name, *tty, *ostype; gint id = -1; - sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); - if (!gtk_tree_selection_get_selected(sel, &model, &iter)) + if (!get_domain(&id, &name, &tty, &ostype)) return; - gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, - XEN_DOMS_COL_I_ID, &id, - XEN_DOMS_COL_S_NAME, &name, - XEN_DOMS_COL_S_TERMINAL, &tty, - -1); + if (debug) + fprintf(stderr, "%s: %d\n", __FUNCTION__, id); + open_vnc(id, name, ostype); +} + +static void menu_cb_open_console(void) +{ + char *name, *tty, *ostype; + gint id = -1; - fprintf(stderr, "%s: %d\n", __FUNCTION__, id); + if (!get_domain(&id, &name, &tty, &ostype)) + return; + if (debug) + fprintf(stderr, "%s: %d\n", __FUNCTION__, id); + open_tty(id, name, tty, 0); +} + +static void menu_cb_attach_screen(void) +{ + char *name, *tty, *ostype; + gint id = -1; + + if (!get_domain(&id, &name, &tty, &ostype)) + return; + if (debug) + fprintf(stderr, "%s: %d\n", __FUNCTION__, id); + open_tty(id, name, tty, 1); +} + +static void menu_cb_display_screen(void) +{ + display_screen_xterm(); } static void menu_cb_about(void) @@ -295,9 +389,21 @@ static void destroy(void) static const GtkActionEntry entries[] = { { + /* menus */ .name = "FileMenu", .label = "_File", },{ + .name = "ViewMenu", + .label = "_View", + },{ + .name = "ActionMenu", + .label = "_Action", + },{ + .name = "HelpMenu", + .label = "_Help", + },{ + + /* menu items */ .name = "Quit", .stock_id = GTK_STOCK_QUIT, .label = "_Quit", @@ -305,32 +411,29 @@ static const GtkActionEntry entries[] = { .tooltip = "Quit the job", .callback = menu_cb_quit, },{ - - .name = "ViewMenu", - .label = "_View", - },{ .name = "Xenstore", .label = "_Xenstore browser", .accelerator = "<control>X", .callback = menu_cb_xenstore, },{ - - .name = "ActionMenu", - .label = "_Action", - },{ - .name = "OpenTTY", - .label = "_Terminal", - .accelerator = "<control>T", - .callback = menu_cb_open_tty, - },{ .name = "OpenVNC", - .label = "_VNC", + .label = "Open _VNC", .accelerator = "<control>V", .callback = menu_cb_open_vnc, },{ - - .name = "HelpMenu", - .label = "_Help", + .name = "OpenConsole", + .label = "Open _Console", + .accelerator = "<control>C", + .callback = menu_cb_open_console, + },{ + .name = "AttachScreen", + .label = "Attach to _screen", + .accelerator = "<control>S", + .callback = menu_cb_attach_screen, + },{ + .name = "DisplayScreen", + .label = "_Display screen", + .callback = menu_cb_display_screen, },{ .name = "About", .label = "_About ...", @@ -348,17 +451,16 @@ static char ui_xml[] = " <menuitem action='Xenstore'/>" " </menu>" " <menu action='ActionMenu'>" -" <menuitem action='OpenTTY'/>" " <menuitem action='OpenVNC'/>" +" <menuitem action='OpenConsole'/>" +" <menuitem action='AttachScreen'/>" +" <menuitem action='DisplayScreen'/>" " </menu>" " <menu action='HelpMenu'>" " <menuitem action='About'/>" " </menu>" " </menubar>" " <toolbar action='ToolBar'>" -" <toolitem action='OpenTTY'/>" -" <toolitem action='OpenVNC'/>" -" <separator/>" " <toolitem action='Quit'/>" " </toolbar>" "</ui>"; @@ -378,7 +480,9 @@ static void activate(GtkTreeView *treeview, gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, XEN_DOMS_COL_I_ID, &id, -1); - fprintf(stderr, "%s: %d\n", __FUNCTION__, id); + if (debug) + fprintf(stderr, "%s: %d\n", __FUNCTION__, id); + /* TODO: something useful ;) */ } static GtkWidget *xen_doms_create_view(XenDoms *store) @@ -521,5 +625,6 @@ void xen_doms_create_window(void) gtk_container_add(GTK_CONTAINER(scroll), view); gtk_box_pack_end(GTK_BOX(vbox), status, FALSE, TRUE, 0); + detect_apps(); return; } |