bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Sharutils 4.8: properly quote file names in shar script


From: Andreas Schwab
Subject: Sharutils 4.8: properly quote file names in shar script
Date: Sun, 21 Feb 2010 10:39:34 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1.92 (gnu/linux)

2010-02-21  Andreas Schwab  <address@hidden>

        * bootstrap: Add quotearg gnulib module.
        * src/shar.c: Include "quotearg.h"
        (generate_mkdir): Properly quote file names in shar script.
        (change_files): Likewise.
        (shar): Likewise.  Don't use fixed size buffer.
        * tests/shar-1.ok: Adjust.

--- bootstrap.~1.53.~   2010-02-19 22:00:24.000000000 +0100
+++ bootstrap   2010-02-21 10:03:10.000000000 +0100
@@ -154,6 +154,7 @@ setup_configure() {
        memset
        mktime
        pathmax
+       quotearg
        realloc
        stpcpy
        string
--- src/shar.c.~1.53.~  2010-02-19 22:00:48.000000000 +0100
+++ src/shar.c  2010-02-21 10:20:56.000000000 +0100
@@ -132,6 +132,7 @@ struct tm *localtime ();
 # define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
 #endif
 
+#include "quotearg.h"
 #include "whoami.c"
 #include "md5.c"
 
@@ -684,6 +685,8 @@ static void
 generate_mkdir (path)
      const char *path;
 {
+  char *quoted_path;
+
   /* If already generated code for this dir creation, don't do again.  */
 
   {
@@ -724,18 +727,19 @@ generate_mkdir (path)
 
   /* Generate the text.  */
 
-  fprintf (output, "if test ! -d '%s'; then\n", path);
+  quoted_path = quotearg_n_style (2, shell_always_quoting_style, path);
+  fprintf (output, "if test ! -d '%s'; then\n", quoted_path);
   if (!quiet_unshar_mode)
     {
       const char* did_pz =
-       N_("x - created directory `%s'\\''.");
+       N_("x - created directory `'%s\\''.");
       const char* not_pz =
-       N_("x - failed to create directory `%s'\\''.");
-      fprintf (output, "  mkdir '%s'\n", path);
-      echo_status ("test $? -eq 0", did_pz, not_pz, path, 1);
+       N_("x - failed to create directory `'%s\\''.");
+      fprintf (output, "  mkdir %s\n", quoted_path);
+      echo_status ("test $? -eq 0", did_pz, not_pz, quoted_path, 1);
     }
   else
-    fprintf (output, "  mkdir '%s' || exit 1\n", path);
+    fprintf (output, "  mkdir %s || exit 1\n", quoted_path);
   fputs ("fi\n", output);
 }
 
@@ -974,7 +978,7 @@ change_files (const char *restore_name,
      failed.  */
 
   fputs (" :\n", output);
-  echo_status ("test $? -ne 0", N_("restore of %s failed"), NULL,
+  echo_status ("test $? -ne 0", N_("restore of '%s' failed"), NULL,
               restore_name, 0);
 
   fputs ("'\n${echo} '", output);
@@ -1038,6 +1042,7 @@ shar (local_name, restore_name)
   const char *file_type;       /* text of binary */
   const char *file_type_remote;        /* text or binary, avoiding locale */
   struct tm *restore_time;
+  const char *quoted_local_name, *quoted_restore_name;
 
   /* Check to see that this is still a regular file and readable.  */
 
@@ -1052,6 +1057,11 @@ shar (local_name, restore_name)
       return 1;
     }
 
+  quoted_local_name = quotearg_n_style (0, shell_always_quoting_style,
+                                       local_name);
+  quoted_restore_name = quotearg_n_style (1, shell_always_quoting_style,
+                                         restore_name);
+
   /* If file_size_limit set, get the current output length.  */
 
   if (file_size_limit)
@@ -1065,7 +1075,7 @@ shar (local_name, restore_name)
               ? struct_stat.st_size + struct_stat.st_size / 3
               : struct_stat.st_size)
              > remaining_size))
