]> Dogcows Code - chaz/tar/commitdiff
(relativize): New function.
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 13 Jan 2001 05:59:29 +0000 (05:59 +0000)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 13 Jan 2001 05:59:29 +0000 (05:59 +0000)
> (relativize): New function, with much of old start_header's guts.
Handle filesystem prefixes.
(start_header): Use this new function.
(init_sparsearray): Don't bother to zero out the new array; it's not needed.
(deal_with_sparse): Fix array allocation bug.
(create_archive): Don't assume '/' is the only separator.
(dump_file): Likewise.
Don't worry about leading / in symlink targets.

src/create.c

index 2a546659ebcf340291be14caae546bc85f587e03..98b16394cbc1807cecbfad76e3525079635e660d 100644 (file)
@@ -1,5 +1,5 @@
 /* Create a tar archive.
-   Copyright 1985, 92, 93, 94, 96, 97, 99, 2000 Free Software Foundation, Inc.
+   Copyright 1985,92,93,94,96,97,99,2000, 2001 Free Software Foundation, Inc.
    Written by John Gilmore, on 1985-08-25.
 
    This program is free software; you can redistribute it and/or modify it
@@ -390,43 +390,14 @@ write_long (const char *p, char type)
   set_next_block_after (header + (size - 1) / BLOCKSIZE);
 }
 \f
-/* Header handling.  */
-
-/* Make a header block for the file whose stat info is st,
-   and return its address.  */
-
-static union block *
-start_header (const char *name, struct stat *st)
+/* Return a suffix of the file NAME that is a relative file name.
+   Warn about `..' in file names.  But return NAME if the user wants
+   absolute file names.  */
+static char const *
+relativize (char const *name)
 {
-  union block *header;
-
-  if (!absolute_names_option)
+  if (! absolute_names_option)
     {
-      size_t prefix_len = FILESYSTEM_PREFIX_LEN (name);
-
-      if (prefix_len)
-       {
-         static int warned_once;
-         if (!warned_once)
-           {
-             warned_once = 1;
-             WARN ((0, 0, _("Removing leading `%.*s' from member names"),
-                    (int) prefix_len, name));
-           }
-         name += prefix_len;
-       }
-
-      while (*name == '/')
-       {
-         static int warned_once;
-         if (!warned_once)
-           {
-             warned_once = 1;
-             WARN ((0, 0, _("Removing leading `/' from member names")));
-           }
-         name++;
-       }
-
       {
        static int warned_once;
        if (! warned_once && contains_dot_dot (name))
@@ -435,8 +406,42 @@ start_header (const char *name, struct stat *st)
            WARN ((0, 0, _("Member names contain `..'")));
          }
       }
+
+      {
+       size_t prefix_len = FILESYSTEM_PREFIX_LEN (name);
+
+       while (ISSLASH (name[prefix_len]))
+         prefix_len++;
+
+       if (prefix_len)
+         {
+           static int warned_once;
+           if (!warned_once)
+             {
+               warned_once = 1;
+               WARN ((0, 0, _("Removing leading `%.*s' from member names"),
+                      (int) prefix_len, name));
+             }
+           name += prefix_len;
+         }
+      }
     }
 
+  return name;
+}
+\f
+/* Header handling.  */
+
+/* Make a header block for the file whose stat info is st,
+   and return its address.  */
+
+static union block *
+start_header (const char *name, struct stat *st)
+{
+  union block *header;
+
+  name = relativize (name);
+
   if (sizeof header->header.name <= strlen (name))
     write_long (name, GNUTYPE_LONGNAME);
   header = find_next_block ();
@@ -595,18 +600,11 @@ zero_block_p (char *buffer)
 static void
 init_sparsearray (void)
 {
-  int counter;
-
   sp_array_size = 10;
 
   /* Make room for our scratch space -- initially is 10 elts long.  */
 
   sparsearray = xmalloc (sp_array_size * sizeof (struct sp_array));
-  for (counter = 0; counter < sp_array_size; counter++)
-    {
-      sparsearray[counter].offset = 0;
-      sparsearray[counter].numbytes = 0;
-    }
 }
 
 static off_t
@@ -651,7 +649,7 @@ deal_with_sparse (char *name, union block *header)
   init_sparsearray ();
   clear_buffer (buffer);
 
-  while (0 < (count = safe_read (file, buffer, sizeof buffer)))
+  for (;;)
     {
       /* Realloc the scratch area as necessary.  FIXME: should reallocate
         only at beginning of a new instance of non-zero data.  */
@@ -663,6 +661,10 @@ deal_with_sparse (char *name, union block *header)
                      2 * sp_array_size * sizeof (struct sp_array));
          sp_array_size *= 2;
        }
+      
+      count = safe_read (file, buffer, sizeof buffer);
+      if (count <= 0)
+       break;
 
       /* Process one block.  */
 
@@ -825,7 +827,7 @@ create_archive (void)
                buffer = xrealloc (buffer, buffer_size);
              }
            memcpy (buffer, p, plen);
-           if (buffer[plen - 1] != '/')
+           if (! ISSLASH (buffer[plen - 1]))
              buffer[plen++] = '/';
            q = gnu_list_name->dir_contents;
            if (q)
@@ -971,7 +973,7 @@ dump_file (char *p, int top_level, dev_t parent_device)
 
       errno = 0;
 
-      directory = savedir (p, current_stat.st_size);
+      directory = savedir (p);
       if (! directory)
        {
          if (ignore_failed_read_option)
@@ -987,7 +989,7 @@ dump_file (char *p, int top_level, dev_t parent_device)
       buflen = len + NAME_FIELD_SIZE;
       namebuf = xmalloc (buflen + 1);
       memcpy (namebuf, p, len);
-      while (len >= 1 && namebuf[len - 1] == '/')
+      while (len >= 1 && ISSLASH (namebuf[len - 1]))
        len--;
       namebuf[len++] = '/';
       namebuf[len] = '\0';
@@ -1156,18 +1158,6 @@ dump_file (char *p, int top_level, dev_t parent_device)
 
              free (lp);
 
-             if (! absolute_names_option)
-               for (; *link_name == '/'; link_name++)
-                 {
-                   static int warned_once;
-                   if (!warned_once)
-                     {
-                       warned_once = 1;
-                       WARN ((0, 0,
-                              _("Removing leading `/' from link names")));
-                     }
-                 }
-
              if (NAME_FIELD_SIZE <= strlen (link_name))
                write_long (link_name, GNUTYPE_LONGLINK);
              assign_string (&current_link_name, link_name);
This page took 0.029012 seconds and 4 git commands to generate.