lvc@cbsck.UUCP (Larry Cipriani) (11/21/85)
If you're as impatient as I am you'll appreciate this program. It lists files sorted in columns, but, because of it's limited scope, is much faster than the lsc command. It runs on every version of UNIX I know of. Larry Cipriani #!/bin/sh : This is a shar archive. Extract with sh, not csh. : The rest of this file will extract: : 'l.c' echo extracting - 'l.c' sed 's/^X//' > 'l.c' << 'END_OF_FILE' X/* X** This program lists all the file names in <directory>. They X** are listed in at most five columns. Directories are listed X** with a terminating /, executables with a terminating *. X** The current directory is the default directory. X** X** usage: l [-a] [directory] X*/ X X#include <stdio.h> /* standard i/o package */ X#include <sys/types.h> /* needed for <sys/stat.h> */ X#include <sys/stat.h> /* stat structure declared */ X#include <sys/dir.h> /* direct structure declared */ X X#define TABSIZ=8 X#define MAXCOL=5 /* maximum number of columns = 80/16 */ X /* 80 = number of columns on terminal */ X /* 16 = DIRSIZ + 2 blanks for spacing */ X Xchar *malloc(); /* memory allocator - section 3 */ X Xint copyn(); /* copies s2 to s1, returns number copied */ Xint error(); /* prints an error message */ Xint namecmp(); /* comparison function for file names */ Xint qsort(); /* quicker sort - section 3 */ X Xchar *progname; X Xmain(argc, argv) X int argc; X char *argv[]; X{ X int fd, i, aflg; X int ncols, nrows, nfiles, nstructs, ntabs; X int col, row, filenum, len, pad; X char filename[DIRSIZ+1], *fmt1, *fmt2; X char iobuf[BUFSIZ]; X char *usage = "usage: %s [-a] [directory]\n"; X char *cannot = "%s: cannot %s %s\n"; X char *dir, *dot; X unsigned dirsize; X struct direct *head, **headp; X struct stat stbuf; X X aflg = 0; X dir = (char *)0; X dot = "."; X progname = argv[0]; X X if (argc > 3) X error(usage, (char *)0, (char *)0); X X for (i = 1; i < argc; i++) X { X if (strcmp(argv[i], "-a") == 0 && aflg == 0) X aflg++; X else X if (dir == (char *)0) X dir = argv[i]; X else X error(usage, (char *)0, (char *)0); X } X X if (dir == (char *)0) X dir = dot; X else X if (chdir(dir) == -1) X error(cannot, "chdir", dir); X X if ((fd = open(dot , 0)) == -1) X error(cannot, "open", dir); X X if (stat(dot, &stbuf) == -1) X error(cannot, "stat", dir); X X setbuf(stdout, iobuf); X X dirsize = (unsigned)stbuf.st_size; X nstructs = dirsize/sizeof(struct direct); X head = (struct direct *)malloc(dirsize); X if (read(fd, (char *)head, dirsize) == -1) X error(cannot, "read", dir); X headp = (struct direct **)malloc(sizeof(struct direct **) * nstructs); X X /* set up pointers only to the files to be listed */ X X if (aflg) X { X for (nfiles = i = 0; i < nstructs; i++) X if (head[i].d_ino != (ino_t)0) X headp[nfiles++] = &head[i]; X } X else X { X for (nfiles = i = 0 ; i < nstructs; i++) X if (head[i].d_ino != (ino_t)0 && X head[i].d_name[0] != '.') X headp[nfiles++] = &head[i]; X } X X if (nfiles == 0) X exit(0); X X /* sort only the pointers */ X X qsort((char *)headp, nfiles, (int)sizeof(struct direct **), namecmp); X X nrows = nfiles / MAXCOL + (nfiles % MAXCOL ? 1 : 0); X ncols = nfiles / nrows + (nfiles % nrows ? 1 : 0); X X for (row = 0; row < nrows; row++) X { X for (col = 0; col < ncols; col++) X { X if ((filenum = col*nrows + row) >= nfiles) X continue; X X len = copyn(filename, headp[filenum]->d_name, DIRSIZ); X X stat(filename, &stbuf); X X if (stbuf.st_mode & S_IFDIR) X { X pad = 1; X fmt1 = "%s/\n"; X fmt2 = "%.*s/%.*s"; X } X else X if (stbuf.st_mode & S_IEXEC) X { X pad = 1; X fmt1 = "%s*\n"; X fmt2 = "%.*s*%.*s"; X } X else X { X pad = 2; X fmt1 = "%s\n"; X fmt2 = "%.*s%.*s"; X } X X if ((col == ncols - 1) || (filenum + nrows >= nfiles)) X fprintf(stdout, fmt1, filename); X else X { X ntabs = ((DIRSIZ+pad-len) > TABSIZ ? 2 : 1); X fprintf(stdout, fmt2, len, X filename, ntabs, "\t\t"); X } X } X fflush(stdout); /* write the row out */ X } X X exit(0); X} X X/* X** Sorts the file names in alphabetical order. X*/ X Xint namecmp(pp1, pp2) X struct direct **pp1, **pp2; X{ X register struct direct *p1 = *pp1; X register struct direct *p2 = *pp2; X X return(strncmp(&p1->d_name[0], &p2->d_name[0], DIRSIZ)); X} X X/* X** Copies s2 to s1 until n characters have been copied X** or the null of s2 is reached, whichever occurs sooner. X** Returns the number of non-null characters copied, X** and s1 is null terminated. X*/ X Xint copyn(s1, s2, n) X register char *s1, *s2; X register int n; X{ X register int i; X X for (i = 0 ; i < n; i++) X if ((*s1++ = *s2++) == '\0') X return(i); X *s1 = '\0'; X return(i); X} X Xerror(format, verb, noun) X char *format, *verb, *noun; X{ X fprintf(stderr, format, progname, verb, noun); X exit(-1); X} END_OF_FILE Larry Cipriani cbscc!lvc