-        change_files (restore_name, remaining_size);
+        change_files (quoted_restore_name, remaining_size);
     }
   else
     remaining_size = 0;                /* give some value to the variable */
@@ -1174,23 +1184,24 @@ shar (local_name, restore_name)
              /* Start writing the pipe with encodes.  */
 
              FILE *outptr;
+             char *cmdline = alloca (strlen (quoted_local_name) + 100);
 
              if (compressed_file_mode)
                {
-                 sprintf (buffer, "compress -b%d < '%s'",
-                          bits_per_compressed_byte, local_name);
-                 input = popen (buffer, "r");
+                 sprintf (cmdline, "compress -b%d < %s",
+                          bits_per_compressed_byte, quoted_local_name);
+                 input = popen (cmdline, "r");
                }
              else if (gzipped_file_mode)
                {
-                 sprintf (buffer, "gzip -%d < '%s'",
-                          gzip_compression_level, local_name);
-                 input = popen (buffer, "r");
+                 sprintf (cmdline, "gzip -%d < %s",
+                          gzip_compression_level, quoted_local_name);
+                 input = popen (cmdline, "r");
                }
              else if (bzipped_file_mode)
                {
-                 sprintf (buffer, "bzip2 < '%s'", local_name);
-                 input = popen (buffer, "r");
+                 sprintf (cmdline, "bzip2 < '%s'", quoted_local_name);
+                 input = popen (cmdline, "r");
                }
              else
                input = fopen (local_name, "rb");
@@ -1234,27 +1245,27 @@ shar (local_name, restore_name)
 
   if (check_existing_mode)
     {
-      fprintf (output, "if test -f '%s' && test \"$first_param\" != -c; 
then\n",
-              restore_name);
+      fprintf (output, "if test -f %s && test \"$first_param\" != -c; then\n",
+              quoted_restore_name);
 
       if (query_user_mode)
        {
           char* pzOverwriting = scribble;
           char* pzOverwrite;
 
-          sprintf (pzOverwriting, N_("overwriting %s"), restore_name);
+          sprintf (pzOverwriting, N_("overwriting '%s'"), quoted_restore_name);
           pzOverwrite = scribble + strlen(pzOverwriting) + 2;
-          sprintf (pzOverwrite, N_("overwrite %s"), restore_name);
+          sprintf (pzOverwrite, N_("overwrite '%s'"), quoted_restore_name);
 
           fprintf (output, query_user_z, pzOverwriting, pzOverwrite);
 
-          sprintf (pzOverwriting, N_("SKIPPING %s"), restore_name);
+          sprintf (pzOverwriting, N_("SKIPPING '%s'"), quoted_restore_name);
           fprintf (output, query_check_z, N_("extraction aborted"),
                   pzOverwriting, pzOverwriting);
        }
       else
-        echo_text (N_("SKIPPING %s (file already exists)"),
-                   restore_name, 0);
+        echo_text (N_("SKIPPING '%s' (file already exists)"),
+                   quoted_restore_name, 0);
 
       if (split_file_mode)
        fputs ("  rm -f ${lock_dir}/new\nelse\n  > ${lock_dir}/new\n", output);
@@ -1267,8 +1278,8 @@ shar (local_name, restore_name)
 
   if (!quiet_unshar_mode)
     {
-      sprintf (scribble, N_("x - extracting %s %s"),
-               restore_name, file_type_remote);
+      sprintf (scribble, N_("x - extracting '%s' %s"),
+               quoted_restore_name, file_type_remote);
       fprintf (output, echo_string_z, scribble);
     }
 
@@ -1277,8 +1288,8 @@ shar (local_name, restore_name)
 
       /* Just touch the file, or empty it if it exists.  */
 
-      fprintf (output, "  > '%s' &&\n",
-              restore_name);
+      fprintf (output, "  > %s &&\n",
+              quoted_restore_name);
     }
   else
     {
@@ -1301,8 +1312,8 @@ shar (local_name, restore_name)
 
          /* Just run it into the file.  */
 
-         fprintf (output, "  sed 's/^%c//' << '%s' > '%s' &&\n",
-                  line_prefix, here_delimiter, restore_name);
+         fprintf (output, "  sed 's/^%c//' << '%s' > %s &&\n",
+                  line_prefix, here_delimiter, quoted_restore_name);
        }
 
       while (fgets (buffer, BUFSIZ, input))
