<< 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 >>