Thread View: gnu.utils.bug
1 messages
1 total messages
Started by Norbert Kiesel
Thu, 10 Sep 1992 21:02
tar-1.11 bugs (with fixes)
Author: 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);
}
/*
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads