[comp.sources.bugs] 2 bugs in PAX

droege@infko.UUCP (Detlev Droege) (02/23/89)

Hi there,

I found 2 bugs in Marks PAX archiver.

 - 1. BUG:

In name_next()/namelist.c there is a call of close(), but it
must be a call to closedir() !!! (dirp is the argument ... )

This squirrels up pax after some time, as dir's are not
(properly) closed and thus NFILE might be exeeded or something
like that. The fix is easy, see cdiff below.

 - 2. BUG:

Also in name_next()/namelist.c, near the end of the routine,
a warn() message is given if a directory can't be opened for 
searching (dirp is NULL). However nothing is done to deal with this
situation (it might occur, if pax doesn't run under 'root' and some
user has "closed" (chmod 0700) a directory) causing pax to
abort nastily with the next call to readdir().

The fix is to ignore the contents of closed directories.
I moved the opendir() call to the start of the if (... == S_IFDIR)
and perform any manipulation on dirp, curr_dir etc. only
if the opendir() was successful.
Also I added a "skiped" to the warning message.
(Maybe it should be entirely changed ...)

(both errors caused trouble on SUNs and a MIPS R2000 running
UMIPS UNIX System V Rel 3.0)

Any comments ?

	Bye
		Detlev
PS:
 PAX is a fine thing, isn't it ?

------------------ cut here for fixes ---------------------------
*** namelist.c.orig     Mon Feb 20 11:02:25 1989
--- namelist.c  Mon Feb 20 14:43:39 1989
***************
*** 364,373 ****
	    continue;
	}
	if (!names_from_stdin && (statbuf->sb_mode & S_IFMT) == S_IFDIR) {
	    if (in_subdir) {
		curr_dir->where = telldir(dirp);
		pushdir(curr_dir);
!               close(dirp);
	    } 
	    in_subdir++;
  
--- 364,383 ----
	    continue;
	}
	if (!names_from_stdin && (statbuf->sb_mode & S_IFMT) == S_IFDIR) {
+               /* made opendir() first operation to check for accessability
+                * thus handling non-readable directories gracefully.
+                *      droege@infko
+                */
+         DIR * newdirp;
+ 
+         errno = 0;
+         if ((newdirp = opendir(name)) == NULL) {
+               warn(name, "error opening directory (2) - skiped");
+         } else {
	    if (in_subdir) {
		curr_dir->where = telldir(dirp);
		pushdir(curr_dir);
!               closedir(dirp); /* was close(dirp)      droege@infko */
	    } 
	    in_subdir++;
  
***************
*** 384,393 ****
	    curr_dir->dirname[len++] = '/';     /* Now add exactly one back */
	    curr_dir->dirname[len] = '\0';/* Make sure null-terminated */
  
!           errno = 0;
!           if ((dirp = opendir(curr_dir->dirname)) == NULL) {
!               warn(curr_dir->dirname, "error opening directory (2)");
!           }
	}
      } while (err < 0);
      return (0);
--- 394,401 ----
	    curr_dir->dirname[len++] = '/';     /* Now add exactly one back */
	    curr_dir->dirname[len] = '\0';/* Make sure null-terminated */
  
!           dirp = newdirp;
!         }
	}
      } while (err < 0);
      return (0);
------------------------ stop cutting here ----------------------
--
Detlev Droege, University of Koblenz (EWH), Dept. of Computer Sience
	       Rheinau 3-4, D-5400 Koblenz  (West Germany)
UUCP: ..!unido!infko!droege   droege@infko.UUCP   (Voice: +49 261 12156)