home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / arc-lbr / delbr12.ark / DELBR12.C next >
Text File  |  1989-11-24  |  7KB  |  285 lines

  1. /*
  2.  * A program to extract all files from a "Novosielski" archive (foo.LBR)
  3.  *
  4.  *    Jeff Martin, 10/9/82
  5.  *
  6.  *  11/24/89 - Increased library entries from 64 to 256.  (BP)
  7.  *
  8.  *    07/28/84 - Fixed AZTEC conditional defines.  (Tried it this
  9.  *           time, instead of guessing). Removed DESMET stuff,
  10.  *           as the Read() function dosen't always know how many
  11.  *           bytes it has read!  That didn't work too well. <pjh>
  12.  *
  13.  *    06/10/84 - Kludged up to work with a variety of unix-like compilers.
  14.  *           BUFFERING added. <pjh>
  15.  *
  16.  *    04/07/84 - reworked to compile under DeSmet 'C' Compiler
  17.  *           for use under CP/M-86   Peter A. Polansky
  18.  *
  19.  *    01/01/83 - Bug in large LBR files removed. --JEC
  20.  *
  21.  *    11/12/83 - CP/M 68k version created.  Jim Cathey
  22.  *
  23.  *    01/03/83 - BDS version reworked to provide the generally-useful
  24.  *           getldir() function --JCM
  25.  *
  26.  *    01/02/83 - BDS C version created --JCM
  27.  *
  28.  *    11/27/82 - Fixed bug that was causing one-sector files to
  29.  *           be rejected as invalid directory entries  --JCM
  30.  */
  31.  
  32.  
  33. /* "#define" your compiler here to pick from following #define blocks */
  34. /* DRC, C86, and AZTEC have all been tested */
  35.  
  36. #define AZTEC
  37.  
  38. #ifdef    DRC        /* digital research */
  39. #define    VERSION        "1.1 6-Jun-84 DRC"
  40. #include        <ctype.h>
  41. #define    OPN        openb    /* open a file, binary mode        */
  42. #define FOPN        fopenb    /* open a buffered file, binary mode    */
  43. #define CRET        creatb    /* create a file, binary mode        */
  44. #define FO_BREAD    "r"    /* read mode for fopen()        */
  45. #define O_RDONLY    0    /* binary read for open()        */
  46. #define C_BWRITE    0    /* binary write for creat()        */
  47.                 /* doesn't matter, DRC ignores mode on creat */
  48. #define FGETC        fgetc
  49. #endif
  50.  
  51. #ifdef CIC86        /* computer innovations */
  52. #define    VERSION        "1.1 6-Jun-84 CI C86"
  53. #define    OPN        open
  54. #define FOPN        fopen
  55. #define CRET        creat
  56. #define FO_BREAD    "rb"
  57. #define O_RDONLY    4
  58. #define C_BWRITE    5
  59. #define FGETC        fgetc
  60. #endif
  61.  
  62. #ifdef AZTEC        /* aztec c ii v 1.05 */
  63. #define    VERSION        "1.1 28-Jul-84 Aztec"
  64. #include <fcntl.h>
  65. #define    OPN        open
  66. #define FOPN        fopen
  67. #define CRET        creat
  68. #define FO_BREAD    "r"
  69. #define C_BWRITE    0666
  70. #define FGETC        getc
  71. #endif
  72.  
  73. #define NAMESIZE     13    /* Max chars in filename.typ, plus null */
  74. #define MAXDIRENT    256        /* Increased from 64 (BP) */
  75. #define TOOBIG        1024    /* Assume dir is bad if > this many sectors */
  76. #define SECSIZ        128
  77. #define BUFFSIZ        16384    /* be sure this is a multiple of 128 */
  78. #define ERR        (-1)
  79.  
  80. #include <stdio.h>
  81.  
  82. main(argc, argv)
  83. int    argc;
  84. char    *argv[];
  85. {
  86.     int    c, i;
  87.     char    *s, *buf;
  88.     char    filename[20];
  89.     int    fdi, fdo;        /* file descriptors */
  90.     int    ndir, dirent;
  91.     char    names[MAXDIRENT][NAMESIZE];
  92.     long    offsets[MAXDIRENT];
  93.     unsigned sizes[MAXDIRENT];
  94.     int    temp, toRead, didRead;
  95.     long    lseek(), bytes;
  96.  
  97.     while (--argc > 0 && (*++argv)[0] == '-') {
  98.         for (s = argv[0]+1; *s != '\0'; s++) {
  99.             switch (*s) {
  100.                 default:
  101.                     printf("Illegal Option: '%c'\n", *s);
  102.                     argc = 0;
  103.                     break;
  104.             }
  105.         }
  106.     }
  107.     if (argc != 1) {
  108.         printf("delbr v%s\n",VERSION);
  109.         printf("Usage: delbr filename(.LBR assumed)\n");
  110.         printf("Strip all files from a \"Novosielski\" archive.\n");
  111.         exit(1);
  112.     }
  113.     
  114.     if ((buf= malloc(BUFFSIZ)) == NULL)    /* get memory for buffer */
  115.     {
  116.         printf("Not enough memory.  MALLOC returned NULL\n");
  117.         exit(0);
  118.     }
  119.     strcpy(filename,argv[0]);
  120.     strcat(filename,".lbr");
  121.     upcase(filename);
  122.  
  123.     if ((ndir= getldir(filename,MAXDIRENT,names,offsets,sizes)) == ERR) {
  124.         printf("Trouble getting directory from %s\n", filename);
  125.         exit (2);
  126.     }
  127.     
  128.     fdi = OPN(filename, O_RDONLY);
  129.     if (fdi == ERR) {
  130.         printf("Cannot open %s.\n", filename);
  131.         exit(2);
  132.     }
  133.     
  134.     for (dirent = 0; dirent < ndir; dirent++) {
  135.         
  136.         if ((fdo = CRET(names[dirent], C_BWRITE)) == ERR) {
  137.             printf("Cannot create %s.\n", names[dirent]);
  138.             exit(2);
  139.         }
  140.         printf("Extracting: %-12s\n", names[dirent]);
  141.         if (lseek(fdi, offsets[dirent], 0) == ERR) {
  142.             printf("\nError seeking this entry - aborting.\n");
  143.             exit(2);
  144.         }
  145.  
  146.         bytes= (long) sizes[dirent] * 128L;
  147.         while (bytes != 0L) {
  148.             if (bytes > (long) BUFFSIZ) {
  149.                 toRead= BUFFSIZ;
  150.                 bytes-= BUFFSIZ;
  151.             }
  152.             else {
  153.                 toRead= bytes;
  154.                 bytes= 0L;
  155.             }
  156.             if ((didRead= read(fdi, buf, toRead)) != toRead) {
  157.               printf("\nError reading this entry - aborting.  Read %u bytes\n",didRead);
  158.               exit (2);
  159.             }
  160.             if (write(fdo, buf, toRead) != toRead) {
  161.               printf("\nError writing this entry - aborting.\n");
  162.               exit (2);
  163.             }
  164.         }
  165.         close(fdo);
  166.     }
  167.     printf("\n");
  168.     close(fdi);
  169. }
  170.  
  171.  
  172. /*
  173.  * Get .LBR directory  -- names, offsets, and sizes of entries in an LBR file.
  174.  *
  175.  *   The returned function value is the number of actual entries found,
  176.  *    or ERR (if couldn't open file).
  177.  *
  178.  *  Input parameters:
  179.  *
  180.  *   fname - pointer to the string containing the full pathname of the LBR
  181.  *    file.
  182.  *   maxent - maximum number of entries to get (i. e., usually the size of
  183.  *    the following arrays).
  184.  *   files - pointer to an array of filenames to be populated by this function.
  185.  *    This array must have a column dimension of NAMESIZE.
  186.  *   offsets - pointer to an array of file offsets, in units of bytes, to
  187.  *    be populated by this function.
  188.  *   sizes - pointer to an array of file sizes, in units of CPM sectors, to be
  189.  *    populated by this function.
  190.  */
  191. getldir(fname, maxent, files, offsets, sizes)
  192. char *fname;
  193. int maxent;
  194. char files[][NAMESIZE];
  195. long offsets[];
  196. unsigned sizes[];
  197. {
  198.     int    c, i, j;
  199.     char    *s;
  200.     char    entryname[20];
  201.     FILE    *dir, *FOPN();
  202.     int    ndir, dirent, nentry;
  203.     long    ostart;
  204.     unsigned osize;
  205.  
  206.     if ((dir = FOPN(fname, FO_BREAD)) == 0)
  207.         return (ERR);
  208.  
  209.     fskip(dir, 14); /* Point to dir size */
  210.     ndir = FGETC(dir);
  211.     ndir = (ndir + (FGETC(dir)<<8))*4;
  212.   
  213.     fskip(dir, 16); /* Skip unused dir bytes */
  214.  
  215.     nentry = 0; /* Init count of live entries */
  216.     for (dirent = 1; (dirent < ndir) && (nentry < maxent); dirent++) {
  217.         
  218.         if (FGETC(dir) != 0) {  /* Ignore defunct entries in dir */
  219.             fskip(dir, 31);
  220.             continue;
  221.         }
  222.         /* Build the next entryname */
  223.         j = 0;
  224.         for (i=1; i<=8; i++) {
  225.             c = FGETC(dir) & 0x7f;
  226.             c = tolower(c);
  227.             if(c != ' ')
  228.                 entryname[j++] = c;
  229.         }
  230.         entryname[j++] = '.';
  231.         for (i=1; i<=3; i++) {
  232.             c = FGETC(dir) & 0x7f;
  233.             c = tolower(c);
  234.             if(c != ' ')
  235.                 entryname[j++] = c;
  236.         }
  237.         entryname[j] = '\0';
  238.  
  239.         upcase(entryname);
  240.  
  241.         /* Check for any no-no chars. */
  242.         for (s = entryname; *s != '\0'; s++)
  243.             if (*s == ';' || *s == '*' || *s < ' ')
  244.                 *s = '.';
  245.  
  246.         strcpy(files[nentry], entryname); /* Return the hacked name */
  247.  
  248.         /* Determine where this file is in the archive */
  249.         ostart = FGETC(dir);
  250.         ostart |= FGETC(dir) << 8;
  251.         ostart *= SECSIZ;
  252.         offsets[nentry] = ostart; /* Return the file's offset */
  253.         
  254.         osize = FGETC(dir);
  255.         osize |= FGETC(dir) << 8;
  256.         sizes[nentry] = osize; /* ... and its size */
  257.  
  258.         fskip(dir, 16); /* Skip unused dir bytes */
  259.         nentry++;
  260.     }
  261.     fclose(dir);
  262.     return (nentry);
  263. }
  264.  
  265. /*
  266.  * Skip specified number of bytes in the specified file
  267.  */
  268. fskip(file, bytes)
  269. FILE *file;
  270. int bytes;
  271. {
  272.     while (bytes-- > 0)
  273.         FGETC(file);
  274. }
  275.  
  276. /*
  277.  * Uppercase a string
  278.  */
  279. upcase(str)
  280. char *str;
  281. {
  282.     for ( ; *str; ++str)
  283.         *str = toupper(*str);
  284. }
  285.