X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fextract.c;h=9d47c58bcd8b1fdc04799bcc1cf7e1c54fcc3f91;hb=196caec187f27a3c3e4a68eee6bb388d79dac960;hp=e859c169dfdfc0e51d98acbdd2c67dcd297225a7;hpb=72290b64a6433a3c88ecb7b3044c3047beffeadc;p=chaz%2Ftar diff --git a/src/extract.c b/src/extract.c index e859c16..9d47c58 100644 --- a/src/extract.c +++ b/src/extract.c @@ -18,11 +18,6 @@ #include "system.h" -#include -#ifndef time -time_t time (); -#endif - #if HAVE_UTIME_H # include #else @@ -35,20 +30,10 @@ struct utimbuf #include "common.h" -static time_t now; /* current time */ static int we_are_root; /* true if our effective uid == 0 */ static mode_t newdir_umask; /* umask when creating new directories */ static mode_t current_umask; /* current umask (which is set to 0 if -p) */ -#if 0 -/* "Scratch" space to store the information about a sparse file before - writing the info into the header or extended header. */ -struct sp_array *sparsearray; - -/* Number of elts storable in the sparsearray. */ -int sp_array_size = 10; -#endif - struct delayed_set_stat { struct delayed_set_stat *next; @@ -65,15 +50,16 @@ static struct delayed_set_stat *delayed_set_stat_head; void extr_init (void) { - now = time (0); we_are_root = geteuid () == 0; + same_permissions_option += we_are_root; + same_owner_option += we_are_root; /* Option -p clears the kernel umask, so it does not affect proper restoration of file permissions. New intermediate directories will comply with umask at start of program. */ newdir_umask = umask (0); - if (same_permissions_option) + if (0 < same_permissions_option) current_umask = 0; else { @@ -105,7 +91,7 @@ set_mode (char *file_name, struct stat *stat_info) normal, we merely skip the chmod. This works because we did umask (0) when -p, so umask will have left the specified mode alone. */ - if ((we_are_root || same_permissions_option) + if (0 < same_permissions_option && ((!keep_old_files_option && !unlink_first_option) || (stat_info->st_mode & (S_ISUID | S_ISGID | S_ISVTX)))) if (chmod (file_name, ~current_umask & stat_info->st_mode) < 0) @@ -146,7 +132,7 @@ set_stat (char *file_name, struct stat *stat_info, int symlink_flag) if (incremental_option) utimbuf.actime = stat_info->st_atime; else - utimbuf.actime = now; + utimbuf.actime = start_time; utimbuf.modtime = stat_info->st_mtime; @@ -167,10 +153,8 @@ set_stat (char *file_name, struct stat *stat_info, int symlink_flag) extract as the original owner. Or else, if we are running as a user, leave the owner and group as they are, so we extract as that user. */ - if (we_are_root || same_owner_option) + if (0 < same_owner_option) { -#if HAVE_LCHOWN - /* When lchown exists, it should be used to change the attributes of the symbolic link itself. In this case, a mere chown would change the attributes of the file the symbolic link is pointing to, and @@ -178,11 +162,13 @@ set_stat (char *file_name, struct stat *stat_info, int symlink_flag) if (symlink_flag) { +#if HAVE_LCHOWN if (lchown (file_name, stat_info->st_uid, stat_info->st_gid) < 0) ERROR ((0, errno, _("%s: Cannot lchown to uid %lu gid %lu"), file_name, (unsigned long) stat_info->st_uid, (unsigned long) stat_info->st_gid)); +#endif } else { @@ -191,28 +177,13 @@ set_stat (char *file_name, struct stat *stat_info, int symlink_flag) file_name, (unsigned long) stat_info->st_uid, (unsigned long) stat_info->st_gid)); - } - -#else /* not HAVE_LCHOWN */ - - if (!symlink_flag) - - if (chown (file_name, stat_info->st_uid, stat_info->st_gid) < 0) - ERROR ((0, errno, _("%s: Cannot chown to uid %lu gid %lu"), - file_name, - (unsigned long) stat_info->st_uid, - (unsigned long) stat_info->st_gid)); -#endif/* not HAVE_LCHOWN */ - - if (!symlink_flag) - - /* On a few systems, and in particular, those allowing to give files - away, changing the owner or group destroys the suid or sgid bits. - So let's attempt setting these bits once more. */ - - if (stat_info->st_mode & (S_ISUID | S_ISGID | S_ISVTX)) - set_mode (file_name, stat_info); + /* On a few systems, and in particular, those allowing to give files + away, changing the owner or group destroys the suid or sgid bits. + So let's attempt setting these bits once more. */ + if (stat_info->st_mode & (S_ISUID | S_ISGID | S_ISVTX)) + set_mode (file_name, stat_info); + } } } @@ -231,7 +202,7 @@ make_directories (char *file_name) int status; for (cursor = strchr (file_name, '/'); - cursor != NULL; + cursor; cursor = strchr (cursor + 1, '/')) { /* Avoid mkdir of empty string, if leading or double '/'. */ @@ -272,7 +243,7 @@ make_directories (char *file_name) break; } - errno = saved_errno; /* FIXME: errno should be read-only */ + errno = saved_errno; return did_something; /* tell them to retry if we made one */ } @@ -344,7 +315,7 @@ extract_sparse_file (int fd, off_t *sizeleft, off_t totalsize, char *name) while (*sizeleft > 0) { union block *data_block = find_next_block (); - if (data_block == NULL) + if (! data_block) { ERROR ((0, 0, _("Unexpected EOF on archive file"))); return; @@ -488,15 +459,14 @@ extract_archive (void) case GNUTYPE_SPARSE: sp_array_size = 10; - sparsearray = (struct sp_array *) + sparsearray = xmalloc (sp_array_size * sizeof (struct sp_array)); for (counter = 0; counter < SPARSES_IN_OLDGNU_HEADER; counter++) { - sparsearray[counter].offset = - OFF_FROM_CHARS (current_header->oldgnu_header.sp[counter].offset); - sparsearray[counter].numbytes = - SIZE_FROM_CHARS (current_header->oldgnu_header.sp[counter].numbytes); + struct sparse const *s = ¤t_header->oldgnu_header.sp[counter]; + sparsearray[counter].offset = OFF_FROM_HEADER (s->offset); + sparsearray[counter].numbytes = SIZE_FROM_HEADER (s->numbytes); if (!sparsearray[counter].numbytes) break; } @@ -519,22 +489,23 @@ extract_archive (void) } for (counter = 0; counter < SPARSES_IN_SPARSE_HEADER; counter++) { + struct sparse const *s = &exhdr->sparse_header.sp[counter]; if (counter + ind > sp_array_size - 1) { /* Realloc the scratch area since we've run out of room. */ sp_array_size *= 2; - sparsearray = (struct sp_array *) + sparsearray = xrealloc (sparsearray, - sp_array_size * (sizeof (struct sp_array))); + sp_array_size * sizeof (struct sp_array)); } - if (exhdr->sparse_header.sp[counter].numbytes[0] == 0) + if (s->numbytes[0] == 0) break; sparsearray[counter + ind].offset = - OFF_FROM_CHARS (exhdr->sparse_header.sp[counter].offset); + OFF_FROM_HEADER (s->offset); sparsearray[counter + ind].numbytes = - SIZE_FROM_CHARS (exhdr->sparse_header.sp[counter].numbytes); + SIZE_FROM_HEADER (s->numbytes); } if (!exhdr->sparse_header.isextended) break; @@ -605,7 +576,7 @@ extract_archive (void) #else /* not O_CTG */ if (typeflag == CONTTYPE) { - static int conttype_diagnosed = 0; + static int conttype_diagnosed; if (!conttype_diagnosed) { @@ -645,7 +616,7 @@ extract_archive (void) REAL interesting unless we do this. */ name_length_bis = strlen (CURRENT_FILE_NAME) + 1; - name = (char *) xmalloc (name_length_bis); + name = xmalloc (name_length_bis); memcpy (name, CURRENT_FILE_NAME, name_length_bis); size = current_stat.st_size; extract_sparse_file (fd, &size, current_stat.st_size, name); @@ -667,7 +638,7 @@ extract_archive (void) worked. */ data_block = find_next_block (); - if (data_block == NULL) + if (! data_block) { ERROR ((0, 0, _("Unexpected EOF on archive file"))); break; /* FIXME: What happens, then? */ @@ -677,7 +648,7 @@ extract_archive (void) if (written > size) written = size; - errno = 0; /* FIXME: errno should be read-only */ + errno = 0; sstatus = full_write (fd, data_block->buffer, written); set_next_block_after ((union block *) @@ -701,7 +672,7 @@ extract_archive (void) } if (multi_volume_option) - assign_string (&save_name, NULL); + assign_string (&save_name, 0); /* If writing to stdout, don't try to do anything to the filename; it doesn't exist, or we don't want to touch it anyway. */ @@ -753,7 +724,7 @@ extract_archive (void) #else { - static int warned_once = 0; + static int warned_once; if (!warned_once) { @@ -915,7 +886,7 @@ extract_archive (void) if (stat (CURRENT_FILE_NAME, &st1) == 0 && S_ISDIR (st1.st_mode)) goto check_perms; - errno = saved_errno; /* FIXME: errno should be read-only */ + errno = saved_errno; } if (maybe_recoverable (CURRENT_FILE_NAME)) @@ -946,7 +917,7 @@ extract_archive (void) } #if !MSDOS - /* MSDOS does not associate timestamps with directories. In this + /* MSDOS does not associate time stamps with directories. In this case, no need to try delaying their restoration. */ if (touch_option) @@ -959,8 +930,7 @@ extract_archive (void) else { - data = ((struct delayed_set_stat *) - xmalloc (sizeof (struct delayed_set_stat))); + data = xmalloc (sizeof (struct delayed_set_stat)); data->file_name = xstrdup (CURRENT_FILE_NAME); data->stat_info = current_stat; data->next = delayed_set_stat_head; @@ -1014,7 +984,7 @@ apply_delayed_set_stat (void) { struct delayed_set_stat *data; - while (delayed_set_stat_head != NULL) + while (delayed_set_stat_head) { data = delayed_set_stat_head; delayed_set_stat_head = delayed_set_stat_head->next;