X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fextract.c;h=aa699805eee3d0e68d0dd698bba4038b267df452;hb=559eeb2b522e7354ab21985d562d4f2a626288e0;hp=b3f06dc4db6744381c17f016222723c5a16f3b69;hpb=c402183f88a299868f78db5852c65f1b6eb8217f;p=chaz%2Ftar diff --git a/src/extract.c b/src/extract.c index b3f06dc..aa69980 100644 --- a/src/extract.c +++ b/src/extract.c @@ -1,5 +1,5 @@ /* Extract files from a tar archive. - Copyright (C) 1988, 92,93,94,96,97,98, 1999 Free Software Foundation, Inc. + Copyright 1988, 92,93,94,96,97,98, 1999 Free Software Foundation, Inc. Written by John Gilmore, on 1985-11-19. This program is free software; you can redistribute it and/or modify it @@ -18,9 +18,6 @@ #include "system.h" -#include -time_t time (); - #if HAVE_UTIME_H # include #else @@ -33,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; @@ -63,15 +50,16 @@ static struct delayed_set_stat *delayed_set_stat_head; void extr_init (void) { - now = time ((time_t *) 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 { @@ -103,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) @@ -144,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; @@ -165,7 +153,7 @@ 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 @@ -229,7 +217,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 '/'. */ @@ -247,16 +235,6 @@ make_directories (char *file_name) if (status == 0) { - /* Fix ownership. */ - - if (we_are_root) - if (chown (file_name, current_stat.st_uid, current_stat.st_gid) < 0) - ERROR ((0, errno, - _("%s: Cannot change owner to uid %lu, gid %lu"), - file_name, - (unsigned long) current_stat.st_uid, - (unsigned long) current_stat.st_gid)); - print_for_mkdir (file_name, cursor - file_name, ~newdir_umask & MODE_RWX); did_something = 1; @@ -352,7 +330,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; @@ -375,6 +353,11 @@ extract_sparse_file (int fd, off_t *sizeleft, off_t totalsize, char *name) *sizeleft -= count; set_next_block_after (data_block); data_block = find_next_block (); + if (! data_block) + { + ERROR ((0, 0, _("Unexpected EOF on archive file"))); + return; + } } count = full_write (fd, data_block->buffer, written); @@ -447,15 +430,14 @@ extract_archive (void) skipcrud = 0; while (!absolute_names_option && CURRENT_FILE_NAME[0] == '/') { - static int warned_once = 0; + static int warned_once; - skipcrud++; /* force relative path */ if (!warned_once) { warned_once = 1; - WARN ((0, 0, _("\ -Removing leading `/' from absolute path names in the archive"))); + WARN ((0, 0, _("Removing leading `/' from archive names"))); } + skipcrud++; /* force relative path */ } /* Take a safety backup of a previously existing file. */ @@ -492,15 +474,14 @@ Removing leading `/' from absolute path names in the archive"))); 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; } @@ -516,26 +497,30 @@ Removing leading `/' from absolute path names in the archive"))); while (1) { exhdr = find_next_block (); + if (! exhdr) + { + ERROR ((0, 0, _("Unexpected EOF on archive file"))); + return; + } 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)); } - /* Compare to 0, or use !(int)..., for Pyramid's dumb - compiler. */ - if (exhdr->sparse_header.sp[counter].numbytes == 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; @@ -606,7 +591,7 @@ Removing leading `/' from absolute path names in the archive"))); #else /* not O_CTG */ if (typeflag == CONTTYPE) { - static int conttype_diagnosed = 0; + static int conttype_diagnosed; if (!conttype_diagnosed) { @@ -646,7 +631,7 @@ Removing leading `/' from absolute path names in the archive"))); 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); @@ -668,7 +653,7 @@ Removing leading `/' from absolute path names in the archive"))); 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? */ @@ -702,7 +687,7 @@ Removing leading `/' from absolute path names in the archive"))); } 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. */ @@ -754,13 +739,13 @@ Removing leading `/' from absolute path names in the archive"))); #else { - static int warned_once = 0; + static int warned_once; if (!warned_once) { warned_once = 1; - WARN ((0, 0, _("\ -Attempting extraction of symbolic links as hard links"))); + WARN ((0, 0, + _("Attempting extraction of symbolic links as hard links"))); } } /* Fall through. */ @@ -947,7 +932,7 @@ Attempting extraction of symbolic links as hard links"))); } #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) @@ -960,8 +945,7 @@ Attempting extraction of symbolic links as hard links"))); 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; @@ -980,8 +964,8 @@ Attempting extraction of symbolic links as hard links"))); break; case GNUTYPE_MULTIVOL: - ERROR ((0, 0, _("\ -Cannot extract `%s' -- file is continued from another volume"), + ERROR ((0, 0, + _("Cannot extract `%s' -- file is continued from another volume"), current_file_name)); skip_file (current_stat.st_size); if (backup_option) @@ -1015,7 +999,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;