home *** CD-ROM | disk | FTP | other *** search
/ CBM Funet Archive / cbm-funet-archive-2003.iso / cbm / csbruce / bcode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-25  |  8.8 KB  |  301 lines

  1. /*  bcode: BCODE ENCODER VERSION 1.03-KR BY cRAIG bRUCE 05-oCT-93
  2. **
  3. **  crc-32 CODE BASED ON "fILE vERIFICATION uSING crc" BY mARK r. nELSON IN
  4. **  dR. dOBB'S jOURNAL, mAY 1992, PP. 64-67.  nOTE THAT crc-32 VALUES are THE
  5. **  SAME AS IN zmodem AND pkzip.
  6. **
  7. **  V1.00-KR: ORIGINAL RELEASE, OF COURSE, IN k&r c.
  8. **  V1.01-KR: FIXED SOME BAD PRINT FORMATS.
  9. **  V1.02-KR: FIXED SOME MORE BAD PRINT FORMATS.
  10. **  V1.03-KR: CHANGED THE ENCODING FORMAT TO USE 72 CHARS/LINE, RATHER THAN 76.
  11. */
  12.  
  13. #INCLUDE <STDIO.H>
  14. #INCLUDE <STRING.H>
  15.  
  16. #DEFINE version"1.03-KR"
  17. #DEFINE max_chunk54
  18. #DEFINE max_line80
  19. #DEFINE max_filename85
  20.  
  21. TYPEDEF UNSIGNED CHAR byte;
  22. TYPEDEF UNSIGNED LONG ulong;
  23. TYPEDEF INT bool;
  24. #DEFINE true1
  25. #DEFINE false0
  26.  
  27. VOIDMAIN();
  28. VOIDeNCODEfILE();
  29. booleNCODEsEG();
  30. ulongeNCODElINE();
  31. INTrEADcHUNK();
  32.  
  33. CHARBASE64cHAR[64] = {$7b}
  34. 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p',
  35. 'q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F',
  36. 'G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V',
  37. 'W','X','Y','Z','0','1','2','3','4','5','6','7','8','9','+','/'
  38. {$7d};
  39.  
  40. CHAR   *PROGNAME;
  41. boolVERBOSE;
  42.  
  43. ulong CRCtABLE[256] = {$7b}
  44.     0X00000000, 0X77073096, 0Xee0e612c, 0X990951ba, 0X076dc419, 0X706af48f, 
  45.     0Xe963a535, 0X9e6495a3, 0X0edb8832, 0X79dcb8a4, 0Xe0d5e91e, 0X97d2d988, 
  46.     0X09b64c2b, 0X7eb17cbd, 0Xe7b82d07, 0X90bf1d91, 0X1db71064, 0X6ab020f2, 
  47.     0Xf3b97148, 0X84be41de, 0X1adad47d, 0X6ddde4eb, 0Xf4d4b551, 0X83d385c7, 
  48.     0X136c9856, 0X646ba8c0, 0Xfd62f97a, 0X8a65c9ec, 0X14015c4f, 0X63066cd9, 
  49.     0Xfa0f3d63, 0X8d080df5, 0X3b6e20c8, 0X4c69105e, 0Xd56041e4, 0Xa2677172, 
  50.     0X3c03e4d1, 0X4b04d447, 0Xd20d85fd, 0Xa50ab56b, 0X35b5a8fa, 0X42b2986c, 
  51.     0Xdbbbc9d6, 0Xacbcf940, 0X32d86ce3, 0X45df5c75, 0Xdcd60dcf, 0Xabd13d59, 
  52.     0X26d930ac, 0X51de003a, 0Xc8d75180, 0Xbfd06116, 0X21b4f4b5, 0X56b3c423, 
  53.     0Xcfba9599, 0Xb8bda50f, 0X2802b89e, 0X5f058808, 0Xc60cd9b2, 0Xb10be924, 
  54.     0X2f6f7c87, 0X58684c11, 0Xc1611dab, 0Xb6662d3d, 0X76dc4190, 0X01db7106, 
  55.     0X98d220bc, 0Xefd5102a, 0X71b18589, 0X06b6b51f, 0X9fbfe4a5, 0Xe8b8d433, 
  56.     0X7807c9a2, 0X0f00f934, 0X9609a88e, 0Xe10e9818, 0X7f6a0dbb, 0X086d3d2d, 
  57.     0X91646c97, 0Xe6635c01, 0X6b6b51f4, 0X1c6c6162, 0X856530d8, 0Xf262004e, 
  58.     0X6c0695ed, 0X1b01a57b, 0X8208f4c1, 0Xf50fc457, 0X65b0d9c6, 0X12b7e950, 
  59.     0X8bbeb8ea, 0Xfcb9887c, 0X62dd1ddf, 0X15da2d49, 0X8cd37cf3, 0Xfbd44c65, 
  60.     0X4db26158, 0X3ab551ce, 0Xa3bc0074, 0Xd4bb30e2, 0X4adfa541, 0X3dd895d7, 
  61.     0Xa4d1c46d, 0Xd3d6f4fb, 0X4369e96a, 0X346ed9fc, 0Xad678846, 0Xda60b8d0, 
  62.     0X44042d73, 0X33031de5, 0Xaa0a4c5f, 0Xdd0d7cc9, 0X5005713c, 0X270241aa, 
  63.     0Xbe0b1010, 0Xc90c2086, 0X5768b525, 0X206f85b3, 0Xb966d409, 0Xce61e49f, 
  64.     0X5edef90e, 0X29d9c998, 0Xb0d09822, 0Xc7d7a8b4, 0X59b33d17, 0X2eb40d81, 
  65.     0Xb7bd5c3b, 0Xc0ba6cad, 0Xedb88320, 0X9abfb3b6, 0X03b6e20c, 0X74b1d29a, 
  66.     0Xead54739, 0X9dd277af, 0X04db2615, 0X73dc1683, 0Xe3630b12, 0X94643b84, 
  67.     0X0d6d6a3e, 0X7a6a5aa8, 0Xe40ecf0b, 0X9309ff9d, 0X0a00ae27, 0X7d079eb1, 
  68.     0Xf00f9344, 0X8708a3d2, 0X1e01f268, 0X6906c2fe, 0Xf762575d, 0X806567cb, 
  69.     0X196c3671, 0X6e6b06e7, 0Xfed41b76, 0X89d32be0, 0X10da7a5a, 0X67dd4acc, 
  70.     0Xf9b9df6f, 0X8ebeeff9, 0X17b7be43, 0X60b08ed5, 0Xd6d6a3e8, 0Xa1d1937e, 
  71.     0X38d8c2c4, 0X4fdff252, 0Xd1bb67f1, 0Xa6bc5767, 0X3fb506dd, 0X48b2364b, 
  72.     0Xd80d2bda, 0Xaf0a1b4c, 0X36034af6, 0X41047a60, 0Xdf60efc3, 0Xa867df55, 
  73.     0X316e8eef, 0X4669be79, 0Xcb61b38c, 0Xbc66831a, 0X256fd2a0, 0X5268e236, 
  74.     0Xcc0c7795, 0Xbb0b4703, 0X220216b9, 0X5505262f, 0Xc5ba3bbe, 0Xb2bd0b28, 
  75.     0X2bb45a92, 0X5cb36a04, 0Xc2d7ffa7, 0Xb5d0cf31, 0X2cd99e8b, 0X5bdeae1d, 
  76.     0X9b64c2b0, 0Xec63f226, 0X756aa39c, 0X026d930a, 0X9c0906a9, 0Xeb0e363f, 
  77.     0X72076785, 0X05005713, 0X95bf4a82, 0Xe2b87a14, 0X7bb12bae, 0X0cb61b38, 
  78.     0X92d28e9b, 0Xe5d5be0d, 0X7cdcefb7, 0X0bdbdf21, 0X86d3d2d4, 0Xf1d4e242, 
  79.     0X68ddb3f8, 0X1fda836e, 0X81be16cd, 0Xf6b9265b, 0X6fb077e1, 0X18b74777, 
  80.     0X88085ae6, 0Xff0f6a70, 0X66063bca, 0X11010b5c, 0X8f659eff, 0Xf862ae69, 
  81.     0X616bffd3, 0X166ccf45, 0Xa00ae278, 0Xd70dd2ee, 0X4e048354, 0X3903b3c2, 
  82.     0Xa7672661, 0Xd06016f7, 0X4969474d, 0X3e6e77db, 0Xaed16a4a, 0Xd9d65adc, 
  83.     0X40df0b66, 0X37d83bf0, 0Xa9bcae53, 0Xdebb9ec5, 0X47b2cf7f, 0X30b5ffe9, 
  84.     0Xbdbdf21c, 0Xcabac28a, 0X53b39330, 0X24b4a3a6, 0Xbad03605, 0Xcdd70693, 
  85.     0X54de5729, 0X23d967bf, 0Xb3667a2e, 0Xc4614ab8, 0X5d681b02, 0X2a6f2b94, 
  86.     0Xb40bbe37, 0Xc30c8ea1, 0X5a05df1b, 0X2d02ef8d
  87. {$7d};
  88.  
  89. /****************************************************************************/
  90. VOID MAIN( ARGC, ARGV )
  91. INTARGC;
  92. CHAR   *ARGV[];
  93. {$7b}
  94. file   *FIN;
  95. INTI;
  96. ulongMAXLINES;
  97. boolFILENAMEuSED;
  98. CHAR   *ALIAS;
  99.  
  100. PROGNAME = ARGV[0];
  101. FILENAMEuSED = false;
  102. VERBOSE = false;
  103. ALIAS = "STDIN";
  104. MAXLINES = 0;
  105.  
  106. I = 1;
  107. WHILE (I<ARGC) {$7b}
  108. IF (ARGV[I][0] == '-') {$7b}
  109. SWITCH (ARGV[I][1]) {$7b}
  110. CASE 'L':
  111. MAXLINES = ATOI( ARGV[I+1] );
  112. I++;
  113. BREAK;
  114. CASE 'A':
  115. ALIAS = ARGV[I+1];
  116. I++;
  117. BREAK;
  118. CASE 'V':
  119. VERBOSE = true;
  120. FPRINTF(STDERR, "BCODE: VERSION %S\N",version);
  121. BREAK;
  122. DEFAULT:
  123. FPRINTF(STDERR,
  124. "USAGE: %S [-L MAX_LINE_COUNT] [-V] [[FILENAME][-A ENCODING_ALIAS]] ...\N",
  125. PROGNAME);
  126. EXIT( 1 );
  127. BREAK;
  128. {$7d}
  129. {$7d} ELSE {$7b}
  130. FILENAMEuSED = true;
  131. IF (VERBOSE) {$7b}
  132. FPRINTF(STDERR, "%S: BCODING FILE \"%S\"\N",
  133. PROGNAME, ARGV[I]);
  134. {$7d}
  135. IF( (FIN = FOPEN(ARGV[I], "RB")) == null) {$7b}
  136. FPRINTF(STDERR, "%S: ERROR OPENING \"%S\"\N",
  137. PROGNAME, ARGV[I]);
  138. {$7d} ELSE {$7b}
  139. IF (I+2<ARGC && ARGV[I+1][0]=='-'
  140.   && ARGV[I+1][1]=='A') {$7b}
  141. eNCODEfILE( FIN, ARGV[I], ARGV[I+2],
  142. MAXLINES );
  143. I += 2;
  144. {$7d} ELSE {$7b}
  145. eNCODEfILE( FIN, ARGV[I], ARGV[I],
  146. MAXLINES );
  147. {$7d}
  148. FCLOSE( FIN );
  149. {$7d}
  150. {$7d}
  151. I++;
  152. {$7d}
  153. IF (!FILENAMEuSED) {$7b}
  154. IF (VERBOSE) {$7b}
  155. FPRINTF(STDERR, "%S: ENCODING FROM STANDARD INPUT\N",
  156. PROGNAME);
  157. {$7d}
  158. eNCODEfILE( STDIN, "STDIN", ALIAS, MAXLINES );
  159. {$7d}
  160. {$7d}
  161.  
  162. /****************************************************************************/
  163. VOID eNCODEfILE( FIN, FILENAME, ALIAS, MAXLINES )
  164. file   *FIN;
  165. CHAR   *FILENAME;
  166. CHAR   *ALIAS;
  167. INTMAXLINES;
  168. {$7b}
  169. file   *FOUT;
  170. ulongSEGNUM;
  171. boolMOREsEGS;
  172. CHAROUTNAME[max_filename];
  173.  
  174. FOR( SEGNUM = 1; ; SEGNUM++ ) {$7b}
  175. IF (MAXLINES>0) {$7b}
  176. SPRINTF(OUTNAME, "%S.B%02LU", FILENAME, SEGNUM);
  177. IF (VERBOSE) {$7b}
  178. FPRINTF(STDERR,
  179. "%S: OUTPUTTING TO FILE \"%S\"\N",
  180. PROGNAME, OUTNAME);
  181. {$7d}
  182. FOUT = FOPEN(OUTNAME, "W");
  183. IF (FOUT == null) {$7b}
  184. FPRINTF(STDERR,
  185.    "%S: ERROR OPENING \"%S\" FOR WRITING\N",
  186.    PROGNAME, OUTNAME);
  187. RETURN;
  188. {$7d}
  189. {$7d} ELSE {$7b}
  190. FOUT = STDOUT;
  191. {$7d}
  192. MOREsEGS = eNCODEsEG(ALIAS, SEGNUM, MAXLINES, FIN, FOUT);
  193. IF (!MOREsEGS) BREAK;
  194. IF (MAXLINES>0) {$7b}
  195. FCLOSE( FOUT );
  196. {$7d}
  197. {$7d}
  198. {$7d}
  199.  
  200. /****************************************************************************/
  201. bool eNCODEsEG( FILENAME, SEGNUM, MAXLINES, FIN, FOUT )
  202. CHAR   *FILENAME;
  203. ulongSEGNUM;
  204. ulongMAXLINES;
  205. file   *FIN;
  206. file   *FOUT;
  207. {$7b}
  208. ulongSEGCRC, SEGLEN, LEN;
  209. ulongLINENUM;
  210. CHAR   *ENDS;
  211.  
  212. FPRINTF(FOUT,"--BCODE-BEGIN %LU %S\N", SEGNUM, FILENAME);
  213.  
  214. SEGLEN = 0;
  215. SEGCRC = 0Xffffffff;
  216. LINENUM = 1;
  217. WHILE (!MAXLINES {$7c}{$7c} LINENUM<=MAXLINES) {$7b}
  218. LEN = eNCODElINE( FIN, FOUT, &SEGCRC );
  219. SEGLEN += LEN;
  220. IF (LEN <= 0) BREAK;
  221. LINENUM++;
  222. {$7d}
  223. SEGCRC ^= 0Xffffffff;
  224.  
  225. IF (LINENUM>MAXLINES && MAXLINES) {$7b}
  226. ENDS = "CONTINUED";
  227. {$7d} ELSE {$7b}
  228. ENDS = "END";
  229. {$7d}
  230. FPRINTF(FOUT, "--BCODE-%S %LU %LU %08LX\N", ENDS,SEGNUM,SEGLEN,SEGCRC);
  231. RETURN( LEN );
  232. {$7d}
  233.  
  234. /****************************************************************************/
  235. ulong eNCODElINE( FIN, FOUT, TOTALcRC )
  236. file   *FIN;
  237. file   *FOUT;
  238. ulong  *TOTALcRC;
  239. {$7b}
  240. REGISTER INTB0,B1,B2;
  241. REGISTER ulongCRC;
  242. REGISTER INTBUFPOS, LEN, LINEPOS;
  243. byteBUF[max_chunk+3];
  244. byteLINE[max_line];
  245.  
  246. CRC = *TOTALcRC;
  247. LEN = rEADcHUNK( FIN, BUF );
  248. IF (LEN > 0) {$7b}
  249. BUF[LEN] = 0;
  250. BUF[LEN+1] = 0;
  251. BUF[LEN+2] = 0;
  252.  
  253. /* CONVERT LINE */
  254. FOR (BUFPOS = 0, LINEPOS = 0; BUFPOS < LEN; BUFPOS+=3,
  255. LINEPOS+=4) {$7b}
  256. B0 = BUF[BUFPOS];
  257. B1 = BUF[BUFPOS+1];
  258. B2 = BUF[BUFPOS+2];
  259. LINE[LINEPOS  ] = BASE64cHAR[ B0 >> 2 ];
  260. LINE[LINEPOS+1] = BASE64cHAR[ (B0&0X03)<<4 {$7c}
  261. (B1&0Xf0)>>4 ];
  262. LINE[LINEPOS+2] = BASE64cHAR[ (B1&0X0f)<<2 {$7c}
  263. (B2&0Xc0)>>6 ];
  264. LINE[LINEPOS+3] = BASE64cHAR[ B2 & 0X3f ];
  265. {$7d}
  266.  
  267. /* FIX NON-INTEGRAL-LENGTH (LAST) LINE */
  268. SWITCH( LEN%3 ) {$7b}
  269. CASE 1:LINE[LINEPOS-2] = '='; /* FALL THOUGH */
  270. CASE 2:LINE[LINEPOS-1] = '='; /* FALL THOUGH */
  271. CASE 0:BREAK;
  272. {$7d}
  273. LINE[LINEPOS] = '\N';
  274. LINE[LINEPOS+1] = '\0';
  275. FPUTS(LINE,FOUT);
  276.  
  277. /* TAKE CRC OF LINE DATA */
  278. FOR( BUFPOS=0; BUFPOS < LEN; BUFPOS++ ) {$7b}
  279. CRC = ((CRC>>8) & 0X00ffffff)
  280. ^ CRCtABLE[ (CRC^BUF[BUFPOS]) & 0Xff];
  281. {$7d}
  282. {$7d}
  283. *TOTALcRC = CRC;
  284. RETURN( LEN );
  285. {$7d}
  286.  
  287. /****************************************************************************/
  288. INT rEADcHUNK( FIN, BUF )
  289. file *FIN;
  290. byte *BUF;
  291. {$7b}
  292. INTREM, READlEN;
  293.  
  294. REM = max_chunk;
  295. WHILE( REM>0 && (READlEN=FREAD( BUF, SIZEOF(CHAR), REM, FIN)) > 0) {$7b}
  296. BUF += READlEN;
  297. REM -= READlEN;
  298. {$7d}
  299. RETURN( max_chunk - REM );
  300. {$7d}
  301.