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