@@ -1383,8 +1394,8 @@ shar (local_name, restore_name)
                 failed.  */
 
              fputs (" :\n", output);
-             echo_status ("test $? -ne 0", N_("restore of %s failed\n"), NULL,
-                          restore_name, 0);
+             echo_status ("test $? -ne 0", N_("restore of '%s' failed\n"), 
NULL,
+                          quoted_restore_name, 0);
 
              if (check_existing_mode)
                fputs ("fi\n", output);
@@ -1507,24 +1518,24 @@ shar (local_name, restore_name)
          if (!quiet_unshar_mode)
             echo_text (N_("uncompressing file %s"), restore_name, 1);
 
-         fprintf (output, "  compress -d < ${lock_dir}/cmp > '%s' &&\n",
-                  restore_name);
+         fprintf (output, "  compress -d < ${lock_dir}/cmp > %s &&\n",
+                  quoted_restore_name);
        }
       else if (gzipped_file_mode)
        {
          if (!quiet_unshar_mode)
             echo_text (N_("gunzipping file %s"), restore_name, 1);
 
-         fprintf (output, "  gzip -d < ${lock_dir}/gzi > '%s' &&\n",
-                  restore_name);
+         fprintf (output, "  gzip -d < ${lock_dir}/gzi > %s &&\n",
+                  quoted_restore_name);
        }
       else if (bzipped_file_mode)
        {
          if (!quiet_unshar_mode)
             echo_text (N_("bunzipping file %s"), restore_name, 1);
 
-         fprintf (output, "  bzip2 -d < ${lock_dir}/bzi > '%s' &&\n",
-                  restore_name);
+         fprintf (output, "  bzip2 -d < ${lock_dir}/bzi > %s &&\n",
+                  quoted_restore_name);
        }
     }
 
@@ -1535,12 +1546,12 @@ shar (local_name, restore_name)
 
       restore_time = localtime (&struct_stat.st_mtime);
       fprintf (output, "\
-  (set %02d %02d %02d %02d %02d %02d %02d '%s'; eval \"$shar_touch\") &&\n",
+  (set %02d %02d %02d %02d %02d %02d %02d %s; eval \"$shar_touch\") &&\n",
               (restore_time->tm_year + 1900) / 100,
               (restore_time->tm_year + 1900) % 100,
               restore_time->tm_mon + 1, restore_time->tm_mday,
               restore_time->tm_hour, restore_time->tm_min,
-              restore_time->tm_sec, restore_name);
+              restore_time->tm_sec, quoted_restore_name);
     }
 
   if (vanilla_operation_mode)
@@ -1549,8 +1560,8 @@ shar (local_name, restore_name)
       /* Close the "&&" and report an error if any of the above
         failed.  */
       fputs (":\n", output);
