xref: /netbsd-src/external/gpl2/diffutils/dist/lib/quotesys.c (revision 75f6d617e282811cb173c2ccfbf5df0dd71f7045)
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