<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>
Date   : Fri, 03 May 1985 18:14:42 GMT
From   : bill%persci.uucp@BRL.ARPA
Subject: ldir.c and ltype.c source, for Unix

I am posting this to net.micro.cpm instead of net.sources because I believe it
to be of no interest to anybody other than a CP/M user.

Here are sources for ldir.c and ltype.c, two probably very familiar library
utilities. I acquired these from a local BBS, where they had been posted as
IBM PC utilities. It took a little effort to adapt them to our 4.2bsd 
environment.

Now all that is needed is for somebody to build on these routines (and on the
'usq' I posted a few days ago to net.sources) to create a full 'lu' utility,
which would be *VERY* handy in facilitating file transfers to/from home.

I am sure some of you will improve and enhance these utilities. Please post
your upgrades so we all can share them.

Bill Swan 	{ihnp4|decvax|allegra|...}!uw-beaver!tikal!persci!bill
#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	ldir.c
#	ltype.c
# This archive created: Fri May  3 10:59:32 1985
export PATH; PATH=/bin:$PATH
echo shar: extracting "'ldir.c'" '(10133 characters)'
if test -f 'ldir.c'
then
	echo shar: over-writing existing file "'ldir.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'ldir.c'
X/*	LDIR 	Library Directory display program */
X
X#define	VERSION		3 
X#define	REVISION	1
X#define MOD_DATE	"85-05-03"
X
X/*
XLegal Notices:
X	Copyright (c) 1982, 1983 by Gary P. Novosielski.
X	All rights reserved.
X
X	Permission is hereby granted for noncommercial use.
X	Use or duplication of this or any derivative work for
X	commercial advantage without prior written consent
X	of the author is prohibited.
X
XLIFO Revision Summary:
X	3.01	85-05-03	Modified to run under 4.2bsd. Required changing
X				all ints to shorts. (Bill Swan)
X	3.00	84-29-84	Revised for use on IBM-PC running
X				MS-DOS. Compiler = Lattice 'c'
X				(Pete Mack)
X	2.20	83-10-13	Changed Kb size calculation to
X				round upward.  Added max drive
X				validation.  Moved copyright
X				display to help section.
X	2.11	83-03-21	BDS 1.5 support.
X				Size display in Kb.
X	2.10	82-12-09	Size display in sectors.
X	2.00	82-11-20	[Not released]
X	1.00	82-11-14	Initial source release
X		Gary P. Novosielski
X
XProgram Description:
X	This program is intended for use on RCPM systems to
X	allow callers to see the contents of the directories
X	of .LBR files on the system.  You probably won't need
X	it on your home system, since the -L function of LU.COM
X	provides this ability.  Since LU is not active on
X	remote systems, a program like this is necessary
X	to allow you to see member names in a library without
X	your having to download the library first.
X
X	It has been modified to run under Unix 4.2bsd, as a help
X	to those of us who transfer files between our home systems
X	and VAXen.
X*/
X
X#include <stdio.h>
X#include <ctype.h>
X
X#define	FALSE	0
X#define TRUE	-1
X
X/* Pseudo typedef's */
X#define FLAG		char
X
X/* Number of displayed entries */
X#define NWIDE	4
X
X/* 		EXTERNALS */
XFILE   *lbrfile, *fopen();			 /* fd for library file	*/
Xchar lbrname[20];
X
X#define FROM_START	0
X
XFLAG lbropen;
Xshort  entries, freeent;
X
X/* Entry Size */
X#define ESIZE		32
X
X/* Entries per sector */
X#define EPS		(SECSIZ / ESIZE)
X
X/* Structure of a directory entry */
Xstruct direntry
X{
X    char status;	/* Possible values */
X#define  ACTIVE			0x00
X#define  KILLED			0xFE
X#define	 VIRGIN			0xFF
X    char id[8+3]; 	/* filename.ext */
X    unsigned short indx;	/* Pointer to first sector */
X    unsigned short size;	/* Size of member in sectors */
X    unsigned short crc;	/* CRC check word */
X    /* Future expansion space */
X#define EXPSIZ			14
X    char expand[EXPSIZ];
X}
X*directory, *curentry;	/* two pointers to such a beast */
X
Xtypedef struct direntry dirtype;
X
Xchar sopt;		/* size option: S, N, or K */
Xchar *drmsg;		/* Max drive letter allowed */
X
X/*		END OF EXTERNALS */
X#define SECSIZ	128
X#define OK	0
X#define ERROR	-1
X
X
Xshort	indexc(),entcmp(),bitcmp();	/*non-integer functions*/
X/************************************************
X main
X*************************************************/
X
Xmain (argc,argv)
Xunsigned  argc;
Xchar *argv[];
X{
X    printf(
X      "Library DIRectory   Ver:%d.%02d   %s\n\r%s\n\r",
X      VERSION,REVISION,MOD_DATE,
X      "Press CTRL-S to pause; CTRL-C to cancel"
X      );
X
X
X    /*
X    The FIRST character of the following message is actually
X    used in the test for the maximum legal drive.  This will
X    allow sites which do not support a C compiler to easily
X    find and patch this value in the object code.
X    */
X    drmsg = "P: is highest valid drive";
X
X
X    /* Initialize flags */
X    sopt = 'K';			/* Default option setting */
X    lbropen = FALSE;		/* No library open */
X    directory = NULL;		/* No directory in memory */
X
X
X    if (argc < 2)		/* No command line arguments */
X    {
X	puts("\n\rCopyright (c) 1982, 1983 by Gary P. Novosielski");
X	puts("\n\r\nCorrect syntax is:");
X	puts("\n\rLDIR [<option>] name1 [[<option>] [name2...[nameN]]]");
X	puts("\n\r\nWhere:\tname1 through");
X	puts("\n\r\tnameN\tare library names; default type: .LBR");
X	puts("\n\rOptions:\n\r\t-n\tonly show names of members.");
X	puts("\n\r\t-s\talso show size in sectors.");
X	puts("\n\r\t-k\tlike -s, but size in Kbytes. (default)");
X	puts("\n\rOption flags stay in effect for subsequent names.");
X	puts("\n\rAmbiguous names are not permitted.");
X
X
X
X    }
X    else
X	/* Process command line arguments */
X	while(--argc)
X	{
X	    if (**(++argv) == '-')
X		procopt(*argv);
X	    else if (!namel(*argv))
X		dirlist();
X	    else
X		printf("\n\r%s not found on disk.\n\r",lbrname);
X
X	}
X    /* End of command line.  Clean up and exit */
X}
X/* End of main function */
X
X/************************************************
X Open *name as the current library
X*************************************************/
X
Xnamel(name)
Xchar *name;
X{
X    if (lbropen && close(lbrfile) == ERROR)
X	abend("\n\rCan't close library: %s",lbrname);
X    lbropen = FALSE;
X    if (isambig(name) || indexc(name,' ') != ERROR)
X	abend("\n\rBad library name: %s",name);
X    if (name[1] == ':' && *name > *drmsg)
X	abend("\n\r%s",drmsg);
X    strcpy(lbrname,name);
X    if (indexc(name,'.') == ERROR)
X	strcat(lbrname,".LBR");
X    if ((lbrfile = fopen(lbrname,"r")) != NULL)
X    {
X	printf("\n\rLibrary: %s has ",lbrname);
X	readdir();
X    }
X    else
X	return ERROR;
X    lbropen = TRUE;
X    printf ("%d entries, %d free:\n\r",entries,freeent);
X    return OK;
X}
X
X/************************************************
X   Return flag saying if the requested number of memory bytes
X   are available.  Try to make them available if possible.
X*************************************************/
X
XFLAG avail(request)
Xunsigned short request;	/* in bytes */
X{
X    char *ptr;
X    unsigned short  *curavail, temp;
X    temp = 0;
X
X    curavail = &temp;	/* Pseudo-static kluge */
X
X    if(request < *curavail)
X	return TRUE;
X    if ((ptr = (char *)sbrk(++request - *curavail)) == (char *)ERROR)
X	return FALSE;
X
X    /* If this is the first success, initialize pointer */
X    if (directory == NULL)
X	directory =  (dirtype *) ptr;
X
X    *curavail = request; /* Modify static for next call */
X    return TRUE;
X}
X
X/************************************************/
X/* Read the directory into memory */
X/*************************************************/
X
Xreaddir()
X{
X    if (!avail(SECSIZ))
X	memerr();
X    fseek(lbrfile, 0, FROM_START);
X
X    if (
X      fread(directory,128,1,lbrfile) != 1
X      || entcmp(directory,"\0           ")
X      || directory->indx
X      || !directory->size
X      )
X        abend("no directory.");
X    if (directory->size > 1)
X    {
X	if (!avail(SECSIZ * directory->size))
X	    memerr();
X	if (fread(directory+EPS,128, directory->size - 1,lbrfile)
X	  != directory->size - 1)
X	    abend("a bad directory");
X    }
X
X    freeent = entries = EPS * directory->size;
X
X    for(
X      curentry = directory;
X      curentry->status != VIRGIN && freeent;
X      ++curentry
X      )
X	--freeent;
X}
X
X/************************************************
X memory error
X*************************************************/
X
Xmemerr()
X{
X    abend("an absurdly huge directory");
X}
X
X/************************************************
X  Search string *s for character c.  Return offset 
X*************************************************/
X
Xshort indexc(s, c)
Xchar *s, c;
X{
X    short i;
X    for (i = 0; *s; i++) 
X	if(*s++ == c)
X	    return i;
X    return ERROR;
X}
X
X/************************************************
X  Return TRUE if s contains asterisk(s) or question(s)
X*************************************************/
X
Xisambig(s)
Xchar *s;
X{
X    if (indexc(s,'*') != ERROR || indexc(s,'?') != ERROR)
X	return TRUE;
X    return FALSE;
X}
X
X/************************************************
X Terminate program with error message 
X*************************************************/
X
Xabend(p1, p2, p3, p4)
X{
X    printf(p1, p2, p3, p4);
X    puts("\n\r\nFor help, type LDIR alone.");
X    exit();
X}
X
X/************************************************
X compare string a to string b ignoring some bits of each
X*************************************************/
Xshort
Xbitcmp(a, b, count, mask)
Xchar *a, *b, mask;
Xshort count;
X{
X    short r;
X    while(count--)
X	if (r = (*a++ & mask) - (*b++ & mask))
X	    return r;
X    return 0;
X}
X
X/************************************************
X form a string in dst from a standard format name in src
X*************************************************/
X
Xformname(dst,src)
Xchar *dst, *src;
X{
X    int i,j;
X    j = 0;
X
X/* Remove attributes first so compares will work */
X    for (i = 1; i < 12; i++)
X	src[i] &= 0x7F;
X    for (i = 1; i < 9; i++)
X    {
X	if (src[i] == ' ')
X	    break;
X	dst[j++] = src[i];
X    }
X    if (src[9] != ' ')
X	dst[j++] = '.';
X    for (i = 9; i < 12; i++)
X    {
X	if (src[i] == ' ')
X	    break;
X	dst[j++] = src[i];
X    }
X    dst[j] = '\0';
X    return;
X}
X
X/************************************************
X   Compare two directory entries. Note that status is major
X   sort field.
X*************************************************/
Xshort
Xentcmp(a,b)
Xchar *a, *b;
X{
X    short  i, r;
X
X    for (i = (1+8+3); i--; a++, b++)
X	if ((r = *a - *b) && *b != '?')
X	    return r;
X    return 0;
X}
X
X/************************************************
X   List the directory of the current library, and return number
X   of free entries
X*************************************************/
X
Xdirlist()
X{
X    char name[20];
X    short  i;
X    unsigned del, act;
X
X    curentry = directory;
X    for ((act = del = 0, i = entries - freeent); --i;)
X    {
X	if ((++curentry)->status == ACTIVE) 
X	{
X	    if(!(act % NWIDE))  
X		puts("\n\r");
X	    formname(name, curentry);
X
X	    switch (sopt)
X	    {
X	    case 'S':	/* Size in sectors */
X		printf("%-12s%5ds ", name, curentry->size);
X		break;
X	    case 'K':	/* Size in Kilobytes */
X		printf("%-12s%5dk ",name, (curentry->size+7)/8);
X		break;
X	    case 'N':	/* Name only. More names per line */
X		printf("%-14s",name);
X	    }
X	    ++act;
X	}
X	else
X	    ++del;
X    }
X    printf("\n\r Active entries: %u, Deleted: %u, Free: %u, Total: %u.\n\r",
X      ++act, del, freeent, entries);
X    return --act;
X}
X
X/************************************************
X Process option string (-xx)
X*************************************************/
X
Xprocopt(s)
Xchar *s;
X{
X
X    while(*(++s))
X	switch (*s)
X	{
X	case 'S':
X	case 'N':
X	case 'K':
X	case 's':
X	case 'n':
X	case 'k':
X	    sopt = toupper(*s);
X	    break;
X	default:
X	    abend("'%c' is an invalid option",*s);
X	}
X}
SHAR_EOF
if test 10133 -ne "`wc -c 'ldir.c'`"
then
	echo shar: error transmitting "'ldir.c'" '(should have been 10133 characters)'
