From: tegge@pvv.unit.NO (Tor Egge)
Subject: GNU tar 1.11: bugs & patches for m88k-dolphin-svr3
Organization: Gnus Not Usenet
Distribution: gnu
Date: Sun, 13 Sep 1992 02:34:42 GMT

4 problems:

	1. date of files randomly set, since utime() on this machine 
	   is a posix variant, using the struct utimbuf. 
	  
	2. The malloc package defines malloc, etc... 
	   In the C library on m88k-dolphin-svr3, malloc is just a
	   "jump" to _malloc, and so on. The routines in the C library
	   does not call malloc, only _malloc. Therefore, if the malloc
	   package is to be used, it must define _malloc, _free, _realloc and
	   _calloc, instead of malloc, free, realloc, and calloc. Also, since
	   the system didn't have valloc as standard, valloc was defined 
	   in both malloc.c and port.c.  

	3. demangling of long name symbolic links fails, due to lack of
	   null-termination of the name of the symbolic link.

	4. Dereferencing of NULL if used with e.g. cvf option.
	   (current_file_name not initialized)
	
The 4th has been discussed on gnu.utils.bug. Appended to this mail is a 
diff which tries to solve the first 3 problems. 

- Tor Egge

-------- patches follows here --------
diff -rc ../src/tar-1.11/Makefile.in tar-1.11/Makefile.in
*** ../src/tar-1.11/Makefile.in	Wed Sep  9 22:12:31 1992
--- tar-1.11/Makefile.in	Sat Sep 12 22:59:16 1992
***************
*** 65,70 ****
--- 65,73 ----
  # -DNO_OPEN3		If you lack the 3-argument open and want to
  #			disable the tar -k option instead of emulating open.
  # -DXENIX		If you have sys/inode.h and need it to be included.
+ # -DHAVE_UTIMBUF	If utime() is POSIX
+ # -DHAVE_UTIMBUF_USEC   if struct utimbuf and struct stat both have usecs.
+ # -DMALLOC_IS_TRAMPOLINE If malloc (and rest of libc routines) calls _malloc
  
  DEF_AR_FILE = @DEF_AR_FILE@
  DEFBLOCKING = 20
diff -rc ../src/tar-1.11/configure tar-1.11/configure
*** ../src/tar-1.11/configure	Wed Sep  9 19:47:36 1992
--- tar-1.11/configure	Sat Sep 12 22:59:04 1992
***************
*** 611,617 ****
  echo checking for BSD
  test -f /vmunix && DEFS="$DEFS -DBSD42=1"
  echo checking for HP-UX
! test -f /hp-ux && test -f /vmunix || MALLOC=malloc.o
  
  echo checking for Xenix
  cat <<EOF > conftest.c
--- 611,617 ----
  echo checking for BSD
  test -f /vmunix && DEFS="$DEFS -DBSD42=1"
  echo checking for HP-UX
! test -f /hp-ux && test -f /vmunix || MALLOC=malloc.o DEFS="$DEFS -DHAVE_VALLOC"
  
  echo checking for Xenix
  cat <<EOF > conftest.c
***************
*** 636,641 ****
--- 636,673 ----
    esac
  fi
  
+ # Local additions for pvv.
+ # 1. Redefining malloc when malloc is a trampoline to _malloc, and
+ #    all routines in the C library calls _malloc directly, may cause
+ #    problems. 
+ echo checking for malloc being a trampoline to _malloc
+ echo "#include <sys/types.h>
+ void _malloc() { exit(1); } main() { (void) malloc(1); exit(0); }" > conftest.c
+ if eval $compile; then
+   :
+ else
+   DEFS="$DEFS -DMALLOC_IS_TRAMPOLINE"
+ fi
+ rm -f conftest*
+ echo checking for posix utime
+ echo "#include <sys/types.h>
+ #include <utime.h>
+ main() { exit(0); } t() { struct utimbuf buf; }" > conftest.c
+ if eval $compile; then
+ # Should maybe use POSIX_UTIME instead of HAVE_UTIMBUF
+   DEFS="$DEFS -DHAVE_UTIMBUF"
+   echo checking for usecs in utimbuf and stat structures
+   echo "#include <sys/times.h>
+ #include <sys/stat.h>
+ #include <utime.h>
+ main() { exit(0); } t() { struct utimbuf buf; struct stat hstat;
+ buf.acusec=hstat.st_ausec;}" > conftest.c
+   if eval $compile; then
+ # Both the stat structure and the utimbuf structure have usecs. 
+     DEFS="$DEFS -DHAVE_UTIMBUF_USEC"
+   fi
+ fi
+ rm -f conftest*
  if test -n "$prefix"; then
    test -z "$exec_prefix" && exec_prefix='$(prefix)'
    prsub="s,^prefix[ 	]*=.*$,prefix = $prefix,"
