Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

396 lines
9.5 KiB

  1. ------------------------------------------------------------------------------
  2. README.1ST:
  3. MIME64 Encoder/Decoder
  4. WHAT MIME64 IS: MIME64 is an encoding described in RFC1341 as MIME base64.
  5. Its purpose is to encode binary files into ASCII so that they may be passed
  6. through e-mail gates. In this regard, MIME64 is similar to UUENCODE.
  7. Although most binaries these days are transmitted using UUENCODE, I
  8. have seen a few using MIME64, and I have had requests from friends that
  9. I decode MIME64 files that have fallen into their hands. As long as
  10. some MIME64 continues to exist, a package such as this one is useful
  11. to have.
  12. WHAT THIS PACKAGE CONTAINS: This package contains both executable
  13. and ANSI-C source code for a MIME64 encoder/decoder (MIME.EXE and
  14. MIME.C respecively). It also contains this README file, and a MIME64
  15. encoded file called MIME.64. The latter will decode to MIME.ZIP if
  16. you issue the DOS command line:
  17. MIME64 MIME.64 MIME.ZIP
  18. If you unzip the zip file, you will get an essay by Mark Grand about
  19. MIME.
  20. HOW TO USE THIS PACKAGE: To decode a MIME64 file you may type:
  21. MIME64 infile outfile
  22. If you leave out the outfile specification, the output file will
  23. overwrite the input file.
  24. To encode a file into MIME64 format, type:
  25. MIME64 infile outfile -e
  26. Again, if you leave off the outfile specification, the output will
  27. overwrite the input.
  28. STATUS OF THIS PACKAGE: This package is freeware. As author, I
  29. claim no copyright. If you change the source code and intend to
  30. propogate that change to other users, please include a comment to
  31. that effect at the top that states: The date of the change, the
  32. nature of the change, and who made the change. As a courtesy, I also
  33. ask that you retain the comment that acknowledges me as the original
  34. author.
  35. SEND QUESTIONS ABOUT THIS PACKAGE TO: [email protected]
  36. Karl Hahn
  37. ------------------------------------------------------------------------------
  38. MIME64.C:
  39. /* mime64 */
  40. /* MIME base64 encoder/decoder by Karl Hahn [email protected] 3-Aug-94 */
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  44. "0123456789+/";
  45. void fputch( char blivit, FILE *f )
  46. {
  47. /* if (blivit == '\n') fputc( '\r', f );*/
  48. fputc( blivit, f );
  49. }
  50. int classify_args( int narg,
  51. char *rawargs[], char *fileargs[], char *optargs[] )
  52. {
  53. int index, jndex, kndex;
  54. char *argptr;
  55. for ( index = 0, jndex = 0, kndex = 0; index < narg; index++ )
  56. {
  57. argptr = rawargs[index];
  58. if (*argptr == '-')
  59. {
  60. argptr++;
  61. optargs[kndex++] = argptr;
  62. }
  63. else
  64. {
  65. fileargs[jndex++] = argptr;
  66. }
  67. }
  68. return kndex;
  69. }
  70. int cvt_ascii( unsigned char alpha )
  71. {
  72. if ( (alpha >= 'A') && (alpha <= 'Z') ) return (int)(alpha - 'A');
  73. else if ( (alpha >= 'a') && (alpha <= 'z') )
  74. return 26 + (int)(alpha - 'a');
  75. else if ( (alpha >= '0') && (alpha <= '9' ) )
  76. return 52 + (int)(alpha - '0');
  77. else if ( alpha == '+' ) return 62;
  78. else if ( alpha == '/' ) return 63;
  79. else if ( alpha == '=' ) return -2;
  80. else return -1;
  81. }
  82. char *fileargs[64], *optargs[64];
  83. struct STATE64 {
  84. unsigned long int accum;
  85. int shift;
  86. };
  87. int main( int nargs, char *cargs[] )
  88. {
  89. int n_options, n_files, index, jndex, shift, save_shift;
  90. enum { ENCODE, DECODE } whattodo = DECODE;
  91. int help_flag = 0, replace_flag = 0, quit = 0;
  92. FILE *fin, *fout;
  93. unsigned char blivit;
  94. unsigned long accum, value;
  95. char buf[80];
  96. char *cptr, *altptr;
  97. int decode_state;
  98. n_options = classify_args( nargs, cargs, fileargs, optargs );
  99. n_files = nargs - n_options;
  100. if ( n_files < 2 ) help_flag = 1;
  101. for ( index = 0; index < n_options; index++ )
  102. {
  103. if ( ( optargs[index][0] == 'e' ) ||
  104. ( optargs[index][0] == 'E' ) ) whattodo = ENCODE;
  105. if ( optargs[index][0] == '?' ) help_flag = 1;
  106. }
  107. if ( help_flag )
  108. {
  109. printf( "mime64 infile [outfile] [-option] [-option] etc.\n\n"
  110. "convert between binary and MIME BASE64 format\n\n"
  111. " -e MIME base64 encode (default is decode)\n"
  112. " -? display help message\n\n"
  113. "if no outfile given, output file replaces infile\n" );
  114. }
  115. if ( n_files < 2 ) exit(0);
  116. if ( whattodo == DECODE )
  117. {
  118. fin = fopen( fileargs[1], "r" );
  119. }
  120. else
  121. {
  122. fin = fopen( fileargs[1], "rb" );
  123. }
  124. if ( fin == 0 )
  125. {
  126. printf( "%s file not found\n", fileargs[1] );
  127. exit(-1);
  128. }
  129. if ( n_files > 2 )
  130. {
  131. if ( whattodo == DECODE )
  132. {
  133. fout = fopen( fileargs[2], "wb" );
  134. }
  135. else
  136. {
  137. fout = fopen( fileargs[2], "w" );
  138. }
  139. if ( fout == 0 )
  140. {
  141. printf( "Couldn't open %s for output\n", fileargs[2] );
  142. }
  143. }
  144. else
  145. {
  146. if ( whattodo == DECODE )
  147. {
  148. fout = fopen( "$$$$$$$$.$$$", "wb" );
  149. }
  150. else
  151. {
  152. fout = fopen( "$$$$$$$$.$$$", "w" );
  153. }
  154. replace_flag = 1;
  155. }
  156. if ( whattodo == DECODE )
  157. {
  158. shift = 0;
  159. accum = 0;
  160. decode_state = 0;
  161. while ( ( !feof( fin ) ) && (quit == 0) )
  162. {
  163. fgets( buf, 80, fin );
  164. if ( decode_state == 0 )
  165. {
  166. for ( index = 0;
  167. (buf[index] != '\n') && (buf[index] != '\0') &&
  168. (decode_state >= 0);
  169. index++ )
  170. {
  171. if ( ( (buf[index] >= 'A') && (buf[index] <= 'Z') ) ||
  172. ( (buf[index] >= 'a') && (buf[index] <= 'z') ) ||
  173. ( (buf[index] >= '0') && (buf[index] <= '9') ) ||
  174. (buf[index] == '+') ||
  175. (buf[index] == '/') ||
  176. (buf[index] == '=') )
  177. {
  178. decode_state = 1;
  179. }
  180. else
  181. {
  182. decode_state = -2;
  183. }
  184. }
  185. if ( decode_state <= 0 )
  186. {
  187. decode_state = 0;
  188. continue;
  189. }
  190. }
  191. if ( feof(fin) )
  192. {
  193. quit = 1;
  194. }
  195. if ( quit != 0 )
  196. {
  197. buf[0] = '\0';
  198. }
  199. for ( index = 0; (buf[index] != '\n') && (buf[index] != '\0'); index++)
  200. {
  201. value = cvt_ascii( buf[index] );
  202. if ( value < 64 )
  203. {
  204. accum <<= 6;
  205. shift += 6;
  206. accum |= value;
  207. if ( shift >= 8 )
  208. {
  209. shift -= 8;
  210. value = accum >> shift;
  211. blivit = (unsigned char)value & 0xFFl;
  212. fputc( blivit, fout );
  213. }
  214. }
  215. else
  216. {
  217. quit = 1;
  218. break;
  219. }
  220. }
  221. }
  222. }
  223. else
  224. {
  225. fprintf ( fout,
  226. "Content-Type: text/plain; charset=US-ASCII\n"
  227. "Content-transfer-encoding: base64\n\n" );
  228. shift = 0;
  229. accum = 0;
  230. index = 0;
  231. while ( ( !feof( fin ) ) || (shift != 0) )
  232. {
  233. if ( ( !feof( fin ) ) && ( quit == 0 ) )
  234. {
  235. blivit = fgetc( fin );
  236. if ( feof( fin ) )
  237. {
  238. quit = 1;
  239. save_shift = shift;
  240. blivit = 0;
  241. }
  242. }
  243. else
  244. {
  245. quit = 1;
  246. save_shift = shift;
  247. blivit = 0;
  248. }
  249. if ( (quit == 0) || (shift != 0) )
  250. {
  251. value = (unsigned long)blivit;
  252. accum <<= 8;
  253. shift += 8;
  254. accum |= value;
  255. } /* ENDIF */
  256. while ( shift >= 6 )
  257. {
  258. shift -= 6;
  259. value = (accum >> shift) & 0x3Fl;
  260. blivit = alphabet[value];
  261. buf[index++] = blivit;
  262. if ( index >= 60 )
  263. {
  264. buf[index] = '\0';
  265. fprintf( fout, "%s\n", buf );
  266. index = 0;
  267. }
  268. if ( quit != 0 )
  269. {
  270. shift = 0;
  271. }
  272. }
  273. }
  274. if ( save_shift == 2 )
  275. {
  276. buf[index++] = '=';
  277. if ( index >= 60 )
  278. {
  279. buf[index] = '\0';
  280. fprintf( fout, "%s\n", buf );
  281. index = 0;
  282. }
  283. buf[index++] = '=';
  284. if ( index >= 60 )
  285. {
  286. buf[index] = '\0';
  287. fprintf( fout, "%s\n", buf );
  288. index = 0;
  289. }
  290. }
  291. else if ( save_shift == 4 )
  292. {
  293. buf[index++] = '=';
  294. if ( index >= 60 )
  295. {
  296. buf[index] = '\0';
  297. fprintf( fout, "%s\n", buf );
  298. index = 0;
  299. }
  300. }
  301. if ( index != 0 )
  302. {
  303. buf[index] = '\0';
  304. fprintf( fout, "%s\n", buf );
  305. }
  306. }
  307. fclose( fin );
  308. fclose( fout );
  309. if ( replace_flag )
  310. {
  311. if ( ( whattodo == DECODE ) && ( decode_state <= 0 ) )
  312. {
  313. remove( "$$$$$$$$.$$$" );
  314. printf( "No MIME base64 lines found in %s\n", fileargs[1] );
  315. }
  316. else
  317. {
  318. remove( fileargs[1] );
  319. rename( "$$$$$$$$.$$$", fileargs[1] );
  320. }
  321. }
  322. else
  323. {
  324. if ( ( whattodo == DECODE ) && ( decode_state <= 0 ) )
  325. {
  326. remove( fileargs[2] );
  327. printf( "No MIME base64 lines found in %s\n", fileargs[1] );
  328. }
  329. }
  330. }
  331. ------------------------------------------------------------------------------