]>
diplodocus.org Git - nmh/blob - sbr/arglist.c
3 * arglist.c -- Routines for handling argument lists for execvp() and friends
5 * This code is Copyright (c) 2013, by the authors of nmh. See the
6 * COPYRIGHT file in the root directory of the nmh distribution for
7 * complete copyright information.
14 * Split up a command into an appropriate array to pass to execvp()
15 * or similar function. Returns an allocated argv[] array.
19 * command - String to split up
20 * file - the first argument to "command", suitable for the first argument
21 * to execvp(). Returns allocated memory that must be free()d.
22 * argp - Index to last element (NULL) of returned argv[] array.
24 * Our basic algorithm is this:
26 * - If there are no spaces or shell metacharacters in "command", then
28 * - If there are spaces in command, space-split command string.
29 * - If we have shell metacharacters, run the command using
30 * /bin/sh -c 'command "$@"'. In this case, any additional arguments
31 * appended to the arglist will be expanded by "$@".
33 * In all cases additional arguments can be added to the argv[] array.
36 /* Shell metacharacters we use to trigger a call to the shell */
38 #define METACHARS "$&*(){}[]'\";\\|?<>~`\n"
41 argsplit(char *command
, char **file
, int *argp
)
44 int space
= 0, metachar
= 0, i
;
46 for (p
= command
; *p
; p
++) {
47 if (*p
== ' ' || *p
== '\t') {
49 } else if (strchr(METACHARS
, *p
)) {
55 argvarray
= (char **) mh_xmalloc((sizeof(char **) * MAXARGS
));
58 * The simple case - no spaces or shell metacharacters
61 if (!space
&& !metachar
) {
62 argvarray
[0] = getcpy(r1bindex(command
, '/'));
64 *file
= getcpy(command
);
71 * Spaces, but no shell metacharacters; space-split into seperate
75 if (space
&& !metachar
) {
78 split
= brkstring(p
, " \t", NULL
);
79 if (split
[0] == NULL
) {
80 adios(NULL
, "Invalid blank command found");
82 argvarray
[0] = getcpy(r1bindex(split
[0], '/'));
83 for (i
= 1; split
[i
] != NULL
; i
++) {
85 adios(NULL
, "Command exceeded argument limit");
87 argvarray
[i
] = getcpy(split
[i
]);
90 *file
= getcpy(split
[0]);
98 * Remaining option - pass to the shell.
102 * - The command passed to "sh -c" is actually:
105 * If there are additional arguments they will be expanded by the
106 * shell, otherwise "$@" expands to nothing.
108 * - Every argument after the -c string gets put into positional
109 * parameters starting at $0, but $@ starts expanding with $1.
110 * So we put in a dummy argument (we just use /bin/sh)
113 *file
= getcpy("/bin/sh");
114 argvarray
[0] = getcpy("sh");
115 argvarray
[1] = getcpy("-c");
116 argvarray
[2] = getcpy(command
);
117 argvarray
[2] = add(" \"$@\"", argvarray
[2]);
118 argvarray
[3] = getcpy("/bin/sh");
128 * Free our argument array
132 arglist_free(char *command
, char **argvarray
)
139 if (argvarray
!= NULL
) {
140 for (i
= 0; argvarray
[i
] != NULL
; i
++)