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)