dennis@rlgvax.UUCP (Dennis Bednar) (01/06/87)
I have added a couple of #ifdef's so that the lln.c tool posted
to net.sources should work on 4.2 machines in addition to Sys 5
machines. Theoretically, all you have to do is define one of
USG, BSD4X, or CCI632, and it should work. I haved tested it
on the cci632, but have not tried it on a pure 4.2 or 4.3 system.
If you have problems with it, I also added some #ifdef DEBUG code,
which may be enabled by changing the "#undef DEBUG" to "#define
DEBUG 1".
In summary, the changes I made were:
- the cci632 uses <mtab.h> and /etc/mtab instead of <mnttab.h>
and /etc/mnttab. I assume that the former is 4.2, and the
later is pure S5. (Our machine is a Sys5/4.2 hybrid,
Sys 5 at the cmd(1) level, some 4.2'isms still hiding under
the hood in the kernel.)
- the cci632 uses 4.2 filesystem with variable length directory
entries, instead of 14 char fixed length entries.
- the cci632 has symbolic links, normally found in 4.2.
Below is only the lln.c file. Don't forget to remove the trailer
(USENET trailer decapsulation protocol :-) )
------ CUT HERE ---------
/* define your OS type:
* USG S3 or S5
* BSD4X V7 or 4.2 or 4.3
* CCI632 Sys5 r2 on CCI Power 6/32
*/
#define CCI632 1
/* the OS type, in turn, defines the lower level #defines that
* are typical for that system. If your system is usual,
* add its type either alongside USG or BSD4X, otherwise if
* your machine is weird, add it near last #else.
*/
#ifdef USG
# undef MTAB /* use /etc/mnttab and mnttab.h */
# undef BSD_FILESYS /* use 14 char fix len dir entries */
# undef BSD_SYMLINK /* don't have symbolic links */
#else /* !USG */
/* CCI632 Sys5r2 really has a 4.2 engine under the hood :-) */
#if defined(BSD4X) || defined(CCI632)
# define MTAB 1 /* have /etc/mtab and mtab.h instead of /etc/mnttab and mnttab.h */
# define BSD_FILESYS 1 /* have BSD4_2 file system */
#else /* !BSD4X && !CCI632 && !USG */
Unknown System. This causes a compiler error.
#endif /* BSD4X */
#endif /* USG */
#undef DEBUG /* enables debug code */
#include <sys/types.h>
#include <sys/dir.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#if defined(MTAB)
#include <fstab.h>
#include <sys/param.h> /* NMOUNT */
#include <mtab.h>
#define MNTTAB mtab
#define MT_FILSYS m_path
/* MT_FILSYS is field in mtab with directory name */
#else
#include <mnttab.h>
#define MNTTAB mnttab
#define MT_FILSYS mt_filsys
#endif
#ifdef BSD_SYMLINK
#define STAT lstat
/* special stat() to handle regular and symbolically linked files */
#else
#define STAT stat /* regular old stat() sys call */
#endif
#define BOOL char
/*
lln: list links for files
not (c) 1986 Paul Heffner @ AT&T-IS Altamonte Springs, FL.
use it however you wish.
rlgvax!dennis 01 06 86 Added MTAB, and BSD_FILESYS,
and BSD_SYMLINK #ifdefs to work on CCI632.
Enquiries, advice, and calm criticism to:
ihnp4 \
akgua - bsdpkh!heff
attmail /
*/
#ifdef MTAB
#define MTE_SIZE sizeof(struct mtab)
#else
#define MTE_SIZE sizeof(struct mnttab)
#endif
#define DIRESIZ sizeof(struct direct)
#define PATHMAX 512
#define STR_SAME !strcmp
#if defined(BSD_FILESYS)
#if !defined(DEBUG)
#define OPENDIR opendir
#define CLOSEDIR closedir
#else /* debug */
/* use OPENDIR(), CLOSEDIR() debug routines that are default */
/* don't redefine OPENDIR as OPENDIR, because macro recursion expansion */
DIR *OPENDIR(); /* fw ref */
void CLOSEDIR(); /* fw ref */
#endif
#endif
char *u_errmesg(); /* fw ref - return perror() like string */
extern int errno;
/*
program globals
*/
static int inn; /* inode number of file being searched for... */
static int found; /* count of found directory entries.. */
static int need; /* count of directory entries to find.. */
static int curdev; /* device # of disk holding fs of objective file. */
static char pathbuf[PATHMAX]; /* holds current search path */
main(argc,argv)
int argc;
char **argv;
{
#ifdef MTAB
static char *mtfil = "/etc/mtab";
#else
static char *mtfil = "/etc/mnttab";
#endif
struct stat ssfil, junk1, junk2, ssfs;
/* junk1, junk2 are dummy vars because lstat() would write
* past end of ssfil into ssfs, and corrupt it otherwise.
* lstat(2) bug on rlgvax!!!
*/
struct MNTTAB mte;
int i, mth, x;
#ifdef BSD_FILESYS
DIR *dirfd;
#else
int dirfd; /* 14 char fixed length directory entries */
#endif
if (argc < 2) exit(0);
fclose(stdin); /* free up an extra fd (just in case) */
if ((mth = open(mtfil,O_RDONLY)) == -1)
{ fprintf(stderr,"%s: errno %d, cannot open %s\n",argv[0],errno,mtfil);
exit(16);
}
#ifdef DEBUG
printf("opened mount table file okay\n");
#endif
for (i = 1; i < argc; ++i)
{
if (STAT(argv[i],&ssfil))
{ fprintf(stderr,"%s:errno %d can not access %s\n",argv[0],errno,argv[i]);
continue;
}
if ((ssfil.st_mode & S_IFMT) == S_IFDIR)
{ fprintf(stderr,"%s: %s is a directory file.\n",argv[0],argv[i]);
continue;
}
inn = ssfil.st_ino; /* establish search inode number */
found = 0; /* set count of # found */
need = ssfil.st_nlink; /* set count of # of links */
curdev = ssfil.st_dev; /* # of device holding file */
#ifdef DEBUG
printf("lln: debug: dev = %d, inode = %d, links = %d\n",
curdev, inn, need);
#endif
/*
Scratch through mount table looking for fs hosting file
seeking a match on device number...
*/
for (x = 0; x < NMOUNT; ++x)
{ if (read(mth,&mte,MTE_SIZE) != MTE_SIZE)
{ fprintf(stderr,"%s: errno %d reading mnttab\n",argv[0],errno);
exit(32);
}
STAT(mte.MT_FILSYS,&ssfs); /* name of directory mounted as */
#ifdef DEBUG
printf("lln: debug: Looking at mounted dir %s\n", mte.MT_FILSYS);
printf(" st_dev=%d, st_rdev=%d, want dev # = %d\n", ssfs.st_dev, ssfs.st_rdev, curdev);
#endif /* debug */
if (ssfs.st_dev == ssfil.st_dev) break;
#ifdef DEBUG
else printf("debug: wrong dir (%d != %d)\n",
ssfs.st_dev, ssfil.st_dev);
#endif
}
#ifdef DEBUG
printf("lln: debug: found mounted dir starting point\n");
#endif
/*
The path name is constructed in 'pathbuf'.
We start with mounted directory from /etc/mnttab entry...
*/
#ifdef BSD_FILESYS
strncpy(pathbuf,mte.MT_FILSYS,strlen(mte.MT_FILSYS)+1);
#else
strncpy(pathbuf,mte.MT_FILSYS,14);
#endif
#ifdef DEBUG
printf("lln: debug: search starting at mounted dir %s\n", pathbuf);
#endif
if (pathbuf[1] == '\0') pathbuf[0] = '\0'; /* special case for root fs (avoids // at front of path) */
if (chdir(mte.MT_FILSYS) == -1)
{
fprintf(stderr, "lln: chdir(%s) failed\n", mte.MT_FILSYS);
exit(1);
}
#ifdef BSD_FILESYS
if ((dirfd = OPENDIR(mte.MT_FILSYS)) == (DIR *)NULL)
#else
if ((dirfd = open(mte.MT_FILSYS,O_RDONLY)) == -1)
#endif
{ fprintf(stderr,"%s: errno %d opening %s\n",argv[0],errno,mte.MT_FILSYS);
exit(-1);
}
if (lnsrch(dirfd))
fprintf(stderr,"%s incomplete list: only %d of %d links were found.\n",argv[0],found,need);
#ifdef BSD_FILESYS
CLOSEDIR(dirfd);
#else
close(dirfd);
#endif
lseek(mth,0L,0); /* reset to beginning of mnttab */
}
close(mth);
exit(0);
}
lnsrch(dirfd)
#ifdef BSD_FILESYS
DIR *dirfd;
#else
int dirfd;
#endif
{ struct stat curf;
#ifdef BSD_FILESYS
struct direct *cd;
DIR *newdfd;
#else
struct direct cd;
int newdfd;
#endif
char *pathend;
BOOL isdir;
#ifdef BSD_SYMLINK
BOOL issymlink;
#endif
#ifdef BSD_FILESYS
/* skip over . and .. in read loop of directory */
#else
lseek(dirfd,(long) (DIRESIZ << 1),0); /* go past . and .. */
/* BUG FIX (long) added for mchs with diff size int & long. rlgvax!dennis */
#endif
#ifdef BSD_FILESYS
while (cd = readdir(dirfd) )
{
if (STR_SAME(cd->d_name, ".") || STR_SAME(cd->d_name, "..") )
continue; /* skip . and .. entries */
if (STAT(cd->d_name,&curf))
{ fprintf(stderr,"lln: stat error %s/%s\n",pathbuf,cd->d_name);
#else
while (read(dirfd,&cd,DIRESIZ) == DIRESIZ) /* bug fix - don't let -1 be okay, rlgvax!dennis */
{
if (!cd.d_ino) continue; /* skip empty entries (i = 0) */
if (STAT(cd.d_name,&curf))
{ fprintf(stderr,"lln: stat error %s/%s\n",pathbuf,cd.d_name);
#endif
continue;
}
isdir = ((curf.st_mode & S_IFMT) == S_IFDIR);
#ifdef BSD_SYMLINK
issymlink = ((curf.st_mode & S_IFMT) == S_IFLNK);
if (isdir && issymlink)
continue; /* avoid infinite recursion */
/* recursion when /a/b/c symlinked to /a */
#endif
if ( isdir ) /* sub-dir?? */
{
/*
ignore MT directories and keep search to objective fs (dev)
*/
#ifdef BSD_FILSYS
if (curf.st_dev != curdev) continue; /* diff mount point */
#else
if (curf.st_size == (2*DIRESIZ) || /* . && .. ie dir empty */
curf.st_dev != curdev) continue; /* wrong mount pt */
#endif
#ifdef BSD_FILESYS
#ifdef DEBUG
/* track down cannot visit problem */
printf("Will OPENDIR(%s) Current directory is ", cd->d_name);
fflush(stdout);
system("pwd");
#endif
if ((newdfd = OPENDIR(cd->d_name)) == (DIR *)NULL)
{ fprintf(stderr,"lln: Can't open %s/%s: %s\n",pathbuf,cd->d_name, u_errmesg());
#else
if ((newdfd = open(cd.d_name,O_RDONLY)) == -1)
{ fprintf(stderr,"lln: Can't open %s/%s\n",pathbuf,cd.d_name);
#endif
continue;
}
/*
Maintain current path in pathbuf global area
*/
for (pathend = pathbuf; *pathend; ++pathend) ;
*pathend = '/';
#ifdef BSD_FILESYS
strncpy(pathend + 1,cd->d_name,cd->d_namlen + 1);
chdir(cd->d_name);
#else /* !bsd_filsys */
strncpy(pathend + 1,cd.d_name,14);
chdir(cd.d_name);
#endif
#ifdef DEBUG
printf("lln: debug: visiting %s\n", pathbuf);
#endif /* debug */
if (!lnsrch(newdfd))
{
#ifdef BSD_FILESYS
#ifdef DEBUG
printf("WILL CLOSEDIR\n");
#endif
CLOSEDIR(newdfd);
#else
close(newdfd);
#endif
return 0; /* recursively return 0 if all were found */
}
#ifdef BSD_FILESYS
#ifdef DEBUG
printf("WILL CLOSEDIR()!\n");
#endif
CLOSEDIR(newdfd);
#else
close(newdfd);
#endif
chdir("..");
*pathend = '\0';
continue;
}
#ifdef DEBUG
else
printf("debug: reg file: %s/%s\n", pathbuf,
#ifdef BSD_FILESYS
cd->d_name);
#else
cd.d_name);
#endif /* bsd */
#endif /* debug */
#ifdef BSD_FILESYS
if (cd->d_ino == inn) /* Print out path on match!! */
{ printf("%s/%.14s\n",pathbuf,cd->d_name);
#else
if (cd.d_ino == inn) /* Print out path on match!! */
{ printf("%s/%.14s\n",pathbuf,cd.d_name);
#endif
if (++found == need) return 0;
}
}
return -1;
}
#if defined(BSD_FILESYS) && defined(DEBUG)
/*
* OPENDIR and CLOSEDIR are debug routines instead of the
* regular OPENDIR(), CLOSEDIR() routines. It is used
* to help track down a problem that I think is "too many
* files open".
*/
static open_count = 0; /* number of open files */
#define MAXFILES _NFILE+1 /* one extra for precaution */
static char *fname[MAXFILES]; /* file names, fname[0] is first file name */
static DIR *fptr[MAXFILES]; /* store DIR * ptrs in parellel w fname[] */
/*
* the array fname[] is needed since we cannot derive the directory
* name when we are closing it.
*/
DIR *
OPENDIR(name)
char *name;
{
DIR *dirp;
char *str_malloc(); /* fw ref */
fname[open_count] = str_malloc(name);
dirp = opendir(name);
fptr[ open_count ] = dirp;
++open_count;
printf("OPENDIR(%s) %d\n", name, open_count); /* number open *after* open */
return (dirp);
}
void
CLOSEDIR( dirp )
DIR *dirp;
{
int i;
if (open_count < 1 ) /* nothing open now */
error("CLOSEDIR without OPENDIR");
/* must check all slots, not just first open_count,
* because of "holes" in middle!!! */
for (i = 0; i < MAXFILES; ++i)
if (dirp == fptr[i])
break; /* found ptr */
if (i >= MAXFILES)
error("not found in table");
--open_count;
printf("CLOSEDIR(%s) %d\n", fname[i], open_count);
free( fname[i]);
return;
}
/*
* malloc space for a string and copy it in
* return ptr to malloc'd string
*/
char *
str_malloc( s )
char *s;
{
extern char *malloc();
char *cp;
cp = malloc( strlen(s) + 1);
if (!cp )
error("out of space");
strcpy( cp, s );
return cp;
}
error(msg)
char *msg;
{
fprintf(stderr, "%s\n", msg);
exit (1);
}
#endif /* bsd && debug */
/*
* return UNIX error message associated with errno
* more flexible than perror(3)
*/
char *
u_errmesg()
{
extern int errno;
extern int sys_nerr;
extern char *sys_errlist[];
static char buffer[50]; /* don't loose it !!! */
if (errno < 0 || errno >= sys_nerr)
{
sprintf( buffer, "errno %d undefined (%d=max)", errno, sys_nerr);
return(buffer);
}
return( sys_errlist[errno] );
}
--
-Dennis Bednar
{decvax,ihnp4,harpo,allegra}!seismo!rlgvax!dennis UUCPtim@dciem.UUCP (Tim Pointing) (01/08/87)
Despite the comment near the top of the source for the new version on lln.c
recently posted, lln does not run under V7. Below is a patch to allow lln
to run under V7. It will also allow lln to find files on the root filesystem
on systems which do not have an entry for the root filesystem in the
mount table. There are also some fixes which cause lln to gracefully bypass
directories which allow read (i.e. open) but not search (i.e. chdir).
-------------CUT-HERE------------------------------CUT-HERE---------------
*** lln.c.dist Thu Jan 8 09:02:23 1987
--- lln.c Thu Jan 8 10:33:04 1987
***************
*** 1,6
/* define your OS type:
* USG S3 or S5
! * BSD4X V7 or 4.2 or 4.3
* CCI632 Sys5 r2 on CCI Power 6/32
*/
#define CCI632 1
--- 1,7 -----
/* define your OS type:
* USG S3 or S5
! * BSD4X 4.2 or 4.3
! * V7 V7
* CCI632 Sys5 r2 on CCI Power 6/32
*/
***************
*** 3,9
* BSD4X V7 or 4.2 or 4.3
* CCI632 Sys5 r2 on CCI Power 6/32
*/
- #define CCI632 1
/* the OS type, in turn, defines the lower level #defines that
* are typical for that system. If your system is usual,
--- 4,9 -----
* V7 V7
* CCI632 Sys5 r2 on CCI Power 6/32
*/
/* the OS type, in turn, defines the lower level #defines that
* are typical for that system. If your system is usual,
***************
*** 20,25
# define MTAB 1 /* have /etc/mtab and mtab.h instead of /etc/mnttab and mnttab.h */
# define BSD_FILESYS 1 /* have BSD4_2 file system */
#else /* !BSD4X && !CCI632 && !USG */
Unknown System. This causes a compiler error.
#endif /* BSD4X */
#endif /* USG */
--- 20,28 -----
# define MTAB 1 /* have /etc/mtab and mtab.h instead of /etc/mnttab and mnttab.h */
# define BSD_FILESYS 1 /* have BSD4_2 file system */
#else /* !BSD4X && !CCI632 && !USG */
+ #if defined(V7)
+ # define MTAB 1 /* have /etc/mtab but no mtab.h */
+ #else /* !BSD4X && !CCI632 && !USG && !V7 */
Unknown System. This causes a compiler error.
#endif /* V7 */
#endif /* BSD4X */
***************
*** 21,26
# define BSD_FILESYS 1 /* have BSD4_2 file system */
#else /* !BSD4X && !CCI632 && !USG */
Unknown System. This causes a compiler error.
#endif /* BSD4X */
#endif /* USG */
--- 24,30 -----
# define MTAB 1 /* have /etc/mtab but no mtab.h */
#else /* !BSD4X && !CCI632 && !USG && !V7 */
Unknown System. This causes a compiler error.
+ #endif /* V7 */
#endif /* BSD4X */
#endif /* USG */
***************
*** 29,34
#include <sys/dir.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#if defined(MTAB)
#include <fstab.h>
--- 33,39 -----
#include <sys/dir.h>
#include <sys/stat.h>
#include <stdio.h>
+ #if !defined(V7)
#include <fcntl.h>
#else
#define O_RDONLY (0)
***************
*** 30,35
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#if defined(MTAB)
#include <fstab.h>
#include <sys/param.h> /* NMOUNT */
--- 35,43 -----
#include <stdio.h>
#if !defined(V7)
#include <fcntl.h>
+ #else
+ #define O_RDONLY (0)
+ #endif /* V7 */
#if defined(MTAB)
#if !defined(V7)
#include <fstab.h>
***************
*** 31,36
#include <stdio.h>
#include <fcntl.h>
#if defined(MTAB)
#include <fstab.h>
#include <sys/param.h> /* NMOUNT */
#include <mtab.h>
--- 39,45 -----
#define O_RDONLY (0)
#endif /* V7 */
#if defined(MTAB)
+ #if !defined(V7)
#include <fstab.h>
#include <sys/param.h> /* NMOUNT */
#include <mtab.h>
***************
*** 34,39
#include <fstab.h>
#include <sys/param.h> /* NMOUNT */
#include <mtab.h>
#define MNTTAB mtab
#define MT_FILSYS m_path
/* MT_FILSYS is field in mtab with directory name */
--- 43,56 -----
#include <fstab.h>
#include <sys/param.h> /* NMOUNT */
#include <mtab.h>
+ #else /* V7 */
+ # define NAMSIZ 32
+ # define NMOUNT 16
+ struct mtab {
+ char m_path[NAMSIZ];
+ char m_dev[NAMSIZ];
+ };
+ #endif /* V7 */
#define MNTTAB mtab
#define MT_FILSYS m_path
/* MT_FILSYS is field in mtab with directory name */
***************
*** 119,124
#else
int dirfd; /* 14 char fixed length directory entries */
#endif
if (argc < 2) exit(0);
--- 136,142 -----
#else
int dirfd; /* 14 char fixed length directory entries */
#endif
+ int nread, mount_found;
if (argc < 2) exit(0);
***************
*** 155,160
seeking a match on device number...
*/
for (x = 0; x < NMOUNT; ++x)
{ if (read(mth,&mte,MTE_SIZE) != MTE_SIZE)
{ fprintf(stderr,"%s: errno %d reading mnttab\n",argv[0],errno);
--- 173,180 -----
seeking a match on device number...
*/
+ mount_found = 0; /* haven't fount the mount dir yet */
+
for (x = 0; x < NMOUNT; ++x)
{ nread = read(mth,&mte,MTE_SIZE);
if (nread != MTE_SIZE && nread != 0)
***************
*** 156,163
*/
for (x = 0; x < NMOUNT; ++x)
! { if (read(mth,&mte,MTE_SIZE) != MTE_SIZE)
! { fprintf(stderr,"%s: errno %d reading mnttab\n",argv[0],errno);
exit(32);
}
STAT(mte.MT_FILSYS,&ssfs); /* name of directory mounted as */
--- 176,185 -----
mount_found = 0; /* haven't fount the mount dir yet */
for (x = 0; x < NMOUNT; ++x)
! { nread = read(mth,&mte,MTE_SIZE);
! if (nread != MTE_SIZE && nread != 0)
! {
! fprintf(stderr,"%s: errno %d reading mnttab\n",argv[0],errno);
exit(32);
}
STAT(mte.MT_FILSYS,&ssfs); /* name of directory mounted as */
***************
*** 165,171
printf("lln: debug: Looking at mounted dir %s\n", mte.MT_FILSYS);
printf(" st_dev=%d, st_rdev=%d, want dev # = %d\n", ssfs.st_dev, ssfs.st_rdev, curdev);
#endif /* debug */
! if (ssfs.st_dev == ssfil.st_dev) break;
#ifdef DEBUG
else printf("debug: wrong dir (%d != %d)\n",
ssfs.st_dev, ssfil.st_dev);
--- 187,197 -----
printf("lln: debug: Looking at mounted dir %s\n", mte.MT_FILSYS);
printf(" st_dev=%d, st_rdev=%d, want dev # = %d\n", ssfs.st_dev, ssfs.st_rdev, curdev);
#endif /* debug */
! if (ssfs.st_dev == ssfil.st_dev)
! {
! mount_found = 1;
! break;
! }
#ifdef DEBUG
else printf("debug: wrong dir (%d != %d)\n",
ssfs.st_dev, ssfil.st_dev);
***************
*** 171,176
ssfs.st_dev, ssfil.st_dev);
#endif
}
#ifdef DEBUG
printf("lln: debug: found mounted dir starting point\n");
--- 197,218 -----
ssfs.st_dev, ssfil.st_dev);
#endif
}
+ if (!mount_found)
+ {
+ strcpy(mte.MT_FILSYS, "/");
+ STAT(mte.MT_FILSYS,&ssfs);
+ #ifdef DEBUG
+ printf("lln: debug: Looking at mounted dir %s\n", mte.MT_FILSYS);
+ printf(" st_dev=%d, st_rdev=%d, want dev # = %d\n", ssfs.st_dev, ssfs.st_rdev, curdev);
+ #endif /* debug */
+ if (ssfs.st_dev == ssfil.st_dev)
+ {
+ mount_found = 1;
+ }
+ #ifdef DEBUG
+ else printf("debug: wrong dir (%d != %d)\n",
+ ssfs.st_dev, ssfil.st_dev);
+ #endif
}
if (!mount_fount)
***************
*** 172,177
#endif
}
#ifdef DEBUG
printf("lln: debug: found mounted dir starting point\n");
#endif
--- 214,226 -----
ssfs.st_dev, ssfil.st_dev);
#endif
+ }
+ if (!mount_fount)
+ {
+ fprintf(stderr, "lln: cannot find mount point of file system containing file '%s'\n", argv[i]);
+ continue;
+ }
+
#ifdef DEBUG
printf("lln: debug: found mounted dir starting point\n");
#endif
***************
*** 298,304
*pathend = '/';
#ifdef BSD_FILESYS
strncpy(pathend + 1,cd->d_name,cd->d_namlen + 1);
! chdir(cd->d_name);
#else /* !bsd_filsys */
strncpy(pathend + 1,cd.d_name,14);
chdir(cd.d_name);
--- 347,353 -----
*pathend = '/';
#ifdef BSD_FILESYS
strncpy(pathend + 1,cd->d_name,cd->d_namlen + 1);
! if (chdir(cd->d_name) < 0)
#else /* !bsd_filsys */
strncpy(pathend + 1,cd.d_name,14);
if (chdir(cd.d_name))
***************
*** 301,307
chdir(cd->d_name);
#else /* !bsd_filsys */
strncpy(pathend + 1,cd.d_name,14);
! chdir(cd.d_name);
#endif
#ifdef DEBUG
printf("lln: debug: visiting %s\n", pathbuf);
--- 350,356 -----
if (chdir(cd->d_name) < 0)
#else /* !bsd_filsys */
strncpy(pathend + 1,cd.d_name,14);
! if (chdir(cd.d_name))
#endif
{
fprintf(stderr, "lln: cannot chdir to %s\n",
***************
*** 303,308
strncpy(pathend + 1,cd.d_name,14);
chdir(cd.d_name);
#endif
#ifdef DEBUG
printf("lln: debug: visiting %s\n", pathbuf);
#endif /* debug */
--- 352,367 -----
strncpy(pathend + 1,cd.d_name,14);
if (chdir(cd.d_name))
#endif
+ {
+ fprintf(stderr, "lln: cannot chdir to %s\n",
+ pathbuf);
+ #ifdef BSD_FILESYS
+ CLOSEDIR(newdfd);
+ #else
+ close(newdfd);
+ #endif
+ continue;
+ }
#ifdef DEBUG
printf("lln: debug: visiting %s\n", pathbuf);
#endif /* debug */
--
Tim Pointing, DCIEM
{decvax|ihnp4|watmath}!utzoo!dciem!tim
or uw-beaver!utcsri!dciem!tim
or seismo!mnetor!lsuc!dciem!tim