aboutsummaryrefslogtreecommitdiffstats
path: root/xd_view.c
diff options
context:
space:
mode:
authorkraxel <kraxel>2005-12-12 12:36:17 +0000
committerkraxel <kraxel>2005-12-12 12:36:17 +0000
commit773bcf34b9ec8720822d36d07516fb861bc695f5 (patch)
treeb6004f9f7ee13f1323c93ac0759669b948126e1a /xd_view.c
parent7e6f3f2478ddb5194dc842a016658319dad1099d (diff)
downloadxenwatch-773bcf34b9ec8720822d36d07516fb861bc695f5.tar.gz
- console handling.
Diffstat (limited to 'xd_view.c')
-rw-r--r--xd_view.c315
1 files changed, 210 insertions, 105 deletions
diff --git a/xd_view.c b/xd_view.c
index 6611d07..77bab72 100644
--- a/xd_view.c
+++ b/xd_view.c
@@ -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;
}