🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by Norbert Kiesel Thu, 10 Sep 1992 21:02
tar-1.11 bugs (with fixes)
#798
Author: Norbert Kiesel
Date: Thu, 10 Sep 1992 21:02
351 lines
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