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

  1. From: np@doc.imperial.ac.uk (Nigel Perry)
  2. Newsgroups: comp.sources.mac
  3. Subject: AufsTools (part 2 of 4)
  4. Message-ID: <CSM.91.2>
  5. Date: 20 Feb 91 19:00:07 GMT
  6. Approved: bytebug@dhw68k.cts.com (Roger L. Long)
  7.  
  8. [AufsTools - part 2 of 4]
  9.  
  10. ---
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 2 (of 4)."
  18. # Contents:  capit/capit.c mcvert/mactypes.h mcvert/mcvert.1
  19. #   mcvert/unpack.c stuffit/updcrc.c unstuffit/updcrc.c
  20. # Wrapped by np@asun5 on Mon Dec  3 13:15:56 1990
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'capit/capit.c' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'capit/capit.c'\"
  24. else
  25. echo shar: Extracting \"'capit/capit.c'\" \(8984 characters\)
  26. sed "s/^X//" >'capit/capit.c' <<'END_OF_FILE'
  27. X/* unmacbin - reverse of macbin - change a MacBinary file back in to
  28. X   the .info .data .rsrc style that xbin, macput and macget understand.
  29. X   Stole some from macbin. */
  30. X
  31. X/* Written by John M. Sellens, jmsellens@watdragon.uwaterloo.ca,
  32. X   Math Faculty Computing Facility,
  33. X   University of Waterloo
  34. X   Waterloo, Ontario, Canada
  35. X   N2L 3G1    */
  36. X
  37. X/* capit - convert a macbin file into a CAP file on a CAP Unix Mac disc.
  38. X   Basically:
  39. X      file.data => file
  40. X      file.rsrc => .resource/file
  41. X      file.info => mangle it then .finderinfo/file
  42. X   Nigel Perry, Dept of Computing, Imperial College, London SW7 2BZ, England. July 90.
  43. X   np@doc.ic.ac.uk
  44. X */
  45. X
  46. X#include <stdio.h>
  47. X#include <sys/types.h>
  48. X#include <sys/dir.h>
  49. X#include <strings.h>
  50. X
  51. X#define BSIZE    (128)    /* size of blocks in MacBinary file */
  52. Xtypedef long    int4;
  53. X
  54. X
  55. X/* following from mcvert program */
  56. X
  57. X/* Useful, though not particularly Mac related, values */
  58. Xtypedef unsigned char byte;     /* one byte, obviously */
  59. Xtypedef unsigned short word;    /* must be 2 bytes */
  60. Xtypedef unsigned long ulong;    /* 4 bytes */
  61. X
  62. X#define NAMELEN 63              /* maximum legal Mac file name length */
  63. X
  64. X/* Format of a bin file:
  65. XA bin file is composed of 128 byte blocks.  The first block is the
  66. Xinfo_header (see below).  Then comes the data fork, null padded to fill the
  67. Xlast block.  Then comes the resource fork, padded to fill the last block.  A
  68. Xproposal to follow with the text of the Get Info box has not been implemented,
  69. Xto the best of my knowledge.  Version, zero1 and zero2 are what the receiving
  70. Xprogram looks at to determine if a MacBinary transfer is being initiated.
  71. X*/ 
  72. Xtypedef struct {     /* info file header (128 bytes). Unfortunately, these
  73. X                        longs don't align to word boundaries */
  74. X            byte version;           /* there is only a version 0 at this time */
  75. X            byte nlen;              /* Length of filename. */
  76. X            byte name[NAMELEN];     /* Filename (only 1st nlen are significant)*/
  77. X            byte type[4];           /* File type. */
  78. X            byte auth[4];           /* File creator. */
  79. X            byte flags;             /* file flags: LkIvBnSyBzByChIt */
  80. X            byte zero1;             /* Locked, Invisible,Bundle, System */
  81. X                                    /* Bozo, Busy, Changed, Init */
  82. X            byte icon_vert[2];      /* Vertical icon position within window */
  83. X            byte icon_horiz[2];     /* Horizontal icon postion in window */
  84. X            byte window_id[2];      /* Window or folder ID. */
  85. X            byte protect;           /* = 1 for protected file, 0 otherwise */
  86. X            byte zero2;
  87. X            byte dflen[4];          /* Data Fork length (bytes) -   most sig.  */
  88. X            byte rflen[4];          /* Resource Fork length         byte first */
  89. X            byte cdate[4];          /* File's creation date. */
  90. X            byte mdate[4];          /* File's "last modified" date. */
  91. X            byte ilen[2];           /* GetInfo message length */
  92. X        byte flags2;            /* Finder flags, bits 0-7 */
  93. X        byte unused[14];       
  94. X        byte packlen[4];        /* length of total files when unpacked */
  95. X        byte headlen[2];        /* length of secondary header */
  96. X        byte uploadvers;        /* Version of MacBinary II that the uploading program is written for */
  97. X        byte readvers;          /* Minimum MacBinary II version needed to read this file */
  98. X            byte crc[2];            /* CRC of the previous 124 bytes */
  99. X        byte padding[2];        /* two trailing unused bytes */
  100. X            } info_header;
  101. X
  102. X/* end of mcvert stuff */
  103. X/* from CAP aufs documentation */
  104. X
  105. X#define FINFOLEN 32
  106. X#define MAXCLEN 199
  107. Xtypedef struct
  108. X{  /* byte fi_fndr[FINFOLEN]; */    /* finder info */
  109. X   /* what I think the above is... */
  110. X   ulong fndr_type, fndr_creator;
  111. X   word fndr_flags;
  112. X   ulong fndr_loc;
  113. X   word fndr_fldr;
  114. X   word fndr_icon;
  115. X   byte fndr_unused[8];
  116. X   word fndr_comment;
  117. X   ulong fndr_putaway;
  118. X   /* end of fi_fndr */
  119. X
  120. X   word fi_attr;            /* attributes */
  121. X#define FI_MAGIC1 255
  122. X   byte fi_magic1;        /* was: length of comment */
  123. X#define FI_VERSION 0x10        /* version major 1, minor 0 */
  124. X                /* if more than 8 versions then */
  125. X                /* something wrong anyway */
  126. X   byte fi_version;        /* version number */
  127. X#define FI_MAGIC 0xda
  128. X   byte fi_magic;        /* magic word check */
  129. X   byte fi_bitmap;        /* bitmap of included info */
  130. X#define FI_BM_SHORTFILENAME 0x1    /* is this included? */
  131. X#define FI_BM_MACINTOSHFILENAME 0x2 /* is this included? */
  132. X   byte fi_shortfilename[12+1];    /* possible short file name */
  133. X   byte fi_macfilename[32+1];    /* possible macintosh file name */
  134. X   byte fi_comln;        /* comment length */
  135. X   byte fi_comnt[MAXCLEN+1];    /* comment string */
  136. X} FileInfo;
  137. X
  138. X/* end aufs */
  139. X
  140. Xstatic info_header info;
  141. Xstatic FileInfo fndr_info;
  142. X
  143. Xstatic union trans {
  144. X    int4    num;
  145. X    char    ch[4];
  146. X} trans;
  147. X
  148. X
  149. Xmain(argc,argv)
  150. Xint argc;
  151. Xchar **argv;
  152. X{
  153. X    FILE *fp, *ofp;
  154. X    char bname[MAXNAMLEN];
  155. X    char iname[MAXNAMLEN];
  156. X    char dname[MAXNAMLEN];
  157. X    char rname[MAXNAMLEN];
  158. X    char buf[BSIZE];
  159. X    char * charp;
  160. X    int verbose = 0;
  161. X    int len;
  162. X    int arg;
  163. X    int err = 0;
  164. X    long dflen, rflen;
  165. X    char *ext, *disc;
  166. X    extern char *getenv();
  167. X
  168. X    if((ext = getenv("MAC_EXT")) == NULL) ext = ".bin";
  169. X    if((disc = getenv("MAC_DISC")) == NULL) disc = ".";
  170. X
  171. X    arg = 1;
  172. X    if (argc > 1 && strcmp(argv[1], "-v") == 0 ) {
  173. X    verbose = 1;
  174. X    ++arg;
  175. X    }
  176. X    if ( arg >= argc ) {
  177. X    fprintf(stderr,"%s: Usage: %s [-v] filename(s)\n",argv[0],argv[0]);
  178. X    exit(1);
  179. X    }
  180. X    for ( ; arg < argc; arg++ ) {
  181. X    if ( (charp = rindex (argv[arg], '.')) != NULL
  182. X        && strcmp(charp, ext) == 0 ) {
  183. X        *charp = '\0';
  184. X        strcpy(bname, argv[arg]);
  185. X        *charp = '.';
  186. X    } else
  187. X        strcpy(bname, argv[arg]);
  188. X
  189. X    sprintf(iname, "%s/.finderinfo/%s", disc, bname);
  190. X    sprintf(dname, "%s/%s", disc, bname);
  191. X    sprintf(rname, "%s/.resource/%s", disc, bname);
  192. X
  193. X    if (verbose)
  194. X        printf( "Converting '%s'\n", argv[arg] );
  195. X    if ( (fp = fopen( argv[arg], "r" )) == NULL ) {
  196. X        fprintf( stderr, "%s: couldn't open '%s' for reading",
  197. X        argv[0], argv[arg] );
  198. X        perror( "" );
  199. X        exit(++err);
  200. X    }
  201. X    if ( fread(&info, sizeof(info), 1, fp) <= 0 ) {
  202. X        fprintf( stderr, "%s: couldn't read .info header from '%s'",
  203. X        argv[0], argv[arg] );
  204. X        perror( "" );
  205. X        exit(++err);
  206. X    }
  207. X    if ( info.zero1 || info.zero2 || info.version ) {
  208. X        fprintf( stderr, "%s: '%s' is not in MacBinary format - skipped\n",
  209. X        argv[0], argv[arg] );
  210. X        ++err;
  211. X        continue;
  212. X    }
  213. X
  214. X    /* make the .finderinfo file */
  215. X    bzero(&fndr_info, sizeof(FileInfo));
  216. X    bcopy(info.type, &fndr_info.fndr_type, 4);
  217. X    bcopy(info.auth, &fndr_info.fndr_creator, 4);
  218. X        if(info.protect == '\1' ) fndr_info.fndr_flags = 0x40; /* maybe? */
  219. X    fndr_info.fi_magic1 = FI_MAGIC1;
  220. X    fndr_info.fi_version = FI_VERSION;
  221. X    fndr_info.fi_magic = FI_MAGIC;
  222. X    fndr_info.fi_bitmap = FI_BM_MACINTOSHFILENAME;
  223. X    bcopy(info.name, fndr_info.fi_macfilename, info.nlen);
  224. X
  225. X    /* write the .finderinfo file */
  226. X    if ( (ofp = fopen( iname, "w" )) == NULL ) {
  227. X        fprintf( stderr, "%s: couldn't open '%s' for writing",
  228. X        argv[0], iname );
  229. X        perror( "" );
  230. X        exit(++err);
  231. X    }
  232. X    fwrite( &fndr_info, sizeof(FileInfo), 1, ofp );
  233. X    fclose( ofp );
  234. X
  235. X    /* It appears that the .data and .rsrc parts of the MacBinary file
  236. X       are padded to the nearest 128 (BSIZE) byte boundary, but they
  237. X       should be trimmed to their proper size when we split them. */
  238. X
  239. X    trans.ch[0] = info.dflen[0]; trans.ch[1] = info.dflen[1];
  240. X    trans.ch[2] = info.dflen[2]; trans.ch[3] = info.dflen[3];
  241. X    dflen = ntohl( trans.num );
  242. X    trans.ch[0] = info.rflen[0]; trans.ch[1] = info.rflen[1];
  243. X    trans.ch[2] = info.rflen[2]; trans.ch[3] = info.rflen[3];
  244. X    rflen = ntohl( trans.num );
  245. X
  246. X    /* write the data fork */
  247. X    if ( (ofp = fopen( dname, "w" )) == NULL ) {
  248. X        fprintf( stderr, "%s: couldn't open '%s' for writing",
  249. X        argv[0], dname );
  250. X        perror( "" );
  251. X        exit(++err);
  252. X    }
  253. X    for ( len=0; len<dflen;  ) {
  254. X        if ( fread( buf, sizeof(char), BSIZE, fp ) != BSIZE ) {
  255. X        fprintf( stderr, "%s: couldn't read %d bytes from '%s'",
  256. X            argv[0], BSIZE, argv[arg] );
  257. X        fprintf(stderr,"got %d of %d'n",len,dflen);
  258. X        perror( "" );
  259. X        exit(++err);
  260. X        }
  261. X        len += BSIZE;
  262. X        if ( len > dflen )
  263. X        fwrite( buf, sizeof(char), BSIZE-len+dflen, ofp );
  264. X        else
  265. X        fwrite( buf, sizeof(char), BSIZE, ofp );
  266. X    }
  267. X    fclose( ofp );
  268. X        
  269. X    /* write the .resource file */
  270. X    if ( (ofp = fopen( rname, "w" )) == NULL ) {
  271. X        fprintf( stderr, "%s: couldn't open '%s' for writing",
  272. X        argv[0], rname );
  273. X        perror( "" );
  274. X        exit(++err);
  275. X    }
  276. X    for ( len=0; len<rflen;  ) {
  277. X        if ( fread( buf, sizeof(char), BSIZE, fp ) != BSIZE ) {
  278. X        fprintf( stderr, "%s: couldn't read %d bytes from '%s'",
  279. X            argv[0], BSIZE, argv[arg] );
  280. X        fprintf(stderr,"got %d of %d'n",len,rflen);
  281. X        perror( "" );
  282. X        exit(++err);
  283. X        }
  284. X        len += BSIZE;
  285. X        if ( len > rflen )
  286. X        fwrite( buf, sizeof(char), BSIZE-len+rflen, ofp );
  287. X        else
  288. X        fwrite( buf, sizeof(char), BSIZE, ofp );
  289. X    }
  290. X    fclose( ofp );
  291. X    fclose( fp );
  292. X    }
  293. X    exit( err );
  294. X}
  295. END_OF_FILE
  296. if test 8984 -ne `wc -c <'capit/capit.c'`; then
  297.     echo shar: \"'capit/capit.c'\" unpacked with wrong size!
  298. fi
  299. # end of 'capit/capit.c'
  300. fi
  301. if test -f 'mcvert/mactypes.h' -a "${1}" != "-c" ; then 
  302.   echo shar: Will not clobber existing file \"'mcvert/mactypes.h'\"
  303. else
  304. echo shar: Extracting \"'mcvert/mactypes.h'\" \(7478 characters\)
  305. sed "s/^X//" >'mcvert/mactypes.h' <<'END_OF_FILE'
  306. X#include <stdio.h>
  307. X#include <sys/types.h>
  308. X#include <sys/dir.h>
  309. X#include <sys/stat.h>
  310. X#include <sys/timeb.h>
  311. X
  312. X/* Useful, though not particularly Mac related, values */
  313. Xtypedef unsigned char byte;     /* one byte, obviously */
  314. Xtypedef unsigned short word;    /* must be 2 bytes */
  315. Xtypedef unsigned long ulong;    /* 4 bytes */
  316. X#define TRUE  1
  317. X#define FALSE 0
  318. X#define CR 0x0d
  319. X#define LF 0x0a
  320. X
  321. X/* Compatibility issues */
  322. X#ifdef BSD
  323. X#define mac2word (word) ntohs
  324. X#define mac2long (ulong) ntohl
  325. X#define word2mac (word) htons
  326. X#define long2mac (ulong) htonl
  327. X#else
  328. X#define mac2word
  329. X#define mac2long
  330. X#define word2mac
  331. X#define long2mac
  332. X#endif
  333. X
  334. X#ifdef MAXNAMLEN/* 4.2 BSD, stdio.h */
  335. X#define SYSNAMELEN MAXNAMLEN
  336. X#else
  337. X#define SYSNAMELEN DIRSIZ
  338. X#endif
  339. X
  340. X#define NAMELEN 63              /* maximum legal Mac file name length */
  341. X#define BINNAMELEN 68           /* NAMELEN + len(".bin\0") */
  342. X
  343. X/* Format of a bin file:
  344. XA bin file is composed of 128 byte blocks.  The first block is the
  345. Xinfo_header (see below).  Then comes the data fork, null padded to fill the
  346. Xlast block.  Then comes the resource fork, padded to fill the last block.  A
  347. Xproposal to follow with the text of the Get Info box has not been implemented,
  348. Xto the best of my knowledge.  Version, zero1 and zero2 are what the receiving
  349. Xprogram looks at to determine if a MacBinary transfer is being initiated.
  350. X*/ 
  351. Xtypedef struct {     /* info file header (128 bytes). Unfortunately, these
  352. X                        longs don't align to word boundaries */
  353. X            byte version;           /* there is only a version 0 at this time */
  354. X            byte nlen;              /* Length of filename. */
  355. X            byte name[NAMELEN];     /* Filename (only 1st nlen are significant)*/
  356. X            byte type[4];           /* File type. */
  357. X            byte auth[4];           /* File creator. */
  358. X            byte flags;             /* file flags: LkIvBnSyBzByChIt */
  359. X            byte zero1;             /* Locked, Invisible,Bundle, System */
  360. X                                    /* Bozo, Busy, Changed, Init */
  361. X            byte icon_vert[2];      /* Vertical icon position within window */
  362. X            byte icon_horiz[2];     /* Horizontal icon postion in window */
  363. X            byte window_id[2];      /* Window or folder ID. */
  364. X            byte protect;           /* = 1 for protected file, 0 otherwise */
  365. X            byte zero2;
  366. X            byte dlen[4];           /* Data Fork length (bytes) -   most sig.  */
  367. X            byte rlen[4];           /* Resource Fork length         byte first */
  368. X            byte ctim[4];           /* File's creation date. */
  369. X            byte mtim[4];           /* File's "last modified" date. */
  370. X            byte ilen[2];           /* GetInfo message length */
  371. X        byte flags2;            /* Finder flags, bits 0-7 */
  372. X        byte unused[14];       
  373. X        byte packlen[4];        /* length of total files when unpacked */
  374. X        byte headlen[2];        /* length of secondary header */
  375. X        byte uploadvers;        /* Version of MacBinary II that the uploading program is written for */
  376. X        byte readvers;          /* Minimum MacBinary II version needed to read this file */
  377. X            byte crc[2];            /* CRC of the previous 124 bytes */
  378. X        byte padding[2];        /* two trailing unused bytes */
  379. X            } info_header;
  380. X
  381. X/* The *.info file of a MacTerminal file transfer either has exactly this
  382. Xstructure or has the protect bit in bit 6 (near the sign bit) of byte zero1.
  383. XThe code I have for macbin suggests the difference, but I'm not so sure */
  384. X
  385. X/* Format of a hqx file:
  386. XIt begins with a line that begins "(This file
  387. Xand the rest is 64 character lines (except possibly the last, and not
  388. Xincluding newlines) where the first begins and the last ends with a colon.
  389. XThe characters between colons should be only from the set in tr86, below,
  390. Xeach of which corresponds to 6 bits of data.  Once that is translated to
  391. X8 bit bytes, you have the real data, except that the byte 0x90 may 
  392. Xindicate, if the following character is nonzero, that the previous
  393. Xbyte is to be repeated 1 to 255 times.  The byte 0x90 is represented by
  394. X0x9000.  The information in the file is the hqx_buf (see below),
  395. Xa CRC word, the data fork, a CRC word, the resource fork, and a CRC word.
  396. XThere is considerable confusion about the flags.  An official looking document
  397. Xunclearly states that the init bit is always clear, as is the following byte.
  398. XThe experience of others suggests, however, that this is not the case.
  399. X*/
  400. X
  401. X#define HQXLINELEN 64
  402. Xtypedef struct {
  403. X            byte version;           /* there is only a version 0 at this time */
  404. X            byte type[4];           /* File type. */
  405. X            byte auth[4];           /* File creator. */
  406. X            byte flags;             /* file flags: LkIvBnSyBzByChIt */
  407. X            byte protect;           /* ?Pr??????, don't know what ? bits mean */
  408. X            byte dlen[4];           /* Data Fork length (bytes) -   most sig.  */
  409. X            byte rlen[4];           /* Resource Fork length         byte first */
  410. X            byte bugblank;             /* to fix obscure sun 3/60 problem
  411. X                                          that always makes sizeof(hqx_header
  412. X                                          even */
  413. X            } hqx_header;
  414. Xtypedef struct {     /* hqx file header buffer (includes file name) */
  415. X            byte nlen;              /* Length of filename. */
  416. X            byte name[NAMELEN];     /* Filename: only nlen actually appear */
  417. X            hqx_header all_the_rest;/* and all the rest follows immediately */
  418. X            } hqx_buf;
  419. X
  420. X/* Format of a Packit file:
  421. XRepeat the following sequence for each file in the Packit file:
  422. X    4 byte identifier ("PMag" = not compressed, "Pma4" = compressed)
  423. X    320 byte compression data (if compressed file)
  424. X        = preorder transversal of Huffman tree
  425. X        255 0 bits corresponding to nonleaf nodes
  426. X        256 1 bits corresponding to leaf nodes
  427. X        256 bytes associating leaf nodes with bytes
  428. X        1   completely wasted bit
  429. X    92 byte header (see pit_header below) *
  430. X    2 bytes CRC word for header *
  431. X    data fork (length from header) *
  432. X    resource fork (length from header) *
  433. X    2 bytes CRC word for forks *
  434. X
  435. XLast file is followed by the 4 byte Ascii string, "Pend", and then the EOF.
  436. XThe CRC calculations differ from those in the binhex format.
  437. X
  438. X* these are in compressed form if compression is on for the file
  439. X
  440. X*/
  441. X
  442. Xtypedef struct {     /* Packit file header (92 bytes) */
  443. X            byte nlen;              /* Length of filename. */
  444. X            byte name[NAMELEN];     /* Filename (only 1st nlen are significant)*/
  445. X            byte type[4];           /* File type. */
  446. X            byte auth[4];           /* File creator. */
  447. X            byte flags;             /* file flags: LkIvBnSyBzByChIt */
  448. X            byte zero1;
  449. X            byte protect;           /* = 1 for protected file, 0 otherwise */
  450. X            byte zero2;
  451. X            byte dlen[4];           /* Data Fork length (bytes) -   most sig.  */
  452. X            byte rlen[4];           /* Resource Fork length         byte first */
  453. X            byte ctim[4];           /* File's creation date. */
  454. X            byte mtim[4];           /* File's "last modified" date. */
  455. X            } pit_header;
  456. X
  457. X/* types for constructing the Huffman tree */
  458. Xtypedef struct branch_st {
  459. X            byte flag;
  460. X            struct branch_st *one, *zero;
  461. X            } branch;
  462. X
  463. Xtypedef struct leaf_st {
  464. X            byte flag;
  465. X            byte data;
  466. X            } leaf;
  467. END_OF_FILE
  468. if test 7478 -ne `wc -c <'mcvert/mactypes.h'`; then
  469.     echo shar: \"'mcvert/mactypes.h'\" unpacked with wrong size!
  470. fi
  471. # end of 'mcvert/mactypes.h'
  472. fi
  473. if test -f 'mcvert/mcvert.1' -a "${1}" != "-c" ; then 
  474.   echo shar: Will not clobber existing file \"'mcvert/mcvert.1'\"
  475. else
  476. echo shar: Extracting \"'mcvert/mcvert.1'\" \(5991 characters\)
  477. sed "s/^X//" >'mcvert/mcvert.1' <<'END_OF_FILE'
  478. X.TH MCVERT LOCAL "May 5, 1987"
  479. X.UC 4.2
  480. X.SH NAME
  481. Xmcvert \- BinHex 4.0 to MacBinary file conversion utility
  482. X.SH SYNOPSIS
  483. X.B mcvert
  484. X[-options] name... [[-options] name...]...
  485. X.br
  486. X.SH DESCRIPTION
  487. XThe
  488. X.I mcvert
  489. Xprogram translates MacIntosh files from one format to another.
  490. XThe primary formats in which MacIntosh files are represented on non-Macs are:
  491. X.TP
  492. X.B MacBinary:
  493. XAn eight bit wide representation of the data and resource forks of a Mac
  494. Xfile and of relevant Finder information, MacBinary files are recognized
  495. Xas "special" by several MacIntosh terminal emulators.  These emulators,
  496. Xusing Kermit or Xmodem or any other file transfer protocol, can separate
  497. Xthe incoming file into forks and appropriately modify the Desktop to display
  498. Xicons, types, creation dates, and the like.
  499. X.TP
  500. X.B BinHex 4.0:
  501. XA seven bit wide representation of a Mac file with CRC error checking,
  502. XBinHex 4.0 files are designed for communication of Mac files over long
  503. Xdistance, possibly noisy, seven bit wide paths.
  504. X.TP
  505. X.B PackIt:
  506. XPackIt files are actually representations of collections of Mac files, possibly
  507. XHuffman compressed.  Packing many small related files together before
  508. Xa MacBinary transfer or a translation to BinHex 4.0 is common practice.
  509. X.TP
  510. X.B Text:
  511. XA MacIntosh ends each line of a plain text file with a carriage return
  512. Xcharacter (^M), rather than the newline character (^J) that some systems
  513. Xseem to prefer.  Moreover, a MacBinary file has prepended Finder information
  514. Xthat non-MacIntoshes don't need.
  515. X.TP
  516. X.B Data, Rsrc:
  517. XA Data or Rsrc file is the exact copy of the data or resource fork of a
  518. XMacIntosh file.
  519. X.PP
  520. XIt is the purpose of this program to convert to the MacBinary format
  521. Xfiles in other of the above formats, and vice versa.
  522. X.PP
  523. X.SH PARAMETERS
  524. XExactly one of the following operations may be specified for an input name:
  525. X.TP
  526. X.B x
  527. XBinHex 4.0 - files in the MacBinary format are translated to BinHex
  528. Xfiles, or vice versa.  The name argument may be the name of a file to be
  529. Xconverted or a basename to which an appropriate suffix must be appended
  530. Xto get a filename.  If the conversion is from Binhex 4.0 to MacBinary,
  531. Xseveral files may comprise the BinHex representation of the Mac file.
  532. XRather than manually concatenate the files and manually delete mail
  533. Xheaders and other extraneous garbage, one may specify the names of the
  534. Xfiles in order and
  535. X.I mcvert
  536. Xwill do the concatenating and deleting.  Conversely, in converting
  537. Xa MacBinary file to BinHex 4.0 format for mailing over long distances,
  538. Xone may be restricted to mail messages of no greater that some fixed
  539. Xlength.  In this case,
  540. X.I mcvert
  541. Xcan automatically divide the BinHex file into pieces and label each
  542. Xpiece appropriately.
  543. XOption 'x' is selected by default.
  544. X.TP
  545. X.B r
  546. XResource - files in the MacBinary format with empty data forks
  547. Xand nonempty resource forks are made from ordinary data files, or vice versa.
  548. X.TP
  549. X.B d
  550. XData - files in the MacBinary format with nonempty data forks
  551. Xand empty resource forks are made from ordinary data files, or vice versa.
  552. X.TP
  553. X.B u
  554. XText - files in the MacBinary format with nonempty data forks
  555. Xand empty resource forks are made from ordinary data files, or vice versa.
  556. XUnix newline
  557. Xcharacters are interchanged with MacIntosh carriage return
  558. Xcharacters, and a newly created MacBinary file has creator field given by
  559. Xthe MAC_EDITOR environment variable.
  560. X.PP
  561. X.SH OPTIONS
  562. X.TP
  563. X.B p | q
  564. XIf a BinHex to MacBinary conversion is taking place and option 'p' is selected,
  565. Xany file of type "PIT "
  566. Xwill be unpacked into its constituent parts.  This option does not recursively
  567. Xunpack "PIT " files packed in "PIT " files.
  568. XIf a MacBinary to BinHex conversion is taking place, this option is currently
  569. Xignored.  By default, option 'q' is selected.
  570. X.TP
  571. X.B U | D
  572. XWhen option 'U' is selected, the conversion that takes place is the one suitable
  573. Xfor Uploading files.  That is, the conversion is from MacBinary to something
  574. Xelse when 'U' is selected.  Conversely, option 'D', as in Download,
  575. Xconverts from something to MacBinary.  Option 'D' is the default.
  576. X.TP
  577. X.B s | v
  578. XNormally,
  579. X.I mcvert
  580. Xprints to stderr information about the files it is creating.  Selecting
  581. Xoption 's', as in silent, disables this reporting.  Option 'v', for verbose,
  582. Xis the default.
  583. X.SH "ENVIRONMENT VARIABLES"
  584. XThere are four environment variables one may use to customize 
  585. Xthe behavior of
  586. X.I mcvert
  587. Xslightly.
  588. X.TP
  589. X.B MAC_EDITOR
  590. XThe creator of MacBinary text files produced with options -uD.  
  591. XThe default is MACA, the creator type of MacWrite.
  592. X.TP
  593. X.B MAC_DLOAD_DIR
  594. XThe MacBinary files created when option -D is selected are placed in this
  595. Xdirectory.  The default is ".", the current working directory.
  596. X.TP
  597. X.B MAC_EXT
  598. XThe MacBinary files created when option -D is selected are named according
  599. Xto the filename field stored in the file header, with the name extended by
  600. Xthis suffix.  The default is ".bin".
  601. X.TP
  602. X.B MAC_LINE_LIMIT
  603. XThe BinHex files created when option -U is selected may be no longer than
  604. Xthis many lines long.  Files that would otherwise exceed this line limit
  605. Xare broken up into several files with numbers embedded into their file 
  606. Xnames to show their order.  Each such file has "Start of part x" and "End
  607. Xof part x" messages included where appropriate.
  608. X.SH BUGS
  609. XIt should be possible to discard bad input now and successfully translate
  610. Xgood input later, but bad input mostly just causes immediate termination.
  611. X.PP
  612. XA more diligent person would support BinHex 3.0 and BinHex 2.0 and BinHex
  613. X5000.0 B. C., but I've never seen anyone use them in three years.  A
  614. Xmore diligent person would also do something for users of macget and
  615. Xmacput, but hopefully someone will make those programs support the
  616. XMacBinary file protocol.
  617. X.SH SEE ALSO
  618. Xxbin(1), macget(1), macput(1), xmodem(1), kermit(1)
  619. X.SH AUTHOR
  620. XDoug Moore, Cornell University Computer Science.  Based upon
  621. X.I xbin
  622. Xby Dave Johnson, Brown University, as modified by Guido van Rossum, and upon
  623. X.I unpit
  624. Xby Allan G. Weber, as well as upon correspondence with several helpful
  625. Xreaders of USENET.
  626. X
  627. END_OF_FILE
  628. if test 5991 -ne `wc -c <'mcvert/mcvert.1'`; then
  629.     echo shar: \"'mcvert/mcvert.1'\" unpacked with wrong size!
  630. fi
  631. # end of 'mcvert/mcvert.1'
  632. fi
  633. if test -f 'mcvert/unpack.c' -a "${1}" != "-c" ; then 
  634.   echo shar: Will not clobber existing file \"'mcvert/unpack.c'\"
  635. else
  636. echo shar: Extracting \"'mcvert/unpack.c'\" \(6606 characters\)
  637. sed "s/^X//" >'mcvert/unpack.c' <<'END_OF_FILE'
  638. X#include "mactypes.h"
  639. X
  640. Xextern word magic[];
  641. Xextern FILE *verbose;
  642. Xextern char *dir, *ext;
  643. X
  644. Xulong pit_datalen, pit_rsrclen;
  645. Xword hqx_crc, write_pit_fork(); 
  646. Xchar pitfname[BINNAMELEN];              /* name of file being unpacked */
  647. XFILE *pitfile;                          /* output file */
  648. X
  649. Xbranch branchlist[255], *branchptr, *read_tree();
  650. Xleaf leaflist[256], *leafptr;
  651. Xword Huff_nibble, Huff_bit_count;
  652. Xbyte (*read_char)(), get_crc_byte(), getHuffbyte();
  653. X
  654. Xword un_pit()
  655. X{   char PitId[4];
  656. X    int i;
  657. X    word pit_crc;
  658. X
  659. X    hqx_crc = 0;
  660. X    /* Read and unpack until the PackIt End message is read */
  661. X    for (;;) {
  662. X        read_char = get_crc_byte;
  663. X        for (i = 0; i < 4; i++) PitId[i] = (char) get_crc_byte();
  664. X        if (!strncmp(PitId, "PEnd", 4)) break;
  665. X
  666. X        if (strncmp(PitId, "PMag", 4) && strncmp(PitId, "PMa4", 4))
  667. X            error("Unrecognized Packit format message %s", PitId);
  668. X
  669. X        if (PitId[3] == '4') {          /* if this file is compressed */
  670. X            branchptr = branchlist;     /* read the Huffman decoding  */
  671. X            leafptr = leaflist;         /* tree that is on the input  */
  672. X            Huff_bit_count = 0;         /* and use Huffman decoding   */
  673. X            read_tree();                /* subsequently               */
  674. X            read_char = getHuffbyte;
  675. X            }
  676. X
  677. X        read_pit_hdr();     /* also calculates datalen, rsrclen,
  678. X                               pitfile, pitfname */
  679. X        pit_crc = write_pit_fork(pit_datalen, 0);
  680. X        pit_crc = write_pit_fork(pit_rsrclen, pit_crc);
  681. X        check_pit_crc(pit_crc, "  File data/rsrc CRC mismatch in %s", pitfname);
  682. X        fclose(pitfile);
  683. X        }
  684. X    hqx_crc = (hqx_crc << 8) ^ magic[hqx_crc >> 8];
  685. X    hqx_crc = (hqx_crc << 8) ^ magic[hqx_crc >> 8];
  686. X    return hqx_crc;
  687. X    }
  688. X
  689. Xcheck_pit_crc(calc_crc, msg, name)
  690. Xword calc_crc;
  691. Xchar msg[], name[];
  692. X{   word read_crc;
  693. X    read_crc = (*read_char)() << 8;
  694. X    read_crc |= (*read_char)();
  695. X    if (read_crc != calc_crc) error(msg, name);
  696. X    }
  697. X
  698. X/* This routine reads the header of a packed file and appropriately twiddles it,
  699. X    determines if it has CRC problems, creates the .bin file, and puts the info
  700. X    into the .bin file.
  701. X    Output is pit_datalen, pit_rsrclen, pitfname, pitfile */
  702. Xread_pit_hdr()
  703. X{   register int n;
  704. X    register byte *pit_byte;
  705. X    register ulong pit_crc;
  706. X    pit_header pit;
  707. X    info_header info;
  708. X    short crc;
  709. X
  710. X    extern short calc_mb_crc();
  711. X    /* read the pit header and compute the CRC */
  712. X    pit_crc = 0;
  713. X    pit_byte = (byte *) &pit;
  714. X    for (n = 0; n < sizeof(pit_header); n++) {
  715. X        *pit_byte = (*read_char)();
  716. X        pit_crc = ((pit_crc & 0xff) << 8)
  717. X                    ^ magic[*pit_byte++ ^ (pit_crc >> 8)];
  718. X        }
  719. X
  720. X    /* stuff the pit header data into the info header */
  721. X    bzero(&info, sizeof(info_header));
  722. X    info.nlen = pit.nlen;
  723. X    strncpy(info.name, pit.name, pit.nlen);     /* name */
  724. X    bcopy(pit.type, info.type, 9);              /* type, author, flag */
  725. X    bcopy(pit.dlen, info.dlen, 16);             /* (d,r)len, (c,m)tim */
  726. X    info.flags  &= 0x7e;                        /* reset lock bit, init bit */
  727. X    if (pit.protect & 0x40) info.protect = 1;   /* copy protect bit */
  728. X    info.uploadvers = '\201';
  729. X    info.readvers = '\201';
  730. X
  731. X    /* calculate MacBinary CRC */
  732. X    crc = calc_mb_crc(&info, 124, 0);
  733. X    info.crc[0] = (char) (crc >> 8);
  734. X    info.crc[1] = (char) crc;
  735. X
  736. X    /* Create the .bin file and write the info to it */
  737. X    pit.name[pit.nlen] = '\0';
  738. X    unixify(pit.name);
  739. X    sprintf(pitfname, "%s/%s%s", dir, pit.name, ext);
  740. X    fprintf(verbose,
  741. X        " %-14s%-30s type = \"%4.4s\", author = \"%4.4s\"\n",
  742. X        (read_char == get_crc_byte) ? "Unpacking" : "Decompressing",
  743. X        pit.name, pit.type, pit.auth);
  744. X    if ((pitfile = fopen(pitfname, "w")) == NULL)
  745. X        error("  Cannot open %s", pitfname);
  746. X    check_pit_crc(pit_crc, "  File header CRC mismatch in %s", pitfname);
  747. X    fwrite(&info, sizeof(info_header), 1, pitfile);
  748. X
  749. X    /* Get a couple of items we'll need later */
  750. X    bcopy(pit.dlen, &pit_datalen, 4);
  751. X    pit_datalen = mac2long(pit_datalen);
  752. X    bcopy(pit.rlen, &pit_rsrclen, 4);
  753. X    pit_rsrclen = mac2long(pit_rsrclen);
  754. X    }
  755. X
  756. X/* This routine copies bytes from the decoded input stream to the output
  757. X    and calculates the CRC.  It also pads to a multiple of 128 bytes on the
  758. X    output, which is part of the .bin format */
  759. Xword write_pit_fork(nbytes, calc_crc)
  760. Xregister ulong nbytes;
  761. Xregister ulong calc_crc;
  762. X{   register ulong b;
  763. X    int extra_bytes;
  764. X
  765. X    extra_bytes = 127 - (nbytes+127)%128; /* pad fork to mult of 128 bytes */
  766. X    while (nbytes--) {
  767. X        b = (*read_char)();
  768. X        calc_crc = ((calc_crc & 0xff) << 8) ^ magic[b ^ (calc_crc >> 8)];
  769. X        putc(b, pitfile);
  770. X        }
  771. X    while (extra_bytes--) putc(0, pitfile);
  772. X    return (word) calc_crc;
  773. X    }
  774. X
  775. X/* This routine recursively reads the compression decoding data.
  776. X   It appears to be Huffman compression.  Every leaf is represented
  777. X   by a 1 bit, then the byte it represents.  A branch is represented
  778. X   by a 0 bit, then its zero and one sons */
  779. Xbranch *read_tree()
  780. X{   register branch *branchp;
  781. X    register leaf *leafp;
  782. X    register ulong b;
  783. X    if (!Huff_bit_count--) {
  784. X        Huff_nibble = get_crc_byte();
  785. X        Huff_bit_count = 7;
  786. X        }
  787. X    if ((Huff_nibble<<=1) & 0x0100) {
  788. X        leafp = leafptr++;
  789. X        leafp->flag = 1;
  790. X        b = get_crc_byte();
  791. X        leafp->data = Huff_nibble | (b >> Huff_bit_count);
  792. X        Huff_nibble = b << (8 - Huff_bit_count);
  793. X        return (branch *) leafp;
  794. X        }
  795. X    else {
  796. X        branchp = branchptr++;
  797. X        branchp->flag = 0;
  798. X        branchp->zero = read_tree();
  799. X        branchp->one  = read_tree();
  800. X        return branchp;
  801. X        }
  802. X    }
  803. X
  804. X/* This routine returns the next 8 bits.  It finds the byte in the
  805. X   Huffman decoding tree based on the bits from the input stream. */
  806. Xbyte getHuffbyte()
  807. X{   register branch *branchp;
  808. X    branchp = branchlist;
  809. X    while (!branchp->flag) {
  810. X        if (!Huff_bit_count--) {
  811. X            Huff_nibble = get_crc_byte();
  812. X            Huff_bit_count = 7;
  813. X            }
  814. X        branchp = ((Huff_nibble<<=1) & 0x0100) ? branchp->one : branchp->zero;
  815. X        }
  816. X    return ((leaf *) branchp)->data;
  817. X    }
  818. X
  819. X/* This routine returns the next byte on the .hqx input stream, hiding
  820. X    most file system details at a lower level.  .hqx CRC is maintained
  821. X    here */
  822. Xbyte get_crc_byte()
  823. X{   register ulong c;
  824. X    extern byte *buf_ptr, *buf_end;
  825. X    if (buf_ptr == buf_end) fill_hqxbuf();
  826. X    c = *buf_ptr++;
  827. X    hqx_crc = ((hqx_crc << 8) | c) ^ magic[hqx_crc >> 8];
  828. X    return (byte) c;
  829. X    }
  830. END_OF_FILE
  831. if test 6606 -ne `wc -c <'mcvert/unpack.c'`; then
  832.     echo shar: \"'mcvert/unpack.c'\" unpacked with wrong size!
  833. fi
  834. # end of 'mcvert/unpack.c'
  835. fi
  836. if test -f 'stuffit/updcrc.c' -a "${1}" != "-c" ; then 
  837.   echo shar: Will not clobber existing file \"'stuffit/updcrc.c'\"
  838. else
  839. echo shar: Extracting \"'stuffit/updcrc.c'\" \(5848 characters\)
  840. sed "s/^X//" >'stuffit/updcrc.c' <<'END_OF_FILE'
  841. X/* updcrc(3), crc(1) - calculate crc polynomials
  842. X *
  843. X * Calculate, intelligently, the CRC of a dataset incrementally given a 
  844. X * buffer full at a time.
  845. X * 
  846. X * Usage:
  847. X *     newcrc = updcrc( oldcrc, bufadr, buflen )
  848. X *         unsigned int oldcrc, buflen;
  849. X *         char *bufadr;
  850. X *
  851. X * Compiling with -DTEST creates a program to print the CRC of stdin to stdout.
  852. X * Compile with -DMAKETAB to print values for crctab to stdout.  If you change
  853. X *    the CRC polynomial parameters, be sure to do this and change
  854. X *    crctab's initial value.
  855. X *
  856. X * Notes:
  857. X *  Regards the data stream as an integer whose MSB is the MSB of the first
  858. X *  byte recieved.  This number is 'divided' (using xor instead of subtraction)
  859. X *  by the crc-polynomial P.
  860. X *  XMODEM does things a little differently, essentially treating the LSB of
  861. X * the first data byte as the MSB of the integer. Define SWAPPED to make
  862. X * things behave in this manner.
  863. X *
  864. X * Author:    Mark G. Mendel, 7/86
  865. X *        UUCP: ihnp4!umn-cs!hyper!mark, GEnie: mgm
  866. X */
  867. X
  868. X/* The CRC polynomial.
  869. X * These 4 values define the crc-polynomial.
  870. X * If you change them, you must change crctab[]'s initial value to what is
  871. X * printed by initcrctab() [see 'compile with -DMAKETAB' above].
  872. X */
  873. X    /* Value used by:                CITT    XMODEM    ARC      */
  874. X#define    P     0xA001     /* the poly:    0x1021    0x1021    A001    */
  875. X#define INIT_CRC 0L     /* init value:    -1    0    0    */
  876. X#define SWAPPED         /* bit order:    undef    defined    defined */
  877. X#define W    16     /* bits in CRC:16    16    16    */
  878. X
  879. X    /* data type that holds a W-bit unsigned integer */
  880. X#if W <= 16
  881. X#  define WTYPE    unsigned short
  882. X#else
  883. X#  define WTYPE   unsigned long
  884. X#endif
  885. X
  886. X    /* the number of bits per char: don't change it. */
  887. X#define B    8
  888. X
  889. Xstatic WTYPE crctab[1<<B] = /* as calculated by initcrctab() */ {
  890. X0x0,  0xc0c1,  0xc181,  0x140,  0xc301,  0x3c0,  0x280,  0xc241,
  891. X0xc601,  0x6c0,  0x780,  0xc741,  0x500,  0xc5c1,  0xc481,  0x440,
  892. X0xcc01,  0xcc0,  0xd80,  0xcd41,  0xf00,  0xcfc1,  0xce81,  0xe40,
  893. X0xa00,  0xcac1,  0xcb81,  0xb40,  0xc901,  0x9c0,  0x880,  0xc841,
  894. X0xd801,  0x18c0,  0x1980,  0xd941,  0x1b00,  0xdbc1,  0xda81,  0x1a40,
  895. X0x1e00,  0xdec1,  0xdf81,  0x1f40,  0xdd01,  0x1dc0,  0x1c80,  0xdc41,
  896. X0x1400,  0xd4c1,  0xd581,  0x1540,  0xd701,  0x17c0,  0x1680,  0xd641,
  897. X0xd201,  0x12c0,  0x1380,  0xd341,  0x1100,  0xd1c1,  0xd081,  0x1040,
  898. X0xf001,  0x30c0,  0x3180,  0xf141,  0x3300,  0xf3c1,  0xf281,  0x3240,
  899. X0x3600,  0xf6c1,  0xf781,  0x3740,  0xf501,  0x35c0,  0x3480,  0xf441,
  900. X0x3c00,  0xfcc1,  0xfd81,  0x3d40,  0xff01,  0x3fc0,  0x3e80,  0xfe41,
  901. X0xfa01,  0x3ac0,  0x3b80,  0xfb41,  0x3900,  0xf9c1,  0xf881,  0x3840,
  902. X0x2800,  0xe8c1,  0xe981,  0x2940,  0xeb01,  0x2bc0,  0x2a80,  0xea41,
  903. X0xee01,  0x2ec0,  0x2f80,  0xef41,  0x2d00,  0xedc1,  0xec81,  0x2c40,
  904. X0xe401,  0x24c0,  0x2580,  0xe541,  0x2700,  0xe7c1,  0xe681,  0x2640,
  905. X0x2200,  0xe2c1,  0xe381,  0x2340,  0xe101,  0x21c0,  0x2080,  0xe041,
  906. X0xa001,  0x60c0,  0x6180,  0xa141,  0x6300,  0xa3c1,  0xa281,  0x6240,
  907. X0x6600,  0xa6c1,  0xa781,  0x6740,  0xa501,  0x65c0,  0x6480,  0xa441,
  908. X0x6c00,  0xacc1,  0xad81,  0x6d40,  0xaf01,  0x6fc0,  0x6e80,  0xae41,
  909. X0xaa01,  0x6ac0,  0x6b80,  0xab41,  0x6900,  0xa9c1,  0xa881,  0x6840,
  910. X0x7800,  0xb8c1,  0xb981,  0x7940,  0xbb01,  0x7bc0,  0x7a80,  0xba41,
  911. X0xbe01,  0x7ec0,  0x7f80,  0xbf41,  0x7d00,  0xbdc1,  0xbc81,  0x7c40,
  912. X0xb401,  0x74c0,  0x7580,  0xb541,  0x7700,  0xb7c1,  0xb681,  0x7640,
  913. X0x7200,  0xb2c1,  0xb381,  0x7340,  0xb101,  0x71c0,  0x7080,  0xb041,
  914. X0x5000,  0x90c1,  0x9181,  0x5140,  0x9301,  0x53c0,  0x5280,  0x9241,
  915. X0x9601,  0x56c0,  0x5780,  0x9741,  0x5500,  0x95c1,  0x9481,  0x5440,
  916. X0x9c01,  0x5cc0,  0x5d80,  0x9d41,  0x5f00,  0x9fc1,  0x9e81,  0x5e40,
  917. X0x5a00,  0x9ac1,  0x9b81,  0x5b40,  0x9901,  0x59c0,  0x5880,  0x9841,
  918. X0x8801,  0x48c0,  0x4980,  0x8941,  0x4b00,  0x8bc1,  0x8a81,  0x4a40,
  919. X0x4e00,  0x8ec1,  0x8f81,  0x4f40,  0x8d01,  0x4dc0,  0x4c80,  0x8c41,
  920. X0x4400,  0x84c1,  0x8581,  0x4540,  0x8701,  0x47c0,  0x4680,  0x8641,
  921. X0x8201,  0x42c0,  0x4380,  0x8341,  0x4100,  0x81c1,  0x8081,  0x4040,
  922. X} ;
  923. X
  924. XWTYPE
  925. Xupdcrc( icrc, icp, icnt )
  926. X    WTYPE icrc;
  927. X    unsigned char *icp;
  928. X    int icnt;
  929. X{
  930. X    register WTYPE crc = icrc;
  931. X    register unsigned char *cp = icp;
  932. X    register int cnt = icnt;
  933. X
  934. X    while( cnt-- ) {
  935. X#ifndef SWAPPED
  936. X    crc = (crc<<B) ^ crctab[(crc>>(W-B)) ^ *cp++];
  937. X#else
  938. X    crc = (crc>>B) ^ crctab[(crc & ((1<<B)-1)) ^ *cp++]; 
  939. X#endif SWAPPED
  940. X    }
  941. X
  942. X    return( crc );
  943. X}
  944. X
  945. X#ifdef MAKETAB
  946. X
  947. X#include <stdio.h>
  948. Xmain()
  949. X{
  950. X    initcrctab();
  951. X}
  952. X
  953. Xinitcrctab()
  954. X{
  955. X    register  int b, i;
  956. X    WTYPE v;
  957. X
  958. X    
  959. X    for( b = 0; b <= (1<<B)-1; ++b ) {
  960. X#ifndef SWAPPED
  961. X    for( v = b<<(W-B), i = B; --i >= 0; )
  962. X        v = v & ((WTYPE)1<<(W-1)) ? (v<<1)^P : v<<1;
  963. X#else
  964. X    for( v = b, i = B; --i >= 0; )
  965. X        v = v & 1 ? (v>>1)^P : v>>1;
  966. X#endif        
  967. X    crctab[b] = v;
  968. X
  969. X    printf( "0x%lx,", v & ((1L<<W)-1L));
  970. X    if( (b&7) == 7 )
  971. X        printf("\n" );
  972. X    else
  973. X        printf("  ");
  974. X    }
  975. X}
  976. X#endif
  977. X
  978. X#ifdef TEST
  979. X
  980. X#include <stdio.h>
  981. X#include <fcntl.h>
  982. X
  983. X#define MAXBUF    4096
  984. X
  985. X
  986. X
  987. Xmain( ac, av )
  988. X    int ac; char **av;
  989. X{
  990. X    int fd;
  991. X    int nr;
  992. X    int i;
  993. X    char buf[MAXBUF];
  994. X    WTYPE crc, crc2;
  995. X
  996. X    fd = 0;
  997. X    if( ac > 1 )
  998. X    if( (fd = open( av[1], O_RDONLY )) < 0 ) {
  999. X        perror( av[1] );
  1000. X        exit( -1 );
  1001. X    }
  1002. X    crc = crc2 = INIT_CRC;
  1003. X
  1004. X    while( (nr = read( fd, buf, MAXBUF )) > 0 ) {
  1005. X    crc = updcrc( crc, buf, nr );
  1006. X    }
  1007. X
  1008. X    if( nr != 0 )
  1009. X    perror( "reading" );
  1010. X    else {
  1011. X    printf( "%lx\n", crc );
  1012. X    }
  1013. X
  1014. X#ifdef MAGICCHECK
  1015. X    /* tack one's complement of crc onto data stream, and
  1016. X       continue crc calculation.  Should get a constant (magic number)
  1017. X       dependent only on P, not the data.
  1018. X     */
  1019. X    crc2 = crc ^ -1L;
  1020. X    for( nr = W-B; nr >= 0; nr -= B ) {
  1021. X    buf[0] = (crc2 >> nr);
  1022. X    crc = updcrc(crc, buf, 1);
  1023. X    }
  1024. X
  1025. X    /* crc should now equal magic */
  1026. X    buf[0] = buf[1] = buf[2] = buf[3] = 0;
  1027. X    printf( "magic test: %lx =?= %lx\n", crc, updcrc(-1, buf, W/B));
  1028. X#endif MAGICCHECK
  1029. X}
  1030. X
  1031. X#endif
  1032. END_OF_FILE
  1033. if test 5848 -ne `wc -c <'stuffit/updcrc.c'`; then
  1034.     echo shar: \"'stuffit/updcrc.c'\" unpacked with wrong size!
  1035. fi
  1036. # end of 'stuffit/updcrc.c'
  1037. fi
  1038. if test -f 'unstuffit/updcrc.c' -a "${1}" != "-c" ; then 
  1039.   echo shar: Will not clobber existing file \"'unstuffit/updcrc.c'\"
  1040. else
  1041. echo shar: Extracting \"'unstuffit/updcrc.c'\" \(5848 characters\)
  1042. sed "s/^X//" >'unstuffit/updcrc.c' <<'END_OF_FILE'
  1043. X/* updcrc(3), crc(1) - calculate crc polynomials
  1044. X *
  1045. X * Calculate, intelligently, the CRC of a dataset incrementally given a 
  1046. X * buffer full at a time.
  1047. X * 
  1048. X * Usage:
  1049. X *     newcrc = updcrc( oldcrc, bufadr, buflen )
  1050. X *         unsigned int oldcrc, buflen;
  1051. X *         char *bufadr;
  1052. X *
  1053. X * Compiling with -DTEST creates a program to print the CRC of stdin to stdout.
  1054. X * Compile with -DMAKETAB to print values for crctab to stdout.  If you change
  1055. X *    the CRC polynomial parameters, be sure to do this and change
  1056. X *    crctab's initial value.
  1057. X *
  1058. X * Notes:
  1059. X *  Regards the data stream as an integer whose MSB is the MSB of the first
  1060. X *  byte recieved.  This number is 'divided' (using xor instead of subtraction)
  1061. X *  by the crc-polynomial P.
  1062. X *  XMODEM does things a little differently, essentially treating the LSB of
  1063. X * the first data byte as the MSB of the integer. Define SWAPPED to make
  1064. X * things behave in this manner.
  1065. X *
  1066. X * Author:    Mark G. Mendel, 7/86
  1067. X *        UUCP: ihnp4!umn-cs!hyper!mark, GEnie: mgm
  1068. X */
  1069. X
  1070. X/* The CRC polynomial.
  1071. X * These 4 values define the crc-polynomial.
  1072. X * If you change them, you must change crctab[]'s initial value to what is
  1073. X * printed by initcrctab() [see 'compile with -DMAKETAB' above].
  1074. X */
  1075. X    /* Value used by:                CITT    XMODEM    ARC      */
  1076. X#define    P     0xA001     /* the poly:    0x1021    0x1021    A001    */
  1077. X#define INIT_CRC 0L     /* init value:    -1    0    0    */
  1078. X#define SWAPPED         /* bit order:    undef    defined    defined */
  1079. X#define W    16     /* bits in CRC:16    16    16    */
  1080. X
  1081. X    /* data type that holds a W-bit unsigned integer */
  1082. X#if W <= 16
  1083. X#  define WTYPE    unsigned short
  1084. X#else
  1085. X#  define WTYPE   unsigned long
  1086. X#endif
  1087. X
  1088. X    /* the number of bits per char: don't change it. */
  1089. X#define B    8
  1090. X
  1091. Xstatic WTYPE crctab[1<<B] = /* as calculated by initcrctab() */ {
  1092. X0x0,  0xc0c1,  0xc181,  0x140,  0xc301,  0x3c0,  0x280,  0xc241,
  1093. X0xc601,  0x6c0,  0x780,  0xc741,  0x500,  0xc5c1,  0xc481,  0x440,
  1094. X0xcc01,  0xcc0,  0xd80,  0xcd41,  0xf00,  0xcfc1,  0xce81,  0xe40,
  1095. X0xa00,  0xcac1,  0xcb81,  0xb40,  0xc901,  0x9c0,  0x880,  0xc841,
  1096. X0xd801,  0x18c0,  0x1980,  0xd941,  0x1b00,  0xdbc1,  0xda81,  0x1a40,
  1097. X0x1e00,  0xdec1,  0xdf81,  0x1f40,  0xdd01,  0x1dc0,  0x1c80,  0xdc41,
  1098. X0x1400,  0xd4c1,  0xd581,  0x1540,  0xd701,  0x17c0,  0x1680,  0xd641,
  1099. X0xd201,  0x12c0,  0x1380,  0xd341,  0x1100,  0xd1c1,  0xd081,  0x1040,
  1100. X0xf001,  0x30c0,  0x3180,  0xf141,  0x3300,  0xf3c1,  0xf281,  0x3240,
  1101. X0x3600,  0xf6c1,  0xf781,  0x3740,  0xf501,  0x35c0,  0x3480,  0xf441,
  1102. X0x3c00,  0xfcc1,  0xfd81,  0x3d40,  0xff01,  0x3fc0,  0x3e80,  0xfe41,
  1103. X0xfa01,  0x3ac0,  0x3b80,  0xfb41,  0x3900,  0xf9c1,  0xf881,  0x3840,
  1104. X0x2800,  0xe8c1,  0xe981,  0x2940,  0xeb01,  0x2bc0,  0x2a80,  0xea41,
  1105. X0xee01,  0x2ec0,  0x2f80,  0xef41,  0x2d00,  0xedc1,  0xec81,  0x2c40,
  1106. X0xe401,  0x24c0,  0x2580,  0xe541,  0x2700,  0xe7c1,  0xe681,  0x2640,
  1107. X0x2200,  0xe2c1,  0xe381,  0x2340,  0xe101,  0x21c0,  0x2080,  0xe041,
  1108. X0xa001,  0x60c0,  0x6180,  0xa141,  0x6300,  0xa3c1,  0xa281,  0x6240,
  1109. X0x6600,  0xa6c1,  0xa781,  0x6740,  0xa501,  0x65c0,  0x6480,  0xa441,
  1110. X0x6c00,  0xacc1,  0xad81,  0x6d40,  0xaf01,  0x6fc0,  0x6e80,  0xae41,
  1111. X0xaa01,  0x6ac0,  0x6b80,  0xab41,  0x6900,  0xa9c1,  0xa881,  0x6840,
  1112. X0x7800,  0xb8c1,  0xb981,  0x7940,  0xbb01,  0x7bc0,  0x7a80,  0xba41,
  1113. X0xbe01,  0x7ec0,  0x7f80,  0xbf41,  0x7d00,  0xbdc1,  0xbc81,  0x7c40,
  1114. X0xb401,  0x74c0,  0x7580,  0xb541,  0x7700,  0xb7c1,  0xb681,  0x7640,
  1115. X0x7200,  0xb2c1,  0xb381,  0x7340,  0xb101,  0x71c0,  0x7080,  0xb041,
  1116. X0x5000,  0x90c1,  0x9181,  0x5140,  0x9301,  0x53c0,  0x5280,  0x9241,
  1117. X0x9601,  0x56c0,  0x5780,  0x9741,  0x5500,  0x95c1,  0x9481,  0x5440,
  1118. X0x9c01,  0x5cc0,  0x5d80,  0x9d41,  0x5f00,  0x9fc1,  0x9e81,  0x5e40,
  1119. X0x5a00,  0x9ac1,  0x9b81,  0x5b40,  0x9901,  0x59c0,  0x5880,  0x9841,
  1120. X0x8801,  0x48c0,  0x4980,  0x8941,  0x4b00,  0x8bc1,  0x8a81,  0x4a40,
  1121. X0x4e00,  0x8ec1,  0x8f81,  0x4f40,  0x8d01,  0x4dc0,  0x4c80,  0x8c41,
  1122. X0x4400,  0x84c1,  0x8581,  0x4540,  0x8701,  0x47c0,  0x4680,  0x8641,
  1123. X0x8201,  0x42c0,  0x4380,  0x8341,  0x4100,  0x81c1,  0x8081,  0x4040,
  1124. X} ;
  1125. X
  1126. XWTYPE
  1127. Xupdcrc( icrc, icp, icnt )
  1128. X    WTYPE icrc;
  1129. X    unsigned char *icp;
  1130. X    int icnt;
  1131. X{
  1132. X    register WTYPE crc = icrc;
  1133. X    register unsigned char *cp = icp;
  1134. X    register int cnt = icnt;
  1135. X
  1136. X    while( cnt-- ) {
  1137. X#ifndef SWAPPED
  1138. X    crc = (crc<<B) ^ crctab[(crc>>(W-B)) ^ *cp++];
  1139. X#else
  1140. X    crc = (crc>>B) ^ crctab[(crc & ((1<<B)-1)) ^ *cp++]; 
  1141. X#endif SWAPPED
  1142. X    }
  1143. X
  1144. X    return( crc );
  1145. X}
  1146. X
  1147. X#ifdef MAKETAB
  1148. X
  1149. X#include <stdio.h>
  1150. Xmain()
  1151. X{
  1152. X    initcrctab();
  1153. X}
  1154. X
  1155. Xinitcrctab()
  1156. X{
  1157. X    register  int b, i;
  1158. X    WTYPE v;
  1159. X
  1160. X    
  1161. X    for( b = 0; b <= (1<<B)-1; ++b ) {
  1162. X#ifndef SWAPPED
  1163. X    for( v = b<<(W-B), i = B; --i >= 0; )
  1164. X        v = v & ((WTYPE)1<<(W-1)) ? (v<<1)^P : v<<1;
  1165. X#else
  1166. X    for( v = b, i = B; --i >= 0; )
  1167. X        v = v & 1 ? (v>>1)^P : v>>1;
  1168. X#endif        
  1169. X    crctab[b] = v;
  1170. X
  1171. X    printf( "0x%lx,", v & ((1L<<W)-1L));
  1172. X    if( (b&7) == 7 )
  1173. X        printf("\n" );
  1174. X    else
  1175. X        printf("  ");
  1176. X    }
  1177. X}
  1178. X#endif
  1179. X
  1180. X#ifdef TEST
  1181. X
  1182. X#include <stdio.h>
  1183. X#include <fcntl.h>
  1184. X
  1185. X#define MAXBUF    4096
  1186. X
  1187. X
  1188. X
  1189. Xmain( ac, av )
  1190. X    int ac; char **av;
  1191. X{
  1192. X    int fd;
  1193. X    int nr;
  1194. X    int i;
  1195. X    char buf[MAXBUF];
  1196. X    WTYPE crc, crc2;
  1197. X
  1198. X    fd = 0;
  1199. X    if( ac > 1 )
  1200. X    if( (fd = open( av[1], O_RDONLY )) < 0 ) {
  1201. X        perror( av[1] );
  1202. X        exit( -1 );
  1203. X    }
  1204. X    crc = crc2 = INIT_CRC;
  1205. X
  1206. X    while( (nr = read( fd, buf, MAXBUF )) > 0 ) {
  1207. X    crc = updcrc( crc, buf, nr );
  1208. X    }
  1209. X
  1210. X    if( nr != 0 )
  1211. X    perror( "reading" );
  1212. X    else {
  1213. X    printf( "%lx\n", crc );
  1214. X    }
  1215. X
  1216. X#ifdef MAGICCHECK
  1217. X    /* tack one's complement of crc onto data stream, and
  1218. X       continue crc calculation.  Should get a constant (magic number)
  1219. X       dependent only on P, not the data.
  1220. X     */
  1221. X    crc2 = crc ^ -1L;
  1222. X    for( nr = W-B; nr >= 0; nr -= B ) {
  1223. X    buf[0] = (crc2 >> nr);
  1224. X    crc = updcrc(crc, buf, 1);
  1225. X    }
  1226. X
  1227. X    /* crc should now equal magic */
  1228. X    buf[0] = buf[1] = buf[2] = buf[3] = 0;
  1229. X    printf( "magic test: %lx =?= %lx\n", crc, updcrc(-1, buf, W/B));
  1230. X#endif MAGICCHECK
  1231. X}
  1232. X
  1233. X#endif
  1234. END_OF_FILE
  1235. if test 5848 -ne `wc -c <'unstuffit/updcrc.c'`; then
  1236.     echo shar: \"'unstuffit/updcrc.c'\" unpacked with wrong size!
  1237. fi
  1238. # end of 'unstuffit/updcrc.c'
  1239. fi
  1240. echo shar: End of archive 2 \(of 4\).
  1241. cp /dev/null ark2isdone
  1242. MISSING=""
  1243. for I in 1 2 3 4 ; do
  1244.     if test ! -f ark${I}isdone ; then
  1245.     MISSING="${MISSING} ${I}"
  1246.     fi
  1247. done
  1248. if test "${MISSING}" = "" ; then
  1249.     echo You have unpacked all 4 archives.
  1250.     rm -f ark[1-9]isdone
  1251. else
  1252.     echo You still need to unpack the following archives:
  1253.     echo "        " ${MISSING}
  1254. fi
  1255. ##  End of shell archive.
  1256. exit 0
  1257. --- end of part 2 ---
  1258.