Fast subdirectory lister for 4.2 BSD.
Stephen J. Muir
stephen at dcl-cs.UUCP
Thu Jun 6 23:20:43 AEST 1985
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 at uk.ac.lancs.comp DARPA: stephen%lancs.comp at 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
More information about the Comp.sources.unix
mailing list