home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: gnu.utils.bug
- Path: sparky!uunet!cis.ohio-state.edu!mozart.informatik.rwth-aachen.de!norbert
- From: norbert@mozart.informatik.rwth-aachen.de (Norbert Kiesel)
- Subject: tar-1.11 bugs (with fixes)
- Message-ID: <9209101702.AA10675@rwthi3.informatik.rwth-aachen.de>
- Sender: gnulists@ai.mit.edu
- Organization: GNUs Not Usenet
- Distribution: gnu
- Date: Thu, 10 Sep 1992 21:02:20 GMT
- Approved: bug-gnu-utils@prep.ai.mit.edu
- Lines: 352
-
- Hello,
- there are bugs within tar-1.11 which make it quite useless: both the
- creation and the extracting of tar files fails (and dumps core)
- because tar isn't aware of the current file name. The variable
- current_file_name either points into a data block which is filled with
- the contents of the files (extraction) or points to nowhere (creation
- with verbose flag).
-
- I've changed (i.e hacked :-) the program to avoid this errors (patch
- below). However, I think the maintainers of tar should have a close
- look upon the usage of the global variables and clean this code!
-
-
- so long
-
- Norbert
-
-
- *******************************************************************************
- * Norbert Kiesel Institut f. Informatik III NN NN KK KK *
- * RWTH Aachen Ahornstr. 55 NNN NN KK KK *
- * West Germany D-5100 Aachen NN N NN KK KK *
- * +49 241 80-7266 NN N NN KKKK *
- * NN N NN KKKK *
- * EUNET: norbert@rwthi3.uucp NN N NN KK KK *
- * USENET: ...!mcvax!unido!rwthi3!norbert NN N NN KK KK *
- * INTERNET: norbert@rwthi3.informatik.rwth-aachen.de NN NNN KK KK *
- *******************************************************************************
-
- --- list.c~ Tue Sep 8 22:22:38 1992
- +++ list.c Thu Sep 10 18:47:49 1992
- @@ -529,6 +529,8 @@
- fprintf(msg_file,"rec %10d: ",baserec + (ar_record - ar_block));
- /* annofile(msg_file, (char *)NULL); */
-
- + current_file_name = head->header.arch_name;
- +
- if (f_verbose <= 1) {
- /* Just the fax, mam. */
- char *name;
- --- extract.c~ Tue Sep 8 22:09:11 1992
- +++ extract.c Thu Sep 10 18:26:17 1992
- @@ -147,7 +147,9 @@
- /* int end_nulls; */
- char **longp;
- char *bp;
- + char *name;
-
- +
- saverec(&head); /* Make sure it sticks around */
- userec(head); /* And go past it in the archive */
- decode_header(head, &hstat, &head_standard, 1); /* Snarf fields */
- @@ -183,11 +185,15 @@
- }
- }
-
- - switch (head->header.linkflag) {
- + namelen = strlen(skipcrud + current_file_name);
- + name = (char *) malloc((sizeof(char)) * namelen);
- + strcpy(name, skipcrud+current_file_name);
- +
- + switch (head->header.linkflag) {
-
- - default:
- + default:
- msg("Unknown file type '%c' for %s, extracted as normal file",
- - head->header.linkflag, skipcrud+current_file_name);
- + head->header.linkflag, name);
- /* FALL THRU */
-
- /*
- @@ -266,8 +272,8 @@
- * Appears to be a file.
- * See if it's really a directory.
- */
- - namelen = strlen(skipcrud+current_file_name)-1;
- - if (current_file_name[skipcrud+namelen] == '/')
- + namelen = strlen(name)-1;
- + if (name[namelen] == '/')
- goto really_dir;
-
- /* FIXME, deal with protection issues */
- @@ -319,16 +325,14 @@
- /*
- * With 3-arg open(), we can do this up right.
- */
- - fd = open(skipcrud + current_file_name,
- - openflag, hstat.st_mode);
- + fd = open(name, openflag, hstat.st_mode);
- #endif
- }
-
- if (fd < 0) {
- - if (make_dirs(skipcrud + current_file_name))
- + if (make_dirs(name))
- goto again_file;
- - msg_perror("Could not create file %s",
- - skipcrud + current_file_name);
- + msg_perror("Could not create file %s", name);
- if (head->header.isextended)
- skip_extended_headers();
- skip_file((long)hstat.st_size);
- @@ -337,8 +341,6 @@
-
- extract_file:
- if (head->header.linkflag == LF_SPARSE) {
- - char *name;
- - int namelen;
-
- /*
- * Kludge alert. NAME is assigned to header.name
- @@ -348,9 +350,7 @@
- * that happen to contain the filename will look
- * REAL interesting unless we do this.
- */
- - namelen = strlen(skipcrud + current_file_name);
- - name = (char *) malloc((sizeof(char)) * namelen);
- - bcopy(skipcrud+current_file_name, name, namelen);
- + namelen = strlen(name);
- size = hstat.st_size;
- extract_sparse_file(fd, &size, hstat.st_size, name);
- }
- @@ -410,10 +410,10 @@
- */
- if(check<0)
- msg_perror("couldn't write to file %s",
- - skipcrud + current_file_name);
- + name);
- else
- msg("could only write %d of %d bytes to file %s",
- - written,check,skipcrud + current_file_name);
- + written,check,name);
- skip_file((long)(size - written));
- break; /* Still do the close, mod time, chmod, etc */
- }
- @@ -450,8 +450,7 @@
- }*/
- check = close(fd);
- if (check < 0) {
- - msg_perror("Error while closing %s",
- - skipcrud + current_file_name);
- + msg_perror("Error while closing %s", name);
- }
-
-
- @@ -464,11 +463,9 @@
- * 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) {
- + if (chown(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);
- + name, hstat.st_uid,hstat.st_gid);
- }
- }
-
- @@ -485,9 +482,8 @@
- acc_upd_times[0]=hstat.st_atime;
- else acc_upd_times[0] = now; /* Accessed now */
- acc_upd_times[1] = hstat.st_mtime; /* Mod'd */
- - if (utime(skipcrud + current_file_name,
- - acc_upd_times) < 0) {
- - msg_perror("couldn't change access and modification times of %s",skipcrud + current_file_name);
- + if (utime(name, acc_upd_times) < 0) {
- + msg_perror("couldn't change access and modification times of %s",name);
- }
- }
- /* We do the utime before the chmod because some versions of
- @@ -509,11 +505,9 @@
- */
- if ((!f_keep)
- || (hstat.st_mode & (S_ISUID|S_ISGID|S_ISVTX))) {
- - if (chmod(skipcrud + current_file_name,
- - notumask & (int)hstat.st_mode) < 0) {
- + if (chmod(name, notumask & (int)hstat.st_mode) < 0) {
- msg_perror("cannot change mode of file %s to %ld",
- - skipcrud + current_file_name,
- - notumask & (int)hstat.st_mode);
- + name, notumask & (int)hstat.st_mode);
- }
- }
-
- @@ -525,22 +519,21 @@
- {
- struct stat st1,st2;
-
- - check = link (current_link_name, skipcrud + current_file_name);
- + check = link (current_link_name, name);
-
- if (check == 0)
- break;
- - if (make_dirs(skipcrud + current_file_name))
- + if (make_dirs(name))
- goto again_link;
- if(f_gnudump && errno==EEXIST)
- break;
- if(stat(current_link_name, &st1) == 0
- - && stat(current_file_name + skipcrud, &st2)==0
- + && stat(name, &st2)==0
- && st1.st_dev==st2.st_dev
- && st1.st_ino==st2.st_ino)
- break;
- msg_perror("Could not link %s to %s",
- - skipcrud + current_file_name,
- - current_link_name);
- + name, current_link_name);
- }
- break;
-
- @@ -547,12 +540,11 @@
- #ifdef S_ISLNK
- case LF_SYMLINK:
- again_symlink:
- - check = symlink(current_link_name,
- - skipcrud + current_file_name);
- + check = symlink(current_link_name, name);
- /* FIXME, don't worry uid, gid, etc... */
- if (check == 0)
- break;
- - if (make_dirs(current_file_name + skipcrud))
- + if (make_dirs(name))
- goto again_symlink;
- msg_perror("Could not create symlink to %s",
- current_link_name);
- @@ -571,13 +563,11 @@
- #endif
- #if defined(S_IFCHR) || defined(S_IFBLK)
- make_node:
- - check = mknod(current_file_name + skipcrud,
- - (int) hstat.st_mode, (int) hstat.st_rdev);
- + check = mknod(name, (int) hstat.st_mode, (int) hstat.st_rdev);
- if (check != 0) {
- - if (make_dirs(skipcrud + current_file_name))
- + if (make_dirs(name))
- goto make_node;
- - msg_perror("Could not make %s",
- - current_file_name + skipcrud);
- + msg_perror("Could not make %s", name);
- break;
- };
- goto set_filestat;
- @@ -587,13 +577,11 @@
- /* If local system doesn't support FIFOs, use default case */
- case LF_FIFO:
- make_fifo:
- - check = mkfifo(current_file_name + skipcrud,
- - (int) hstat.st_mode);
- + check = mkfifo(name, (int) hstat.st_mode);
- if (check != 0) {
- - if (make_dirs(current_file_name + skipcrud))
- + if (make_dirs(name))
- goto make_fifo;
- - msg_perror("Could not make %s",
- - skipcrud + current_file_name);
- + msg_perror("Could not make %s", name);
- break;
- };
- goto set_filestat;
- @@ -601,12 +589,11 @@
-
- case LF_DIR:
- case LF_DUMPDIR:
- - namelen = strlen(current_file_name) + skipcrud - 1;
- + namelen = strlen(name) - 1;
- really_dir:
- /* Check for trailing /, and zap as many as we find. */
- - while (namelen
- - && current_file_name[skipcrud+namelen] == '/')
- - current_file_name[skipcrud+namelen--] = '\0';
- + while (namelen && name[namelen] == '/')
- + name[namelen--] = '\0';
- if(f_gnudump) { /* Read the entry and delete files
- that aren't listed in the archive */
- gnu_restore(skipcrud);
- @@ -616,23 +603,22 @@
-
-
- again_dir:
- - check = mkdir(skipcrud+current_file_name,
- + check = mkdir(name,
- (we_are_root ? 0 : 0300) | (int)hstat.st_mode);
- if (check != 0) {
- struct stat st1;
-
- - if (make_dirs(skipcrud+current_file_name))
- + if (make_dirs(name))
- goto again_dir;
- /* If we're trying to create '.', let it be. */
- - if (current_file_name[skipcrud+namelen] == '.' &&
- - (namelen==0 ||
- - current_file_name[skipcrud+namelen-1]=='/'))
- + if (name[namelen] == '.' &&
- + (namelen==0 || name[namelen-1]=='/'))
- goto check_perms;
- if( errno==EEXIST
- - && stat(skipcrud+current_file_name,&st1)==0
- + && stat(name,&st1)==0
- && (S_ISDIR(st1.st_mode)))
- break;
- - msg_perror("Could not create directory %s",skipcrud+current_file_name);
- + msg_perror("Could not create directory %s",name);
- break;
- }
-
- @@ -640,14 +626,14 @@
- 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);
- + name);
- }
-
- if (f_modified)
- goto set_filestat;
- tmp = (struct saved_dir_info *) malloc (sizeof (struct saved_dir_info));
- - tmp->path = malloc (strlen (skipcrud + current_file_name) + 1);
- - strcpy (tmp->path, skipcrud + current_file_name);
- + tmp->path = malloc (strlen (name) + 1);
- + strcpy (tmp->path, name);
- tmp->mode = hstat.st_mode;
- tmp->atime = hstat.st_atime;
- tmp->mtime = hstat.st_mtime;
- @@ -655,7 +641,7 @@
- saved_dir_info_head = tmp;
- case LF_VOLHDR:
- if(f_verbose) {
- - printf("Reading %s\n", current_file_name);
- + printf("Reading %s\n", name);
- }
- break;
-
- @@ -664,7 +650,7 @@
- break;
-
- case LF_MULTIVOL:
- - msg("Can't extract '%s'--file is continued from another volume\n",current_file_name);
- + msg("Can't extract '%s'--file is continued from another volume\n",name);
- skip_file((long)hstat.st_size);
- break;
-
- @@ -677,6 +663,7 @@
-
- /* We don't need to save it any longer. */
- saverec((union record **) 0); /* Unsave it */
- + free(name);
- }
-
- /*
-
-