X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fextract.c;h=84e6a234371f34016a98b1a355e110f22ad903ca;hb=f0ee8aa69ea34b9f6601877a03d70a32faa4b44a;hp=bea66ef9efbefcc84d34591b0dda4f8cd077f0cb;hpb=32841f71caa7337a62ce231ed787609003bce86f;p=chaz%2Ftar diff --git a/src/extract.c b/src/extract.c index bea66ef..84e6a23 100644 --- a/src/extract.c +++ b/src/extract.c @@ -542,7 +542,7 @@ extract_archive () if (chmod (skipcrud + current_file_name, notumask & (int) hstat.st_mode) < 0) { - msg_perror ("cannot change mode of file %s to %ld", + msg_perror ("cannot change mode of file %s to %lo", skipcrud + current_file_name, notumask & (int) hstat.st_mode); } @@ -680,16 +680,53 @@ extract_archive () skipcrud + current_file_name); } - if (f_modified) - goto set_filestat; - tmp = (struct saved_dir_info *) ck_malloc (sizeof (struct saved_dir_info)); - tmp->path = 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; + /* + * 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; + case LF_VOLHDR: if (f_verbose) { @@ -860,7 +897,7 @@ restore_saved_dir_info () if (chmod (saved_dir_info_head->path, notumask & saved_dir_info_head->mode) < 0) { - msg_perror ("cannot change mode of file %s to %ld", + msg_perror ("cannot change mode of file %s to %lo", saved_dir_info_head->path, notumask & saved_dir_info_head->mode); }