118fd37a7SXin LI /* Shell command argument quoting.
218fd37a7SXin LI Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
318fd37a7SXin LI
418fd37a7SXin LI This program is free software; you can redistribute it and/or modify
518fd37a7SXin LI it under the terms of the GNU General Public License as published by
618fd37a7SXin LI the Free Software Foundation; either version 2, or (at your option)
718fd37a7SXin LI any later version.
818fd37a7SXin LI
918fd37a7SXin LI This program is distributed in the hope that it will be useful,
1018fd37a7SXin LI but WITHOUT ANY WARRANTY; without even the implied warranty of
1118fd37a7SXin LI MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1218fd37a7SXin LI GNU General Public License for more details.
1318fd37a7SXin LI
1418fd37a7SXin LI You should have received a copy of the GNU General Public License
1518fd37a7SXin LI along with this program; see the file COPYING.
1618fd37a7SXin LI If not, write to the Free Software Foundation,
1718fd37a7SXin LI 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
1818fd37a7SXin LI
1918fd37a7SXin LI /* Written by Paul Eggert <eggert@twinsun.com> */
2018fd37a7SXin LI
2118fd37a7SXin LI #if HAVE_CONFIG_H
2218fd37a7SXin LI # include <config.h>
2318fd37a7SXin LI #endif
2418fd37a7SXin LI
2518fd37a7SXin LI #include <sys/types.h>
2618fd37a7SXin LI #include <quotesys.h>
2718fd37a7SXin LI
2818fd37a7SXin LI /* Place into QUOTED a quoted version of ARG suitable for `system'.
2918fd37a7SXin LI Return the length of the resulting string (which is not null-terminated).
3018fd37a7SXin LI If QUOTED is null, return the length without any side effects. */
3118fd37a7SXin LI
3218fd37a7SXin LI size_t
quote_system_arg(quoted,arg)3318fd37a7SXin LI quote_system_arg (quoted, arg)
3418fd37a7SXin LI char *quoted;
3518fd37a7SXin LI char const *arg;
3618fd37a7SXin LI {
3718fd37a7SXin LI char const *a;
3818fd37a7SXin LI size_t len = 0;
3918fd37a7SXin LI
4018fd37a7SXin LI /* Scan ARG, copying it to QUOTED if QUOTED is not null,
4118fd37a7SXin LI looking for shell metacharacters. */
4218fd37a7SXin LI
4318fd37a7SXin LI for (a = arg; ; a++)
4418fd37a7SXin LI {
4518fd37a7SXin LI char c = *a;
4618fd37a7SXin LI switch (c)
4718fd37a7SXin LI {
4818fd37a7SXin LI case 0:
4918fd37a7SXin LI /* ARG has no shell metacharacters. */
5018fd37a7SXin LI return len;
5118fd37a7SXin LI
5218fd37a7SXin LI case '=':
5318fd37a7SXin LI if (*arg == '-')
5418fd37a7SXin LI break;
5518fd37a7SXin LI /* Fall through. */
5618fd37a7SXin LI case '\t': case '\n': case ' ':
5718fd37a7SXin LI case '!': case '"': case '#': case '$': case '%': case '&': case '\'':
5818fd37a7SXin LI case '(': case ')': case '*': case ';':
5918fd37a7SXin LI case '<': case '>': case '?': case '[': case '\\':
6018fd37a7SXin LI case '^': case '`': case '|': case '~':
6118fd37a7SXin LI {
6218fd37a7SXin LI /* ARG has a shell metacharacter.
6318fd37a7SXin LI Start over, quoting it this time. */
6418fd37a7SXin LI
6518fd37a7SXin LI len = 0;
6618fd37a7SXin LI c = *arg++;
6718fd37a7SXin LI
6818fd37a7SXin LI /* If ARG is an option, quote just its argument.
6918fd37a7SXin LI This is not necessary, but it looks nicer. */
7018fd37a7SXin LI if (c == '-' && arg < a)
7118fd37a7SXin LI {
7218fd37a7SXin LI c = *arg++;
7318fd37a7SXin LI
7418fd37a7SXin LI if (quoted)
7518fd37a7SXin LI {
7618fd37a7SXin LI quoted[len] = '-';
7718fd37a7SXin LI quoted[len + 1] = c;
7818fd37a7SXin LI }
7918fd37a7SXin LI len += 2;
8018fd37a7SXin LI
8118fd37a7SXin LI if (c == '-')
8218fd37a7SXin LI while (arg < a)
8318fd37a7SXin LI {
8418fd37a7SXin LI c = *arg++;
8518fd37a7SXin LI if (quoted)
8618fd37a7SXin LI quoted[len] = c;
8718fd37a7SXin LI len++;
8818fd37a7SXin LI if (c == '=')
8918fd37a7SXin LI break;
9018fd37a7SXin LI }
9118fd37a7SXin LI c = *arg++;
9218fd37a7SXin LI }
9318fd37a7SXin LI
9418fd37a7SXin LI if (quoted)
9518fd37a7SXin LI quoted[len] = '\'';
9618fd37a7SXin LI len++;
9718fd37a7SXin LI
9818fd37a7SXin LI for (; c; c = *arg++)
9918fd37a7SXin LI {
10018fd37a7SXin LI if (c == '\'')
10118fd37a7SXin LI {
10218fd37a7SXin LI if (quoted)
10318fd37a7SXin LI {
10418fd37a7SXin LI quoted[len] = '\'';
10518fd37a7SXin LI quoted[len + 1] = '\\';
10618fd37a7SXin LI quoted[len + 2] = '\'';
10718fd37a7SXin LI }
10818fd37a7SXin LI len += 3;
10918fd37a7SXin LI }
11018fd37a7SXin LI if (quoted)
11118fd37a7SXin LI quoted[len] = c;
11218fd37a7SXin LI len++;
11318fd37a7SXin LI }
11418fd37a7SXin LI
11518fd37a7SXin LI if (quoted)
11618fd37a7SXin LI quoted[len] = '\'';
11718fd37a7SXin LI return len + 1;
11818fd37a7SXin LI }
11918fd37a7SXin LI }
12018fd37a7SXin LI
12118fd37a7SXin LI if (quoted)
12218fd37a7SXin LI quoted[len] = c;
12318fd37a7SXin LI len++;
12418fd37a7SXin LI }
12518fd37a7SXin LI }
126