1 #include "elementary_config.h"
8 #include <sys/socket.h>
11 # define _GNU_SOURCE 1
21 extern char **environ;
24 #define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
27 main(int argc, char **argv)
29 int sock, socket_unix_len, i, n;
30 struct sockaddr_un socket_unix;
34 int we_are_elementary_run = 0;
38 int sargc, slen, envnum;
39 unsigned char *sbuf = NULL, *pos;
42 if (!getcwd(buf, sizeof(buf) - 1))
44 fprintf(stderr, "elementary_quicklaunch: currect working dir too big.\n");
48 if (!(disp = getenv("DISPLAY"))) disp = "unknown";
49 snprintf(buf, sizeof(buf), "/tmp/elm-ql-%i/%s", getuid(), disp);
50 if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
52 perror("elementary_quicklaunch: socket(AF_UNIX, SOCK_STREAM, 0)");
55 socket_unix.sun_family = AF_UNIX;
56 strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
57 socket_unix.sun_path[(int)(sizeof(socket_unix.sun_path)/sizeof(socket_unix.sun_path[0])) - 1] = '\0';
58 socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
59 if (connect(sock, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
61 perror("elementary_quicklaunch: connect(sock, (struct sockaddr *)&socket_unix, socket_unix_len)");
62 printf("elementary_quicklaunch: cannot connect to socket '%s'\n", buf);
66 if (!(((exe[0] == '/')) ||
67 ((exe[0] == '.') && (exe[1] == '/')) ||
68 ((exe[0] == '.') && (exe[1] == '.') && (exe[2] == '/'))))
70 char *path = getenv("PATH");
71 int exelen = strlen(argv[0]);
81 if ((*p == ':') || (!*p))
86 if (len < (sizeof(buf) - exelen - 3))
88 strncpy(buf, pp, len);
89 strcpy(buf + len, "/");
90 strcpy(buf + len + 1, argv[0]);
91 if (!access(buf, R_OK | X_OK))
111 if (!lstat(exe, &st))
113 if (S_ISLNK(st.st_mode))
117 ssize_t len = readlink(exe, buf2, sizeof(buf2) - 1);
122 p = strrchr(buf2, '/');
125 if (!strncasecmp(p, "elementary_run", 14))
126 we_are_elementary_run = 1;
131 if (we_are_elementary_run)
149 slen += sizeof(unsigned long) * 3;
151 for (i = 0; i < sargc; i++)
153 slen += sizeof(unsigned long);
154 slen += strlen(sargv[i]) + 1;
158 // count how much space is needed for environment
159 for (i = 0; environ[i]; i++)
161 slen += sizeof(unsigned long);
162 slen += strlen(environ[i]) + 1;
167 // how much space is needed for cwd
168 slen += sizeof(unsigned long);
169 slen += strlen(cwd) + 1;
171 // allocate buffer on stack
175 ((unsigned long *)(sbuf))[0] = slen - sizeof(unsigned long);
176 ((unsigned long *)(sbuf))[1] = sargc;
177 ((unsigned long *)(sbuf))[2] = envnum;
178 // pos pointer after header
179 pos = (unsigned char *)(&((((unsigned long *)(sbuf))[3 + sargc + envnum + 1])));
183 for (i = 0; i < sargc; i++)
185 ((unsigned long *)(sbuf))[n] = (unsigned long)pos - (unsigned long)sbuf;
186 strcpy((char *)pos, sargv[i]);
187 pos += strlen(sargv[i]) + 1;
193 for (i = 0; environ[i]; i++)
195 ((unsigned long *)(sbuf))[n] = (unsigned long)pos - (unsigned long)sbuf;
196 strcpy((char *)pos, environ[i]);
197 pos += strlen(environ[i]) + 1;
203 ((unsigned long *)(sbuf))[n] = (unsigned long)pos - (unsigned long)sbuf;
205 strcpy((char *)pos, cwd);
207 if (write(sock, sbuf, slen) < 0)
208 printf("elementary_quicklaunch: cannot write to socket '%s'\n", buf);