1 /* $NetBSD: quotesys.c,v 1.1.1.1 2016/01/13 03:15:30 christos Exp $ */
2
3 /* Shell command argument quoting.
4 Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING.
18 If not, write to the Free Software Foundation,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21 /* Written by Paul Eggert <eggert@twinsun.com> */
22
23 #if HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 #include <sys/types.h>
28 #include <quotesys.h>
29
30 /* Place into QUOTED a quoted version of ARG suitable for `system'.
31 Return the length of the resulting string (which is not null-terminated).
32 If QUOTED is null, return the length without any side effects. */
33
34 size_t
quote_system_arg(quoted,arg)35 quote_system_arg (quoted, arg)
36 char *quoted;
37 char const *arg;
38 {
39 char const *a;
40 size_t len = 0;
41
42 /* Scan ARG, copying it to QUOTED if QUOTED is not null,
43 looking for shell metacharacters. */
44
45 for (a = arg; ; a++)
46 {
47 char c = *a;
48 switch (c)
49 {
50 case 0:
51 /* ARG has no shell metacharacters. */
52 return len;
53
54 case '=':
55 if (*arg == '-')
56 break;
57 /* Fall through. */
58 case '\t': case '\n': case ' ':
59 case '!': case '"': case '#': case '$': case '%': case '&': case '\'':
60 case '(': case ')': case '*': case ';':
61 case '<': case '>': case '?': case '[': case '\\':
62 case '^': case '`': case '|': case '~':
63 {
64 /* ARG has a shell metacharacter.
65 Start over, quoting it this time. */
66
67 len = 0;
68 c = *arg++;
69
70 /* If ARG is an option, quote just its argument.
71 This is not necessary, but it looks nicer. */
72 if (c == '-' && arg < a)
73 {
74 c = *arg++;
75
76 if (quoted)
77 {
78 quoted[len] = '-';
79 quoted[len + 1] = c;
80 }
81 len += 2;
82
83 if (c == '-')
84 while (arg < a)
85 {
86 c = *arg++;
87 if (quoted)
88 quoted[len] = c;
89 len++;
90 if (c == '=')
91 break;
92 }
93 c = *arg++;
94 }
95
96 if (quoted)
97 quoted[len] = '\'';
98 len++;
99
100 for (; c; c = *arg++)
101 {
102 if (c == '\'')
103 {
104 if (quoted)
105 {
106 quoted[len] = '\'';
107 quoted[len + 1] = '\\';
108 quoted[len + 2] = '\'';
109 }
110 len += 3;
111 }
112 if (quoted)
113 quoted[len] = c;
114 len++;
115 }
116
117 if (quoted)
118 quoted[len] = '\'';
119 return len + 1;
120 }
121 }
122
123 if (quoted)
124 quoted[len] = c;
125 len++;
126 }
127 }
128