home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
vol_100
/
182_01
/
ldir.c
< prev
next >
Wrap
Text File
|
1990-07-31
|
12KB
|
487 lines
/* Paul Homchick 31 Aug 84
*
* directory display routines from lu86
*
* will compile with Computer Innovations C86, or
* Digital Research C
*
* v 1.03 added 'close(lbr)'s' in error return code in get_directory()
* v 1.04 expanded input list definitions to 128 from 30
* checked for wildexp error in CI C86 version
*/
#include <stdio.h>
/************************************************************************/
/* PREPROCESSOR DEFINITIONS */
/************************************************************************/
#define VERNO " 1.04" /* VERSION number */
#define VERDATE "26 Sep 84" /* VERSION date */
#define ERROR -1
#define FLAG int
#define ACTIVE 0 /* active, non-deleted file, */
#define UNUSED 0xff /* never used slot, */
#define DELETED 0xfe /* deleted file slot, */
#define MAXNAMES 128 /* maximum number of names in cmnd line */
#define MAXFILES 256 /* max files per LBR file */
#define NOCOLS 4 /* number of colums on 80 col screen */
#define JBASE 1965 /* for julian date routines */
#define DATEADJ 4748 /* to conform to DRI julian date */
#define DRC 1 /* using Dig Res Compiler */
#ifdef DRC
#include <ctype.h>
#define BREAD 0
#define UNSIGNED
#define OPEN openb
#else /* else use CI C86 */
#define OPEN open
#define UNSIGNED unsigned
#endif
/************************************************************************/
/* STRUCTURES */
/************************************************************************/
/* This is the structure of the LBR file directory. One per slot. */
struct _ludir {
UNSIGNED char stat; /* file status, */
char name[11]; /* FCB type filename, */
unsigned off; /* offset to data, (sectors) */
unsigned len; /* length (sectors) of data , */
unsigned crc; /* CRC checksum for member */
unsigned cdate; /* file create date, uses DRI julian dt format */
/* (jan 1, 1978 = 1; july 4, 1984 =2273, etc.) */
unsigned udate; /* file update date, uses Dig Res format */
unsigned ctime; /* file create time, uses MSDOS format */
unsigned utime; /* file update time, uses MSDOS format */
UNSIGNED char padchar; /* number of pad bytes in last sector */
UNSIGNED char filler; /* fill out to 32 bytes */
int fill[2]; /* fill out to 32 bytes */
} ludir; /* (dummy ludir so we can sizeof() it) */
struct dtbl {
struct _ludir ldir[MAXFILES];
};
struct _date {
int day;
int month;
int year;
int yearday;
}; /* date */
struct _tod {
int hr;
int min;
int sec;
}; /* time */
static int day_tab[2][13] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
/************************************************************************/
/* TYPE DECLARATIONS */
/************************************************************************/
struct dtbl *dtblPtr;
struct _date *datePtr;
struct _tod *todPtr;
char names[MAXNAMES][30]; /* list of names from command line, */
char *substr, *index();
FLAG crcflag;
int lbr; /* LBR file handle, */
int num_names; /* number of names in above list */
int num_slots; /* number of slots in LBR file, */
unsigned updcrc(),checksum; /* crc support for LU 3.0 compatibility */
/************************************************************************/
/* main() */
/************************************************************************/
main(argc,argv)
int argc;
char *argv[];
{
int i;
#ifndef DRC
if (wildexp(&argc, &argv) == ERROR) /* parse ambig. names */
abort("ldir: wildexp error.");
#endif
++argv; --argc;
if (argc < 1) {
fprintf(stderr,"ldir Ver%s, %s; Paul Homchick\n",VERNO,VERDATE);
fprintf(stderr,"Use: ldir lbrfile ... [ >output ]\n");
fprintf(stderr," displays Novosielski LBR directories.\n");
fprintf(stderr,"examples:\tldir one.lbr\t\tldir one\n");
fprintf(stderr,"\t\tldir *.lbr\t\tldir a:*.lbr\n");
fprintf(stderr,"\t\tldir one two three\tldir a*.lbr >a-lbr.dir\n");
exit(0);
}
num_names= argc;
for( i= 0; i < argc; i++) {
cpyarg(names[i],argv[i]);
stoupper(names[i]); /* add ".lbr" if not already there */
if ( ((substr= index(names[i],'.')) != 0) &&
(cmdeq(substr,".LBR")) )
; /* do nothing in this case */
else {
if (substr) {
fprintf(stderr,"ldir:\tError- illegal filetype for library file.\n");
fprintf(stderr,"\tIf a filetype is supplied, it must be \".LBR\".\n");
fprintf(stderr,"\tIf no filetype is supplied, \".LBR\" is assumed.\n");
exit(1);
} else
strcat(names[i],".LBR"); /* add .lbr type */
}
}
if (argc > MAXNAMES) {
fprintf(stderr,"ldir: Program only allows 128 input names,\n");
fprintf(stderr," and %d names are present. Please cut\n",argc);
fprintf(stderr," down on size of input list.\n");
exit(1);
}
dtblPtr= calloc(sizeof(struct dtbl),1);
todPtr= calloc(sizeof(struct _tod),1);
/* note 2000 byte insurance */
if ( ! (datePtr= calloc((sizeof(struct _date)+2000),1)) )
abort("ldir: CALLOC returned NULL, not enough memory.");
list();
}
list()
{
int i,j;
long size, unused;
char name[14];
int active,deleted,empty;
for(j= 0; j < num_names; j++) {
size= unused= 0L;
active= deleted= empty= 0;
if (get_directory(names[j]) == -1)
{
fprintf(stderr,"ldir: Error %s, invalid or not found\n",names[j]);
close(lbr);
return;
}
printf("\nLibrary: %s",names[j]);
if (!(dtblPtr->ldir[0].udate))
slist();
else {
printf("\nFilename Bytes Sectors Index");
printf(" --- Created --- --- Updated ---");
for (i= 0; i < num_slots; i++)
{
if (dtblPtr->ldir[i].stat == ACTIVE)
{
cvt_from_fcb(dtblPtr->ldir[i].name,name);
if(!i)
printf("\ndirectory %7lu %6u %5u",
(long)dtblPtr->ldir[i].len * 128L,dtblPtr->ldir[i].len,
dtblPtr->ldir[i].off);
else
printf("\n%-12s %7lu %6u %5u",name,
(((long)dtblPtr->ldir[i].len * 128L)-dtblPtr->ldir[i].padchar),
dtblPtr->ldir[i].len,dtblPtr->ldir[i].off);
if(dtblPtr->ldir[i].cdate) {
pdate(dtblPtr->ldir[i].cdate);
ptime(dtblPtr->ldir[i].ctime);
}
if(!(dtblPtr->ldir[i].cdate) && dtblPtr->ldir[i].udate)
printf("%19s"," ");
if(dtblPtr->ldir[i].udate) {
pdate(dtblPtr->ldir[i].udate);
ptime(dtblPtr->ldir[i].utime);
}
size+= (((long)dtblPtr->ldir[i].len * 128L)-dtblPtr->ldir[i].padchar);
++active;
}
if (dtblPtr->ldir[i].stat == DELETED) {
unused+= dtblPtr->ldir[i].len * 128;
++deleted;
}
if (dtblPtr->ldir[i].stat == UNUSED) ++empty;
}
if (unused != 0L)
printf("\n(%6lu bytes unused)",unused);
else
printf("\n");
printf("\n%7lu bytes used;",size);
printf("%5u active entries; %5u deleted; %5u empty.\n",
active,deleted,empty);
}
close(lbr);
}
}
/*
* short list for pre version 4.0 lbrs
*/
slist()
{
long tot_siz, unused;
int i, room, ndir, deleted, empty, newline;
char name[14];
tot_siz= unused= 0;
ndir= deleted= empty= newline= 0;
room = (NOCOLS);
printf("\n");
while(room--)
printf("Name Sectors ");
printf("\n\n");
room = (NOCOLS);
for (i = 0; i < num_slots; i++) {
if (dtblPtr->ldir[i].stat == ACTIVE) {
newline= 0;
ndir++;
tot_siz += dtblPtr->ldir[i].len;
cvt_from_fcb(dtblPtr->ldir[i].name,name);
if (!i)
printf("%-12s %4d ","directory",dtblPtr->ldir[i].len);
else
printf("%-12s %4d ",name,dtblPtr->ldir[i].len);
if(--room == 0) {
room = (NOCOLS);
printf("\n");
newline= 1;
}
}
if (dtblPtr->ldir[i].stat == DELETED) {
unused+= dtblPtr->ldir[i].len * 128;
++deleted;
}
if (dtblPtr->ldir[i].stat == UNUSED) ++empty;
}
if (!newline)
printf("\n");
if (unused != 0L)
printf("(%6lu bytes unused)\n",unused);
else
printf("\n");
printf("%7lu bytes used;",tot_siz*128);
printf("%5u active entries; %5u deleted; %5u empty.\n",
ndir,deleted,empty);
}
/* Read the directory. */
get_directory(lbrname)
char *lbrname;
{
unsigned size, checksum, dirchk;
int i, j, count;
UNSIGNED char *bp;
lbr= OPEN(lbrname,BREAD);
if (lbr == -1) return(-1);
if (read(lbr,&dtblPtr->ldir[0],sizeof(ludir)) != sizeof(ludir)) {
return(-1);
}
num_slots= (dtblPtr->ldir[0].len * 128) / sizeof(ludir);
size= (num_slots - 1) * sizeof(ludir); /* already read one, */
if (num_slots > MAXFILES) {
fprintf(stderr,"Directory error: %s is bad or not an LBR file\n"
,lbrname);
return(-1);
}
if ( ! ((dtblPtr->ldir[0].stat == 0) &&
(!strncmp(dtblPtr->ldir[0].name," ",11)) &&
(dtblPtr->ldir[0].off == 0)) ) {
fprintf(stderr,"%s is not a Library.\n",lbrname);
return(-1);
}
if (read(lbr,&dtblPtr->ldir[1],size) != size) {
fprintf(stderr,"Directory error: is %s an LBR file?\n",lbrname);
return(-1);
}
/* disable CRC if master entry is 0 */
crcflag = !(dtblPtr->ldir[0].crc == 0);
checksum= 0;
count= size + sizeof(ludir);
dirchk= dtblPtr->ldir[0].crc;
dtblPtr->ldir[0].crc= 0;
bp = &dtblPtr->ldir[0]; /* start of directory */
for(j = 0;j < count;j++) /* do crc */
checksum = updcrc(*bp++,checksum);
checksum= updcrc(0,updcrc(0,checksum));
dtblPtr->ldir[0].crc= dirchk;
if (crcflag && (checksum != dirchk)) {
printf("Warning: Directory CRC error in %s.\007\n",lbrname);
printf("Directory seems to have %d entries.\n",num_slots);
}
return(1);
}
/*
* Convert a CP/M like filename to a normal ASCIZ name.
* Filter out characters undersireable on MSDOS.
*/
cvt_from_fcb(inname,outname)
char *inname,*outname;
{
int i;
char c;
for (i= 8; i != 0; i--) { /* do name portion, */
c= toupper(*inname);
++inname;
if (c != ' ') /* if not space, */
*outname++= c; /* set it, */
} /* do all 8 chars, */
if (*inname != ' ') { /* if there is an extention, */
*outname++= '.'; /* add the dot, */
for (i= 3; i != 0; i--) { /* do extention, */
c= toupper(*inname);
++inname;
if (c == ' ')
break;
*outname++= c;
}
}
*outname= '\0'; /* terminate it, */
return;
}
/* Convert a string to all upper case. */
stoupper(s)
char *s;
{
while (*s) {
*s= toupper(*s);
++s;
}
}
cpyarg(to,from)
char *to,*from;
{
char *cp;
cp = from;
while(*cp)
*to++ = *cp++;
}
cmdeq(s,p)
char *s, *p;
{
while(*p)
if(*s++ != *p++)
return(0);
return(1);
}
/*
* convert MS-DOS time to hh:mm:ss
*/
word2hms(mstime)
register unsigned int mstime;
{
todPtr->hr= (mstime&0xf800) >> 11;
todPtr->min= (mstime&0x07e0) >> 5;
todPtr->sec= (mstime&0x001f) << 1;
}
ptime(time)
unsigned time;
{
word2hms(time);
printf("%02d:%02d:%02d",todPtr->hr,
todPtr->min,
todPtr->sec);
}
pdate(date)
unsigned date;
{
jul2greg(date);
printf(" %02d/%02d/%02d ",datePtr->month,
datePtr->day,
datePtr->year-1900);
}
/*
** julian to calendar date conversion
**
** (with greatful acknowledgement to Steve Passe)
*/
jul2greg(jdate)
unsigned jdate;
{
register unsigned days, years;
int x, leap;
jdate += DATEADJ;
for (years = days = 0; days < jdate; )
days += (++years % 4 ? 365 : 366);
days -= (years-- % 4 ? 365 : 366);
datePtr->year = years + JBASE;
datePtr->yearday = (int)jdate - days;
leap = datePtr->year % 4 == 0 && datePtr->year % 100 != 0
|| datePtr->year % 400 == 0;
datePtr->day = datePtr->yearday;
for (x = 1; datePtr->day > day_tab[leap][x]; ++x)
datePtr->day -= day_tab[leap][x];
datePtr->month = x;
}
/*
* update CRC
* Copyright 1983 Computer Development Inc Beaverton Or USA
* All rights reserved
*/
unsigned short updcrc(c, crc)
register c;
register unsigned short crc;
{
register count;
for(count=8; --count>=0;) {
if(crc & 0x8000) {
crc <<= 1;
crc += (((c<<=1) & 0400) != 0);
crc ^= 0x1021;
}
else {
crc <<= 1;
crc += (((c<<=1) & 0400) != 0);
}
}
return crc;
}
#ifdef DRC
abort(s)
char *s;
{
fprintf(stderr,"ABORT: %s\007\n",s);
exit(1);
}
#endif