/* dock.c- built-in Dock module for WindowMaker * WindowMaker window manager * * Copyright (c) 1997 Alfredo K. Kojima * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "list.h" #include "misc.h" /* *---------------------------------------------------------------------- * parse_command-- * Divides a command line into a argv/argc pair. *---------------------------------------------------------------------- */ #define PRC_ALPHA 0 #define PRC_BLANK 1 #define PRC_ESCAPE 2 #define PRC_DQUOTE 3 #define PRC_EOS 4 #define PRC_SQUOTE 5 typedef struct { short nstate; short output; } DFA; static DFA mtable[9][6] = { { {3, 1}, {0, 0}, {4, 0}, {1, 0}, {8, 0}, {6, 0}}, { {1, 1}, {1, 1}, {2, 0}, {3, 0}, {5, 0}, {1, 1}}, { {1, 1}, {1, 1}, {1, 1}, {1, 1}, {5, 0}, {1, 1}}, { {3, 1}, {5, 0}, {4, 0}, {1, 0}, {5, 0}, {6, 0}}, { {3, 1}, {3, 1}, {3, 1}, {3, 1}, {5, 0}, {3, 1}}, { {-1, -1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, /* final state */ { {6, 1}, {6, 1}, {7, 0}, {6, 1}, {5, 0}, {3, 0}}, { {6, 1}, {6, 1}, {6, 1}, {6, 1}, {5, 0}, {6, 1}}, { {-1, -1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, /* final state */ }; char * next_token (char *word, char **next) { char *ptr; char *ret, *t; int state, ctype; t = ret = malloc (strlen (word) + 1); ptr = word; state = 0; *t = 0; while (1) { if (*ptr == 0) ctype = PRC_EOS; else if (*ptr == '\\') ctype = PRC_ESCAPE; else if (*ptr == '"') ctype = PRC_DQUOTE; else if (*ptr == '\'') ctype = PRC_SQUOTE; else if (*ptr == ' ' || *ptr == '\t') ctype = PRC_BLANK; else ctype = PRC_ALPHA; if (mtable[state][ctype].output) { *t = *ptr; t++; *t = 0; } state = mtable[state][ctype].nstate; ptr++; if (mtable[state][0].output < 0) { break; } } if (*ret == 0) t = NULL; else t = strdup (ret); free (ret); if (ctype == PRC_EOS) *next = NULL; else *next = ptr; return t; } extern void parse_command (char *command, char ***argv, int *argc) { LinkedList *list = NULL; char *token, *line; int count, i; line = command; do { token = next_token (line, &line); if (token) { list = list_cons (token, list); } } while (token != NULL && line != NULL); count = list_length (list); *argv = malloc (sizeof (char *) * count); i = count; while (list != NULL) { (*argv)[--i] = list->head; list_remove_head (&list); } *argc = count; } extern pid_t execCommand (char *command) { pid_t pid; char **argv; int argc; parse_command (command, &argv, &argc); if (argv == NULL) { return 0; } if ((pid = fork ()) == 0) { char **args; int i; args = malloc (sizeof (char *) * (argc + 1)); if (!args) exit (10); for (i = 0; i < argc; i++) { args[i] = argv[i]; } args[argc] = NULL; execvp (argv[0], args); exit (10); } return pid; }