Leaked source code of windows server 2003
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.

279 lines
8.1 KiB

  1. /*
  2. This file was derived from the libwww code, version 2.15, from CERN.
  3. A number of modifications have been made by Spyglass.
  4. eric@spyglass.com
  5. This file was removed from LibWWW and placed into the
  6. Security Protocol Module.
  7. jeff@spyglass.com
  8. */
  9. /* MODULE HTUU.c
  10. ** UUENCODE AND UUDECODE
  11. **
  12. ** ACKNOWLEDGEMENT:
  13. ** This code is taken from rpem distribution, and was originally
  14. ** written by Mark Riordan.
  15. **
  16. ** AUTHORS:
  17. ** MR Mark Riordan riordanmr@clvax1.cl.msu.edu
  18. ** AL Ari Luotonen luotonen@dxcern.cern.ch
  19. **
  20. ** HISTORY:
  21. ** Added as part of the WWW library and edited to conform
  22. ** with the WWW project coding standards by: AL 5 Aug 1993
  23. ** Originally written by: MR 12 Aug 1990
  24. ** Original header text:
  25. ** -------------------------------------------------------------
  26. ** File containing routines to convert a buffer
  27. ** of bytes to/from RFC 1113 printable encoding format.
  28. **
  29. ** This technique is similar to the familiar Unix uuencode
  30. ** format in that it maps 6 binary bits to one ASCII
  31. ** character (or more aptly, 3 binary bytes to 4 ASCII
  32. ** characters). However, RFC 1113 does not use the same
  33. ** mapping to printable characters as uuencode.
  34. **
  35. ** Mark Riordan 12 August 1990 and 17 Feb 1991.
  36. ** This code is hereby placed in the public domain.
  37. ** -------------------------------------------------------------
  38. **
  39. ** BUGS:
  40. **
  41. **
  42. */
  43. const static char six2pr[64] =
  44. {
  45. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
  46. 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
  47. 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
  48. 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
  49. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
  50. };
  51. static unsigned char pr2six[256];
  52. /*--- function HTUU_encode -----------------------------------------------
  53. *
  54. * Encode a single line of binary data to a standard format that
  55. * uses only printing ASCII characters (but takes up 33% more bytes).
  56. *
  57. * Entry bufin points to a buffer of bytes. If nbytes is not
  58. * a multiple of three, then the byte just beyond
  59. * the last byte in the buffer must be 0.
  60. * nbytes is the number of bytes in that buffer.
  61. * This cannot be more than 48.
  62. * bufcoded points to an output buffer. Be sure that this
  63. * can hold at least 1 + (4*nbytes)/3 characters.
  64. * outbufmax maximum size of the buffer bufcoded.
  65. *
  66. * Exit bufcoded contains the coded line. The first 4*nbytes/3 bytes
  67. * contain printing ASCII characters representing
  68. * those binary bytes. This may include one or
  69. * two '=' characters used as padding at the end.
  70. * The last byte is a zero byte.
  71. * Returns the number of ASCII characters in "bufcoded".
  72. */
  73. int HTUU_encode(unsigned char *bufin, unsigned int nbytes, char *bufcoded,
  74. long outbufmax)
  75. {
  76. /* ENC is the basic 1 character encoding function to make a char printing */
  77. #define ENC(c) six2pr[c]
  78. register char *outptr = bufcoded;
  79. unsigned int i;
  80. for (i = 0; i < nbytes; i += 3)
  81. {
  82. if ( (outptr - bufcoded + 4) > outbufmax )
  83. return (-1);
  84. *(outptr++) = ENC(*bufin >> 2); /* c1 */
  85. *(outptr++) = ENC(((*bufin << 4) & 060) | ((bufin[1] >> 4) & 017)); /*c2 */
  86. *(outptr++) = ENC(((bufin[1] << 2) & 074) | ((bufin[2] >> 6) & 03)); /*c3 */
  87. *(outptr++) = ENC(bufin[2] & 077); /* c4 */
  88. bufin += 3;
  89. }
  90. /* If nbytes was not a multiple of 3, then we have encoded too
  91. * many characters. Adjust appropriately.
  92. */
  93. if (i == nbytes + 1)
  94. {
  95. /* There were only 2 bytes in that last group */
  96. outptr[-1] = '=';
  97. }
  98. else if (i == nbytes + 2)
  99. {
  100. /* There was only 1 byte in that last group */
  101. outptr[-1] = '=';
  102. outptr[-2] = '=';
  103. }
  104. if ( (outptr - bufcoded) + 1 < outbufmax )
  105. *outptr = '\0';
  106. return ((int)(outptr - bufcoded));
  107. }
  108. /*--- function HTUU_decode ------------------------------------------------
  109. *
  110. * Decode an ASCII-encoded buffer back to its original binary form.
  111. *
  112. * Entry bufcoded points to a uuencoded string. It is
  113. * terminated by any character not in
  114. * the printable character table six2pr, but
  115. * leading whitespace is stripped.
  116. * bufplain points to the output buffer; must be big
  117. * enough to hold the decoded string (generally
  118. * shorter than the encoded string) plus
  119. * as many as two extra bytes used during
  120. * the decoding process.
  121. * outbufsize is the maximum number of bytes that
  122. * can fit in bufplain.
  123. *
  124. * Exit Returns the number of binary bytes decoded.
  125. * bufplain contains these bytes.
  126. */
  127. int HTUU_decode(char *bufcoded, unsigned char *bufplain, int outbufsize)
  128. {
  129. /* single character decode */
  130. #define DEC(c) pr2six[(int)c]
  131. #define MAXVAL 63
  132. static int first = 1;
  133. int nbytesdecoded, j;
  134. register char *bufin = bufcoded;
  135. register unsigned char *bufout = bufplain;
  136. register int nprbytes;
  137. /* If this is the first call, initialize the mapping table.
  138. * This code should work even on non-ASCII machines.
  139. */
  140. if (first)
  141. {
  142. first = 0;
  143. for (j = 0; j < 256; j++)
  144. pr2six[j] = MAXVAL + 1;
  145. for (j = 0; j < 64; j++)
  146. pr2six[(int) six2pr[j]] = (unsigned char) j;
  147. #if 0
  148. pr2six['A'] = 0;
  149. pr2six['B'] = 1;
  150. pr2six['C'] = 2;
  151. pr2six['D'] = 3;
  152. pr2six['E'] = 4;
  153. pr2six['F'] = 5;
  154. pr2six['G'] = 6;
  155. pr2six['H'] = 7;
  156. pr2six['I'] = 8;
  157. pr2six['J'] = 9;
  158. pr2six['K'] = 10;
  159. pr2six['L'] = 11;
  160. pr2six['M'] = 12;
  161. pr2six['N'] = 13;
  162. pr2six['O'] = 14;
  163. pr2six['P'] = 15;
  164. pr2six['Q'] = 16;
  165. pr2six['R'] = 17;
  166. pr2six['S'] = 18;
  167. pr2six['T'] = 19;
  168. pr2six['U'] = 20;
  169. pr2six['V'] = 21;
  170. pr2six['W'] = 22;
  171. pr2six['X'] = 23;
  172. pr2six['Y'] = 24;
  173. pr2six['Z'] = 25;
  174. pr2six['a'] = 26;
  175. pr2six['b'] = 27;
  176. pr2six['c'] = 28;
  177. pr2six['d'] = 29;
  178. pr2six['e'] = 30;
  179. pr2six['f'] = 31;
  180. pr2six['g'] = 32;
  181. pr2six['h'] = 33;
  182. pr2six['i'] = 34;
  183. pr2six['j'] = 35;
  184. pr2six['k'] = 36;
  185. pr2six['l'] = 37;
  186. pr2six['m'] = 38;
  187. pr2six['n'] = 39;
  188. pr2six['o'] = 40;
  189. pr2six['p'] = 41;
  190. pr2six['q'] = 42;
  191. pr2six['r'] = 43;
  192. pr2six['s'] = 44;
  193. pr2six['t'] = 45;
  194. pr2six['u'] = 46;
  195. pr2six['v'] = 47;
  196. pr2six['w'] = 48;
  197. pr2six['x'] = 49;
  198. pr2six['y'] = 50;
  199. pr2six['z'] = 51;
  200. pr2six['0'] = 52;
  201. pr2six['1'] = 53;
  202. pr2six['2'] = 54;
  203. pr2six['3'] = 55;
  204. pr2six['4'] = 56;
  205. pr2six['5'] = 57;
  206. pr2six['6'] = 58;
  207. pr2six['7'] = 59;
  208. pr2six['8'] = 60;
  209. pr2six['9'] = 61;
  210. pr2six['+'] = 62;
  211. pr2six['/'] = 63;
  212. #endif
  213. }
  214. /* Strip leading whitespace. */
  215. while (*bufcoded == ' ' || *bufcoded == '\t')
  216. bufcoded++;
  217. /* Figure out how many characters are in the input buffer.
  218. * If this would decode into more bytes than would fit into
  219. * the output buffer, adjust the number of input bytes downwards.
  220. */
  221. bufin = bufcoded;
  222. while (pr2six[(int) *(bufin++)] <= MAXVAL) ;
  223. nprbytes = (int)(bufin - bufcoded) - 1;
  224. nbytesdecoded = ((nprbytes + 3) / 4) * 3;
  225. if (nbytesdecoded > outbufsize)
  226. {
  227. nprbytes = (outbufsize * 4) / 3;
  228. }
  229. bufin = bufcoded;
  230. while (nprbytes > 0)
  231. {
  232. *(bufout++) = (unsigned char) (DEC(*bufin) << 2 | DEC(bufin[1]) >> 4);
  233. *(bufout++) = (unsigned char) (DEC(bufin[1]) << 4 | DEC(bufin[2]) >> 2);
  234. *(bufout++) = (unsigned char) (DEC(bufin[2]) << 6 | DEC(bufin[3]));
  235. bufin += 4;
  236. nprbytes -= 4;
  237. }
  238. if (nprbytes & 03)
  239. {
  240. if (pr2six[(int) bufin[-2]] > MAXVAL)
  241. {
  242. nbytesdecoded -= 2;
  243. }
  244. else
  245. {
  246. nbytesdecoded -= 1;
  247. }
  248. }
  249. return (nbytesdecoded);
  250. }