madtty: erease display with A_NORMAL character attributes
[dvtm.git] / cmdfifo.c
blob8a33abcac7d0eb5333fe17d323bf3076dc432ddc
1 static int cmdfd = -1;
2 static unsigned short int client_id = 0;
3 static const char *cmdpath = NULL;
5 /* glibc has a non-standard realpath(3) implementation which allocates
6 * the destination buffer, other C libraries may have a broken implementation
7 * which expect an already allocated destination buffer.
8 */
10 #ifndef __GLIBC__
11 # include <limits.h>
12 # ifndef PATH_MAX
13 # define PATH_MAX 1024
14 # endif
15 #endif
17 static char *get_realpath(const char *path) {
18 #ifdef __GLIBC__
19 return realpath(path, NULL);
20 #else
21 static char buf[PATH_MAX];
22 return realpath(path, buf);
23 #endif
26 static Cmd *
27 get_cmd_by_name(const char *name) {
28 for (int i = 0; i < countof(commands); i++) {
29 if (!strcmp(name, commands[i].name))
30 return &commands[i];
32 return NULL;
35 static void
36 handle_cmdfifo() {
37 int r;
38 char *p, *s, cmdbuf[512], c;
39 Cmd *cmd;
40 switch (r = read(cmdfd, cmdbuf, sizeof cmdbuf - 1)) {
41 case -1:
42 case 0:
43 cmdfd = -1;
44 break;
45 default:
46 cmdbuf[r] = '\0';
47 p = cmdbuf;
48 while (*p) {
49 /* find the command name */
50 for (; *p == ' ' || *p == '\n'; p++);
51 for (s = p; *p && *p != ' ' && *p != '\n'; p++);
52 if ((c = *p))
53 *p++ = '\0';
54 if (*s && (cmd = get_cmd_by_name(s)) != NULL) {
55 bool quote = false;
56 int argc = 0;
57 /* XXX: initializer assumes MAX_ARGS == 2 use a initialization loop? */
58 const char *args[MAX_ARGS] = { NULL, NULL}, *arg;
59 /* if arguments were specified in config.h ignore the one given via
60 * the named pipe and thus skip everything until we find a new line
62 if (cmd->action.args[0] || c == '\n') {
63 debug("execute %s", s);
64 cmd->action.cmd(cmd->action.args);
65 while (*p && *p != '\n')
66 p++;
67 continue;
69 /* no arguments were given in config.h so we parse the command line */
70 while (*p == ' ')
71 p++;
72 arg = p;
73 for (; (c = *p); p++) {
74 switch (*p) {
75 case '\\':
76 /* remove the escape character '\\' move every
77 * following character to the left by one position
79 switch (*(++p)) {
80 case '\\':
81 case '\'':
82 case '\"': {
83 char *t = p;
84 for (;;) {
85 *(t - 1) = *t;
86 if (*t++ == '\0')
87 break;
89 p -= 2;
92 break;
93 case '\'':
94 case '\"':
95 quote = !quote;
96 break;
97 case ' ':
98 if (!quote) {
99 case '\n':
100 /* remove trailing quote if there is one */
101 if (*(p - 1) == '\'' || *(p - 1) == '\"')
102 *(p - 1) = '\0';
103 *p++ = '\0';
104 /* remove leading quote if there is one */
105 if (*arg == '\'' || *arg == '\"')
106 arg++;
107 if (argc < MAX_ARGS)
108 args[argc++] = arg;
110 while (*p == ' ')
111 ++p;
112 arg = p;
114 break;
117 if (c == '\n' || *p == '\n') {
118 debug("execute %s", s);
119 for(int i = 0; i < argc; i++)
120 debug(" %s", args[i]);
121 debug("\n");
122 cmd->action.cmd(args);
123 break;