diff -rc ../src/tar-1.11/configure.in tar-1.11/configure.in
*** ../src/tar-1.11/configure.in	Wed Sep  9 19:47:27 1992
--- tar-1.11/configure.in	Sat Sep 12 22:58:44 1992
***************
*** 45,51 ****
  echo checking for BSD
  test -f /vmunix && AC_DEFINE(BSD42)
  echo checking for HP-UX
! test -f /hp-ux && test -f /vmunix || MALLOC=malloc.o
  AC_SUBST(MALLOC)
  AC_XENIX_DIR
  AC_OUTPUT(Makefile)
--- 45,83 ----
  echo checking for BSD
  test -f /vmunix && AC_DEFINE(BSD42)
  echo checking for HP-UX
! test -f /hp-ux && test -f /vmunix || MALLOC=malloc.o DEFS="$DEFS -DHAVE_VALLOC"
  AC_SUBST(MALLOC)
  AC_XENIX_DIR
+ # Local additions for pvv.
+ # 1. Redefining malloc when malloc is a trampoline to _malloc, and
+ #    all routines in the C library calls _malloc directly, may cause
+ #    problems. 
+ echo checking for malloc being a trampoline to _malloc
+ echo "#include <sys/types.h>
+ void _malloc() { exit(1); } main() { (void) malloc(1); exit(0); }" > conftest.c
+ if eval $compile; then
+   :
+ else
+   DEFS="$DEFS -DMALLOC_IS_TRAMPOLINE"
+ fi
+ rm -f conftest*
+ echo checking for posix utime
+ echo "#include <sys/types.h>
+ #include <utime.h>
+ main() { exit(0); } t() { struct utimbuf buf; }" > conftest.c
+ if eval $compile; then
+ # Should maybe use POSIX_UTIME instead of HAVE_UTIMBUF
+   DEFS="$DEFS -DHAVE_UTIMBUF"
+   echo checking for usecs in utimbuf and stat structures
+   echo "#include <sys/times.h>
+ #include <sys/stat.h>
+ #include <utime.h>
+ main() { exit(0); } t() { struct utimbuf buf; struct stat hstat;
+ buf.acusec=hstat.st_ausec;}" > conftest.c
+   if eval $compile; then
+ # Both the stat structure and the utimbuf structure have usecs. 
+     DEFS="$DEFS -DHAVE_UTIMBUF_USEC"
+   fi
+ fi
+ rm -f conftest*
  AC_OUTPUT(Makefile)
diff -rc ../src/tar-1.11/create.c tar-1.11/create.c
*** ../src/tar-1.11/create.c	Tue Sep  8 21:53:02 1992
--- tar-1.11/create.c	Sat Sep 12 20:41:15 1992
***************
*** 32,37 ****
--- 32,40 ----
  #ifndef STDC_HEADERS
  extern int	errno;
  #endif
+ #ifdef HAVE_UTIMBUF
+ #include <utime.h>
+ #endif
  
  #ifdef BSD42
  #include <sys/file.h>
***************
*** 206,212 ****
--- 209,219 ----
  	char save_linkflag;
  	extern time_t new_time;
  	int critical_error = 0;
+ #ifdef HAVE_UTIMBUF
+ 	struct utimbuf restore_times;
+ #else
  	time_t restore_times[2];
+ #endif
  /*	int sparse_ind = 0;*/
  
  
***************
*** 234,241 ****
--- 241,259 ----
  		return;
  	}
  	
+ #ifdef HAVE_UTIMBUF
+ 	/* First zero out everything optional */
+ 	bzero(&restore_times,sizeof(restore_times)); 
+ 	restore_times.actime = hstat.st_atime;
+ 	restore_times.modtime = hstat.st_mtime;
+ #ifdef HAVE_UTIMBUF_USEC
+ 	restore_times.acusec = hstat.st_ausec;
+ 	restore_times.modusec = hstat.st_musec;
+ #endif
+ #else
  	restore_times[0] = hstat.st_atime;
  	restore_times[1] = hstat.st_mtime;
