home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
cpm
/
arc-lbr
/
delbr12.ark
/
DELBR12.C
next >
Wrap
Text File
|
1989-11-24
|
7KB
|
285 lines
/*
* A program to extract all files from a "Novosielski" archive (foo.LBR)
*
* Jeff Martin, 10/9/82
*
* 11/24/89 - Increased library entries from 64 to 256. (BP)
*
* 07/28/84 - Fixed AZTEC conditional defines. (Tried it this
* time, instead of guessing). Removed DESMET stuff,
* as the Read() function dosen't always know how many
* bytes it has read! That didn't work too well. <pjh>
*
* 06/10/84 - Kludged up to work with a variety of unix-like compilers.
* BUFFERING added. <pjh>
*
* 04/07/84 - reworked to compile under DeSmet 'C' Compiler
* for use under CP/M-86 Peter A. Polansky
*
* 01/01/83 - Bug in large LBR files removed. --JEC
*
* 11/12/83 - CP/M 68k version created. Jim Cathey
*
* 01/03/83 - BDS version reworked to provide the generally-useful
* getldir() function --JCM
*
* 01/02/83 - BDS C version created --JCM
*
* 11/27/82 - Fixed bug that was causing one-sector files to
* be rejected as invalid directory entries --JCM
*/
/* "#define" your compiler here to pick from following #define blocks */
/* DRC, C86, and AZTEC have all been tested */
#define AZTEC
#ifdef DRC /* digital research */
#define VERSION "1.1 6-Jun-84 DRC"
#include <ctype.h>
#define OPN openb /* open a file, binary mode */
#define FOPN fopenb /* open a buffered file, binary mode */
#define CRET creatb /* create a file, binary mode */
#define FO_BREAD "r" /* read mode for fopen() */
#define O_RDONLY 0 /* binary read for open() */
#define C_BWRITE 0 /* binary write for creat() */
/* doesn't matter, DRC ignores mode on creat */
#define FGETC fgetc
#endif
#ifdef CIC86 /* computer innovations */
#define VERSION "1.1 6-Jun-84 CI C86"
#define OPN open
#define FOPN fopen
#define CRET creat
#define FO_BREAD "rb"
#define O_RDONLY 4
#define C_BWRITE 5
#define FGETC fgetc
#endif
#ifdef AZTEC /* aztec c ii v 1.05 */
#define VERSION "1.1 28-Jul-84 Aztec"
#include <fcntl.h>
#define OPN open
#define FOPN fopen
#define CRET creat
#define FO_BREAD "r"
#define C_BWRITE 0666
#define FGETC getc
#endif
#define NAMESIZE 13 /* Max chars in filename.typ, plus null */
#define MAXDIRENT 256 /* Increased from 64 (BP) */
#define TOOBIG 1024 /* Assume dir is bad if > this many sectors */
#define SECSIZ 128
#define BUFFSIZ 16384 /* be sure this is a multiple of 128 */
#define ERR (-1)
#include <stdio.h>
main(argc, argv)
int argc;
char *argv[];
{
int c, i;
char *s, *buf;
char filename[20];
int fdi, fdo; /* file descriptors */
int ndir, dirent;
char names[MAXDIRENT][NAMESIZE];
long offsets[MAXDIRENT];
unsigned sizes[MAXDIRENT];
int temp, toRead, didRead;
long lseek(), bytes;
while (--argc > 0 && (*++argv)[0] == '-') {
for (s = argv[0]+1; *s != '\0'; s++) {
switch (*s) {
default:
printf("Illegal Option: '%c'\n", *s);
argc = 0;
break;
}
}
}
if (argc != 1) {
printf("delbr v%s\n",VERSION);
printf("Usage: delbr filename(.LBR assumed)\n");
printf("Strip all files from a \"Novosielski\" archive.\n");
exit(1);
}
if ((buf= malloc(BUFFSIZ)) == NULL) /* get memory for buffer */
{
printf("Not enough memory. MALLOC returned NULL\n");
exit(0);
}
strcpy(filename,argv[0]);
strcat(filename,".lbr");
upcase(filename);
if ((ndir= getldir(filename,MAXDIRENT,names,offsets,sizes)) == ERR) {
printf("Trouble getting directory from %s\n", filename);
exit (2);
}
fdi = OPN(filename, O_RDONLY);
if (fdi == ERR) {
printf("Cannot open %s.\n", filename);
exit(2);
}
for (dirent = 0; dirent < ndir; dirent++) {
if ((fdo = CRET(names[dirent], C_BWRITE)) == ERR) {
printf("Cannot create %s.\n", names[dirent]);
exit(2);
}
printf("Extracting: %-12s\n", names[dirent]);
if (lseek(fdi, offsets[dirent], 0) == ERR) {
printf("\nError seeking this entry - aborting.\n");
exit(2);
}
bytes= (long) sizes[dirent] * 128L;
while (bytes != 0L) {
if (bytes > (long) BUFFSIZ) {
toRead= BUFFSIZ;
bytes-= BUFFSIZ;
}
else {
toRead= bytes;
bytes= 0L;
}
if ((didRead= read(fdi, buf, toRead)) != toRead) {
printf("\nError reading this entry - aborting. Read %u bytes\n",didRead);
exit (2);
}
if (write(fdo, buf, toRead) != toRead) {
printf("\nError writing this entry - aborting.\n");
exit (2);
}
}
close(fdo);
}
printf("\n");
close(fdi);
}
/*
* Get .LBR directory -- names, offsets, and sizes of entries in an LBR file.
*
* The returned function value is the number of actual entries found,
* or ERR (if couldn't open file).
*
* Input parameters:
*
* fname - pointer to the string containing the full pathname of the LBR
* file.
* maxent - maximum number of entries to get (i. e., usually the size of
* the following arrays).
* files - pointer to an array of filenames to be populated by this function.
* This array must have a column dimension of NAMESIZE.
* offsets - pointer to an array of file offsets, in units of bytes, to
* be populated by this function.
* sizes - pointer to an array of file sizes, in units of CPM sectors, to be
* populated by this function.
*/
getldir(fname, maxent, files, offsets, sizes)
char *fname;
int maxent;
char files[][NAMESIZE];
long offsets[];
unsigned sizes[];
{
int c, i, j;
char *s;
char entryname[20];
FILE *dir, *FOPN();
int ndir, dirent, nentry;
long ostart;
unsigned osize;
if ((dir = FOPN(fname, FO_BREAD)) == 0)
return (ERR);
fskip(dir, 14); /* Point to dir size */
ndir = FGETC(dir);
ndir = (ndir + (FGETC(dir)<<8))*4;
fskip(dir, 16); /* Skip unused dir bytes */
nentry = 0; /* Init count of live entries */
for (dirent = 1; (dirent < ndir) && (nentry < maxent); dirent++) {
if (FGETC(dir) != 0) { /* Ignore defunct entries in dir */
fskip(dir, 31);
continue;
}
/* Build the next entryname */
j = 0;
for (i=1; i<=8; i++) {
c = FGETC(dir) & 0x7f;
c = tolower(c);
if(c != ' ')
entryname[j++] = c;
}
entryname[j++] = '.';
for (i=1; i<=3; i++) {
c = FGETC(dir) & 0x7f;
c = tolower(c);
if(c != ' ')
entryname[j++] = c;
}
entryname[j] = '\0';
upcase(entryname);
/* Check for any no-no chars. */
for (s = entryname; *s != '\0'; s++)
if (*s == ';' || *s == '*' || *s < ' ')
*s = '.';
strcpy(files[nentry], entryname); /* Return the hacked name */
/* Determine where this file is in the archive */
ostart = FGETC(dir);
ostart |= FGETC(dir) << 8;
ostart *= SECSIZ;
offsets[nentry] = ostart; /* Return the file's offset */
osize = FGETC(dir);
osize |= FGETC(dir) << 8;
sizes[nentry] = osize; /* ... and its size */
fskip(dir, 16); /* Skip unused dir bytes */
nentry++;
}
fclose(dir);
return (nentry);
}
/*
* Skip specified number of bytes in the specified file
*/
fskip(file, bytes)
FILE *file;
int bytes;
{
while (bytes-- > 0)
FGETC(file);
}
/*
* Uppercase a string
*/
upcase(str)
char *str;
{
for ( ; *str; ++str)
*str = toupper(*str);
}