-      echo_status ("test $? -ne 0", N_("restore of %s failed"), NULL,
-                  restore_name, 0);
+      echo_status ("test $? -ne 0", N_("restore of '%s' failed"), NULL,
+                  quoted_restore_name, 0);
     }
   else
     {
@@ -1560,13 +1571,13 @@ shar (local_name, restore_name)
 
       /* Set the permissions as they were.  */
 
-      fprintf (output, "  chmod %04o '%s'\n",
-              (unsigned) (struct_stat.st_mode & 0777), restore_name);
+      fprintf (output, "  chmod %04o %s\n",
+              (unsigned) (struct_stat.st_mode & 0777), quoted_restore_name);
 
       /* Report an error if any of the above failed.  */
 
-      echo_status ("test $? -ne 0", N_("restore of %s failed"), NULL,
-                  restore_name, 0);
+      echo_status ("test $? -ne 0", N_("restore of '%s' failed"), NULL,
+                  quoted_restore_name, 0);
 
       if (md5_count_mode && (fp = fopen (local_name, "r")) != NULL
          && md5_stream (fp, md5buffer) == 0)
@@ -1575,7 +1586,7 @@ shar (local_name, restore_name)
          size_t cnt;
          did_md5 = 1;
 
-         fprintf (output, md5test_z, restore_name,
+         fprintf (output, md5test_z, quoted_restore_name,
                   N_("MD5 check failed"), here_delimiter);
 
          for (cnt = 0; cnt < 16; ++cnt)
@@ -1595,9 +1606,10 @@ shar (local_name, restore_name)
          /* Validate the transferred file using simple `wc' command.  */
 
          FILE *pfp;
-         char command[BUFSIZ];
+         char *command = alloca (strlen (CHARACTER_COUNT_COMMAND)
+                                  + strlen (quoted_local_name) + 2);
 
-         sprintf (command, "LC_ALL=C wc -c < '%s'", local_name);
+         sprintf (command, "%s %s", CHARACTER_COUNT_COMMAND, 
quoted_local_name);
          if (pfp = popen (command, "r"), pfp)
            {
              char wc[BUFSIZ];
@@ -1629,11 +1641,11 @@ shar (local_name, restore_name)
               }
 
              fprintf (output,
-                       "test `LC_ALL=C wc -c < '%s'` -ne %s && \\\n  ${echo} ",
-                       restore_name, wc);
+                       "test `%s %s` -ne %s && \\\n  ${echo} ",
+                       CHARACTER_COUNT_COMMAND, quoted_restore_name, wc);
               fprintf (output,
-                       N_("'restoration warning:  size of %s is not %s'\n"),
-                       restore_name, wc);
+                       N_("'restoration warning:  size of '%s' is not %s'\n"),
+                       quoted_restore_name, wc);
              pclose (pfp);
            }
        }
--- tests/shar-1.ok.~1.25.~     2010-02-18 16:33:00.000000000 +0100
+++ tests/shar-1.ok     2010-02-21 10:22:33.000000000 +0100
@@ -94,26 +94,26 @@ else ${echo} 'x - failed to create lock
 fi
 # ============= shar-1.in ==============
 if test -f 'shar-1.in' && test "$first_param" != -c; then
-  ${echo} 'x -SKIPPING shar-1.in (file already exists)'
+  ${echo} 'x -SKIPPING ''shar-1.in'' (file already exists)'
 else
-${echo} 'x - extracting shar-1.in (text)'
+${echo} 'x - extracting ''shar-1.in'' (text)'
   sed 's/^X//' << 'SHAR_EOF' > 'shar-1.in' &&
 This is a test
 SHAR_EOF
   (set <date> 'shar-1.in'; eval "$shar_touch") &&
   chmod 0644 'shar-1.in'
 if test $? -ne 0
-then ${echo} 'restore of shar-1.in failed'
+then ${echo} 'restore of ''shar-1.in'' failed'
 fi
   if ${md5check}
   then (
-       ${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'shar-1.in: MD5 check failed'
+       ${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'shar-1.in': 'MD5 check failed'
        ) << \SHAR_EOF
 ff22941336956098ae9a564289d1bf1b  shar-1.in
 SHAR_EOF
   else
 test `LC_ALL=C wc -c < 'shar-1.in'` -ne 15 && \
-  ${echo} 'restoration warning:  size of shar-1.in is not 15'
+  ${echo} 'restoration warning:  size of ''shar-1.in'' is not 15'
   fi
 fi
 if rm -fr ${lock_dir}

Andreas.

-- 
Andreas Schwab, address@hidden
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."




reply via email to

[Prev in Thread] Current Thread [Next in Thread]