fixed plugin image size problem
[framework/uifw/elementary.git] / src / bin / run.c
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
19 int
20 main(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 }