#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
+#ifdef HAVE_ENVIRON
+# define _GNU_SOURCE 1
+#endif
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
# include <alloca.h>
#endif
+#ifdef HAVE_ENVIRON
+extern char **environ;
+#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;
+ int sock, socket_unix_len, i, n;
struct sockaddr_un socket_unix;
char buf[PATH_MAX];
struct stat st;
char *disp;
char *cwd;
- int sargc, slen;
+ int sargc, slen, envnum;
unsigned char *sbuf = NULL, *pos;
char **sargv = NULL;
exit(-1);
}
cwd = strdup(buf);
- if (!(disp = getenv("DISPLAY")))
- {
- fprintf(stderr, "elementary_quicklaunch: DISPLAY env var not set\n");
- exit(-1);
- }
+ if (!(disp = getenv("DISPLAY"))) disp = "unknown";
snprintf(buf, sizeof(buf), "/tmp/elm-ql-%i/%s", getuid(), disp);
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
{
}
socket_unix.sun_family = AF_UNIX;
strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
+ socket_unix.sun_path[(int)(sizeof(socket_unix.sun_path)/sizeof(socket_unix.sun_path[0])) - 1] = '\0';
socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
if (connect(sock, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
{
sargc = argc - 1;
sargv = &(argv[1]);
}
- slen = sizeof(unsigned long) + sizeof(unsigned long);
+
+ slen = 0;
+ envnum = 0;
+
+ // header:
+ // UL 'total bytes'
+ // UL 'argnum'
+ // UL 'envnum'
+ slen += sizeof(unsigned long) * 3;
+
for (i = 0; i < sargc; i++)
{
slen += sizeof(unsigned long);
slen += strlen(sargv[i]) + 1;
}
+
+#ifdef HAVE_ENVIRON
+ // count how much space is needed for environment
+ for (i = 0; environ[i]; i++)
+ {
+ slen += sizeof(unsigned long);
+ slen += strlen(environ[i]) + 1;
+ envnum++;
+ }
+#endif
+
+ // how much space is needed for cwd
+ slen += sizeof(unsigned long);
slen += strlen(cwd) + 1;
+
+ // allocate buffer on stack
sbuf = alloca(slen);
+
+ // fill in header
((unsigned long *)(sbuf))[0] = slen - sizeof(unsigned long);
((unsigned long *)(sbuf))[1] = sargc;
- pos = (unsigned char *)(&((((unsigned long *)(sbuf))[2 + sargc])));
+ ((unsigned long *)(sbuf))[2] = envnum;
+ // pos pointer after header
+ pos = (unsigned char *)(&((((unsigned long *)(sbuf))[3 + sargc + envnum + 1])));
+ n = 3;
+
+ // fill in args
for (i = 0; i < sargc; i++)
{
- ((unsigned long *)(sbuf))[2 + i] =
- (unsigned long)pos - ((unsigned long)sbuf + sizeof(unsigned long));
+ ((unsigned long *)(sbuf))[n] = (unsigned long)pos - (unsigned long)sbuf;
strcpy((char *)pos, sargv[i]);
pos += strlen(sargv[i]) + 1;
+ n++;
}
+
+#ifdef HAVE_ENVIRON
+ // fill in environ
+ for (i = 0; environ[i]; i++)
+ {
+ ((unsigned long *)(sbuf))[n] = (unsigned long)pos - (unsigned long)sbuf;
+ strcpy((char *)pos, environ[i]);
+ pos += strlen(environ[i]) + 1;
+ n++;
+ }
+#endif
+
+ // fill in cwd
+ ((unsigned long *)(sbuf))[n] = (unsigned long)pos - (unsigned long)sbuf;
+ n++;
strcpy((char *)pos, cwd);
+
if (write(sock, sbuf, slen) < 0)
printf("elementary_quicklaunch: cannot write to socket '%s'\n", buf);
close(sock);