Path: utzoo!attcan!uunet!husc6!purdue!i.cc.purdue.edu!j.cc.purdue.edu!ain
From: ain@j.cc.purdue.edu (Patrick White)
Newsgroups: comp.sources.amiga
Subject: disklib (sources 1 of 1)
Keywords: disk libraries, compiled.
Message-ID: <7305@j.cc.purdue.edu>
Date: 27 Jun 88 13:00:20 GMT
Organization: PUCC Land, USA
Lines: 704
Approved: ain@j.cc.purdue.edu (Patrick White)
Submitted by: snyderw@life.pawl.rpi.edu
Summary: Generate disk library listings from $$DES$$ files in the directories.
Poster Boy: Patrick White (ain@j.cc.purdue.edu)
Archive Name: sources/amiga/volume5/disklib.s.sh.Z
Tested.
NOTES:
This is really two programs -- lib and tolib.
The $$DES$$ file for these programs is in the docs, along with a brief
description of the format of a $$DES$$ file (basically none).
-- Pat White (co-moderator comp.sources/binaries.amiga)
ARPA/UUCP: j.cc.purdue.edu!ain BITNET: PATWHITE@PURCCVM PHONE: (317) 743-8421
U.S. Mail: 320 Brown St. apt. 406, West Lafayette, IN 47906
========================================
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# lib.c
# tolib.c
# This archive created: Wed Jun 22 12:20:29 1988
# By: Patrick White (PUCC Land, USA)
echo shar: extracting lib.c '(12961 characters)'
cat << \SHAR_EOF > lib.c
/***************************************************************
*
* 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 bottom 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;len1)
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);
}
SHAR_EOF
if test 12961 -ne "`wc -c lib.c`"
then
echo shar: error transmitting lib.c '(should have been 12961 characters)'
fi
echo shar: extracting tolib.c '(4042 characters)'
cat << \SHAR_EOF > tolib.c
/***************************************************************
*
* ToLib.c
*
* Disk Library Documentation System
* Convert README.list files to LIB system
*
* 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
*
***************************************************************/
#include "exec/types.h"
#include "stdio.h"
#define VERSION "AMIGA-TOLIB. Version 1.0.0. By Wilson Snyder"
#define BRK 70 /* Where to break up long, continous lines */
#define BRKTIT 40 /* Where to break title */
#define SPACEEQ 3 /* Spaces seperating filename and description */
void main(argc, argv)
int argc;
char *argv [];
{
FILE *InFile,*OutFile; /* Files for reading and writing */
unsigned char cntr=0; /* Insert line break every BRK chars */
int spaces; /* Number spaces encountered */
int mode; /* 0=line begin, 1=space drop, 2=coping, 3=title extract */
BOOL linelast; /* Copied text on the last line */
char ch; /* Current read character */
/* Print usage information */
if (argv[1][0]=='?') {
printf ("%s\nUseage: %s Input-File Output-File [header]\n",
VERSION, argv[0]);
exit (0);
}
/* Open input file */
if (!(InFile = fopen (argv[1],"r"))) {
printf ("Bad input file.\n");
exit (0);
}
/* Open output file */
if (!(OutFile = fopen (argv[2],"w"))) {
printf ("Bad output file.\n");
fclose (InFile);
exit (0);
}
mode = 0;
cntr = 0;
linelast = FALSE;
/* Begin the copy */
while ((ch=getc(InFile))!=EOF) {
/* Newline, reset mode to 0, */
if (ch=='\n') {
linelast = (mode==1 || mode==2);
if (linelast) {
/* output continuation if text printed on last line */
putc(' ',OutFile);
putc('&',OutFile);
}
putc (ch,OutFile);
mode = 0;
continue;
}
switch (mode) {
case 0: /* Beginning of Line */
cntr = 0;
/* If begins with space or tab is a text line */
if (ch==' ' || ch=='\t') {
mode = 1; /* Skip leading spaces */
}
else {
/* Otherwise is a new title */
if (linelast) putc ('\n',OutFile);
if (argc>3) {
/* Print optional disk title */
fputs (argv[3],OutFile);
putc ('\n',OutFile);
}
spaces = 0;
mode = 3; /* Copy title */
putc(ch,OutFile);
}
break;
case 1: /* Skipping leading spaces or tabs before text */
if (ch==' ' || ch=='\t') break; /* drop it */
putc (ch,OutFile);
cntr = 1;
mode = 2; /* now copy remainder */
break;
case 2: /* Coping to EOL */
cntr++;
if (cntr>BRK) {
putc('&',OutFile);
putc('\n',OutFile);
cntr = 0;
}
putc (ch,OutFile);
break;
case 3: /* Copying title until tab or several spaces */
cntr++;
/* count spaces, after SPACEEQ start text copy */
if (ch==' ')
spaces++;
/* End of title, found a tab or line over length */
if ((spaces>=SPACEEQ) || ch=='\t' || cntr>=BRKTIT) {
putc ('\n', OutFile);
mode = 1; /* skip rest */
break;
}
if (ch==' ') break;
/* Write title info after stored spaces*/
while (spaces--) putc (' ', OutFile);
spaces = 0;
if (ch!=' ') putc (ch, OutFile);
if (cntr>=BRKTIT) mode = 1; /* Chr limit */
break;
default:
/* Bad state */
printf ("Internal mode error\n");
fclose (InFile);
fclose (OutFile);
exit(20);
}
}
/* All done. */
fclose (InFile);
fclose (OutFile);
}
SHAR_EOF
if test 4042 -ne "`wc -c tolib.c`"
then
echo shar: error transmitting tolib.c '(should have been 4042 characters)'
fi
# End of shell archive
exit 0