2009-02-25 03:00:07 -08:00
|
|
|
#include "elementary_config.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <string.h>
|
2009-02-25 07:54:26 -08:00
|
|
|
#include <limits.h>
|
2009-02-25 03:00:07 -08:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <sys/un.h>
|
2012-07-25 02:56:00 -07:00
|
|
|
#ifdef HAVE_ENVIRON
|
|
|
|
# define _GNU_SOURCE 1
|
|
|
|
#endif
|
2009-02-25 03:00:07 -08:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#ifdef HAVE_ALLOCA_H
|
|
|
|
# include <alloca.h>
|
|
|
|
#endif
|
|
|
|
|
2012-07-25 02:56:00 -07:00
|
|
|
#ifdef HAVE_ENVIRON
|
|
|
|
extern char **environ;
|
|
|
|
#endif
|
|
|
|
|
2009-02-25 03:00:07 -08:00
|
|
|
#define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
|
|
|
|
|
|
|
|
int
|
|
|
|
main(int argc, char **argv)
|
|
|
|
{
|
2012-07-25 02:56:00 -07:00
|
|
|
int sock, socket_unix_len, i, n;
|
2009-02-25 03:00:07 -08:00
|
|
|
struct sockaddr_un socket_unix;
|
|
|
|
char buf[PATH_MAX];
|
|
|
|
struct stat st;
|
|
|
|
char *exe;
|
|
|
|
int we_are_elementary_run = 0;
|
|
|
|
char *disp;
|
|
|
|
char *cwd;
|
2009-07-06 23:46:51 -07:00
|
|
|
|
2012-07-25 02:56:00 -07:00
|
|
|
int sargc, slen, envnum;
|
2009-02-25 03:00:07 -08:00
|
|
|
unsigned char *sbuf = NULL, *pos;
|
|
|
|
char **sargv = NULL;
|
2009-07-06 23:46:51 -07:00
|
|
|
|
2009-02-25 03:00:07 -08:00
|
|
|
if (!getcwd(buf, sizeof(buf) - 1))
|
|
|
|
{
|
2009-07-06 23:46:51 -07:00
|
|
|
fprintf(stderr, "elementary_quicklaunch: currect working dir too big.\n");
|
|
|
|
exit(-1);
|
2009-02-25 03:00:07 -08:00
|
|
|
}
|
|
|
|
cwd = strdup(buf);
|
2012-07-25 02:56:00 -07:00
|
|
|
if (!(disp = getenv("DISPLAY"))) disp = "unknown";
|
2009-02-25 03:00:07 -08:00
|
|
|
snprintf(buf, sizeof(buf), "/tmp/elm-ql-%i/%s", getuid(), disp);
|
|
|
|
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
|
|
|
|
{
|
2009-07-06 23:46:51 -07:00
|
|
|
perror("elementary_quicklaunch: socket(AF_UNIX, SOCK_STREAM, 0)");
|
|
|
|
exit(-1);
|
2009-02-25 03:00:07 -08:00
|
|
|
}
|
|
|
|
socket_unix.sun_family = AF_UNIX;
|
|
|
|
strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
|
2013-01-09 18:24:40 -08:00
|
|
|
socket_unix.sun_path[(int)(sizeof(socket_unix.sun_path)/sizeof(socket_unix.sun_path[0])) - 1] = '\0';
|
2009-02-25 03:00:07 -08:00
|
|
|
socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
|
|
|
|
if (connect(sock, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
|
|
|
|
{
|
2009-07-06 23:46:51 -07:00
|
|
|
perror("elementary_quicklaunch: connect(sock, (struct sockaddr *)&socket_unix, socket_unix_len)");
|
|
|
|
printf("elementary_quicklaunch: cannot connect to socket '%s'\n", buf);
|
|
|
|
exit(1);
|
2009-02-25 03:00:07 -08:00
|
|
|
}
|
|
|
|
exe = argv[0];
|
|
|
|
if (!(((exe[0] == '/')) ||
|
2009-07-06 23:46:51 -07:00
|
|
|
((exe[0] == '.') && (exe[1] == '/')) ||
|
|
|
|
((exe[0] == '.') && (exe[1] == '.') && (exe[2] == '/'))))
|
2009-02-25 03:00:07 -08:00
|
|
|
{
|
2009-07-06 23:46:51 -07:00
|
|
|
char *path = getenv("PATH");
|
|
|
|
int exelen = strlen(argv[0]);
|
|
|
|
if (path)
|
|
|
|
{
|
2010-03-09 20:13:34 -08:00
|
|
|
const char *p, *pp;
|
2009-07-06 23:46:51 -07:00
|
|
|
|
|
|
|
p = path;
|
|
|
|
pp = p;
|
|
|
|
exe = NULL;
|
|
|
|
for (;;)
|
|
|
|
{
|
2010-10-22 14:41:27 -07:00
|
|
|
if ((*p == ':') || (!*p))
|
2009-07-06 23:46:51 -07:00
|
|
|
{
|
2010-10-19 11:25:22 -07:00
|
|
|
unsigned int len;
|
2009-07-06 23:46:51 -07:00
|
|
|
|
|
|
|
len = p - pp;
|
|
|
|
if (len < (sizeof(buf) - exelen - 3))
|
|
|
|
{
|
|
|
|
strncpy(buf, pp, len);
|
|
|
|
strcpy(buf + len, "/");
|
|
|
|
strcpy(buf + len + 1, argv[0]);
|
2010-10-22 14:41:27 -07:00
|
|
|
if (!access(buf, R_OK | X_OK))
|
2009-07-06 23:46:51 -07:00
|
|
|
{
|
|
|
|
exe = buf;
|
|
|
|
break;
|
|
|
|
}
|
2010-10-22 14:41:27 -07:00
|
|
|
if (!*p) break;
|
2009-07-06 23:46:51 -07:00
|
|
|
p++;
|
|
|
|
pp = p;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-10-22 14:41:27 -07:00
|
|
|
if (!*p) break;
|
2009-07-06 23:46:51 -07:00
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-02-25 03:00:07 -08:00
|
|
|
}
|
|
|
|
if (exe)
|
|
|
|
{
|
2010-10-22 14:41:27 -07:00
|
|
|
if (!lstat(exe, &st))
|
2009-07-06 23:46:51 -07:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-02-25 03:00:07 -08:00
|
|
|
}
|
|
|
|
if (we_are_elementary_run)
|
|
|
|
{
|
2009-07-06 23:46:51 -07:00
|
|
|
sargc = argc;
|
|
|
|
sargv = argv;
|
2009-02-25 03:00:07 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-07-06 23:46:51 -07:00
|
|
|
sargc = argc - 1;
|
|
|
|
sargv = &(argv[1]);
|
2009-02-25 03:00:07 -08:00
|
|
|
}
|
2013-09-30 03:21:31 -07:00
|
|
|
|
2012-07-25 02:56:00 -07:00
|
|
|
slen = 0;
|
|
|
|
envnum = 0;
|
2013-09-30 03:21:31 -07:00
|
|
|
|
2012-07-25 02:56:00 -07:00
|
|
|
// header:
|
|
|
|
// UL 'total bytes'
|
|
|
|
// UL 'argnum'
|
|
|
|
// UL 'envnum'
|
|
|
|
slen += sizeof(unsigned long) * 3;
|
2013-09-30 03:21:31 -07:00
|
|
|
|
2009-02-25 03:00:07 -08:00
|
|
|
for (i = 0; i < sargc; i++)
|
|
|
|
{
|
2009-07-06 23:46:51 -07:00
|
|
|
slen += sizeof(unsigned long);
|
|
|
|
slen += strlen(sargv[i]) + 1;
|
2009-02-25 03:00:07 -08:00
|
|
|
}
|
2013-09-30 03:21:31 -07:00
|
|
|
|
2012-07-25 02:56:00 -07:00
|
|
|
#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);
|
2009-02-25 03:00:07 -08:00
|
|
|
slen += strlen(cwd) + 1;
|
2012-07-25 02:56:00 -07:00
|
|
|
|
|
|
|
// allocate buffer on stack
|
2009-02-25 03:00:07 -08:00
|
|
|
sbuf = alloca(slen);
|
2013-09-30 03:21:31 -07:00
|
|
|
|
2012-07-25 02:56:00 -07:00
|
|
|
// fill in header
|
2009-02-25 03:00:07 -08:00
|
|
|
((unsigned long *)(sbuf))[0] = slen - sizeof(unsigned long);
|
|
|
|
((unsigned long *)(sbuf))[1] = sargc;
|
2012-07-25 02:56:00 -07:00
|
|
|
((unsigned long *)(sbuf))[2] = envnum;
|
|
|
|
// pos pointer after header
|
|
|
|
pos = (unsigned char *)(&((((unsigned long *)(sbuf))[3 + sargc + envnum + 1])));
|
|
|
|
n = 3;
|
|
|
|
|
|
|
|
// fill in args
|
2009-02-25 03:00:07 -08:00
|
|
|
for (i = 0; i < sargc; i++)
|
|
|
|
{
|
2012-07-25 02:56:00 -07:00
|
|
|
((unsigned long *)(sbuf))[n] = (unsigned long)pos - (unsigned long)sbuf;
|
2010-03-09 20:13:34 -08:00
|
|
|
strcpy((char *)pos, sargv[i]);
|
2009-07-06 23:46:51 -07:00
|
|
|
pos += strlen(sargv[i]) + 1;
|
2012-07-25 02:56:00 -07:00
|
|
|
n++;
|
2009-02-25 03:00:07 -08:00
|
|
|
}
|
2013-09-30 03:21:31 -07:00
|
|
|
|
2012-07-25 02:56:00 -07:00
|
|
|
#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++;
|
2010-03-09 20:13:34 -08:00
|
|
|
strcpy((char *)pos, cwd);
|
2013-09-30 03:21:31 -07:00
|
|
|
|
2010-03-09 20:13:34 -08:00
|
|
|
if (write(sock, sbuf, slen) < 0)
|
|
|
|
printf("elementary_quicklaunch: cannot write to socket '%s'\n", buf);
|
2009-02-25 03:00:07 -08:00
|
|
|
close(sock);
|
2013-03-18 04:46:25 -07:00
|
|
|
|
|
|
|
free(cwd);
|
2009-02-25 03:00:07 -08:00
|
|
|
return 0;
|
|
|
|
}
|