[net.sources] Fast subdirectory lister for 4.2 BSD.

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