Article View: gnu.utils.bug
Article #798tar-1.11 bugs (with fixes)
From: Norbert Kiesel
Date: Thu, 10 Sep 1992 21:02
Date: Thu, 10 Sep 1992 21:02
351 lines
11697 bytes
11697 bytes
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);
}
/*
Technical Details
Message-ID:
<9209101702.AA10675@rwthi3.informatik.rwth-aachen.de>Path:
arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!mozart.informatik.rwth-aachen.de!norbertShow Full Headers
Complete Article Headers
Newsgroups: gnu.utils.bug Path: arc1-ca.pugleaf.net!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