dir.c and dir.1l (directory program)
emigh at ecsvax.UUCP
emigh at ecsvax.UUCP
Tue Sep 27 23:59:15 AEST 1983
: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
all=FALSE
if [ $1x = -ax ]; then
all=TRUE
fi
/bin/echo 'Extracting dir.1l'
sed 's/^X//' <<'//go.sysin dd *' >dir.1l
X.TH DIR 1
X.SH NAME
DIR - Version 1.0 by Richard Conn
X.SH SYNOPSIS
X.nf
Usage:
dir path <-- List Files Along Path
dir -a path <-- List Files Along Path with Attributes
dir -h path <-- List Files Along Path, Including Hidden
dir -ah path <-- -a and -h Combined
X.fi
X.SH DESCRIPTION
DIR is designed to provide a "clean" directory display to the user.
It lists the matching files in a double column format, alphabetizing the
entries down the columns. File names and sizes are included in the listing,
as well as a total at the bottom of the screen. If a file is a directory,
it is preceeded by the letter "D".
If the -a option is used, the attributes (read, write, and execute)
are listed as well.
If the -h option is used, hidden files (those whose names start
with a dot) are listed in addition to the other files.
X.SH EXAMPLES
The following directory displays illustrate the various
options of DIR. Comments are included in these displays, and they
are denoted by "<--" and extend from this symbol to the end of the line.
X.nf
$ dir $HOME/.src <-- Display non-hidden files in $HOME/.src
-- Filename -- - Size - -- Filename -- - Size -
c.c 921 menu.c 10421
chario.c 1498 setek.c 637
comhex.c 2067 type.c 2611
cpmunix.c 2490 uc.c 30629
cpmutl7.c 32032 umodem.c 42252
crc.c 1752 unixcpm.c 1264
crck.c 1254 unixcpm.lbr 139904
dir.c 7485 unixcpm.txt 1361
dirtest.c 1325 xsq107.c 21521
lar.c 13787 xtype107.c 6292
lss.c 711 xusq107.c 6281
mcheck.c 3186
-- 23 Entries Displayed, 331681 Bytes --
$ dir -a $HOME/.src <-- Display non-hidden files in $HOME/.src
<-- with Attributes
-- Filename -- - Size - Atr -- Filename -- - Size - Atr
c.c 921 rw- menu.c 10421 rw-
chario.c 1498 rw- setek.c 637 rw-
comhex.c 2067 rw- type.c 2611 rw-
cpmunix.c 2490 rw- uc.c 30629 rw-
cpmutl7.c 32032 rw- umodem.c 42252 rw-
crc.c 1752 rw- unixcpm.c 1264 rw-
crck.c 1254 rw- unixcpm.lbr 139904 rw-
dir.c 7485 rw- unixcpm.txt 1361 rw-
dirtest.c 1325 rw- xsq107.c 21521 rw-
lar.c 13787 rw- xtype107.c 6292 rw-
lss.c 711 rw- xusq107.c 6281 rw-
mcheck.c 3186 rw-
-- 23 Entries Displayed, 331681 Bytes --
$ dir -a $HOME/.src/*.c <-- Display non-hidden files matching *.c
<-- in $HOME/.src with Attributes
-- Filename -- - Size - Atr -- Filename -- - Size - Atr
c.c 921 rw- mcheck.c 3186 rw-
chario.c 1498 rw- menu.c 10421 rw-
comhex.c 2067 rw- setek.c 637 rw-
cpmunix.c 2490 rw- type.c 2611 rw-
cpmutl7.c 32032 rw- uc.c 30629 rw-
crc.c 1752 rw- umodem.c 42252 rw-
crck.c 1254 rw- unixcpm.c 1264 rw-
dir.c 7485 rw- xsq107.c 21521 rw-
dirtest.c 1325 rw- xtype107.c 6292 rw-
lar.c 13787 rw- xusq107.c 6281 rw-
lss.c 711 rw-
-- 21 Entries Displayed, 190416 Bytes --
$ dir -a $HOME <-- Display non-hidden files in $HOME
<-- with Attributes
-- Filename -- - Size - Atr
uc.log 0 rw-
-- 1 Entries Displayed, 0 Bytes --
$ dir -ah $HOME <-- Display all files in $HOME with
<-- Attributes
-- Filename -- - Size - Atr -- Filename -- - Size - Atr
D . 224 rwx .profile 75 rw-
D .. 160 rwx D .sh 80 rwx
D .bin 320 rwx D .src 480 rwx
D .c 464 rwx .stmenu 225 rw-
D .doc 224 rwx .ucsetup 123 rw-
D .man 432 rwx uc.log 0 rw-
D .new 32 rwx
-- 13 Entries Displayed, 2839 Bytes --
X.fi
X.SH FILES
dir.c <-- source code
X.SH DIAGNOSTICS
DIR issues only two diagnostic messages:
X.sp 2
1. Dynamic Memory Overflow
X.br
While DIR is running, it dynamically allocates memory for the
directory entries as it identifies them. This message means the the
operating system has run out of dynamic memory to give to DIR. This
error is fatal and non-recoverable. I have never seen it occur.
X.sp 2
2. Can't find filename
X.br
DIR cannot locate a file as identified by the user. This occurs
if the file unambigously specified by the user does not exist in the
directory searched.
X.SH BUGS
No known bugs exist within DIR.
X.SH AUTHOR
Richard Conn
X.sp 2
DDN Addresses: rconn at BRL, rconn at SIMTEL20
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 644 dir.1l
/bin/echo -n ' '; /bin/ls -ld dir.1l
fi
/bin/echo 'Extracting dir.c'
sed 's/^X//' <<'//go.sysin dd *' >dir.c
X/*
* DIR Version 1.0 by Richard Conn
*
* DIR is an enhanced directory display utility for UNIX.
* It produces a sorted listing of file names and sizes in two columns,
* and the files are sorted down the columns. If a file is a directory,
* its name is prefixed with a "D". File count and size totals are displayed
* at the bottom of the listing.
*
*/
X/* C Libraries */
#include <stdio.h>
#include <sys/types.h>
#include <sys/dir.h>
#include <sys/stat.h>
#define BUFSIZE 256
X/* Structure of a Directory Element as Stored for DIR */
struct dirnode {
char name[DIRSIZ]; /* Name of File */
int dir; /* Dir or Not? */
off_t size; /* Size in Bytes */
short mode; /* R/W/X */
struct dirnode *next; /* Ptr to Next File */
};
X/* Global Environment */
struct environ {
int showhid; /* Show Hidden Files? */
int showrwx; /* Show Attributes? */
int filecnt; /* Number of Files in List */
off_t totsize; /* Sum of All File Sizes */
struct dirnode *first; /* Ptr to First Elt in List */
struct dirnode *last; /* Ptr to Last Elt in List */
};
main(argc,argv)
char *argv[];
{
char buf[BUFSIZE];
struct environ env;
int i, first;
/* Init Environment */
env.first = NULL; /* No First Entry */
env.showhid = 0; /* No Hidden Files */
env.showrwx = 0; /* No R/W/X */
env.filecnt = 0; /* No Files */
env.totsize = 0; /* Accumulated File Size */
/* Build Linked List of DIR Elements */
if (argc == 1) build(".",&env,0); /* current dir */
else {
first = 1; /* first file is 1 */
if (*argv[1] == '-') {
first = 2; /* first file is 2 */
opts(argv[1],&env);
if (argc == 2) build(".",&env,0); /* curr dir */
}
for (i=first; i<argc; i++) build(argv[i],&env,0); /* ea */
}
/* Sort Linked List of DIR Elements */
sort(&env);
/* Display Results */
display(&env);
}
X/* Process Command Options */
opts(cmdstr,env)
char *cmdstr;
struct environ *env;
{
while (*cmdstr != '\0')
switch (*cmdstr++) {
case 'A' :
case 'a' :
env->showrwx = 1; /* show file attributes */
break;
case 'H' :
case 'h' :
env->showhid = 1; /* show hidden files */
default :
break;
}
}
X/* Display Entries in Linked List */
display(env)
struct environ *env;
{
struct dirnode *lptr, *rptr, *elt();
char *fname;
int i;
if (env->filecnt > 0) {
printf(" -- Filename -- - Size -");
if (env->showrwx) printf(" Atr");
}
if (env->filecnt > 1) {
printf(" -- Filename -- - Size -");
if (env->showrwx) printf(" Atr");
}
printf("\n");
lptr = elt(0,env); /* Pt to first element in left col */
rptr = elt(env->filecnt%2 ? env->filecnt/2+1 : env->filecnt/2, env);
for (i=0; i < env->filecnt/2; i++) {
prelt(lptr,env); /* Print Left Element */
prelt(rptr,env); /* Print Right Element */
printf("\n"); /* New Line */
lptr = lptr->next; /* Pt to next */
rptr = rptr->next;
}
if (env->filecnt%2) {
prelt(lptr,env); /* Print Odd Element */
printf("\n");
}
printf(" -- %d Entries Displayed, %ld Bytes --\n",
env->filecnt, env->totsize);
}
X/* Print Element Pointed To */
prelt(ptr,env)
struct dirnode *ptr;
struct environ *env;
{
char *fname;
int j;
if (ptr->dir) printf("D "); /* Print Dir Flag */
else printf(" ");
fname = ptr->name;
for (j=0; j < DIRSIZ; j++) /* Print File Name */
if (*fname == '\0') putchar(' ');
else putchar(*fname++);
printf(" %8ld", ptr->size); /* Print File Size */
if (env->showrwx) printf(" %c%c%c", /* Print RWX Flags */
(ptr->mode & S_IREAD) ? 'r' : '-',
(ptr->mode & S_IWRITE) ? 'w' : '-',
(ptr->mode & S_IEXEC) ? 'x' : '-');
printf(" ");
}
X/* Shell Sort Directory Entries (See Pg 108 of K&R for Algorithm) */
sort(env)
struct environ *env;
{
int gap, i, j;
struct dirnode dir, *eltj, *eltjg, *elt();
for (gap = env->filecnt/2; gap > 0; gap /= 2)
for (i = gap; i < env->filecnt; i++)
for (j = i-gap; j >= 0; j -= gap) {
eltj = elt(j,env); /* pt to elt j */
eltjg = elt(j+gap,env); /* pt to elt j+gap */
if (strcmp(eltj->name,eltjg->name) <= 0)
break;
/* temp = v[j] */
*dir.name = '\0'; /* clear str */
strcat(dir.name,eltj->name);
dir.dir = eltj->dir;
dir.size = eltj->size;
dir.mode = eltj->mode;
/* v[j] = v[j+gap] */
*eltj->name = '\0'; /* clear str */
strcat(eltj->name,eltjg->name);
eltj->dir = eltjg->dir;
eltj->size = eltjg->size;
eltj->mode = eltjg->mode;
/* v[j+gap] = temp */
*eltjg->name = '\0'; /* clear str */
strcat(eltjg->name,dir.name);
eltjg->dir = dir.dir;
eltjg->size = dir.size;
eltjg->mode = dir.mode;
}
}
X/* Point to Nth (Starting at 0) Element in Linked List */
struct dirnode *elt(n,env)
int n;
struct environ *env;
{
struct dirnode *rover;
int i;
rover = env->first; /* pt to first element */
for (i=0; i<n; i++) rover = rover->next; /* adv thru list */
return (rover);
}
X/* Build Linked List Structure Containing Directory Entries */
build(name,env,level)
char *name;
struct environ *env;
int level;
{
struct stat stbuf;
struct dirnode dir;
struct dirnode *calloc();
char *nameptr;
int i, ccnt;
/* Check for File Existence */
if (stat(name,&stbuf) == -1) {
fprintf(stderr,"Can't find %s\n", name);
return;
}
/* Check to See if File is a Directory */
if ((stbuf.st_mode & S_IFMT) == S_IFDIR) { /* we have a dir */
directory(name,env,level);
if (!level) return;
}
/* Check Hidden Entries */
if (*name == '.' && !(env->showhid)) return;
/* Store Entry in Memory */
if (env->first == NULL) { /* First Entry Processing */
env->first = calloc(1, sizeof(dir));
env->last = env->first;
}
else { /* Nth Entry Processing */
(*env->last).next = calloc(1, sizeof(dir));
env->last = (*env->last).next;
}
if (env->last == NULL) {
fprintf(stderr, "Dynamic Memory Overflow\n");
exit(0);
}
/* Store Entry Values */
env->filecnt++; /* Increment File Count */
(*env->last).next = NULL;
nameptr = name; /* Pt to first char of file name */
ccnt = strlen(name); /* Number of chars in file name */
for (i=0; i < ccnt; i++) /* Find Last Part of Name */
if (*name++ == '/') nameptr = name;
strcat((*env->last).name,nameptr); /* Save File Name */
(*env->last).size = stbuf.st_size; /* Save File Size */
(*env->last).mode = stbuf.st_mode; /* Save Mode Bits */
env->totsize += stbuf.st_size; /* Increment Total Sizes */
if ((stbuf.st_mode & S_IFMT) == S_IFDIR) /* Set Dir Flag */
(*env->last).dir = 1;
else (*env->last).dir = 0;
}
X/* Process All Entries in a Directory */
directory(name,env,level)
char *name;
struct environ *env;
int level;
{
struct direct dirbuf;
char *nbp, *nep;
char dirname[BUFSIZE];
char filename[DIRSIZ];
int i,fd;
if (level) return; /* don't recurse */
/* Build Name of Directory into DIRNAME */
nep = dirname;
nbp = name;
while (*nbp != '\0') *nep++ = *nbp++;
*nep = '\0'; /* terminate string */
if (nep+DIRSIZ+2 >= dirname+BUFSIZE) /* name too long */
return;
/* Log Into Directory */
if (chdir(dirname)) {
fprintf(stderr, "Directory %s Not Found\n", dirname);
return;
}
/* Open Directory File */
if ((fd = open(".",0)) == -1) return;
/* Read Through the Elements in the Directory */
while (read(fd, (char *)&dirbuf, sizeof(dirbuf)) > 0) {
if (dirbuf.d_ino == 0) /* slot not in use */
continue;
for (i=0, nep=filename; i<DIRSIZ; i++) /* build file name */
*nep++ = dirbuf.d_name[i];
*nep++ = '\0';
build(filename,env,level+1); /* reenter build for new file */
}
close(fd);
}
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 644 dir.c
/bin/echo -n ' '; /bin/ls -ld dir.c
fi
More information about the Comp.sources.unix
mailing list