+ #endif
  
  #ifdef S_ISHIDDEN
  	if (S_ISHIDDEN (hstat.st_mode)) {
***************
*** 574,580 ****
--- 592,602 ----
  		      msg_perror ("cannot remove %s", p);
  		  }
  		if (f_atime_preserve)
+ #ifdef HAVE_UTIMBUF
+ 		  utime (p, &restore_times);
+ #else
  		  utime (p, restore_times);
+ #endif
  		return;
  
  		/*
***************
*** 594,600 ****
--- 616,626 ----
  		if(f>=0)
  			(void)close(f);
  		if (f_atime_preserve)
+ #ifdef HAVE_UTIMBUF
+ 		  utime (p, &restore_times);
+ #else
  		  utime (p, restore_times);
+ #endif
  	        return;
  	}
  
***************
*** 727,733 ****
--- 753,763 ----
  			if(f_multivol)
  				save_name = 0;
  			if (f_atime_preserve)
+ #ifdef HAVE_UTIMBUF
+ 			  utime (p, &restore_times);
+ #else
  			  utime (p, restore_times);
+ #endif
   			return;
  		}
  
***************
*** 786,792 ****
--- 816,826 ----
  		closedir(dirp);
  		free(namebuf);
  		if (f_atime_preserve)
+ #ifdef HAVE_UTIMBUF
+ 		  utime (p, &restore_times);
+ #else
  		  utime (p, restore_times);
+ #endif
  		return;
  	}
  
diff -rc ../src/tar-1.11/extract.c tar-1.11/extract.c
*** ../src/tar-1.11/extract.c	Tue Sep  8 22:09:11 1992
--- tar-1.11/extract.c	Sat Sep 12 21:00:13 1992
***************
*** 31,36 ****
--- 31,40 ----
  #include <sys/types.h>
  #include <time.h>
  time_t time();
+ /* Support for POSIX utimbuf structure (POSIX 13 5.6.6.2) */
+ #ifdef HAVE_UTIMBUF
+ #include <utime.h>
+ #endif
  
  #ifdef BSD42
  #include <sys/file.h>
***************
*** 100,105 ****
--- 104,113 ----
    int mode;
    int atime;
    int mtime;
+ #ifdef HAVE_UTIMBUF_USEC
+   int ausec; /* Usecs of access time */
+   int musec; /* Usecs of modify time */
+ #endif
    struct saved_dir_info *next;
  };
    
***************
*** 138,144 ****
--- 146,156 ----
  	register char *data;
  	int fd, check, namelen, written, openflag;
  	long size;
+ #ifdef HAVE_UTIMBUF
+ 	struct utimbuf acc_upd_times;
+ #else
  	time_t acc_upd_times[2];
+ #endif
  	register int skipcrud;
  	register int i;
  /*	int sparse_ind = 0;*/
***************
*** 481,486 ****
--- 493,515 ----
  		  */
  		 if (!f_modified) {
  			 /* fixme if f_gnudump should set ctime too, but how? */
+ #ifdef HAVE_UTIMBUF
+ 		   /* Zero out any optional elements in the buffer */
+ 		   bzero(&acc_upd_times,sizeof(acc_upd_times)); 
+ 		   if (f_gnudump)
+ 		     acc_upd_times.actime= hstat.st_atime;
+ 		   else acc_upd_times.actime=now;	    /* Accessed now */
+ 		   acc_upd_times.modtime=hstat.st_mtime;   /* Mod'd */
+ #ifdef HAVE_UTIMBUF_USEC
+ 		   if (f_gnudump)
+ 		     acc_upd_times.acusec= hstat.st_ausec;
+ 		   else acc_upd_times.acusec= 0; /* FIXME: Just an Approx */
+ 		   acc_upd_times.modusec=hstat.st_musec;
+ #endif
+ 			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);
+ #else		   
  			if(f_gnudump)
  				acc_upd_times[0]=hstat.st_atime;
  			else acc_upd_times[0] = now;	         /* Accessed now */
***************
*** 488,493 ****
--- 517,523 ----
  			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);
