home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************
- *
- * Lib.c
- *
- * Disk Library Documentation System
- * Main Program
- *
- * By Wilson Snyder (c) January 1988
- *
- ****************************************************************
- *
- * NOTICE:
- *
- * This program was written as a service to the amiga
- * users. This program may be used by all parties, including
- * sale (see below) as long as the author's name and address
- * remains intact in the program and documentation.
- * Distribution of this program by parties selling it
- * as part of a commercial for-profit package of over $10
- * must contact the address below before such a package is sold.
- *
- * I make no warranties over this program, performance,
- * etc. And any costs incurred by this program, or its
- * actions are placed on the user.
- *
- * PLEASE FORWARD INPROVEMENTS MADE TO THIS PROGRAM TO:
- *
- * Wilson Snyder, 15 Davis Parkway, South Burlington, VT 05403
- *
- ****************************************************************
- *
- * AddName and base for Process taken from the TSIZE
- * utility written by the excellent work of the
- * Software Distillery.
- *
- ****************************************************************/
-
- #include "libraries/dosextens.h"
- #include "ctype.h"
- #include "stdio.h"
-
- #define VERSION "AMIGA-LIB. Version 1.0.2. By Wilson Snyder"
- #define DESC "$$DES$$"
-
- #define PERSUB 8 /* Characters to indent per subdirectory */
- #define INFOIND 8 /* Indent for description and filesize */
- #define RM 75 /* Right margin */
- #define LM 0 /* Left margin */
- #define TM 1 /* Top margin */
- #define HM 2 /* Header margin (lines after header) */
- #define LINES 60 /* Lines per page */
-
- BPTR Lock(); /* Define functions... */
- BOOL Examine();
- BOOL ExNext();
-
- char path [256]; /* Current search path */
- char header [80]; /* Header for top line */
- BOOL prtsize = FALSE; /* Print the path size information */
- BOOL prtheader = FALSE; /* Print the header and page breaks */
-
- struct Sortem { /* Linked list for insertion sort of directory names */
- char FileName[108]; /* Directory name */
- struct Sortem *Next; /* Pointer to next */
- };
-
- /***************************************************************
- * ADDNAME
- *
- * Add filename to the end of the current path.
- *
- * Routine taken from from TSIZE utility by the Software Distillery.
- ***************************************************************/
-
- int AddName(name, len)
- register char *name;
- int len;
- {
- register char *p; /* current position in path */
- register int i = 0; /* added length counter */
- char ch; /* last character of current path */
-
- p = path + len;
-
- /* add a slash between path and name if legal */
- if (len != 0 && (ch = path[len-1]) != '/' && ch != ':') {
- *p++ = '/';
- i++;
- }
-
- /* copy name to end of path (including null terminator) */
- while (*p++ = *name++) i++;
-
- /* return new length of path */
- return (len + i);
- }
-
-
- /***************************************************************
- * FILECMP
- * Compare two filenames for sort routine (case insensitive.)
- ***************************************************************/
-
- int filecmp(a,b)
- char *a,*b;
- {
- for (;toupper(*a)==toupper(*b);a++,b++)
- if (*a=='\0') return (0);
- return (toupper(*a)-toupper(*b));
- }
-
-
- /***************************************************************
- * INDENT
- * Indent a number of spaces. Outputted to stdout.
- ***************************************************************/
-
- void Indent(num)
- int num;
- {
- while (num--) putchar (' ');
- }
-
- /***************************************************************
- * HEADER
- * Print header every so many lines.
- ***************************************************************/
-
- void Header(inc)
- int inc;
- {
- static int linecount; /* Number of lines down */
- static int page; /* Current page number */
- int t; /* Temp */
-
- if (inc)
- linecount += inc;
- else {
- /* 0 increment resets information */
- linecount = 0;
- page = 0;
- }
-
- if (linecount>LINES && prtheader) {
- /* Time to print the header */
- putchar ('\f');
- page++;
- for (t=TM;t;t--) putchar ('\n');
- printf (header,page);
- for (t=HM;t;t--) putchar ('\n');
- linecount = TM + HM + 1;
- }
- }
-
-
- /***************************************************************
- * ROOT
- * Print information for the page header
- ***************************************************************/
-
- BOOL Root()
- {
- struct FileInfoBlock *info; /* pointer to file info */
- BPTR lock; /* pointer to file lock */
- int t,loc; /* temp stuff */
-
- /* allocate an info block (must be longword alligned) */
- if (!(info = (struct FileInfoBlock *)
- AllocMem(sizeof(struct FileInfoBlock), 0))) {
- printf ("Out of memory.\n");
- return (TRUE);
- }
-
- /* try to obtain lock on current file */
- if (!(lock = Lock(path, ACCESS_READ))) {
- printf ("Invalid file or directory, '%s'.\n", path);
- FreeMem(info, sizeof(struct FileInfoBlock));
- return (TRUE);
- }
-
- /* get information on file or directory associated with lock */
- if (!Examine(lock, info)) {
- printf ("Error examining locked file or directory.\n");
- UnLock(lock);
- FreeMem(info, sizeof(struct FileInfoBlock));
- return (TRUE);
- }
-
- /* Make sure user specified a directory, not a file */
- if (info->fib_DirEntryType <= 0) {
- printf ("Must specify a directory, not a file.\n");
- UnLock(lock);
- FreeMem(info, sizeof(struct FileInfoBlock));
- return (TRUE);
- }
-
- /* Build Header line (will be used with printf) */
- loc = 0;
- for (t=LM;t;t--) header[loc++] = ' ';
- strcpy (&header[loc], "Page %-4d");
- loc += 9;
- for (t=RM-loc-strlen(info->fib_FileName);t;t--) header[loc++] = ' ';
- strcpy (&header[loc],info->fib_FileName);
- loc += strlen(info->fib_FileName);
- header[loc++] = '\n';
- header[loc] = '\0';
-
- /* Initalize header printer, then force header printing */
- Header (0);
- Header (LINES+2);
-
- UnLock(lock);
- FreeMem(info, sizeof(struct FileInfoBlock));
- return (FALSE);
- }
-
-
- /***************************************************************
- * BOTTOM
- * Display size information at bott
- om of directory.
- ***************************************************************/
-
- void Bottom (depth,size,found)
- int depth;
- long size;
- BOOL found;
- {
- if (prtsize) {
- Indent (depth*PERSUB+INFOIND+LM);
- printf ("Total size %ld bytes.\n", size);
- if (found) printf ("\n");
- Header (2);
- }
- }
-
- /***************************************************************
- * DISPLAY
- * Display information from the DESC file in the directory.
- ***************************************************************/
-
- BOOL Display (depth,dirname)
- int depth;
- char *dirname;
- {
- FILE *desc; /* DESCription file info */
- BOOL found; /* Found a description file */
- int lineloc; /* Location on the output line */
- int wordlen; /* Length of word in the buffer */
- char wordstore[RM+10]; /* Storage for current word */
- BOOL Cont; /* & encountered, ignore return */
- BOOL Long; /* Long line/word just printed */
- char ch; /* Character from file */
- int t,lm; /* temp */
-
- /* Print directory name */
- Header (2);
- Indent (depth*PERSUB+LM);
- printf ("%s\n", dirname);
-
- /* Add DESC filename to path, attempt to open the file */
- t = strlen(path);
- AddName (DESC,t);
- found = ((desc=fopen(path,"r"))!=0);
-
- /* If found, justify the file on the way out */
- if (found) {
- lm = depth*PERSUB+INFOIND+LM;
- lineloc = lm;
- Indent (lm);
- wordlen = 0;
- Cont = FALSE;
- Long = FALSE;
- /* Process one character at a time */
- while ((ch=getc(desc))!=EOF) {
- /* Ignore return if proceded by a & */
- if ((ch=='\n') && Cont) {
- Cont = FALSE;
- continue;
- }
- if (Cont) { /* & not proceded by a return */
- wordstore[wordlen++] = '&';
- Cont = FALSE;
- }
- /* Dump out the current word */
- if (ch==' ' || ch=='\n') {
- wordstore[wordlen] = '\0';
- printf ("%s ",wordstore);
- lineloc += wordlen + 1;
- wordlen = 0;
- if (Long || ch=='\n') {
- putchar ('\n');
- Header(1);
- Indent (lm);
- lineloc = lm;
- Long = FALSE;
- }
- continue;
- }
- /* Force return if line goes over right margin */
- if (((wordlen+lineloc)>RM) || (wordlen>(RM-lm))) {
- if (wordlen>(RM-lm)) {
- wordstore[wordlen] = '\0';
- printf ("%s",wordstore);
- wordlen = 0;
- Long = TRUE;
- }
- putchar ('\n');
- Header(1);
- Indent (lm);
- lineloc = lm;
- }
- /* Check for continuation character */
- if (ch=='&') Cont = TRUE;
- else wordstore[wordlen++] = ch;
- }
- fclose (desc);
- /* Dump out any remaining word in the buffer */
- if (wordlen) {
- wordstore[wordlen] = '\0';
- puts (wordstore);
- putchar ('\n');
- Header (1);
- lineloc=0;
- }
- if (lineloc>lm) putchar('\n');
- putchar('\n');
- }
-
- /* Restore path, return status if file was found */
- path[t] = '\0';
- return (found);
- }
-
-
- /*************************************************************
- * PROCESS
- *
- * Find the size of a directory tree by adding the sizes
- * of all files in the directory and all of its subdirectories.
- *
- * General directory searching concept taken from TSIZE
- * utility by the Software Distillery.
- ************************************************************/
-
- long Process(len,depth)
- int len; /* Length of path name */
- int depth; /* Number of directories down */
- {
- struct FileInfoBlock *info = NULL; /* pointer to file info */
- struct Sortem *sort_top = NULL; /* top of sort list */
- struct Sortem *sort_cur = NULL; /* current sort list loc */
- struct Sortem *sort_tmp = NULL; /* current sort temp loc */
- struct Sortem *sort_last= NULL; /* last sort temp loc */
- long size = 0; /* running total of file size */
- BPTR lock; /* pointer to file lock */
- BOOL found; /* found DESC file */
-
- /* Try to obtain lock on current directory */
- if (!(lock = Lock(path, ACCESS_READ))) {
- printf ("Invalid directory, '%s'.\n", path);
- goto EXIT;
- }
-
- /* Allocate an info block (must be longword alligned) */
- if (!(info = (struct FileInfoBlock *)
- AllocMem(sizeof(struct FileInfoBlock), 0))) {
- printf ("Out of memory.\n");
- goto EXIT;
- }
-
- /* Get information on file or directory associated with lock */
- if (!Examine(lock, info)) {
- printf ("Error examining locked directory.\n");
- goto EXIT;
- }
-
- /* This should not happen, but... */
- if (info->fib_DirEntryType <= 0) {
- printf ("Locked a file, not directory.\n");
- goto EXIT;
- }
-
- /* Display top of directory header */
- found = Display (depth,info->fib_FileName);
-
- /* Read this directory */
- while (ExNext(lock, info)) {
- /* This is a directory */
- if (info->fib_DirEntryType > 0) {
- /* sub-directory, allocate sortem node */
- if (!(sort_cur = (struct Sortem *)
- AllocMem(sizeof(struct Sortem), 0))) {
- printf ("Out of memory.\n");
- break;
- }
- strcpy(sort_cur->FileName,info->fib_FileName);
- sort_cur->Next = NULL;
-
- /* Alphabetical insertion sort */
- /* Find insertion location for new node */
- for (sort_tmp = sort_top; sort_tmp;
- sort_tmp = sort_tmp->Next) {
- if (filecmp(sort_tmp->FileName,info->fib_FileName)>0)
- break;
- sort_last = sort_tmp;
- }
-
- /* Insert the node */
- if (sort_tmp==sort_top) {
- sort_cur->Next = sort_top;
- sort_top = sort_cur;
- }
- else if (!sort_tmp) {
- sort_cur->Next = NULL;
- sort_last->Next = sort_cur;
- }
- else {
- sort_cur->Next = sort_last->Next;
- sort_last->Next = sort_cur;
- }
- sort_cur = NULL;
- }
- else /* found a file, just add size */
- size += info->fib_Size;
- }
-
- /* Transverse sorted list, process then deallocate the node */
- for (sort_tmp = sort_top; sort_tmp; sort_tmp = sort_last) {
- size += Process(AddName(sort_tmp->FileName, len),depth+1);
- sort_last = sort_tmp->Next;
- FreeMem(sort_tmp, sizeof(struct Sortem));
- }
-
- /* Repair path */
- path[len] = '\0';
-
- /* Print bottom of directory information */
- Bottom (depth, size, found);
-
- EXIT:
- if (info) FreeMem(info, sizeof(struct FileInfoBlock));
- if (lock) UnLock(lock);
- return(size);
- }
-
- /***************************************************************
- * MAIN
- ***************************************************************/
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int len; /* Length of file name given on command line */
- int t; /* Temp variable */
-
- /* Help information */
- if (argv[1][0]=='?') {
- printf ("%s\nUseage: %s [Read-Path] [-size]\n",
- VERSION, argv[0]);
- exit (0);
- }
-
- /* parse command line (len used as temp param counter) */
- for (len=1;len<argc;len++)
- if (argv[len][0]=='-') { /* switch */
- switch (toupper(argv[len][1])) {
- case 'S': /* Size Flag */
- prtsize = TRUE;
- break;
- case 'H': /* Header Flag */
- prtheader = TRUE;
- break;
- /* ADD OTHER SWITCHES HERE */
- default:
- printf ("Bad Switch.\n");
- }
-
- /* Drop this argument */
- argc--;
- for (t=len;t<argc;t++) argv[t] = argv[t+1];
- }
-
- /* Process pathname */
- if (argc>1)
- len = AddName(argv[1], 0);
- else len = AddName(":", 0);
-
- /* Check root info, exit if invalid */
- if (Root()) return(20);
-
- /* Process root directory */
- (void)Process(len,0);
-
- EXIT:
- return(0);
- }
-