paxutils-forum
[Top][All Lists]
Advanced

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

Re: FW: GNU tar 1.13.17 --overwrite works "wrong"


From: Paul Eggert
Subject: Re: FW: GNU tar 1.13.17 --overwrite works "wrong"
Date: Tue, 13 Mar 2001 17:48:08 -0800 (PST)

> From: "Patterson, Ross" <address@hidden>
> Date: Tue, 13 Mar 2001 15:03:00 -0500
> 
> So, what's a poor boy to do?  I can't ask for a tar patch, I've got
> to be able to install on systems already in the field today.

Create your tar files so that instead of this:

$ tar tvf tar
drwxrwsr-x eggert/eggert     0 2001-03-13 15:33:19 a/
-rw-rw-r-- eggert/eggert     4 2001-03-13 15:33:19 a/x
drwxrwsr-x eggert/eggert     0 2001-03-13 15:33:22 b/
-rw-rw-r-- eggert/eggert     4 2001-03-13 15:33:22 b/x

You see this:

$ tar tvf tar1
drwxrwsr-x eggert/eggert     0 2001-03-13 15:33:19 a/./
-rw-rw-r-- eggert/eggert     4 2001-03-13 15:33:19 a/./x
drwxrwsr-x eggert/eggert     0 2001-03-13 15:33:22 b/./
-rw-rw-r-- eggert/eggert     4 2001-03-13 15:33:22 b/./x

The extra "/." will cause the symlink to be dereferenced.

You didn't ask for a patch, but you might try the following one anyway,
(relative to tar 1.13.19).


--- extract.c   2001/01/13 05:59:29     1.12.0.22
+++ extract.c   2001/03/14 01:42:31
@@ -282,7 +282,6 @@ delay_set_stat (char const *file_name, s
 /* Update the delayed_set_stat info for an intermediate directory
    created on the path to DIR_NAME.  The intermediate directory turned
-   out to be the same as this directory, e.g. due trailing slash or
-   ".." or symbolic links.  *DIR_STAT_INFO is the status of the
-   directory.  */
+   out to be the same as this directory, e.g. due to ".." or symbolic
+   links.  *DIR_STAT_INFO is the status of the directory.  */
 static void
 repair_delayed_set_stat (char const *dir_name,
@@ -1019,4 +1018,9 @@ extract_archive (void)
 
     really_dir:
+      /* Remove any redundant trailing "/"s.  */
+      while (FILESYSTEM_PREFIX_LEN (CURRENT_FILE_NAME) < name_length
+            && CURRENT_FILE_NAME[name_length - 1] == '/')
+       name_length--;
+      CURRENT_FILE_NAME[name_length] = '\0';
 
       if (incremental_option)
@@ -1038,26 +1042,24 @@ extract_archive (void)
 
     again_dir:
-      {
-       /* Do not pass redundant trailing "/" to mkdir, as POSIX does
-          not allow mkdir to ignore it.  */
-       size_t len = name_length;
-       char ch = '\0';
-       while (FILESYSTEM_PREFIX_LEN (CURRENT_FILE_NAME) < len
-              && CURRENT_FILE_NAME[len - 1] == '/')
-         len--, ch = '/';
-       CURRENT_FILE_NAME[len] = '\0';
-       status = mkdir (CURRENT_FILE_NAME, mode);
-       CURRENT_FILE_NAME[len] = ch;
-      }
+      status = mkdir (CURRENT_FILE_NAME, mode);
 
       if (status != 0)
        {
-         if (errno == EEXIST && interdir_made)
+         if (errno == EEXIST
+             && (interdir_made || old_files_option == OVERWRITE_OLD_FILES))
            {
              struct stat st;
              if (stat (CURRENT_FILE_NAME, &st) == 0)
                {
-                 repair_delayed_set_stat (CURRENT_FILE_NAME, &st);
-                 break;
+                 if (interdir_made)
+                   {
+                     repair_delayed_set_stat (CURRENT_FILE_NAME, &st);
+                     break;
+                   }
+                 if (S_ISDIR (st.st_mode))
+                   {
+                     mode = st.st_mode & ~ current_umask;
+                     goto directory_exists;
+                   }
                }
              errno = EEXIST;
@@ -1076,8 +1078,9 @@ extract_archive (void)
        }
 
+    directory_exists:
       if (status == 0
          || old_files_option == OVERWRITE_OLD_FILES)
        delay_set_stat (CURRENT_FILE_NAME, &current_stat,
-                       mode & ~ current_stat.st_mode,
+                       MODE_RWX & (mode ^ current_stat.st_mode),
                        (status == 0
                         ? ARCHIVED_PERMSTATUS



reply via email to

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