1 /* dock.c- built-in Dock module for WindowMaker
2  *
3  *  WindowMaker window manager
4  *
5  *  Copyright (c) 1997 Alfredo K. Kojima
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21 
22 #include <stdlib.h>
23 #include <string.h>
24 #include "list.h"
25 #include "misc.h"
26 
27 /*
28  *----------------------------------------------------------------------
29  * parse_command--
30  * 	Divides a command line into a argv/argc pair.
31  *----------------------------------------------------------------------
32  */
33 #define PRC_ALPHA	0
34 #define PRC_BLANK	1
35 #define PRC_ESCAPE	2
36 #define PRC_DQUOTE	3
37 #define PRC_EOS		4
38 #define PRC_SQUOTE	5
39 
40 typedef struct {
41     short nstate;
42     short output;
43 } DFA;
44 
45 
46 static DFA mtable[9][6] = {
47     {{3,1},{0,0},{4,0},{1,0},{8,0},{6,0}},
48     {{1,1},{1,1},{2,0},{3,0},{5,0},{1,1}},
49     {{1,1},{1,1},{1,1},{1,1},{5,0},{1,1}},
50     {{3,1},{5,0},{4,0},{1,0},{5,0},{6,0}},
51     {{3,1},{3,1},{3,1},{3,1},{5,0},{3,1}},
52     {{-1,-1},{0,0},{0,0},{0,0},{0,0},{0,0}}, /* final state */
53     {{6,1},{6,1},{7,0},{6,1},{5,0},{3,0}},
54     {{6,1},{6,1},{6,1},{6,1},{5,0},{6,1}},
55     {{-1,-1},{0,0},{0,0},{0,0},{0,0},{0,0}}, /* final state */
56 };
57 
58 char*
next_token(char * word,char ** next)59 next_token(char *word, char **next)
60 {
61     char *ptr;
62     char *ret, *t;
63     int state, ctype;
64 
65     t = ret = malloc(strlen(word)+1);
66     ptr = word;
67 
68     state = 0;
69     *t = 0;
70     while (1) {
71 	if (*ptr==0)
72 	    ctype = PRC_EOS;
73 	else if (*ptr=='\\')
74 	    ctype = PRC_ESCAPE;
75 	else if (*ptr=='"')
76 	    ctype = PRC_DQUOTE;
77 	else if (*ptr=='\'')
78 	    ctype = PRC_SQUOTE;
79 	else if (*ptr==' ' || *ptr=='\t')
80 	    ctype = PRC_BLANK;
81 	else
82 	    ctype = PRC_ALPHA;
83 
84 	if (mtable[state][ctype].output) {
85 	    *t = *ptr; t++;
86 	    *t = 0;
87 	}
88 	state = mtable[state][ctype].nstate;
89 	ptr++;
90 	if (mtable[state][0].output<0) {
91 	    break;
92 	}
93     }
94 
95     if (*ret==0)
96 	t = NULL;
97     else
98 	t = strdup(ret);
99 
100     free(ret);
101 
102     if (ctype==PRC_EOS)
103 	*next = NULL;
104     else
105 	*next = ptr;
106 
107     return t;
108 }
109 
110 
111 extern void
parse_command(char * command,char *** argv,int * argc)112 parse_command(char *command, char ***argv, int *argc)
113 {
114     LinkedList *list = NULL;
115     char *token, *line;
116     int count, i;
117 
118     line = command;
119     do {
120 	token = next_token(line, &line);
121 	if (token) {
122 	    list = list_cons(token, list);
123 	}
124     } while (token!=NULL && line!=NULL);
125 
126     count = list_length(list);
127     *argv = malloc(sizeof(char*)*count);
128     i = count;
129     while (list!=NULL) {
130 	(*argv)[--i] = list->head;
131 	list_remove_head(&list);
132     }
133     *argc = count;
134 }
135 
136 extern pid_t
execCommand(char * command)137 execCommand(char *command)
138 {
139     pid_t pid;
140     char **argv;
141     int argc;
142 
143     parse_command(command, &argv, &argc);
144 
145     if (argv==NULL) {
146         return 0;
147     }
148 
149     if ((pid=fork())==0) {
150         char **args;
151         int i;
152 
153         args = malloc(sizeof(char*)*(argc+1));
154         if (!args)
155           exit(10);
156         for (i=0; i<argc; i++) {
157             args[i] = argv[i];
158         }
159         args[argc] = NULL;
160         execvp(argv[0], args);
161         exit(10);
162     }
163     return pid;
164 }
165