home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / apple2 / 46 < prev    next >
Encoding:
Internet Message Format  |  1991-02-17  |  29.9 KB

  1. From: jac@paul.rutgers.edu (Jonathan A. Chandross)
  2. Newsgroups: comp.sources.apple2
  3. Subject: v001SRC028:  Unix Archiving Tools (Part 2/2)
  4. Message-ID: <Feb.16.22.44.19.1991.3114@paul.rutgers.edu>
  5. Date: 17 Feb 91 03:44:19 GMT
  6. Approved: jac@paul.rutgers.edu
  7.  
  8.  
  9. Submitted-by: marcel@duteca.tudelft.nl
  10. Posting-number: Volume 1, Source:28
  11. Archive-name: archive/unix/marcel/part2
  12. Architecture: UNIX
  13. Version-number: 1.00
  14.  
  15. This is part 2 of a 2 part posting.
  16.  
  17. =sciibin.c
  18. -/* @(#) sciibin.c       3.01 12Feb91  */
  19. -/*************************************************************************
  20. - **                                                                     **
  21. - **  Name    :  sciibin                                                 **
  22. - **  Author  :  Marcel J.E. Mol                                         **
  23. - **  Date    :  06Mar89               (first release)                   **
  24. - **  Version :  2.00                                                    **
  25. - **  Files   :  sciibin.c       Main source file                        **
  26. - **  Purpose :  Extract or view BinSCII files                           **
  27. - **                                                                     **
  28. - **  ------------------------- Revision List -------------------------  **
  29. - **  Ver   Date       Name                   Remarks                    **
  30. - **  1.00  06Mar89   Marcel Mol      First release                      **
  31. - **  1.10  27Mar89   Marcel Mol      Fished things up, error routine,   **
  32. - **                                  linecount, all info fields filled  **
  33. - **                                  in, changed info layout.           **
  34. - **  2.00  03Jun89   Marcel Mol      Bug fixes: alphabet to unsigned    **
  35. - **              (Dave Whitney)      char. Some OS's need types.h.      **
  36. - **                                  Fixed CRE/MOD order.               **
  37. - **                                  Output filenames can be wrong      **
  38. - **                                  when multiple files are            **
  39. - **                                  extracted. Made crc and file-      **
  40. - **                                  type arrays in seperate includes   **
  41. - **  3.00  22Mar90   Marcel Mol      Includeed ports of Bruce Kahn      **
  42. - **     1.30  27 Feb 90 Bruce Kahn  Ported to AOS/VS C 4.01 and MSC 5.1 **
  43. - **                                 Added explicit long definitions     **
  44. - **                                 needed.                             **
  45. - **                                 Redid layouts for dates to be US.   **
  46. - **                                 Modified the open routines for MSC  **
  47. - **                                 to include binary mode, not text.   **
  48. - **                                 Changed the way 8 bit integers are  **
  49. - **                                 handled (redone MM).                **
  50. - **                                 Added getopt()  (see below MM).     **
  51. - **  3.01  22Feb91   Marcel Mol      Fixed bug: only close output       **
  52. - **                                  when output is generated.          **
  53. - **  =================================================================  **
  54. - **                                                                     **
  55. - **  Compile as follows:                                                **
  56. - **       If you don't have getopt, compile and link the given getopt.c **
  57. - **                                                                     **
  58. - **      UNIX:           cc sciibin.c -Oso sciibin                      **
  59. - **                                                                     **
  60. - **      MSC 5.1:        cl /c /Ox sciibin.c                            **
  61. - **                              (add /DMSDOS, if MSC didn't do it)     **
  62. - **                      link /CO /STACK:10000 sciibin;                 **
  63. - **                                                                     **
  64. - **      AOS/VS:         cc sciibin.c                                   **
  65. - **                      ccl sciibin                                    **
  66. - **                                                                     **
  67. - **    Defining DEBUG gives some debug information.                     **
  68. - **    Defining DEBUGALL gives input and output of the decode routine.  **
  69. - **                                                                     **
  70. - **  Usage: sciibin [-hvtc] [-o<outputfile>] <infiles>                  **
  71. - **                                                                     **
  72. - **           -v show only info on file, do not create output.          **
  73. - **           -t test file, do not create output.                       **
  74. - **           -c do not check checksums.                                **
  75. - **           -o create given filename instead of the one in            **
  76. - **              binscii file. Use this only if the input files         **
  77. - **              contain only one output file.                          **
  78. - **           -h help.                                                  **
  79. - **                                                                     **
  80. - **                                                                     **
  81. - **   This software is freeware. We can not be held responsible to      **
  82. - **   any damage this program may coase you or anyone or anything else. **
  83. - **                                                                     **
  84. - **   Mail bugs to:      marcel@duteca.tudelft.nl                       **
  85. - **                                                                     **
  86. - ************************************************************************/
  87. -
  88. -
  89. -#include <stdio.h>
  90. -#include <sys/types.h>          /* keep sun OS happy                */
  91. -#include <sys/stat.h>           /* mostly includes types.h ...      */
  92. -#if defined(MSDOS)
  93. -#include <memory.h>             /* For the memset function          */
  94. -#endif
  95. -#include "crc.h"
  96. -#include "filetype.h"
  97. -
  98. -#define BUFLEN         256
  99. -#define FILENAME_LEN    15
  100. -#define BINSCII_HEADER  "FiLeStArTfIlEsTaRt\n"
  101. -#define MAXSEGLEN      0x3000
  102. -
  103. -#if defined(INT8)
  104. -typedef long int16;
  105. -#else
  106. -typedef int  int16;
  107. -#endif
  108. -
  109. -/*                           ==> Expect int variables to be at least 16 bits
  110. - * Global variables          ==>    and longs to be at least 32 bits
  111. - *                           ==> If not, you have some work to do...
  112. - */                              /* MSDOS has 16 bit ints. */
  113. -char          buf[BUFLEN+1];
  114. -unsigned char dec[BUFLEN+1];
  115. -unsigned char alphabet[BUFLEN+1];   /* need $FF in alphabet              */
  116. -char          outfilename[BUFLEN+1];
  117. -
  118. -
  119. -unsigned char outflag = 0,      /* the -o option                    */
  120. -              crcflag = 0,      /* the -c option                    */
  121. -              infoflag = 0,     /* the -v option                    */
  122. -              testflag = 0,     /* the -t option                    */
  123. -              makeoutput,       /* ! (-t | -v)                      */
  124. -              crcok;            /* -t | -c                          */
  125. -FILE *outfp;                    /* output file                      */
  126. -
  127. -unsigned char  filetype, stortype,
  128. -               file_access;               /* access -> file_access for MSDOS */
  129. -unsigned char  modyear, modmonth, modday, modhour, modmin,
  130. -               creyear, cremonth, creday, crehour, cremin;
  131. -int            namlen, linecount,
  132. -               numblocks, auxtype;
  133. -long           filesize, startbyte, segmentlen;
  134. -char * infilename;
  135. -
  136. -char * progname;
  137. -
  138. -
  139. -/*
  140. - * function declarations
  141. - */
  142. -int   main         ();
  143. -int   sciibin      ();
  144. -int   getheader    ();
  145. -int   decode       ();
  146. -int   decodestring ();
  147. -char *myfgets      ();
  148. -void  usage        ();
  149. -void  error        ();
  150. -
  151. -
  152. -char * copyright = "@(#) sciibin.c  3.01 12Feb91 (c) 1989, 1991 M.J.E. Mol";
  153. -
  154. -main(argc, argv)
  155. -int argc;
  156. -char **argv;
  157. -{
  158. -    FILE *fp;
  159. -    int c;
  160. -    extern int optind;            /* For getopt */
  161. -    extern char * optarg;        /* For getopt */
  162. -    int  flag;                /* Flag for getopt */
  163. -
  164. -    progname = *argv;
  165. -
  166. -    while ((flag = getopt(argc, argv, "hvcto:")) != EOF) { /* Process options */
  167. -        switch (flag) {
  168. -            case 'v': infoflag = 1;    /* Want only info of file */
  169. -                      break;
  170. -            case 'h': usage();        /* Give help */
  171. -                      exit(0);
  172. -            case 'c': crcflag = 1;
  173. -                      break;
  174. -            case 't': testflag = 1;
  175. -                      break;
  176. -            case 'o':
  177. -#if defined(MSDOS)
  178. -                      memset(outfilename, NULL, FILENAME_LEN + 1);
  179. -#endif
  180. -                      strcpy(outfilename, optarg);
  181. -                      outflag = 1;
  182. -                      break;
  183. -            default : fprintf(stderr, "%s: skipping unkown flag %c, use -h.\n",
  184. -                                    progname, flag);
  185. -                      break;
  186. -        }
  187. -    }
  188. -
  189. -    makeoutput = !(testflag | infoflag);
  190. -    crcok = testflag | crcflag;
  191. -
  192. -#if defined(DEBUG)
  193. -    fprintf(stderr, "make output: %d, crcok: %d\n", makeoutput, crcok);
  194. -#endif
  195. -
  196. -    if (optind >= argc) {        /* No files given, use stdin */
  197. -        infilename = "stdin";
  198. -        linecount = 0;
  199. -        sciibin(stdin);
  200. -    }
  201. -    else
  202. -        while (optind < argc) {
  203. -            infilename = argv[optind];
  204. -            optind++;
  205. -            if ((fp = fopen(infilename, "r")) == NULL) {
  206. -                perror(infilename);
  207. -                continue;
  208. -            }
  209. -            linecount = 0;
  210. -            sciibin(fp);
  211. -            fclose(fp);
  212. -        }
  213. -
  214. -    exit(0);
  215. -
  216. -} /* main */
  217. -
  218. -
  219. -
  220. -/*
  221. - * Walk over the file processing all segments in it
  222. - */
  223. -sciibin(fp)
  224. -FILE *fp;
  225. -{
  226. -    int processed = 0;          /* number of processed binscii segments     */
  227. -    int status = 0;             /* return codes of calls to decode          */
  228. -
  229. -    while (myfgets(buf, BUFLEN, fp) != NULL) {
  230. -
  231. -#if defined(DEBUG)
  232. -        fprintf(stderr, "(%s) get start:%s", infilename, buf);
  233. -#endif
  234. -
  235. -        if (!strncmp(buf, BINSCII_HEADER, strlen(BINSCII_HEADER))) {
  236. -            if (!getheader(fp) && !infoflag) /* if header ok and not -v flag */
  237. -                status |= decode(fp);
  238. -            processed++;
  239. -        }
  240. -    }
  241. -
  242. -    if (processed == 0) {
  243. -        error("not a BinSCII file");
  244. -        return 1;
  245. -    }
  246. -
  247. -    return status;
  248. -
  249. -} /* sciibin */
  250. -
  251. -
  252. -
  253. -/*
  254. - * Build the alphabet, get the output file info and open output file
  255. - * if necessary.
  256. - * Still contains lots of debug code to find out the header structure.
  257. - *   (every bit is known now...)
  258. - */
  259. -getheader(fp)
  260. -FILE *fp;
  261. -{
  262. -    register int i, j;
  263. -    register int16 crc = 0;
  264. -    struct stat statbuf;            /* MUST know if file exists         */
  265. -    char *iomod;                    /* write or readwrite a file        */
  266. -
  267. -    /*
  268. -     * Get the alphabet
  269. -     */
  270. -    if (myfgets(buf, BUFLEN, fp) == NULL) {
  271. -        error("reading alphabet: unexpected end of file");
  272. -        return 1;
  273. -    }
  274. -
  275. -#if defined(DEBUG)
  276. -    fprintf(stderr, "(%s) alphabet:%s", infilename, buf);
  277. -#endif
  278. -
  279. -    if (strlen(buf) != 65) {
  280. -        error("alphabet corrupted");
  281. -        return 1;
  282. -    }
  283. -
  284. -    /*
  285. -     * Process the alphabet
  286. -     */
  287. -    for (i = 0; i < BUFLEN; i++)
  288. -        alphabet[i] = 0xff;
  289. -
  290. -    for (i = 0; i < 64; i++) {
  291. -        j = buf[i];
  292. -        if (alphabet[j] != 0xff)
  293. -            error("Warning: double character in alphabet");
  294. -        alphabet[j] = i;
  295. -    }
  296. -
  297. -#if defined(DEBUG)
  298. -    for (i = 0; i < BUFLEN; i+=16) {
  299. -        fprintf(stderr, "(%s) alphabet[%3d] =", infilename, i);
  300. -        for (j = 0; j < 16; j++)
  301. -            fprintf(stderr, " %02X", alphabet[i+j]);
  302. -        putc('\n', stderr);
  303. -    }
  304. -#endif
  305. -
  306. -    /*
  307. -     * Get the file header
  308. -     */
  309. -    if (myfgets(buf, BUFLEN, fp) == NULL) {
  310. -        error("reading fileheader: unexpected end of file");
  311. -        return 1;
  312. -    }
  313. -
  314. -#if defined(DEBUG)
  315. -    fprintf(stderr, "(%s) fileheader:%s", infilename, buf);
  316. -#endif
  317. -
  318. -    /*
  319. -     * Extract output filename if needed
  320. -     */
  321. -    if (!outflag) {
  322. -        namlen = *buf - 'A' + 1;              /* IS +1 NEEDED ?? */
  323. -#if defined(MSDOS)
  324. -        memset(outfilename, NULL, FILENAME_LEN + 1);
  325. -#endif
  326. -        strncpy(outfilename, buf+1, namlen);
  327. -        outfilename[namlen] = '\0';
  328. -    }
  329. -
  330. -#if defined(DEBUG)
  331. -    fprintf(stderr, "(%s) filename:**%s**\n", infilename, outfilename);
  332. -    fprintf(stderr, "(%s) fileinfo:**%s**", infilename, buf+16);
  333. -#endif
  334. -
  335. -    /*
  336. -     * Decode and process the file header information
  337. -     */
  338. -    if ((i = decodestring(buf+FILENAME_LEN+1, dec)) != 27)
  339. -        error("warning: corrupted file header length");
  340. -
  341. -    for (i = 0; i < 24; i++) 
  342. -        crc = updcrc(dec[i], crc);
  343. -
  344. -    if (crc != (dec[24] | (dec[25] << 8))) {
  345. -        if (crcok) 
  346. -            error("warning: CRC error in file header");
  347. -        else {
  348. -            error("error: CRC error in file header");
  349. -            return 1;
  350. -        }
  351. -    }
  352. -
  353. -    /* Calculate file length */
  354. -    filesize   = dec[0] + (dec[1]<<8) + ((long) dec[2]<<16);
  355. -    startbyte  = dec[3] + (dec[4]<<8) + ((long) dec[5]<<16);
  356. -
  357. -    /* Calculate file attributes and size */
  358. -    file_access= dec[6];
  359. -    filetype   = dec[7];
  360. -    auxtype    = dec[8] + (dec[9] << 8);
  361. -    stortype   = dec[10];
  362. -    numblocks  = dec[11] + (dec[12]<<8);
  363. -
  364. -    /* Calculate creation and modification dates */
  365. -#define MOD 13
  366. -#define CRE 17          /* perhaps creation and modification date are swapped */
  367. -    creday     = dec[CRE] & 0x1f;
  368. -    cremonth   = ((dec[CRE+1] & 0x01) << 3) | (dec[CRE] >> 5);
  369. -    creyear    = dec[CRE+1] >>1;
  370. -    cremin     = dec[CRE+2] & 0x3f;
  371. -    crehour    = dec[CRE+3] & 0x1f;
  372. -    modday     = dec[MOD] & 0x1f;
  373. -    modmonth   = ((dec[MOD+1] & 0x01) << 3) | (dec[MOD] >> 5);
  374. -    modyear    = dec[MOD+1] >>1;
  375. -    modmin     = dec[MOD+2] & 0x3f;
  376. -    modhour    = dec[MOD+3] & 0x1f;
  377. -
  378. -    segmentlen = dec[21] + (dec[22]<<8) + ((long) dec[23]<<16);
  379. -    if (segmentlen > MAXSEGLEN)
  380. -            error("warning: segmentlen probably to long");
  381. -
  382. -#define READ    0x01
  383. -#define WRITE   0x02
  384. -#define BACKUP  0x20
  385. -#define RENAME  0x40
  386. -#define DESTROY 0x80
  387. -
  388. -    if (infoflag) {
  389. -
  390. -        /* Display the files name, type and auxtype */
  391. -        printf("%-15s  %3s aux: $%04X ",
  392. -                   outfilename, filetypes[filetype], auxtype);
  393. -
  394. -        /* Display the file access type */
  395. -        putchar(file_access & READ    ? 'r' : '-');
  396. -        putchar(file_access & WRITE   ? 'w' : '-');
  397. -        putchar(file_access & RENAME  ? 'n' : '-');
  398. -        putchar(file_access & DESTROY ? 'd' : '-');
  399. -        putchar(file_access & BACKUP  ? 'b' : '-');
  400. -
  401. -        /* Display the type of file this is - ProDOS Specific */
  402. -        switch (stortype) {
  403. -            case 0x0F : printf(" voldir"); break;
  404. -            case 0x0D : printf(" dir"); break;
  405. -            case 0x01 : printf(" seed"); break;
  406. -            case 0x02 : printf(" sap"); break;
  407. -            case 0x03 : printf(" tree"); break;
  408. -            default   : printf(" ???"); break;
  409. -        }
  410. -
  411. -        /* Display modification and creation information */
  412. -        printf(" %02d/%02d/%02d(%02d:%02d) -", modmonth, modday, modyear,
  413. -                                               modhour, modmin);
  414. -        printf(" %02d/%02d/%02d(%02d:%02d)\n", cremonth, creday, creyear,
  415. -                                               crehour, cremin);
  416. -
  417. -        /* Display segment information */
  418. -        printf("Part %4d of %4d,", (int) (startbyte / MAXSEGLEN) + 1,
  419. -                                  (int) ((filesize + MAXSEGLEN-1) / MAXSEGLEN));
  420. -        printf(" bytes %7ld to %7ld of %7ld bytes, %5d blocks\n",
  421. -                 startbyte, startbyte+segmentlen, filesize, numblocks);
  422. -
  423. -    } /* if (infoflag) */
  424. -
  425. -    if (makeoutput) {
  426. -        /* will creating output, not just information so verify the access */
  427. -#if defined(MSDOS)
  428. -        iomod = (stat(outfilename, &statbuf) == 0) ? "r+b" : "wb";
  429. -#else
  430. -        iomod = (stat(outfilename, &statbuf) == 0) ? "r+" : "w";
  431. -#endif
  432. -        if ((outfp = fopen(outfilename, iomod)) == NULL) {
  433. -            error("unable to open output file");
  434. -            perror(outfilename);
  435. -            return 1;
  436. -        }
  437. -        fseek(outfp, startbyte, 0);
  438. -    } /* if (makeoutput) */
  439. -
  440. -    return 0;
  441. -
  442. -} /* getheader */
  443. -
  444. -
  445. -
  446. -/*
  447. - * Do the actual decoding of the bin data.
  448. - */
  449. -decode(fp)
  450. -FILE *fp;
  451. -{
  452. -    register int i;
  453. -    register int crc = 0;
  454. -             int len;
  455. -
  456. -    crc = 0;
  457. -    while (segmentlen > 0) {     
  458. -        if (myfgets(buf, BUFLEN, fp) == NULL) {
  459. -            error("reading file: unexpected end of file");
  460. -            return 1;
  461. -        }
  462. -
  463. -#if defined(DEBUG)
  464. -        fprintf(stderr, "(%s) data:%s", infilename, buf);
  465. -#endif
  466. -
  467. -        if ((len = decodestring(buf, dec)) != 48)
  468. -            error("warning: corrupted line length");
  469. -        for (i = 0; i < 48; i++)
  470. -            crc = updcrc(dec[i], crc);
  471. -        if (makeoutput)
  472. -            for (i = 0; (i < len) && (segmentlen > 0); i++, segmentlen--)
  473. -                putc(dec[i], outfp);        /* COULD CR/NL TXT FILES */
  474. -        else
  475. -            segmentlen -= len;
  476. -
  477. -#if defined(DEBUG)
  478. -        fprintf(stderr, "(%s) still need %d bytes\n", infilename, segmentlen);
  479. -#endif
  480. -
  481. -    }
  482. -
  483. -    /*
  484. -     * must be at end of segment now, with one remaining line containing
  485. -     * the crc check.
  486. -     */
  487. -    if (myfgets(buf, BUFLEN, fp) == NULL) {
  488. -        error("reading file crc: unexpected end of file");
  489. -        return 1;
  490. -    }
  491. -
  492. -#if defined(DEBUG)
  493. -    fprintf(stderr, "(%s) crc:%s", infilename, buf);
  494. -#endif
  495. -
  496. -    if ((len = decodestring(buf, dec)) != 3)
  497. -       error("warning: corrupted crc length");
  498. -    if (crc != (dec[0] | (dec[1] << 8))) {
  499. -        if (crcok)  
  500. -            error("warning: CRC error in file data");
  501. -        else {
  502. -            error("error: CRC error in file data");
  503. -            return 1;
  504. -        }
  505. -    }
  506. -
  507. -    if (makeoutput)
  508. -        fclose(outfp);
  509. -
  510. -    return 0;
  511. -
  512. -} /* decode */
  513. -
  514. -
  515. -/*
  516. - * Decode one string off scii characters to binary data, meanwhile
  517. - * calculating crc.
  518. - */
  519. -decodestring(in, out)
  520. -register          char *in;
  521. -register unsigned char *out;
  522. -{
  523. -    register int len = 0;
  524. -
  525. -#if defined(DEBUGALL)
  526. -    char *b;
  527. -
  528. -    fprintf(stderr, "(%s) decode in: %s\n", infilename, in);
  529. -    b = in;
  530. -    while (*b)
  531. -        fprintf(stderr, ".%02X", alphabet[*b++]);
  532. -    putc('\n', stderr);
  533. -    b = out;
  534. -#endif
  535. -
  536. -    while (strlen(in) > 3) {
  537. -        *out++ = ((alphabet[in[3]] << 2) | (alphabet[in[2]] >> 4)) & 0xFF;
  538. -        *out++ = ((alphabet[in[2]] << 4) | (alphabet[in[1]] >> 2)) & 0xFF;
  539. -        *out++ = ((alphabet[in[1]] << 6) | (alphabet[in[0]]))      & 0xFF;
  540. -        len += 3;
  541. -        in  += 4;
  542. -    }
  543. -
  544. -    *out = '\0';
  545. -    if (*in != '\0' && *in != '\n') 
  546. -        error("warning: line not ended by NULL or NEWLINE");
  547. -
  548. -#if defined(DEBUGALL)
  549. -    fprintf(stderr, "(%s) decode out:\n", infilename);
  550. -    while (b != out) 
  551. -        fprintf(stderr, ".%02X", *b++);
  552. -    putc('\n', stderr);
  553. -#endif
  554. -
  555. -    return len;
  556. -
  557. -} /* decodestring */
  558. -
  559. -
  560. -
  561. -char *myfgets(buf, len, fp)
  562. -char *buf;
  563. -int len;
  564. -FILE *fp;
  565. -{
  566. -
  567. -    linecount++;
  568. -
  569. -    return fgets(buf, len, fp);
  570. -
  571. -} /* myfgets */
  572. -
  573. -
  574. -
  575. -void usage()
  576. -{
  577. -
  578. -    fprintf(stderr, "%s\n\n", copyright);
  579. -    fprintf(stderr, "Usage: sciibin [-vtch] [-o<outputfile>] <infiles>\n\n");
  580. -    fprintf(stderr, "       -v show only info on file, do not create output.\n");
  581. -    fprintf(stderr, "       -t test file, do not create output.\n");
  582. -    fprintf(stderr, "       -c do not check checksums.\n");
  583. -    fprintf(stderr, "       -o create given filename instead of the one in\n");
  584. -    fprintf(stderr, "          binscii file. Use this only if the input files\n");
  585. -    fprintf(stderr, "          contain only one output file.\n");
  586. -    fprintf(stderr, "       -h this help message.\n");
  587. -
  588. -} /* usage */
  589. -
  590. -
  591. -
  592. -void error(str)
  593. -char *str;
  594. -{
  595. -
  596. -    fprintf(stderr, "%s (%s, %d): %s\n", 
  597. -                    progname, infilename, linecount, str);
  598. -
  599. -} /* error */
  600. -
  601. =unblu.c
  602. -/* @(#) unblu.c       2.2 18/06/89  */
  603. -/*************************************************************************
  604. - **                                                                     **
  605. - **  Name    :  unblu                                                   **
  606. - **  Author  :  Marcel J.E. Mol                                         **
  607. - **  Date    :  10/05/88              (first release)                   **
  608. - **  Version :  2.20                                                    **
  609. - **  Files   :  unblu.c         Main source file                        **
  610. - **                                                                     **
  611. - **  ------------------------- Revision List -------------------------  **
  612. - **  Ver   Date       Name                   Remarks                    **
  613. - **  1.00  10/05/88   Marcel Mol             Raw copy of a basic program**
  614. - **  2.00  03/06/88   Marcel Mol             Rewrite after blu info     **
  615. - **                                          was send to the net        **
  616. - **  2.10  18/06/88   Marcel Mol             Added filetype texts       **
  617. - **  2.20  23/09/88   Marcel Mol             Show mod and creation time **
  618. - **                                                                     **
  619. - **  =================================================================  **
  620. - **                                                                     **
  621. - **  Compile as follows: cc unblu.c -Oso unblu                          **
  622. - **                                                                     **
  623. - **  Usage: unblu [-vh] <arcfile> [<files-toextract>]                   **
  624. - **                                                                     **
  625. - ************************************************************************/
  626. -
  627. - /************************************************************************
  628. - **                                                                     **
  629. - **  NAME                                                               **
  630. - **     unblu -   Extract files from an apple binary ][ archive.        **
  631. - **                                                                     **
  632. - **                                                                     **
  633. - **  SYNOPSIS                                                           **
  634. - **     unblu [-vh] arcfile [files-to-extract]                          **
  635. - **                                                                     **
  636. - **                                                                     **
  637. - **  DESCRIPTION                                                        **
  638. - **     Unblu list the contents of a binary ][ archive (the -v option)  **
  639. - **     or extracts the listed files from the archive (without the      **
  640. - **     -v option). If no files are listed, the comlete archive is      **
  641. - **     extracted or listed.                                            **
  642. - **     The -h option gives a help message on the usage of unblu.       **
  643. - **                                                                     **
  644. - **  AUTHOR                                                             **
  645. - **     Marcel J.E. Mol                                                 **
  646. - **                                                                     **
  647. - **  BUGS                                                               **
  648. - **     Mail bugs to:      marcel@duteca.tudelft.nl                     **
  649. - **                                                                     **
  650. - ************************************************************************/
  651. -
  652. -char * copyright = "@(#) unblu.c  2.2 18/06/89  (c) M.J.E. Mol";
  653. -#include <stdio.h>
  654. -#include <fcntl.h>
  655. -#include "filetype.h"
  656. -
  657. -#define BUFSIZE 128                 /* Blu block length */
  658. -#define DEBUG
  659. -
  660. -/* Global variables */
  661. -char * progname;
  662. -char * blufile;
  663. -int    verbose   = 0;
  664. -
  665. -
  666. -/* Function declarations */
  667. -void main ();
  668. -void unblu ();
  669. -void process_file ();
  670. -void extract_file ();
  671. -void print_global_info ();
  672. -int  want ();
  673. -void usage ();
  674. -void printhelp ();
  675. -
  676. -
  677. -void main(argc, argv)
  678. -int     argc;
  679. -char ** argv;
  680. -{
  681. -    int  flag;                /* Flag for getopt */
  682. -    int  bfd;                /* File descriptor for blu file */
  683. -    extern int optind;            /* For getopt */
  684. -    extern char * optarg;        /* For getopt */
  685. -
  686. -    progname = argv[0];
  687. -    while ((flag = getopt(argc, argv, "vh")) != EOF) { /* Process options */
  688. -        switch (flag) {
  689. -            case 'v': verbose = 1;    /* Want only listing of archive */
  690. -                      break;
  691. -            case 'h': usage();        /* Give help */
  692. -              printhelp();
  693. -                      exit(0);
  694. -            default : fprintf(stderr, "%s: skipping unkown flag %c.\n",
  695. -                                    progname, flag);
  696. -                      break;
  697. -        }
  698. -    }
  699. -
  700. -    if (optind >= argc) {        /* No archive given */
  701. -        usage();
  702. -        exit(1);
  703. -    }
  704. -
  705. -    blufile = argv[optind++];        /* Get archive name */
  706. -    if ((bfd = open(blufile, O_RDONLY)) == -1) {
  707. -        perror(blufile);
  708. -        exit(2);
  709. -    }
  710. -
  711. -    unblu(bfd, &argv[optind]);        /* Process wanted files */
  712. -
  713. -    close(bfd);
  714. -
  715. -    exit(0);
  716. -
  717. -} /* main */
  718. -
  719. -
  720. -/*
  721. - * unblu -- process a binary II file fd, and process the filenames 
  722. - *          listed in wated. If wanted is \0, all files are processed.
  723. - */
  724. -void unblu(fd, wanted)
  725. -int     fd;
  726. -char ** wanted;
  727. -{
  728. -    unsigned char buf[BUFSIZE];
  729. -    int  firstblock = 1;    /* First block needs special processing */
  730. -    int  tofollow = 1;        /* Files to follow in the archive */
  731. -    int  n;
  732. -
  733. -    while (tofollow && ((n = read(fd, buf, BUFSIZE)) != -1)) {
  734. -                        /* If there is a header block */
  735. -    if (n != BUFSIZE) {
  736. -        fprintf(stderr, "%s: %s file size is broken\n", progname, blufile);
  737. -        exit(1);
  738. -    }
  739. -        if ((buf[0] != 10) || (buf[1] != 71) ||
  740. -            (buf[2] != 76) || (buf[18] != 2)) { 
  741. -            fprintf(stderr, "%s: %s not a binary II file\n", progname, blufile);
  742. -            exit(1);
  743. -        }
  744. -    tofollow = buf[127];        /* How many files to follow */
  745. -        if (firstblock && verbose) {
  746. -            print_global_info(buf);
  747. -            firstblock = 0;
  748. -        }
  749. -        process_file(fd, buf, wanted);          /* process the file for it    */
  750. -    }
  751. -    return;
  752. -
  753. -} /* unblu */
  754. -
  755. -
  756. -/*
  757. - * process_file -- retrieve or print file information of file given
  758. - *                 in buf
  759. - */
  760. -void process_file(fd, buf, wanted)
  761. -int     fd;
  762. -unsigned char *  buf;
  763. -char ** wanted;
  764. -{
  765. -    int tf;
  766. -    int ftype;
  767. -    int dflags;
  768. -    int fnamelen;
  769. -    int filelen;
  770. -    char fname[64];
  771. -    int nblocks;
  772. -    int modyear, modmonth, modday;
  773. -    int creyear, cremonth, creday;
  774. -    int modhour, modsec;
  775. -    int crehour, cresec;
  776. -
  777. -    /*
  778. -     * Get fileinfo
  779. -     */
  780. -    ftype =  buf[4];                /* File type */
  781. -    fnamelen =  buf[23];            /* filename */
  782. -    strncpy(fname, &buf[24], fnamelen);
  783. -    fname[fnamelen] = '\0';
  784. -    dflags =  buf[125];                /* Data flags */
  785. -    tf =  buf[127];                /* Number of files to follow */
  786. -    filelen = buf[20] + (buf[21]<<8) + (buf[22]<<16);/* Calculate file length */
  787. -    nblocks = (filelen + BUFSIZE-1) / BUFSIZE;
  788. -    modyear = buf[11] >>1;
  789. -    modday  = buf[10] & 0x1f;
  790. -    modmonth= ((buf[11] & 0x01) << 3) + (buf[10] >> 5);
  791. -    modhour = buf[13] & 0x1f;
  792. -    modsec  = buf[12] & 0x3f;
  793. -    creyear = buf[15] >>1;
  794. -    creday  = buf[14] & 0x1f;
  795. -    cremonth= ((buf[15] & 0x01) << 3) + (buf[14] >> 5);
  796. -    crehour = buf[17] & 0x1f;
  797. -    cresec  = buf[16] & 0x3f;
  798. -
  799. -
  800. -    if (*wanted == NULL || want(fname, wanted)) {
  801. -        if (verbose) {                    /* print file information */
  802. -        printf("%-15s  %3s", fname, filetypes[ftype]);
  803. -        printf(" %02d/%02d/%02d(%02d:%02d)", modyear, modmonth, modday,
  804. -                         modhour, modsec);
  805. -        printf(" - %02d/%02d/%02d(%02d:%02d)", creyear, cremonth, creday,
  806. -                           crehour, cresec);
  807. -        printf(" %5d bytes ", filelen);
  808. -        if (dflags == 0)
  809. -        printf("stored");
  810. -        else {
  811. -        if (dflags & 128) {
  812. -                printf("squeezed");
  813. -            }
  814. -            if (dflags & 64) {
  815. -                printf("encrypted");
  816. -            }
  817. -            if (dflags & 1) 
  818. -                printf("packed");
  819. -        }
  820. -        putchar('\n'); 
  821. -
  822. -        if (ftype != 15)              /* If not a directory */
  823. -                lseek(fd, BUFSIZE*nblocks, 1);  /* Seek to next file */
  824. -        }
  825. -    else if (ftype != 15) 
  826. -            extract_file(fd, fname, filelen);
  827. -    }
  828. -    else if (ftype != 15)              /* If not a directory */
  829. -        lseek(fd, BUFSIZE*nblocks, 1);          /* Seek to next file */
  830. -
  831. -    return;
  832. -
  833. -} /* process_file */
  834. -
  835. -
  836. -/*
  837. - * extract_file -- extract file fname from the archive fd. Fname
  838. - *                 comtains filelen bytes.
  839. - */
  840. -void extract_file(fd, fname, filelen)
  841. -int    fd;
  842. -char * fname;
  843. -int    filelen;
  844. -{
  845. -    int ofd;
  846. -    int n;
  847. -    unsigned char buf[BUFSIZE];
  848. -
  849. -    printf("x - %s\n", fname);
  850. -    if ((ofd = open(fname, O_CREAT | O_WRONLY | O_TRUNC, 0644)) == -1) {
  851. -                        /* Open (PRODOS) file */
  852. -        perror(fname);
  853. -        exit(1);
  854. -    }
  855. -
  856. -    while (filelen > 0) {
  857. -        if ((n = read(fd, buf, BUFSIZE)) != BUFSIZE) { /* Read 128 bytes */
  858. -        fprintf(stderr, "%s: %s file size is broken\n", progname, blufile);
  859. -        exit(1);
  860. -    }
  861. -        write(ofd, buf, (filelen >= BUFSIZE ? BUFSIZE : filelen));
  862. -        filelen -= BUFSIZE;
  863. -    }
  864. -
  865. -    close(ofd);                 /* Close (PRODOS) file */
  866. -    return;
  867. -
  868. -} /* extract_file */
  869. -
  870. -
  871. -
  872. -/*
  873. - * print_global_info -- print global information of the binary II file
  874. - */
  875. -void print_global_info(buf)
  876. -unsigned char * buf;
  877. -{
  878. -    int disk_blocks;
  879. -
  880. -    disk_blocks = buf[117] + (buf[118]<<8) + (buf[119]<<16) + (buf[120]<<24);
  881. -    printf("%s, by Blu %d, ", blufile, buf[126]);
  882. -    printf("%d files, using %d blocks\n", buf[127]+1, disk_blocks);
  883. -    return;
  884. -
  885. -} /* print_global_info */
  886. -
  887. -
  888. -
  889. -/*
  890. - * want -- return 1 if name exists in array wantlist,
  891. - *         else return 0
  892. - */
  893. -want(name, wantlist)
  894. -char *  name;
  895. -char ** wantlist;
  896. -{
  897. -    while (*wantlist != NULL) {
  898. -        if (strcmp(name, *wantlist++) == NULL)
  899. -            return(1);
  900. -    }
  901. -    return(0);
  902. -
  903. -} /* want */
  904. -
  905. -
  906. -
  907. -void usage()
  908. -{
  909. -    fprintf(stderr, "usage: %s [-hv] <blufile> [<filetoextract> ...]\n",
  910. -                        progname);
  911. -    return;
  912. -
  913. -} /* usage */
  914. -
  915. -
  916. -
  917. -void printhelp()
  918. -{
  919. -    fprintf(stderr, "\t-h show this help.\n");
  920. -    fprintf(stderr, "\t-v show contents of archive.\n");
  921. -}
  922. + END OF ARCHIVE
  923.