diff options
author | kraxel <kraxel> | 2006-04-07 15:38:39 +0000 |
---|---|---|
committer | kraxel <kraxel> | 2006-04-07 15:38:39 +0000 |
commit | 87fcf49941e76d58934b143a1b1441f263323c12 (patch) | |
tree | d67644a0f4ffda122cec12d02af6f31e2b06437a /apps.c | |
parent | b6b64172f31759d9aa2a9f40438c8ab09f0f9a98 (diff) | |
download | xenwatch-87fcf49941e76d58934b143a1b1441f263323c12.tar.gz |
mdns hacking
Diffstat (limited to 'apps.c')
-rw-r--r-- | apps.c | 261 |
1 files changed, 189 insertions, 72 deletions
@@ -13,48 +13,73 @@ #include <gtk/gtk.h> #include <xs.h> +#include "list.h" #include "apps.h" -#define array_size(x) (sizeof(x)/sizeof(*x)) +/* ------------------------------------------------------------------ */ + +enum desktop_type desktop_type = DESKTOP_OTHER; +char app_error[256]; /* ------------------------------------------------------------------ */ static int debug = 1; -int desktop_kde; -int desktop_gnome; - -int app_have_screen; -int app_have_xenconsole; -int app_have_krdc; -int app_have_vncviewer; -int app_have_kfmclient; -int app_have_firefox; -char app_error[256]; +struct have_app { + char *name; + gboolean present; + struct list_head next; +}; +static LIST_HEAD(apps); /* ------------------------------------------------------------------ */ -static gboolean have_binary(char *name) +static struct have_app *find_app_entry(char *name) { + struct list_head *item; + struct have_app *app; + + list_for_each(item, &apps) { + app = list_entry(item, struct have_app, next); + if (0 == strcmp(app->name, name)) + return app; + } + app = malloc(sizeof(*app)); + memset(app,0,sizeof(*app)); + app->name = strdup(name); + app->present = -1; + list_add_tail(&app->next, &apps); + return app; +} + +int have_application(char *name) +{ + struct have_app *app; char *path, *elem, *binary; struct stat st; int rc; + + app = find_app_entry(name); + if (-1 != app->present) + goto done; + app->present = 0; if (strchr(name,'/')) { /* path specified ... */ if (-1 == stat(name, &st)) - return false; + goto done; if (!S_ISREG(st.st_mode)) - return false; + goto done; if (!(st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) - return false; - return true; + goto done; + app->present = 1; + goto done; } /* walk $PATH */ path = getenv("PATH"); if (NULL == path) - return false; + goto done; path = strdup(path); for (elem = strtok(path, ":"); NULL != elem; elem = strtok(NULL, ":")) { binary = malloc(strlen(elem)+strlen(name)+2); @@ -67,25 +92,19 @@ static gboolean have_binary(char *name) continue; if (!(st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) continue; - free(path); - return true; + app->present = 1; + break; } free(path); - return false; -} -void detect_applications(void) -{ - app_have_screen = have_binary("screen"); - app_have_xenconsole = have_binary(XENCONSOLE); - app_have_krdc = have_binary("krdc"); - app_have_vncviewer = have_binary("vncviewer"); - app_have_kfmclient = have_binary("kfmclient"); - app_have_firefox = have_binary("firefox"); + done: + return app->present; } /* ------------------------------------------------------------------ */ +#if 0 +/* check_wm_capability(dpy, root, _NET_SUPPORTED, _NET_WM_whatever); */ static int check_wm_capability(Display *dpy, Window root, Atom list, Atom wanted) { @@ -117,6 +136,7 @@ check_wm_capability(Display *dpy, Window root, Atom list, Atom wanted) XFree(ldata); return retval; } +#endif static int check_atom_present(Display *dpy, Window root, Atom check) @@ -130,47 +150,72 @@ check_atom_present(Display *dpy, Window root, Atom check) (dpy, root, check, 0, (65536 / sizeof(long)), False, AnyPropertyType, &type, &format, &nitems, &bytesafter, &args)) return -1; + if (NULL == args) + return -1; return 0; } #define INIT_ATOM(dpy,atom) atom = XInternAtom(dpy,#atom,False) -static Atom _NET_SUPPORTED; -static Atom _NET_WM_STATE_ABOVE; static Atom KWIN_RUNNING; +static Atom _METACITY_SENTINEL; void detect_desktop(void) { Display *dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default()); Window root = DefaultRootWindow(dpy); - if (0) { - INIT_ATOM(dpy, _NET_SUPPORTED); - INIT_ATOM(dpy, _NET_WM_STATE_ABOVE); - check_wm_capability(dpy, root, _NET_SUPPORTED, _NET_WM_STATE_ABOVE); - } - INIT_ATOM(dpy, KWIN_RUNNING); - if (0 == check_atom_present(dpy, root, KWIN_RUNNING)) - desktop_kde = 1; + INIT_ATOM(dpy, _METACITY_SENTINEL); - if (desktop_kde) + if (0 == check_atom_present(dpy, root, KWIN_RUNNING)) { fprintf(stderr,"Desktop: KDE\n"); - if (desktop_gnome) - fprintf(stderr,"Desktop: gnome\n"); + desktop_type = DESKTOP_KDE; + } + if (0 == check_atom_present(dpy, root, _METACITY_SENTINEL)) { + fprintf(stderr,"Desktop: Gnome\n"); + desktop_type = DESKTOP_GNOME; + } } /* ------------------------------------------------------------------ */ -int run_application(int do_wait, const char *app, ...) +int run_application_va(int do_wait, const char *app, char **argv) { - va_list args; - char *argv[64]; - int status, rc, i; + int status, rc; pid_t pid; while (waitpid(-1, &status, WNOHANG) > 0) /* collect zombies */; + if (0 == (pid = fork())) { + /* child */ + execvp(app, argv); + fprintf(stderr,"%s: execvp(%s): %s\n", __FUNCTION__, + app, strerror(errno)); + exit(1); + } + + if (!do_wait) + return 0; + + rc = waitpid(pid, &status, 0); + if (rc != pid) { + /* Huh? */ + fprintf(stderr,"%s: waidpid(%d): %s\n", __FUNCTION__, + pid, strerror(errno)); + exit(1); + } + if (!WIFEXITED(status)) + return -1; + return WEXITSTATUS(status); +} + +int run_application(int do_wait, const char *app, ...) +{ + va_list args; + char *argv[64]; + int i; + if (debug) fprintf(stderr,"%s: %s |", __FUNCTION__, app); va_start(args, app); @@ -190,48 +235,120 @@ int run_application(int do_wait, const char *app, ...) return -1; } - if (0 == (pid = fork())) { - /* child */ - execvp(app, argv); - fprintf(stderr,"%s: execvp(%s): %s\n", __FUNCTION__, - app, strerror(errno)); - exit(1); + return run_application_va(do_wait, app, argv); +} + +int run_cmdline(int do_wait, char *line) +{ + char *argbuf, *token, *h; + char *argv[64]; + int rc = -1, argc = 0; + + h = argbuf = strdup(line); + for (;;) { + while (' ' == *h || '\t' == *h) + h++; + if ('\0' == *h) + break; + if ('"' == *h) { + /* quoted string */ + h++; + token = h; + while ('\0' != *h && '"' != *h) + h++; + } else { + /* normal string */ + token = h; + while ('\0' != *h && ' ' != *h && '\t' != *h) + h++; + } + if ('\0' != *h) { + *h = 0; + h++; + } + argv[argc++] = token; + if (argc == array_size(argv)-1) { + fprintf(stderr,"%s: oops: argv too small\n", __FUNCTION__); + goto out; + } } + if (!argc) + goto out; - if (!do_wait) - return 0; + argv[argc++] = NULL; + rc = run_application_va(do_wait, argv[0], argv); - rc = waitpid(pid, &status, 0); - if (rc != pid) { - /* Huh? */ - fprintf(stderr,"%s: waidpid(%d): %s\n", __FUNCTION__, - pid, strerror(errno)); - exit(1); + out: + free(argbuf); + return rc; +} + +int run_cmdline_replace(int do_wait, char *str, ...) +{ + va_list args; + char *tag, *val; + char *src, *dst, *pos; + int start, end, cont, rc = 0; + + va_start(args, str); + src = strdup(str); + for (;;) { + tag = va_arg(args, char*); + if (NULL == tag) + break; + val = va_arg(args, char*); + if (NULL == val) + break; + for (cont = 0;;) { + if (NULL == (pos = strstr(src + cont, tag))) + break; + start = pos - src; + end = start + strlen(tag); + cont = start + strlen(val); + dst = malloc(strlen(src) + strlen(val)); + strncpy(dst, src, start); + strcpy(dst + start, val); + strcpy(dst + cont, src + end); + free(src); + src = dst; + } } - if (!WIFEXITED(status)) - return -1; - return WEXITSTATUS(status); + va_end(args); + + if (1 || debug) + fprintf(stderr,"run: %s\n", src); + rc = run_cmdline(do_wait, src); + free(src); + return rc; } +/* ------------------------------------------------------------------ */ + int open_vnc_session(char *host, int screen) { char display[64]; - char httpurl[64]; + char javaurl[64]; + char vncurl[64]; snprintf(display, sizeof(display), "%s:%d", host, screen); - snprintf(httpurl, sizeof(httpurl), "http://%s:%d/", host, 5800 + screen); + snprintf(javaurl, sizeof(javaurl), "http://%s:%d/", host, 5800 + screen); + snprintf(vncurl, sizeof(vncurl), "vnc://%s:%d/", host, 5900 + screen); - if (app_have_vncviewer) + /* --- try client apps --- */ + if (have_application("vncviewer")) return run_application(0, "vncviewer", "vncviewer", display, NULL); - if (app_have_krdc) + if (have_application("krdc")) + /* KDE remote desktop client */ return run_application(0, "krdc", "krdc", display, NULL); - if (app_have_kfmclient) - return run_application(0, "kfmclient", "kfmclient", "openURL", httpurl, NULL); - if (app_have_firefox) - return run_application(0, "firefox", "firefox", httpurl, NULL); + /* --- try web browser (java applet client) --- */ + if (DESKTOP_KDE == desktop_type && have_application("kfmclient")) + /* open new konqueror window */ + return run_application(0, "kfmclient", "kfmclient", "openURL", javaurl, NULL); + if (have_application("firefox")) + return run_application(0, "firefox", "firefox", javaurl, NULL); snprintf(app_error, sizeof(app_error), - "need vncviewer or krdc, please install\n"); + "no vnc client found, please install one\n"); return -1; } |