stephen@dcl-cs.UUCP (Stephen J. Muir) (06/06/85)
This program prints subdirectories at high speed. It does not (normally) scan directories which have no subdirectories. ----------------------------------- cut here ---------------------------------- #!/bin/sh echo 'Start of pack.out, part 01 of 01:' echo 'x - subdirs.c' sed 's/^X//' > subdirs.c << '/' X/* Written by Stephen J. Muir, Computing Dept., Lancaster University */ X X# include <errno.h> X# include <sys/types.h> X# include <sys/stat.h> X# include <sys/dir.h> X# include <sys/file.h> X# include <stdio.h> X Xextern errno; Xextern char *strcpy (); X Xstruct stat state; X Xchar *dot = ".", *dotdot = "..", dir [4096], linkbuf [4096]; X Xint symlook; X XDIR *dirfd, *fdstack [32], **fdp = &fdstack [0]; X Xerror (name) X char *name; X { fflush (stdout); X perror (name); X } X Xopen_ (name) X char *name; X { *fdp++ = dirfd; X if ((dirfd = opendir (name)) != NULL) X return (0); X dirfd = *--fdp; X return (1); X } X Xclose_ () X { closedir (dirfd); X dirfd = *--fdp; X } X Xptree (ep) X char *ep; X { struct direct *curfile; X if (open_ (dot)) X { if (errno == EMFILE) X printf ("%s/...\n", dir); X else X error (dot); X return; X } X *ep++ = '/'; X while ((curfile = readdir (dirfd)) != NULL) X { if (strcmp (curfile->d_name, dot) == 0 || X strcmp (curfile->d_name, dotdot) == 0 X ) X continue; X lstat (curfile->d_name, &state); X if ((state.st_mode & S_IFMT) == S_IFDIR) X { strcpy (ep, curfile->d_name); X if (state.st_ino == 2) X printf ("%s: mounted file system\n", dir); X else X if (symlook == 0 && state.st_nlink == 2) X printf ("%s\n", dir); X else X if (access (ep, R_OK) == -1 || chdir (ep) == -1) X error (dir); X else X { char *np; X printf ("%s\n", dir); X for (np = ep; *np++; ); X ptree (np - 1); X if (chdir (dotdot) == -1) X error (dotdot); X } X } X else X if ((state.st_mode & S_IFMT) == S_IFLNK) X { int cc; X strcpy (ep, curfile->d_name); X printf ("%s", dir); X if ((cc = readlink (ep, linkbuf, sizeof (linkbuf))) == -1) X error (": readlink"); X else X { linkbuf [cc] = '\0'; X printf (" -> %s\n", linkbuf); X } X } X } X close_ (); X } X X/*ARGSUSED*/ Xmain (argc, argv, envp) X char *argv [], *envp []; X { char *ep = &dir [0], *ap; X close (0); X dup2 (1, 2); X if (argc > 1 && strcmp (argv [1], "-l") == 0) X { --argc; X ++argv; X ++symlook; X } X if (argc > 2) X { printf ("usage: subdirs [-l] [directory name]\n"); X exit (1); X } X ap = argc == 2 ? argv [1] : dot; X if (access (ap, R_OK) == -1 || chdir (ap) == -1) X { error (ap); X exit (1); X } X if (strcmp (ap, "/") == 0) X ++ap; X while (*ep++ = *ap++); X ptree (ep - 1); X exit (0); X } / echo 'x - subdirs.n' sed 's/^X//' > subdirs.n << '/' X.TH SUBDIRS 1 "12 October 1984" X.SH NAME Xsubdirs \- print sub-directories and symbolic links X.SH SYNOPSIS X.B subdirs X[-l] [directory name] X.SH DESCRIPTION X.I Subdirs Xlists the names of all the sub-directories below the directory indicated Xby the parameter given. XIf the directory is not supplied, "." will be assumed. XThe program will report any mounted file systems and symbolic links Xencountered as it scans the directories. XNormally, to speed up X.IR subdirs , Xdirectories with no subdirectories (link count = 2) are not scanned. XThe X.I \-l Xflag causes these to be scanned; finding X.B all Xsymbolic links, but with a speed penalty. X.SH DIAGNOSTICS XA pathname ending in X.B "/..." Xindicates a subdirectory nested too deeply for subdirs to handle. X.SH "SEE ALSO" Xdu (1), ls (1), mount (8) X.SH AUTHOR XStephen J. Muir, Lancaster University. / echo 'Part 01 of pack.out complete.' exit -- NAME: Stephen J. Muir Project:Alvey ECLIPSE Distribution JANET: stephen@uk.ac.lancs.comp DARPA: stephen%lancs.comp@ucl-cs UUCP: ...!ukc!icdoc!dcl-cs!stephen PHONE: +44 524 65201 Ext. 4599 POST: Department of Computing, University of Lancaster, Bailrigg, Lancaster. LA1 4YR