You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
262 lines
5.8 KiB
262 lines
5.8 KiB
/* |
|
* Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors |
|
* Copyright (C) 2004-2020 Kim Woelders |
|
* |
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|
* of this software and associated documentation files (the "Software"), to |
|
* deal in the Software without restriction, including without limitation the |
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
|
* sell copies of the Software, and to permit persons to whom the Software is |
|
* furnished to do so, subject to the following conditions: |
|
* |
|
* The above copyright notice and this permission notice shall be included in |
|
* all copies of the Software, its documentation and marketing & publicity |
|
* materials, and acknowledgment shall be given in the documentation, materials |
|
* and software packages that this Software was used. |
|
* |
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
*/ |
|
#include <sys/select.h> |
|
#include "E.h" |
|
|
|
/* Global vars */ |
|
Display *disp; |
|
|
|
static char buf[10240]; |
|
static int stdin_state; |
|
static char *display_name; |
|
static Client *e; |
|
static Window my_win, comms_win; |
|
|
|
static void |
|
process_line(char *line) |
|
{ |
|
if (!line) |
|
exit(0); |
|
if (*line == '\0') |
|
return; |
|
|
|
CommsSend(e, line); |
|
XSync(disp, False); |
|
} |
|
|
|
static void |
|
stdin_state_setup(void) |
|
{ |
|
stdin_state = fcntl(0, F_GETFL, 0); |
|
fcntl(0, F_SETFL, O_NONBLOCK); |
|
} |
|
|
|
static void |
|
stdin_state_restore(void) |
|
{ |
|
fcntl(0, F_SETFL, stdin_state); |
|
} |
|
|
|
static void |
|
stdin_read(void) |
|
{ |
|
static int j = 0; |
|
int k, ret; |
|
|
|
k = 0; |
|
while ((ret = read(0, &(buf[j]), 1) > 0)) |
|
{ |
|
k = 1; |
|
if (buf[j] == '\n') |
|
{ |
|
buf[j] = 0; |
|
if (strlen(buf) > 0) |
|
process_line(buf); |
|
j = -1; |
|
} |
|
j++; |
|
} |
|
if ((ret < 0) || ((k == 0) && (ret == 0))) |
|
exit(0); |
|
} |
|
|
|
int |
|
main(int argc, char **argv) |
|
{ |
|
XEvent ev; |
|
Client *me; |
|
int i; |
|
fd_set fd; |
|
char *command, *s; |
|
char mode; |
|
int len, l; |
|
|
|
mode = 0; |
|
display_name = NULL; |
|
command = NULL; |
|
#ifdef __clang_analyzer__ |
|
/* Seems not to understand asm FD_ZERO() */ |
|
memset(&fd, 0, sizeof(fd)); |
|
#endif |
|
|
|
for (i = 1; i < argc; i++) |
|
{ |
|
s = argv[i]; |
|
if (*s != '-') |
|
break; |
|
|
|
if (!strcmp(argv[i], "-e")) |
|
{ |
|
mode = -1; |
|
} |
|
else if (!strcmp(argv[i], "-ewait")) |
|
{ |
|
mode = 1; |
|
} |
|
else if (!strcmp(argv[i], "-display")) |
|
{ |
|
if (i != (argc - 1)) |
|
{ |
|
display_name = argv[++i]; |
|
display_name = Estrdup(display_name); |
|
} |
|
} |
|
else if ((!strcmp(argv[i], "-h")) || |
|
(!strcmp(argv[i], "-help")) || (!strcmp(argv[i], "--help"))) |
|
{ |
|
printf |
|
("eesh sends commands to E\n\n" |
|
"Examples:\n" |
|
" eesh Command to Send to E then wait for a reply then exit\n" |
|
" eesh -ewait \"Command to Send to E then wait for a reply then exit\"\n" |
|
" eesh -e \"Command to Send to Enlightenment then exit\"\n\n"); |
|
printf("Use eesh by itself to enter the \"interactive mode\"\n" |
|
" Ctrl-D will exit interactive mode\n" |
|
" Use \"help\" from inside interactive mode for further assistance\n"); |
|
exit(0); |
|
} |
|
} |
|
|
|
/* Open a connection to the diplay nominated by the DISPLAY variable */ |
|
/* Or set with the -display option */ |
|
disp = XOpenDisplay(display_name); |
|
if (!disp) |
|
{ |
|
fprintf(stderr, "Failed to connect to X server\n"); |
|
exit(1); |
|
} |
|
|
|
CommsInit(); |
|
comms_win = CommsFindCommsWindow(); |
|
my_win = CommsSetup(comms_win); |
|
|
|
e = ClientCreate(comms_win); |
|
me = ClientCreate(my_win); |
|
|
|
CommsSend(e, "set clientname eesh"); |
|
CommsSend(e, "set version 0.2"); |
|
#if 0 /* Speed it up */ |
|
CommsSend(e, "set author The Rasterman"); |
|
CommsSend(e, "set email raster@rasterman.com"); |
|
CommsSend(e, "set web http://www.enlightenment.org"); |
|
/* CommsSend(e, "set address NONE"); */ |
|
CommsSend(e, "set info Enlightenment IPC Shell - talk to E direct"); |
|
/* CommsSend(e, "set pixmap 0"); */ |
|
#endif |
|
|
|
if (!command && i < argc) |
|
{ |
|
mode = 1; |
|
len = 0; |
|
for (; i < argc; i++) |
|
{ |
|
l = strlen(argv[i]); |
|
command = EREALLOC(char, command, len + l + 2); |
|
|
|
if (len) |
|
command[len++] = ' '; |
|
strcpy(command + len, argv[i]); |
|
len += l; |
|
} |
|
} |
|
|
|
if (command) |
|
{ |
|
/* Non-interactive */ |
|
CommsSend(e, command); |
|
XSync(disp, False); |
|
#if 0 /* No - Wait for ack */ |
|
if (mode <= 0) |
|
goto done; |
|
#endif |
|
} |
|
else |
|
{ |
|
/* Interactive */ |
|
stdin_state_setup(); |
|
atexit(stdin_state_restore); |
|
} |
|
|
|
for (;;) |
|
{ |
|
XSync(disp, False); |
|
while (XPending(disp)) |
|
{ |
|
XNextEvent(disp, &ev); |
|
switch (ev.type) |
|
{ |
|
case ClientMessage: |
|
s = CommsGet(me, &ev); |
|
if (!s) |
|
break; |
|
if (*s) |
|
printf("%s", s); |
|
fflush(stdout); |
|
Efree(s); |
|
if (mode) |
|
goto done; |
|
break; |
|
case DestroyNotify: |
|
goto done; |
|
} |
|
} |
|
|
|
FD_ZERO(&fd); |
|
if (!command) |
|
FD_SET(0, &fd); |
|
FD_SET(ConnectionNumber(disp), &fd); |
|
|
|
if (select(ConnectionNumber(disp) + 1, &fd, NULL, NULL, NULL) < 0) |
|
break; |
|
|
|
if (FD_ISSET(0, &fd)) |
|
{ |
|
stdin_read(); |
|
} |
|
} |
|
|
|
done: |
|
ClientDestroy(e); |
|
ClientDestroy(me); |
|
free(command); |
|
|
|
return 0; |
|
} |
|
|
|
#if !USE_LIBC_STRDUP |
|
char * |
|
Estrdup(const char *s) |
|
{ |
|
char *ss; |
|
int sz; |
|
|
|
if (!s) |
|
return NULL; |
|
sz = strlen(s); |
|
ss = EMALLOC(char, sz + 1); |
|
memcpy(ss, s, sz + 1); |
|
|
|
return ss; |
|
} |
|
#endif
|
|
|