From 3ad3455551be0d7859ecb02290376206d5e66498 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Sun, 22 Apr 2012 09:20:32 +1000 Subject: And actually include new files, plus elementary libraries. --- libraries/elementary/src/bin/run.c | 160 +++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 libraries/elementary/src/bin/run.c (limited to 'libraries/elementary/src/bin/run.c') diff --git a/libraries/elementary/src/bin/run.c b/libraries/elementary/src/bin/run.c new file mode 100644 index 0000000..ebd9833 --- /dev/null +++ b/libraries/elementary/src/bin/run.c @@ -0,0 +1,160 @@ +#include "elementary_config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_ALLOCA_H +# include +#endif + +#define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path)) + +int +main(int argc, char **argv) +{ + int sock, socket_unix_len, i; + struct sockaddr_un socket_unix; + char buf[PATH_MAX]; + struct stat st; + char *exe; + int we_are_elementary_run = 0; + char *disp; + char *cwd; + + int sargc, slen; + unsigned char *sbuf = NULL, *pos; + char **sargv = NULL; + + if (!getcwd(buf, sizeof(buf) - 1)) + { + fprintf(stderr, "elementary_quicklaunch: currect working dir too big.\n"); + exit(-1); + } + cwd = strdup(buf); + if (!(disp = getenv("DISPLAY"))) + { + fprintf(stderr, "elementary_quicklaunch: DISPLAY env var not set\n"); + exit(-1); + } + snprintf(buf, sizeof(buf), "/tmp/elm-ql-%i/%s", getuid(), disp); + if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + { + perror("elementary_quicklaunch: socket(AF_UNIX, SOCK_STREAM, 0)"); + exit(-1); + } + socket_unix.sun_family = AF_UNIX; + strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path)); + socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix); + if (connect(sock, (struct sockaddr *)&socket_unix, socket_unix_len) < 0) + { + perror("elementary_quicklaunch: connect(sock, (struct sockaddr *)&socket_unix, socket_unix_len)"); + printf("elementary_quicklaunch: cannot connect to socket '%s'\n", buf); + exit(1); + } + exe = argv[0]; + if (!(((exe[0] == '/')) || + ((exe[0] == '.') && (exe[1] == '/')) || + ((exe[0] == '.') && (exe[1] == '.') && (exe[2] == '/')))) + { + char *path = getenv("PATH"); + int exelen = strlen(argv[0]); + if (path) + { + const char *p, *pp; + + p = path; + pp = p; + exe = NULL; + for (;;) + { + if ((*p == ':') || (!*p)) + { + unsigned int len; + + len = p - pp; + if (len < (sizeof(buf) - exelen - 3)) + { + strncpy(buf, pp, len); + strcpy(buf + len, "/"); + strcpy(buf + len + 1, argv[0]); + if (!access(buf, R_OK | X_OK)) + { + exe = buf; + break; + } + if (!*p) break; + p++; + pp = p; + } + } + else + { + if (!*p) break; + p++; + } + } + } + } + if (exe) + { + if (!lstat(exe, &st)) + { + if (S_ISLNK(st.st_mode)) + { + char buf2[PATH_MAX]; + + ssize_t len = readlink(exe, buf2, sizeof(buf2) - 1); + if (len >= 0) + { + char *p; + buf2[len] = 0; + p = strrchr(buf2, '/'); + if (p) p++; + else p = buf2; + if (!strncasecmp(p, "elementary_run", 14)) + we_are_elementary_run = 1; + } + } + } + } + if (we_are_elementary_run) + { + sargc = argc; + sargv = argv; + } + else + { + sargc = argc - 1; + sargv = &(argv[1]); + } + slen = sizeof(unsigned long) + sizeof(unsigned long); + for (i = 0; i < sargc; i++) + { + slen += sizeof(unsigned long); + slen += strlen(sargv[i]) + 1; + } + slen += strlen(cwd) + 1; + sbuf = alloca(slen); + ((unsigned long *)(sbuf))[0] = slen - sizeof(unsigned long); + ((unsigned long *)(sbuf))[1] = sargc; + pos = (unsigned char *)(&((((unsigned long *)(sbuf))[2 + sargc]))); + for (i = 0; i < sargc; i++) + { + ((unsigned long *)(sbuf))[2 + i] = + (unsigned long)pos - ((unsigned long)sbuf + sizeof(unsigned long)); + strcpy((char *)pos, sargv[i]); + pos += strlen(sargv[i]) + 1; + } + strcpy((char *)pos, cwd); + if (write(sock, sbuf, slen) < 0) + printf("elementary_quicklaunch: cannot write to socket '%s'\n", buf); + close(sock); + return 0; +} -- cgit v1.1