aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/elementary/src/bin/run.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/elementary/src/bin/run.c160
1 files changed, 160 insertions, 0 deletions
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 @@
1#include "elementary_config.h"
2#include <stdio.h>
3#include <stdlib.h>
4#include <errno.h>
5#include <string.h>
6#include <limits.h>
7#include <sys/types.h>
8#include <sys/socket.h>
9#include <sys/un.h>
10#include <unistd.h>
11#include <sys/stat.h>
12#include <fcntl.h>
13#ifdef HAVE_ALLOCA_H
14# include <alloca.h>
15#endif
16
17#define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
18
19int
20main(int argc, char **argv)
21{
22 int sock, socket_unix_len, i;
23 struct sockaddr_un socket_unix;
24 char buf[PATH_MAX];
25 struct stat st;
26 char *exe;
27 int we_are_elementary_run = 0;
28 char *disp;
29 char *cwd;
30
31 int sargc, slen;
32 unsigned char *sbuf = NULL, *pos;
33 char **sargv = NULL;
34
35 if (!getcwd(buf, sizeof(buf) - 1))
36 {
37 fprintf(stderr, "elementary_quicklaunch: currect working dir too big.\n");
38 exit(-1);
39 }
40 cwd = strdup(buf);
41 if (!(disp = getenv("DISPLAY")))
42 {
43 fprintf(stderr, "elementary_quicklaunch: DISPLAY env var not set\n");
44 exit(-1);
45 }
46 snprintf(buf, sizeof(buf), "/tmp/elm-ql-%i/%s", getuid(), disp);
47 if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
48 {
49 perror("elementary_quicklaunch: socket(AF_UNIX, SOCK_STREAM, 0)");
50 exit(-1);
51 }
52 socket_unix.sun_family = AF_UNIX;
53 strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
54 socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
55 if (connect(sock, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
56 {
57 perror("elementary_quicklaunch: connect(sock, (struct sockaddr *)&socket_unix, socket_unix_len)");
58 printf("elementary_quicklaunch: cannot connect to socket '%s'\n", buf);
59 exit(1);
60 }
61 exe = argv[0];
62 if (!(((exe[0] == '/')) ||
63 ((exe[0] == '.') && (exe[1] == '/')) ||
64 ((exe[0] == '.') && (exe[1] == '.') && (exe[2] == '/'))))
65 {
66 char *path = getenv("PATH");
67 int exelen = strlen(argv[0]);
68 if (path)
69 {
70 const char *p, *pp;
71
72 p = path;
73 pp = p;
74 exe = NULL;
75 for (;;)
76 {
77 if ((*p == ':') || (!*p))
78 {
79 unsigned int len;
80
81 len = p - pp;
82 if (len < (sizeof(buf) - exelen - 3))
83 {
84 strncpy(buf, pp, len);
85 strcpy(buf + len, "/");
86 strcpy(buf + len + 1, argv[0]);
87 if (!access(buf, R_OK | X_OK))
88 {
89 exe = buf;
90 break;
91 }
92 if (!*p) break;
93 p++;
94 pp = p;
95 }
96 }
97 else
98 {
99 if (!*p) break;
100 p++;
101 }
102 }
103 }
104 }
105 if (exe)
106 {
107 if (!lstat(exe, &st))
108 {
109 if (S_ISLNK(st.st_mode))
110 {
111 char buf2[PATH_MAX];
112
113 ssize_t len = readlink(exe, buf2, sizeof(buf2) - 1);
114 if (len >= 0)
115 {
116 char *p;
117 buf2[len] = 0;
118 p = strrchr(buf2, '/');
119 if (p) p++;
120 else p = buf2;
121 if (!strncasecmp(p, "elementary_run", 14))
122 we_are_elementary_run = 1;
123 }
124 }
125 }
126 }
127 if (we_are_elementary_run)
128 {
129 sargc = argc;
130 sargv = argv;
131 }
132 else
133 {
134 sargc = argc - 1;
135 sargv = &(argv[1]);
136 }
137 slen = sizeof(unsigned long) + sizeof(unsigned long);
138 for (i = 0; i < sargc; i++)
139 {
140 slen += sizeof(unsigned long);
141 slen += strlen(sargv[i]) + 1;
142 }
143 slen += strlen(cwd) + 1;
144 sbuf = alloca(slen);
145 ((unsigned long *)(sbuf))[0] = slen - sizeof(unsigned long);
146 ((unsigned long *)(sbuf))[1] = sargc;
147 pos = (unsigned char *)(&((((unsigned long *)(sbuf))[2 + sargc])));
148 for (i = 0; i < sargc; i++)
149 {
150 ((unsigned long *)(sbuf))[2 + i] =
151 (unsigned long)pos - ((unsigned long)sbuf + sizeof(unsigned long));
152 strcpy((char *)pos, sargv[i]);
153 pos += strlen(sargv[i]) + 1;
154 }
155 strcpy((char *)pos, cwd);
156 if (write(sock, sbuf, slen) < 0)
157 printf("elementary_quicklaunch: cannot write to socket '%s'\n", buf);
158 close(sock);
159 return 0;
160}