Subject: bin/2870: restore doesn't use unique temporary files
To: None <gnats-bugs@gnats.netbsd.org>
From: Luke Mewburn <lukem@supp.cpr.itg.telstra.com.au>
List: netbsd-bugs
Date: 10/20/1996 19:39:27
>Number:         2870
>Category:       bin
>Synopsis:       restore doesn't use unique temporary files
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   lm
>Arrival-Date:   Sun Oct 20 02:50:02 1996
>Last-Modified:
>Originator:     Luke Mewburn
>Organization:
Luke Mewburn <lukem@telstra.com.au>
>Release:        NetBSD-961020
>Environment:

>Description:
	[note that this was originally submitted as bin/2544, with a
	 followup fix in bin/2557. Jason Thorpe suggested that I
	 resubmit as one working patch after the snprint() mods were
	 done. this is that patch.]

	restore doesn't use unique temporary files, so you can't do
	multiple restorations when the dumpdate of an archive is the
	same.

>How-To-Repeat:
	dump to a file. restore in one window, and do a 'restore tvf'
	on the same dump file in another window. Notice how the
	restoration (which will most likely take longer than the list)
	won't have permissions set cause the /tmp/rstmode file won't
	exist.

>Fix:
	apply this.
	close PR bin/2544
	close PR bin/2557
	close this PR

diff -c /ftp/pub/NetBSD/NetBSD-current/src/sbin/restore/dirs.c restore/dirs.c
*** /ftp/pub/NetBSD/NetBSD-current/src/sbin/restore/dirs.c	Tue Oct 15 01:45:00 1996
--- restore/dirs.c	Sun Oct 20 19:27:16 1996
***************
*** 111,119 ****
  static long	seekpt;
  static FILE	*df, *mf;
  static RST_DIR	*dirp;
! static char	dirfile[32] = "#";	/* No file */
! static char	modefile[32] = "#";	/* No file */
! static char	dot[2] = ".";		/* So it can be modified */
  
  /*
   * Format of old style directories.
--- 111,119 ----
  static long	seekpt;
  static FILE	*df, *mf;
  static RST_DIR	*dirp;
! static char	dirfile[MAXPATHLEN] = "#";	/* No file */
! static char	modefile[MAXPATHLEN] = "#";	/* No file */
! static char	dot[2] = ".";			/* So it can be modified */
  
  /*
   * Format of old style directories.
***************
*** 153,158 ****
--- 153,168 ----
  	vprintf(stdout, "Extract directories from tape\n");
  	(void) snprintf(dirfile, sizeof(dirfile), "%s/rstdir%d",
  	    _PATH_TMP, dumpdate);
+ 	if (command != 'r' && command != 'R') {
+ 		(void) snprintf(dirfile, sizeof(dirfile), "%s/rstdir%d-XXXXXX",
+ 		    _PATH_TMP, dumpdate);
+ 		if (mktemp(dirfile) == NULL) {
+ 			fprintf(stderr,
+ 			    "restore: %s - cannot mktemp directory temporary\n",
+ 			    dirfile);
+ 			exit(1);
+ 		}
+ 	}
  	df = fopen(dirfile, "w");
  	if (df == NULL) {
  		fprintf(stderr,
***************
*** 164,169 ****
--- 174,189 ----
  	if (genmode != 0) {
  		(void) snprintf(modefile, sizeof(modefile), "%s/rstmode%d",
  		    _PATH_TMP, dumpdate);
+ 		if (command != 'r' && command != 'R') {
+ 			(void) snprintf(modefile, sizeof(modefile),
+ 			    "%s/rstmode%d-XXXXXX", _PATH_TMP, dumpdate);
+ 			if (mktemp(modefile) == NULL) {
+ 				fprintf(stderr,
+ 				    "restore: %s - cannot mktemp "
+ 				    "directory temporary\n", dirfile);
+ 				exit(1);
+ 			}
+ 		}
  		mf = fopen(modefile, "w");
  		if (mf == NULL) {
  			fprintf(stderr,
***************
*** 593,600 ****
  	char *cp;
  	
  	vprintf(stdout, "Set directory mode, owner, and times.\n");
! 	(void) snprintf(modefile, sizeof(modefile), "%s/rstmode%d",
! 	    _PATH_TMP, dumpdate);
  	mf = fopen(modefile, "r");
  	if (mf == NULL) {
  		fprintf(stderr, "fopen: %s\n", strerror(errno));
--- 613,626 ----
  	char *cp;
  	
  	vprintf(stdout, "Set directory mode, owner, and times.\n");
! 	if (command == 'r' || command == 'R')
! 		(void) snprintf(modefile, sizeof(modefile), "%s/rstmode%d",
! 		    _PATH_TMP, dumpdate);
! 	if (modefile[0] == '#') {
! 		panic("modefile not defined\n");
! 		fprintf(stderr, "directory mode, owner, and times not set\n");
! 		return;
! 	}
  	mf = fopen(modefile, "r");
  	if (mf == NULL) {
  		fprintf(stderr, "fopen: %s\n", strerror(errno));
diff -c /ftp/pub/NetBSD/NetBSD-current/src/sbin/restore/restore.8 restore/restore.8
*** /ftp/pub/NetBSD/NetBSD-current/src/sbin/restore/restore.8	Sat Feb  3 23:19:00 1996
--- restore/restore.8	Sun Oct 20 19:27:16 1996
***************
*** 423,428 ****
--- 423,450 ----
  thus a full dump must be done to get a new set of directories
  reflecting the new inode numbering,
  even though the contents of the files is unchanged.
+ .Pp
+ The temporary files
+ .Pa /tmp/rstdir*
+ and
+ .Pa /tmp/rstmode*
+ are generated with a unique name based on the date of the dump
+ and the process ID (see
+ .Xr mktemp 3 ),
+ except for when 
+ .Fl r
+ or
+ .Fl R
+ is used.
+ Because
+ .Fl R
+ allows you to restart a
+ .Fl r
+ operation that may have been interrupted, the temporary files should
+ be the same across different processes.
+ In all other cases, the files are unique because it is possible to
+ have two different dumps started at the same time, and separate
+ operations shouldn't conflict with each other.
  .Sh HISTORY
  The
  .Nm restore
>Audit-Trail:
>Unformatted: