1 /*
2 * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
3 * Copyright (C) 2004-2020 Kim Woelders
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies of the Software, its documentation and marketing & publicity
14 * materials, and acknowledgment shall be given in the documentation, materials
15 * and software packages that this Software was used.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24 #include <sys/select.h>
25 #include "E.h"
26 #include <sys/select.h>
27
28 /* Global vars */
29 Display *disp;
30
31 static char buf[10240];
32 static int stdin_state;
33 static char *display_name;
34 static Client *e;
35 static Window my_win, comms_win;
36
37 static void
process_line(char * line)38 process_line(char *line)
39 {
40 if (!line)
41 exit(0);
42 if (*line == '\0')
43 return;
44
45 CommsSend(e, line);
46 XSync(disp, False);
47 }
48
49 static void
stdin_state_setup(void)50 stdin_state_setup(void)
51 {
52 stdin_state = fcntl(0, F_GETFL, 0);
53 fcntl(0, F_SETFL, O_NONBLOCK);
54 }
55
56 static void
stdin_state_restore(void)57 stdin_state_restore(void)
58 {
59 fcntl(0, F_SETFL, stdin_state);
60 }
61
62 static void
stdin_read(void)63 stdin_read(void)
64 {
65 static int j = 0;
66 int k, ret;
67
68 k = 0;
69 while ((ret = read(0, &(buf[j]), 1) > 0))
70 {
71 k = 1;
72 if (buf[j] == '\n')
73 {
74 buf[j] = 0;
75 if (strlen(buf) > 0)
76 process_line(buf);
77 j = -1;
78 }
79 j++;
80 }
81 if ((ret < 0) || ((k == 0) && (ret == 0)))
82 exit(0);
83 }
84
85 int
main(int argc,char ** argv)86 main(int argc, char **argv)
87 {
88 XEvent ev;
89 Client *me;
90 int i;
91 fd_set fd;
92 char *command, *s;
93 char mode;
94 int len, l;
95
96 mode = 0;
97 display_name = NULL;
98 command = NULL;
99 #ifdef __clang_analyzer__
100 /* Seems not to understand asm FD_ZERO() */
101 memset(&fd, 0, sizeof(fd));
102 #endif
103
104 for (i = 1; i < argc; i++)
105 {
106 s = argv[i];
107 if (*s != '-')
108 break;
109
110 if (!strcmp(argv[i], "-e"))
111 {
112 mode = -1;
113 }
114 else if (!strcmp(argv[i], "-ewait"))
115 {
116 mode = 1;
117 }
118 else if (!strcmp(argv[i], "-display"))
119 {
120 if (i != (argc - 1))
121 {
122 display_name = argv[++i];
123 display_name = Estrdup(display_name);
124 }
125 }
126 else if ((!strcmp(argv[i], "-h")) ||
127 (!strcmp(argv[i], "-help")) || (!strcmp(argv[i], "--help")))
128 {
129 printf
130 ("eesh sends commands to E\n\n"
131 "Examples:\n"
132 " eesh Command to Send to E then wait for a reply then exit\n"
133 " eesh -ewait \"Command to Send to E then wait for a reply then exit\"\n"
134 " eesh -e \"Command to Send to Enlightenment then exit\"\n\n");
135 printf("Use eesh by itself to enter the \"interactive mode\"\n"
136 " Ctrl-D will exit interactive mode\n"
137 " Use \"help\" from inside interactive mode for further assistance\n");
138 exit(0);
139 }
140 }
141
142 /* Open a connection to the diplay nominated by the DISPLAY variable */
143 /* Or set with the -display option */
144 disp = XOpenDisplay(display_name);
145 if (!disp)
146 {
147 fprintf(stderr, "Failed to connect to X server\n");
148 exit(1);
149 }
150
151 CommsInit();
152 comms_win = CommsFindCommsWindow();
153 my_win = CommsSetup(comms_win);
154
155 e = ClientCreate(comms_win);
156 me = ClientCreate(my_win);
157
158 CommsSend(e, "set clientname eesh");
159 CommsSend(e, "set version 0.2");
160 #if 0 /* Speed it up */
161 CommsSend(e, "set author The Rasterman");
162 CommsSend(e, "set email raster@rasterman.com");
163 CommsSend(e, "set web http://www.enlightenment.org");
164 /* CommsSend(e, "set address NONE"); */
165 CommsSend(e, "set info Enlightenment IPC Shell - talk to E direct");
166 /* CommsSend(e, "set pixmap 0"); */
167 #endif
168
169 if (!command && i < argc)
170 {
171 mode = 1;
172 len = 0;
173 for (; i < argc; i++)
174 {
175 l = strlen(argv[i]);
176 command = EREALLOC(char, command, len + l + 2);
177
178 if (len)
179 command[len++] = ' ';
180 strcpy(command + len, argv[i]);
181 len += l;
182 }
183 }
184
185 if (command)
186 {
187 /* Non-interactive */
188 CommsSend(e, command);
189 XSync(disp, False);
190 #if 0 /* No - Wait for ack */
191 if (mode <= 0)
192 goto done;
193 #endif
194 }
195 else
196 {
197 /* Interactive */
198 stdin_state_setup();
199 atexit(stdin_state_restore);
200 }
201
202 for (;;)
203 {
204 XSync(disp, False);
205 while (XPending(disp))
206 {
207 XNextEvent(disp, &ev);
208 switch (ev.type)
209 {
210 case ClientMessage:
211 s = CommsGet(me, &ev);
212 if (!s)
213 break;
214 if (*s)
215 printf("%s", s);
216 fflush(stdout);
217 Efree(s);
218 if (mode)
219 goto done;
220 break;
221 case DestroyNotify:
222 goto done;
223 }
224 }
225
226 FD_ZERO(&fd);
227 if (!command)
228 FD_SET(0, &fd);
229 FD_SET(ConnectionNumber(disp), &fd);
230
231 if (select(ConnectionNumber(disp) + 1, &fd, NULL, NULL, NULL) < 0)
232 break;
233
234 if (FD_ISSET(0, &fd))
235 {
236 stdin_read();
237 }
238 }
239
240 done:
241 ClientDestroy(e);
242 ClientDestroy(me);
243 free(command);
244
245 return 0;
246 }
247
248 #if !USE_LIBC_STRDUP
249 char *
Estrdup(const char * s)250 Estrdup(const char *s)
251 {
252 char *ss;
253 int sz;
254
255 if (!s)
256 return NULL;
257 sz = strlen(s);
258 ss = EMALLOC(char, sz + 1);
259 memcpy(ss, s, sz + 1);
260
261 return ss;
262 }
263 #endif
264