qp_conv.c
上传用户:minyiyu
上传日期:2018-12-24
资源大小:864k
文件大小:4k
源码类别:

Telnet服务器

开发平台:

Unix_Linux

  1. /* ----------------------------------------------------- */
  2. /* QP code : "0123456789ABCDEF"                          */
  3. /* ----------------------------------------------------- */
  4. static int
  5. qp_code(x)
  6. register int x;
  7. {
  8. if (x >= '0' && x <= '9')
  9. return x - '0';
  10. if (x >= 'a' && x <= 'f')
  11. return x - 'a' + 10;
  12. if (x >= 'A' && x <= 'F')
  13. return x - 'A' + 10;
  14. return -1;
  15. }
  16. /* ------------------------------------------------------------------ */
  17. /* BASE64 :                                                           */
  18. /* "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" */
  19. /* ------------------------------------------------------------------ */
  20. static int
  21. base64_code(x)
  22. register int x;
  23. {
  24. if (x >= 'A' && x <= 'Z')
  25. return x - 'A';
  26. if (x >= 'a' && x <= 'z')
  27. return x - 'a' + 26;
  28. if (x >= '0' && x <= '9')
  29. return x - '0' + 52;
  30. if (x == '+')
  31. return 62;
  32. if (x == '/')
  33. return 63;
  34. return -1;
  35. }
  36. int
  37. ignorestr(str)
  38. char   *str;
  39. {
  40. char   *s;
  41. for (s = str; *s != ''; s++) {
  42. if (!isalnum(*s) && !ispunct(*s) && !isspace(*s))
  43. return 1;
  44. }
  45. return 0;
  46. }
  47. /* ----------------------------------------------------- */
  48. /* judge & decode QP / BASE64                            */
  49. /* ----------------------------------------------------- */
  50. void
  51. str_decode(dst, src)
  52. register unsigned char *dst, *src;
  53. {
  54. register int is_qp, is_base64, is_done;
  55. register int c1, c2, c3, c4;
  56. char   *dsttmp;
  57. char   *srctmp;
  58. char    srcbuf[256];
  59. int     pos;
  60. if (ignorestr(src)) {
  61. strcpy(dst, src);
  62. return;
  63. }
  64. memcpy(srcbuf, src, 256);
  65. dsttmp = dst;
  66. srctmp = src;
  67. pos = (int) src - (int) srctmp;
  68. for (is_done = is_qp = is_base64 = 0; c1 = *src; src++) {
  69. pos = (int) src - (int) srctmp;
  70. if (pos > 254) {
  71. memcpy(dsttmp, srcbuf, 256);
  72. return;
  73. }
  74. if (c1 == '?' && src[1] == '=') {
  75. src++;
  76. continue;
  77. } else if (c1 == 'n') { /* chuan: multi line encoding */
  78. src++;
  79. is_done = is_qp = is_base64 = 0;
  80. continue;
  81. } else if (is_qp && c1 == '=') {
  82. pos = (int) src - (int) srctmp;
  83. if (pos > 254) {
  84. memcpy(dsttmp, srcbuf, 256);
  85. return;
  86. }
  87. c1 = *++src;
  88. pos = (int) src - (int) srctmp;
  89. if (pos > 254) {
  90. memcpy(dsttmp, srcbuf, 256);
  91. return;
  92. }
  93. c2 = *++src;
  94. *dst++ = (qp_code(c1) << 4) | qp_code(c2);
  95. } else if (is_base64 && !is_done) {
  96. while (isspace(c1)) {
  97. pos = (int) src - (int) srctmp;
  98. if (pos > 254) {
  99. memcpy(dsttmp, srcbuf, 256);
  100. return;
  101. }
  102. c1 = *++src;
  103. }
  104. if (!c1)
  105. break;
  106. do {
  107. pos = (int) src - (int) srctmp;
  108. if (pos > 254) {
  109. memcpy(dsttmp, srcbuf, 256);
  110. return;
  111. }
  112. c2 = *++src;
  113. } while (isspace(c2));
  114. if (!c2)
  115. break;
  116. do {
  117. pos = (int) src - (int) srctmp;
  118. if (pos > 254) {
  119. memcpy(dsttmp, srcbuf, 256);
  120. return;
  121. }
  122. c3 = *++src;
  123. } while (isspace(c3));
  124. if (!c3)
  125. break;
  126. do {
  127. pos = (int) src - (int) srctmp;
  128. if (pos > 254) {
  129. memcpy(dsttmp, srcbuf, 256);
  130. return;
  131. }
  132. c4 = *++src;
  133. } while (isspace(c4));
  134. if (!c4)
  135. break;
  136. if (c1 == '=' || c2 == '=') {
  137. is_done = 1;
  138. continue;
  139. }
  140. c2 = base64_code(c2);
  141. *dst++ = (base64_code(c1) << 2) | ((c2 & 0x30) >> 4);
  142. if (c3 == '=')
  143. is_done = 1;
  144. else {
  145. c3 = base64_code(c3);
  146. *dst++ = ((c2 & 0xF) << 4) | ((c3 & 0x3c) >> 2);
  147. if (c4 == '=')
  148. is_done = 1;
  149. else {
  150. *dst++ = ((c3 & 0x03) << 6) | base64_code(c4);
  151. }
  152. }
  153. } else if ((c1 == '=') && (src[1] == '?')) {
  154. /* c2 : qmarks, c3 : code_kind */
  155. c2 = c3 = 0;
  156. for (;;) {
  157. pos = (int) src - (int) srctmp;
  158. if (pos > 254) {
  159. memcpy(dsttmp, srcbuf, 256);
  160. return;
  161. }
  162. c1 = *++src;
  163. if (c1 != '?') {
  164. if (c2 == 2)
  165. c3 = c1 | 0x20;
  166. } else {
  167. if (++c2 >= 3)
  168. break;
  169. }
  170. }
  171. if (c3 == 'q')
  172. is_qp = 1;
  173. else if (c3 == 'b')
  174. is_base64 = 1;
  175. } else
  176. *dst++ = c1;
  177. }
  178. *dst = '';
  179. }