home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / cpm86 / delbr11.c < prev    next >
C/C++ Source or Header  |  1984-06-26  |  7KB  |  288 lines

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