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

Telnet服务器

开发平台:

Unix_Linux

  1. /* 
  2.  * mmdecode.c -- a tool for decoding QP/BASE64 string
  3.  * deliver from Maple 3
  4.  * 
  5.  * of SEEDNetBBS generation 1 (libBBS implement)
  6.  *
  7.  * Copyright (c) 1998, 1999, Edward Ping-Da Chuang <edwardc@edwardc.dhs.org>
  8.  * All rights reserved.
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions
  12.  * are met:
  13.  * 1. Redistributions of source code must retain the above copyright
  14.  *    notice, this list of conditions and the following disclaimer.
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in the
  17.  *    documentation and/or other materials provided with the distribution.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  20.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  23.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29.  * SUCH DAMAGE.
  30.  *
  31.  * CVS: $Id: mmdecode.c,v 1.1 2000/01/15 01:45:26 edwardc Exp $
  32.  */
  33.  
  34. /*-------------------------------------------------------*/
  35. /* lib/str_decode.c ( NTHU CS MapleBBS Ver 3.00 )      */
  36. /*-------------------------------------------------------*/
  37. /* target : included C for QP/BASE64 decoding      */
  38. /* create : 95/03/29                    */
  39. /* update : 97/03/29                    */
  40. /*-------------------------------------------------------*/
  41. /* ----------------------------------------------------- */
  42. /* QP code : "0123456789ABCDEF"              */
  43. /* ----------------------------------------------------- */
  44. static int
  45. qp_code(x)
  46.   register int x;
  47. {
  48.   if (x >= '0' && x <= '9')
  49.     return x - '0';
  50.   if (x >= 'a' && x <= 'f')
  51.     return x - 'a' + 10;
  52.   if (x >= 'A' && x <= 'F')
  53.     return x - 'A' + 10;
  54.   return -1;
  55. }
  56. /* ------------------------------------------------------------------ */
  57. /* BASE64 :       */
  58. /* "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" */
  59. /* ------------------------------------------------------------------ */
  60. static int
  61. base64_code(x)
  62.   register int x;
  63. {
  64.   if (x >= 'A' && x <= 'Z')
  65.     return x - 'A';
  66.   if (x >= 'a' && x <= 'z')
  67.     return x - 'a' + 26;
  68.   if (x >= '0' && x <= '9')
  69.     return x - '0' + 52;
  70.   if (x == '+')
  71.     return 62;
  72.   if (x == '/')
  73.     return 63;
  74.   return -1;
  75. }
  76. /* ----------------------------------------------------- */
  77. /* judge & decode QP / BASE64  */
  78. /* ----------------------------------------------------- */
  79. void
  80. _mmdecode(str)
  81.   unsigned char *str;
  82. {
  83.   int code, c1, c2, c3, c4;
  84.   unsigned char *src, *dst;
  85.   unsigned char buf[256];
  86. #define IS_QP 0x01
  87. #define IS_BASE64 0x02
  88. #define IS_TRAN 0x04
  89.   src = str;
  90.   dst = buf;
  91.   code = 0;
  92.   while (c1 = *src++)
  93.   {
  94.     if (c1 == '?' && *src == '=')
  95.     {
  96.       if (code)
  97.       {
  98. code &= IS_TRAN;
  99. if (*++src == ' ')
  100.   src++;
  101.       }
  102.       continue;
  103.     }
  104.     if (c1 == 'n') /* chuan: multi line encoding */
  105.       goto line;
  106.     if (code & (IS_QP | IS_BASE64))
  107.     {
  108.       if (c1 == '_')
  109.       {
  110. *dst++ = ' ';
  111. continue;
  112.       }
  113.       if ((c1 == '=') && (code & IS_QP))
  114.       {
  115. if (!(c1 = *src))
  116.   break;
  117. if (!(c2 = *++src))
  118.   break;
  119. src++;
  120. *dst++ = (qp_code(c1) << 4) | qp_code(c2);
  121. code |= IS_TRAN;
  122. continue;
  123.       }
  124.       if (code & IS_BASE64)
  125.       {
  126. c2 = *src++;
  127. if (c1 == '=' || c2 == '=')
  128. {
  129.   code ^= IS_BASE64;
  130.   continue;
  131. }
  132. if (!(c3 = *src++))
  133.   break;
  134. if (!(c4 = *src++))
  135.   break;
  136. c2 = base64_code(c2);
  137. *dst++ = (base64_code(c1) << 2) | ((c2 & 0x30) >> 4);
  138. if (c3 == '=')
  139. {
  140.   code ^= IS_BASE64;
  141. }
  142. else
  143. {
  144.   c3 = base64_code(c3);
  145.   *dst++ = ((c2 & 0xF) << 4) | ((c3 & 0x3c) >> 2);
  146.   if (c4 == '=')
  147.     code ^= IS_BASE64;
  148.   else
  149.     *dst++ = ((c3 & 0x03) << 6) | base64_code(c4);
  150. }
  151. code |= IS_TRAN;
  152. continue;
  153.       }
  154.     }
  155.     /* "=?%s?Q?" for QP, "=?%s?B?" for BASE64 */
  156.     if ((c1 == '=') && (*src == '?'))
  157.     {
  158.       c2 = 0;
  159.       for (;;)
  160.       {
  161. c1 = *++src;
  162. if (!c1)
  163.   goto home;
  164. if (c1 == '?')
  165. {
  166.   if (++c2 >= 2)
  167.     break;
  168.   continue;
  169. }
  170. if (c2 == 1)
  171. {
  172.   if (c1 == 'Q')
  173.     code = IS_QP;
  174.   else if (c1 == 'B')
  175.     code = IS_BASE64;
  176. }
  177.       }
  178.       src++;
  179.       continue;
  180.     }
  181.     *dst++ = c1;
  182.   }
  183. home:
  184.   if (code & IS_TRAN)
  185.   {
  186. line:
  187.     *dst = '';
  188.     strcpy(str, buf);
  189.   }
  190. }