home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1994 September / Simtel-MSDOS-Sep1994-CD2.iso / starter / delbr11a.c < prev    next >
C/C++ Source or Header  |  1986-09-09  |  7KB  |  290 lines

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