+ #endif
  			}
  		}
  		/* We do the utime before the chmod because some versions of
***************
*** 651,656 ****
--- 681,690 ----
  		tmp->mode = hstat.st_mode;
  		tmp->atime = hstat.st_atime;
  		tmp->mtime = hstat.st_mtime;
+ #ifdef HAVE_UTIMBUF_USEC
+ 		tmp->ausec = hstat.st_ausec;
+ 		tmp->musec = hstat.st_musec;
+ #endif   
  		tmp->next = saved_dir_info_head;
  		saved_dir_info_head = tmp;
  	case LF_VOLHDR:
***************
*** 792,803 ****
--- 826,858 ----
  /* Set back the utime and mode for all the extracted directories. */
  void restore_saved_dir_info ()
  {
+ #ifdef HAVE_UTIMBUF
+   struct utimbuf acc_upd_times;
+ #else
    time_t acc_upd_times[2];
+ #endif
    struct saved_dir_info *tmp;
  
    while (saved_dir_info_head != NULL)
      {
        /* fixme if f_gnudump should set ctime too, but how? */
+ #ifdef HAVE_UTIMBUF
+       bzero(&acc_upd_times,sizeof(acc_upd_times));
+       if (f_gnudump)
+ 	acc_upd_times.actime=saved_dir_info_head -> atime;
+       else
+ 	acc_upd_times.actime = now; /* Accessed now */
+       acc_upd_times.modtime = saved_dir_info_head -> mtime; /* Mod'd */
+ #ifdef HAVE_UTIMBUF_USEC
+       if (f_gnudump)
+ 	acc_upd_times.acusec= saved_dir_info_head -> ausec;
+       else acc_upd_times.acusec=0; /* FIXME: Just an Approx */
+       acc_upd_times.modusec= hstat.st_musec;
+ #endif
+       if (utime(saved_dir_info_head -> path, &acc_upd_times) < 0) {
+ 	msg_perror("couldn't change access and modification times of %s",
+ 		   saved_dir_info_head -> path);
+ #else
        if(f_gnudump)
  	acc_upd_times[0]=saved_dir_info_head -> atime;
        else acc_upd_times[0] = now; /* Accessed now */
***************
*** 805,810 ****
--- 860,866 ----
        if (utime(saved_dir_info_head -> path, acc_upd_times) < 0) {
  	msg_perror("couldn't change access and modification times of %s",
  		   saved_dir_info_head -> path);
+ #endif
        }
        if ((!f_keep) || (saved_dir_info_head -> mode & (S_ISUID|S_ISGID|S_ISVTX)))
  	{
diff -rc ../src/tar-1.11/list.c tar-1.11/list.c
*** ../src/tar-1.11/list.c	Tue Sep  8 22:22:38 1992
--- tar-1.11/list.c	Sat Sep 12 20:41:50 1992
***************
*** 416,421 ****
--- 416,427 ----
  	char *bp, *data;
  	int size, written;
  
+ #ifdef HAVE_UTIMBUF_USEC
+ 	/* Maybe an intial bzero of st would be better ? */
+ 	st->st_ausec = 0;
+ 	st->st_musec = 0;
+ 	st->st_cusec = 0;
+ #endif
  	st->st_mode = from_oct(8,  header->header.mode);
  	st->st_mtime = from_oct(1+12, header->header.mtime);
  	if(f_gnudump) {
diff -rc ../src/tar-1.11/malloc.c tar-1.11/malloc.c
*** ../src/tar-1.11/malloc.c	Wed Sep  9 09:26:28 1992
--- tar-1.11/malloc.c	Sat Sep 12 22:42:26 1992
***************
*** 187,192 ****
--- 187,205 ----
  #include "vlimit.h"
  #endif
  
+ /* In some C libraries, malloc just calls _malloc, etc. 
+    Also, the routines in the C library calls _malloc, *NOT* malloc.
+    To redefine the actual the routines, instead of just the trampolines,
+    some #defines are necessary.
+ */
+ 
+ #ifdef MALLOC_IS_TRAMPOLINE
+ #define malloc _malloc
+ #define calloc _calloc
+ #define free _free
+ #define realloc _realloc
+ #endif
+ 
  extern char *start_of_data ();
  
  #ifdef BSD
diff -rc ../src/tar-1.11/mangle.c tar-1.11/mangle.c
*** ../src/tar-1.11/mangle.c	Wed Sep  2 21:31:50 1992
--- tar-1.11/mangle.c	Sat Sep 12 21:01:29 1992
***************
*** 237,242 ****
--- 237,243 ----
  				nam1end++;
  				nam1end=index(nam1end,' ');
  			}
+ 			*nam1end='\0'; 
  			un_quote_string(nam1);
  			un_quote_string(nam1end+4);
  			if(symlink(nam1,nam1end+4) && (unlink(nam1end+4) || symlink(nam1,nam1end+4)))


------ end of all patches ------

Newsgroups: gnu.utils.bug