- case LF_LONGNAME:
- longp = &longname;
- goto extract_long;
-
- case LF_LONGLINK
- longp = &longlink;
- extract_long:
-
- if (*longp)
- free (*longp);
- bp = *longp = ck_malloc (hstat.st_size);
-
- for (size = hstat.st_size;
- size > 0;
- size -= written)
- {
- data = findrec ()->charptr;
- if (data == NULL)
- {
- msg ("Unexpected EOF on archive file");
- break;
- }
- written = endofrecs () ->charptr - data;
- if (written > size)
- written = size;
-
- bcopy (data, bp, written);
- bp += written;
- userec ((union record *) (data + written - 1));
- }
- }
-
- if (bumplongs)
- {
- longname = 0;
- longlink = 0;
- }
+ check_perms:
+ if (!we_are_root && 0300 != (0300 & (int) hstat.st_mode))
+ {
+ hstat.st_mode |= 0300;
+ msg ("Added write and execute permission to directory %s",
+ skipcrud + current_file_name);
+ }
+
+ /*
+ * If we are root, set the owner and group of the extracted
+ * file. This does what is wanted both on real Unix and on
+ * System V. If we are running as a user, we extract as that
+ * user; if running as root, we extract as the original owner.
+ */
+ if (we_are_root || f_do_chown)
+ {
+ if (chown (skipcrud + current_file_name,
+ hstat.st_uid, hstat.st_gid) < 0)
+ {
+ msg_perror ("cannot chown file %s to uid %d gid %d",
+ skipcrud + current_file_name,
+ hstat.st_uid, hstat.st_gid);
+ }
+ }
+
+ if (!f_modified)
+ {
+ tmp = ((struct saved_dir_info *)
+ ck_malloc (sizeof (struct saved_dir_info)));
+ tmp->path = (char *) ck_malloc (strlen (skipcrud
+ + current_file_name) + 1);
+ strcpy (tmp->path, skipcrud + current_file_name);
+ tmp->mode = hstat.st_mode;
+ tmp->atime = hstat.st_atime;
+ tmp->mtime = hstat.st_mtime;
+ tmp->next = saved_dir_info_head;
+ saved_dir_info_head = tmp;
+ }
+ else
+ {
+ /* This functions exactly as the code for set_filestat above. */
+ if ((!f_keep)
+ || (hstat.st_mode & (S_ISUID | S_ISGID | S_ISVTX)))
+ {
+ if (chmod (skipcrud + current_file_name,
+ notumask & (int) hstat.st_mode) < 0)
+ {
+ msg_perror ("cannot change mode of file %s to %lo",
+ skipcrud + current_file_name,
+ notumask & (int) hstat.st_mode);
+ }
+ }
+ }
+ break;