fi
echo shar: extracting "'ltype.c'" '(2093 characters)'
if test -f 'ltype.c'
then
	echo shar: over-writing existing file "'ltype.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'ltype.c'
X#define	VERSION		0
X#define REVISION	0
X#define MOD_DATE	"04/18/85"
X
X/* This program will type a member of a LBR file... any member,
X   BUT anything other than an ASCII file will produce a screenful
X   of garbage.
X
X   USE: LTYPE <library> <member>
X*/
X#include <stdio.h>
X#include <sys/file.h>
X
Xchar curdsk, fcb[36];
Xchar fnam[12], libnam[16], dirbuf[128], *dirp;
Xint  fd, dirsiz, filsiz;
X
X#define OK	0
X#define ERROR -1
X
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X{
X	printf("\n\rLTYPE vers:%d.%02d  %s\n\r\n",
X	VERSION,REVISION,MOD_DATE);
X	opnlib(argv[1]);
X	if (fndmem(argv[2]) == ERROR) erxit("\n\rMember not in LBR file!\n\r");
X	printf("\n\rFile present - %d sectors.\n\r",filsiz);
X	doit();
X}
X
Xdoit()
X{
X	int	j;
X	int	c;
X	dirsiz = filsiz;
X	do {
X		reload();
X		for (j=0; j<128; j++){
X			if (*dirp == 0x1a) exit();
X			putchar(*dirp);
X			if(*dirp == 0x0a) putchar(0x0d);
X			dirp++;
X		}
X	}while(dirsiz != 0);
X}
X
Xopnlib(file)
Xchar *file;
X{
X	char l, *npnt;
X	strcpy(libnam,file);
X	fd = open(libnam,O_RDONLY);
X	if(fd == -1) erxit("Library file not found.\n");
X}
X
Xfndmem(file)
Xchar *file;
X{
X	char dnam[16], fname[36];
X	long int	floc;
X	setfcb(fname,file);
X	read(fd,dirbuf,128);
X	dirp = dirbuf;
X	dirsiz = *(dirp+14);
X	dirp += 32;
X	do{
X		if (*dirp == 255) return(ERROR);
X		if (*dirp == 0){
X			strcpy(dnam, dirp+1);
X			dnam[11]=0;
X			if(strcmp(dnam, fname) == 0){
X				filsiz = (*(dirp+14)) + ((*(dirp+15)) * 256);
X				floc=(*(dirp+12)) + ((*(dirp+13)) * 256);
X				lseek(fd,floc *128,0);
X				return(OK);
X			}
X		}
X		dirp += 32;
X		if(dirp > dirbuf+128) reload();
X	} while(dirsiz);
X	return(ERROR);
X}
X
Xreload()
X{
X	read(fd,dirbuf,128);
X	dirp = dirbuf;
X	dirsiz--;
X}
X
Xmatchr(st,ch)
Xchar *st,ch;
X{
X	int i;
X	for(i=0; st[i]; i++){
X		if(st[i] == ch) return(i);
X	}
X	return(0);
X}
X
Xsetfcb(fname,file)
Xchar *fname;
Xchar *file;
X{
X	int i,j;
X	i = 0; j = 0;
X	while (file[j] && file[j] != '.' && i < 8) fname[i++] = file[j++];
X	while (i < 8) fname[i++] = ' ';
X	if (file[j] == '.') while (i < 11 && file[++j]) fname[i++] = file[j];
X	while (i < 11) fname[i++] = ' ';
X	fname[11] = 0;
X}
X
Xerxit(strg)
Xchar *strg;
X{
X	printf(strg);
X	exit();
X}
SHAR_EOF
if test 2093 -ne "`wc -c 'ltype.c'`"
then
	echo shar: error transmitting "'ltype.c'" '(should have been 2093 characters)'
fi
#	End of shell archive
exit 0

-- 
Bill Swan 	{ihnp4|decvax|allegra|...}!uw-beaver!tikal!persci!bill
<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>