states.man: Escape backslashes in namerules and startrules examples.
[enscript.git] / src / util.c
index d214549..39b8441 100644 (file)
@@ -6,22 +6,20 @@
  */
 
 /*
- * This file is part of GNU enscript.
+ * This file is part of GNU Enscript.
  *
- * This program is free software; you can redistribute it and/or modify
+ * Enscript 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.
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
  *
- * This program is distributed in the hope that it will be useful,
+ * Enscript 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; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with Enscript.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "gsint.h"
@@ -1239,6 +1237,8 @@ escape_string (char *string)
 
   /* Create result. */
   cp = xmalloc (len + 1);
+  if (cp == NULL)
+      return NULL;
   for (i = 0, j = 0; string[i]; i++)
     switch (string[i])
       {
@@ -1879,6 +1879,7 @@ is_open (InputStream *is, FILE *fp, char *fname, char *input_filter)
       char *cmd = NULL;
       int cmdlen;
       int i, pos;
+      char *cp;
 
       is->is_pipe = 1;
 
@@ -1902,12 +1903,16 @@ is_open (InputStream *is, FILE *fp, char *fname, char *input_filter)
                {
                case 's':
                  /* Expand cmd-buffer. */
-                 cmdlen += strlen (fname);
-                 cmd = xrealloc (cmd, cmdlen);
+                 if ((cp = shell_escape (fname)) != NULL)
+                   {
+                     cmdlen += strlen (cp);
+                     cmd = xrealloc (cmd, cmdlen);
 
-                 /* Paste filename. */
-                 strcpy (cmd + pos, fname);
-                 pos += strlen (fname);
+                     /* Paste filename. */
+                     strcpy (cmd + pos, cp);
+                     pos += strlen (cp);
+                     free (cp);
+                   }
 
                  i++;
                  break;
@@ -2116,3 +2121,36 @@ buffer_len (Buffer *buffer)
 {
   return buffer->len;
 }
+
+/*
+ * Escapes the name of a file so that the shell groks it in 'single'
+ * quotation marks.  The resulting pointer has to be free()ed when not
+ * longer used.
+*/
+char *
+shell_escape(const char *fn)
+{
+  size_t len = 0;
+  const char *inp;
+  char *retval, *outp;
+
+  for(inp = fn; *inp; ++inp)
+    switch(*inp)
+    {
+      case '\'': len += 4; break;
+      default:   len += 1; break;
+    }
+
+  outp = retval = malloc(len + 1);
+  if(!outp)
+    return NULL; /* perhaps one should do better error handling here */
+  for(inp = fn; *inp; ++inp)
+    switch(*inp)
+    {
+      case '\'': *outp++ = '\''; *outp++ = '\\'; *outp++ = '\'', *outp++ = '\''; break;
+      default:   *outp++ = *inp; break;
+    }
+  *outp = 0;
+
+  return retval;
+}