2.9BSD/usr/src/ucb/vsh/dir.c

Compare this file to the similar file:
Show the results in this format:

#include "hd.h"
#include "mydir.h"

#define	curmtime	wd_stb.st_mtime

/* See dir.h for information about these variables */
int tfiles, tpages, cpage, pageend;

struct stat wd_stb;

int wdfile;
char wdname [MPLEN + 1];

struct direct dirbuf [mfiles + 1];

char *d_namep [mfiles];

int dir_status;
struct stat scr_stb;

char *dirmsg [] = {
	"", "System Error", "Too big to Load", 
	"Executable but not Readable"
};

/*  Enterdir -- Enter into new directory.
    The parameter newdir is the file to change to.  Pass a single
    element file name or a full path name. "file", "..", or "."
    are OK.  "../..", "/a/b/..", "a/", or "a/." must be passed
    to the file procedure instead.

    On success, there is a new current directory, and wdname has been
    modified to reflect the new path name.  ENTERDIR | REPLOT is the
    return value.  On failure, FAILURE is returned.  Nothing is changed.
*/

enterdir (newdir)  char * newdir;  {

int entermode;		/* Type of entry */
#define	FOREWARD	0	/* Deaper into dir */
#define	BACKWARD	1	/* Previous dir (..) */
#define	STOP		2	/* Stay in same place (.) */
#define LOAD		3	/* Load new path name */

if (compe (newdir, DOT)) entermode = STOP;
else if (compe (newdir, DOTDOT)) entermode = BACKWARD;
else if (newdir[0] == '/') entermode = LOAD;
else entermode = FOREWARD;

if (entermode == FOREWARD && strlen (wdname) > LPLEN) {
	putmsg ("Cannot chdir -- Pathname too long");
	return FAILURE;
}

if (chdir (newdir)) {
	myperror (newdir);
	return FAILURE;
}

if (entermode == STOP);			/* change to "." */
else if (entermode == BACKWARDS) {	/* change to ".." */
	todotdot (wdname);
	if (ISROOT (wdname)) chdir (SLASH);
}
else if (entermode == LOAD) strcpy (wdname, newdir);

else {
	if (!ISROOT (wdname)) strcat (wdname, SLASH);
	strcat (wdname, newdir);	/* go deaper into dir */
}

close (wdfile);  wdfile = open (DOT, 0);  dir_status = unloaded;
cpage = 1;
return ENTERDIR | REPLOT;
}

/* loaddir loads dir and sets assoc parameters */
loaddir () {

tpages = tfiles = 0;
if (wdfile < 0) {dir_status = protected;  return;}
else dir_status = unloaded;

fstat (wdfile, &wd_stb);

if (wd_stb.st_size > max_dir_size) {
	dir_status = toobig;  return;
}
lseek (wdfile, 0L, 0);		/* read in entire file */
read (wdfile, dirbuf, (int) wd_stb.st_size);

sortdir ();

tpages = tfiles / nfpp + ((tfiles % nfpp) > 0);
dir_status = loaded;
return;
}

/* sortdir sorts the directory entries.  when done, the following is true:
    1)  tfiles contains the number of files available
    2)  the d_namep array will contain pointers to the files.
	these will be sorted assending.
*/
sortdir () {

struct direct *maxent, *dirp;
int dircmp ();

tfiles = 0;
maxent = & dirbuf [wd_stb.st_size / dirsize];
for (dirp = dirbuf; dirp < maxent; dirp++) {
	if (dirp->d_ino) d_namep [tfiles++] = dirp->d_name;
	dirp->d_ino = 0;
}
qsort (d_namep, tfiles, sizeof d_namep [0], dircmp);
}

dircmp (a, b) char **a, **b; {
	return strcmp (*a, *b);
}

/*  Dispdir displays a page of the directory.
    W A R N I N G.  Dispdir modifies global data.  If the dir is not
    loaded, or is out of date, dispdir will call on loaddir.
    Cpage can be adjusted to conform to the current dir.
    An out of date dir is reloaded only if reload is true.

    In general, the goal of dispdir is to make sure the internal
    representation of the directory is consistent with the real
    directory, and what is displayed is consistent with the internal
    directory.
*/

dispdir (reload) int reload; {

int dirx;		/* index into dirbuf */
int dirchar;		/* char to select file assoc. with dirx */

long lastmtime;		/* last time dir was modified */

bufout ();  clearmsg (-1);
if (reload) {
	lastmtime = curmtime;
	fstat (wdfile, &wd_stb);
	if ((lastmtime != curmtime) || dir_status) loaddir ();
}

cpage = max (1, min (cpage, tpages));
pageend = 0;

erase ();
printf ("Directory = %s  %s", wdname, dirmsg [dir_status]);

if (tfiles == 0) {
	unbufout ();  return;
}

if (tpages > 1) {
	at ((strlen (wdname) > 50) ? 268 : 168);
	printf ("Page %d / %d    ", cpage, tpages);
}

pageend = tfiles % nfpp;
if (cpage != tpages || pageend == 0) pageend = nfpp;

for (dirx = 0, dirchar = 'a'; dirx < pageend;  dirx++, dirchar++) {
	atfile (dirx, 3);
	printf ("%c  %s", dirchar, filename (dirx));
}
unbufout ();
}

/*	Change dir to father of dir  */
todotdot (dir) char *dir; {

	register char *cp;

	for (cp = dir; *cp; cp++);	/* Scan to end of name */
	while (*--cp != '/');		/* Scan back to a slash */
	if (cp == dir) cp++;		/* Must handle root specially */
	*cp = 0;
}