diff options
-rw-r--r-- | lib/ChangeLog | 7 | ||||
-rw-r--r-- | lib/Makefile.am | 9 | ||||
-rw-r--r-- | lib/sh-quote.c | 154 | ||||
-rw-r--r-- | lib/sh-quote.h | 36 |
4 files changed, 202 insertions, 4 deletions
diff --git a/lib/ChangeLog b/lib/ChangeLog index b61da9f..46917cd 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,5 +1,12 @@ 2001-09-06 Bruno Haible <haible@clisp.cons.org> + * sh-quote.h: New file. + * sh-quote.c: New file. + * Makefile.am (libnlsut_a_SOURCES): Add sh-quote.c. + (noinst_HEADERS): Add sh-quote.h. + +2001-09-06 Bruno Haible <haible@clisp.cons.org> + * strpbrk.h: New file. * strpbrk.c: New file, from glibc-2.2.4. * Makefile.am (EXTRA_DIST): Add strpbrk.c. diff --git a/lib/Makefile.am b/lib/Makefile.am index d0fea87..cec62be 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -30,15 +30,16 @@ gen-lbrkprop.c 3level.h libnlsut_a_SOURCES = basename.c c-ctype.c concatpath.c execute.c findprog.c \ fstrcmp.c full-write.c gcd.c getopt.c getopt1.c hash.c linebreak.c \ localcharset.c mbswidth.c obstack.c pipe-bidi.c pipe-in.c pipe-out.c \ -progname.c safe-read.c tmpdir.c wait-process.c xerror.c xgetcwd.c xmalloc.c \ -xstrdup.c +progname.c safe-read.c sh-quote.c tmpdir.c wait-process.c xerror.c xgetcwd.c \ +xmalloc.c xstrdup.c libnlsut_a_LIBADD = @ALLOCA@ @LIBOBJS@ noinst_HEADERS = c-ctype.h error.h execute.h findprog.h fstrcmp.h \ full-write.h gcd.h getline.h getopt.h hash.h lbrkprop.h linebreak.h mbswidth.h \ -mkdtemp.h obstack.h pathmax.h pipe.h progname.h safe-read.h setenv.h strpbrk.h \ -system.h tmpdir.h utf8-ucs4.h utf16-ucs4.h wait-process.h xerror.h +mkdtemp.h obstack.h pathmax.h pipe.h progname.h safe-read.h setenv.h \ +sh-quote.h strpbrk.h system.h tmpdir.h utf8-ucs4.h utf16-ucs4.h wait-process.h \ +xerror.h DEFS = -DLIBDIR=\"$(libdir)\" @DEFS@ INCLUDES = -I. -I$(srcdir) -I.. -I../intl diff --git a/lib/sh-quote.c b/lib/sh-quote.c new file mode 100644 index 0000000..4ecbc52 --- /dev/null +++ b/lib/sh-quote.c @@ -0,0 +1,154 @@ +/* Shell quoting. + Copyright (C) 2001 Free Software Foundation, Inc. + Written by Bruno Haible <haible@clisp.cons.org>, 2001. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +/* Specification. */ +#include "sh-quote.h" + +#include <string.h> + +#include "strpbrk.h" +#include "system.h" + + +#define SHELL_SPECIAL_CHARS "\t\n !\"#$&'()*;<=>?[\\]`{|}~" + +/* Returns the number of bytes needed for the quoted string. */ +size_t +shell_quote_length (string) + const char *string; +{ + if (strpbrk (string, SHELL_SPECIAL_CHARS) == NULL) + return strlen (string); + else + { + char qchar = '\0'; /* last quote character: none or ' or " */ + size_t length = 0; + + for (; *string != '\0'; string++) + { + char c = *string; + char q = (c == '\'' ? '"' : '\''); + + if (qchar != q) + { + if (qchar) + length++; + qchar = q; + length++; + } + length++; + } + if (qchar) + length++; + + return length; + } +} + +/* Copies the quoted string to p and returns the incremented p. */ +char * +shell_quote_copy (p, string) + char *p; + const char *string; +{ + if (strpbrk (string, SHELL_SPECIAL_CHARS) == NULL) + { + memcpy (p, string, strlen (string)); + return p + strlen (string); + } + else + { + char qchar = '\0'; /* last quote character: none or ' or " */ + + for (; *string != '\0'; string++) + { + char c = *string; + char q = (c == '\'' ? '"' : '\''); + + if (qchar != q) + { + if (qchar) + *p++ = qchar; + qchar = q; + *p++ = qchar; + } + *p++ = c; + } + if (qchar) + *p++ = qchar; + + return p; + } +} + +/* Returns the freshly allocated quoted string. */ +char * +shell_quote (string) + const char *string; +{ + size_t length = shell_quote_length (string); + char *quoted = (char *) xmalloc (length + 1); + char *p = shell_quote_copy (quoted, string); + *p = '\0'; + return quoted; +} + +/* Returns a freshly allocated string containing all argument strings, quoted, + separated through spaces. */ +char * +shell_quote_argv (argv) + char **argv; +{ + if (*argv != NULL) + { + char **argp; + size_t length; + char *command; + char *p; + + length = 0; + for (argp = argv; ; ) + { + length += shell_quote_length (*argp) + 1; + argp++; + if (*argp == NULL) + break; + } + + command = (char *) xmalloc (length); + + p = command; + for (argp = argv; ; ) + { + p = shell_quote_copy (p, *argp); + argp++; + if (*argp == NULL) + break; + *p++ = ' '; + } + *p = '\0'; + + return command; + } + else + return xstrdup (""); +} diff --git a/lib/sh-quote.h b/lib/sh-quote.h new file mode 100644 index 0000000..8c18c98 --- /dev/null +++ b/lib/sh-quote.h @@ -0,0 +1,36 @@ +/* Shell quoting. + Copyright (C) 2001 Free Software Foundation, Inc. + Written by Bruno Haible <haible@clisp.cons.org>, 2001. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* When passing a command to a shell, we must quote the program name and + arguments, since Unix shells interpret characters like " ", "'", "<", ">", + "$" etc. in a special way. */ + +#include <stddef.h> + +/* Returns the number of bytes needed for the quoted string. */ +extern size_t shell_quote_length PARAMS ((const char *string)); + +/* Copies the quoted string to p and returns the incremented p. */ +extern char * shell_quote_copy PARAMS ((char *p, const char *string)); + +/* Returns the freshly allocated quoted string. */ +extern char * shell_quote PARAMS ((const char *string)); + +/* Returns a freshly allocated string containing all argument strings, quoted, + separated through spaces. */ +extern char * shell_quote_argv PARAMS ((char **argv)); |