aboutsummaryrefslogtreecommitdiffstats
path: root/apps.c
diff options
context:
space:
mode:
authorkraxel <kraxel>2006-04-07 15:38:39 +0000
committerkraxel <kraxel>2006-04-07 15:38:39 +0000
commit87fcf49941e76d58934b143a1b1441f263323c12 (patch)
treed67644a0f4ffda122cec12d02af6f31e2b06437a /apps.c
parentb6b64172f31759d9aa2a9f40438c8ab09f0f9a98 (diff)
downloadxenwatch-87fcf49941e76d58934b143a1b1441f263323c12.tar.gz
mdns hacking
Diffstat (limited to 'apps.c')
-rw-r--r--apps.c261
1 files changed, 189 insertions, 72 deletions
diff --git a/apps.c b/apps.c
index 7cbcb72..238b67d 100644
--- a/apps.c
+++ b/apps.c
@@ -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;
}