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

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.         
  42.       for(s=str;*s != ''; s++) {
  43.           if(!isalnum(*s) &&!ispunct(*s)&&!isspace(*s)) 
  44.              return 1;
  45.       }
  46.       return 0;
  47. }
  48. /* ----------------------------------------------------- */
  49. /* judge & decode QP / BASE64                            */
  50. /* ----------------------------------------------------- */
  51. void
  52. str_decode(dst, src)
  53.   register unsigned char *dst, *src;
  54. {
  55.   register int is_qp, is_base64, is_done;
  56.   register int c1, c2, c3, c4;
  57.   if(ignorestr(src))
  58.   {
  59.      strcpy(dst,src);
  60.      return;
  61.   }
  62.   for (is_done = is_qp = is_base64 = 0; c1 = *src; src++)
  63.   {
  64.     if (c1 == '?' && src[1] == '=')
  65.     {
  66.       src++;
  67.       continue;
  68.     }
  69.     else if (c1 == 'n')        /* chuan: multi line encoding */
  70.     {
  71.       src++;
  72.       is_done = is_qp = is_base64 = 0;
  73.       continue;
  74.     }
  75.     else if (is_qp && c1 == '=')
  76.     {
  77.       c1 = *++src;
  78.       c2 = *++src;
  79.       *dst++ = (qp_code(c1) << 4) | qp_code(c2);
  80.     }
  81.     else if (is_base64 && !is_done)
  82.     {
  83.       while (isspace(c1))
  84.       {
  85.         c1 = *++src;
  86.       }
  87.       if (!c1)
  88.         break;
  89.       do
  90.       {
  91.         c2 = *++src;
  92.       } while (isspace(c2));
  93.       if (!c2)
  94.         break;
  95.       do
  96.       {
  97.         c3 = *++src;
  98.       } while (isspace(c3));
  99.       if (!c3)
  100.         break;
  101.       do
  102.       {
  103.         c4 = *++src;
  104.       } while (isspace(c4));
  105.       if (!c4)
  106.         break;
  107.       if (c1 == '=' || c2 == '=')
  108.       {
  109.         is_done = 1;
  110.         continue;
  111.       }
  112.       c2 = base64_code(c2);
  113.       *dst++ = (base64_code(c1) << 2) | ((c2 & 0x30) >> 4);
  114.       if (c3 == '=')
  115.         is_done = 1;
  116.       else
  117.       {
  118.         c3 = base64_code(c3);
  119.         *dst++ = ((c2 & 0xF) << 4) | ((c3 & 0x3c) >> 2);
  120.         if (c4 == '=')
  121.           is_done = 1;
  122.         else
  123.         {
  124.           *dst++ = ((c3 & 0x03) << 6) | base64_code(c4);
  125.         }
  126.       }
  127.     }
  128.     else if ((c1 == '=') && (src[1] == '?'))
  129.     {
  130.       /* c2 : qmarks, c3 : code_kind */
  131.       c2 = c3 = 0;
  132.       for (;;)
  133.       {
  134.         c1 = *++src;
  135.         if (c1 != '?')
  136.         {
  137.           if (c2 == 2)
  138.             c3 = c1 | 0x20;
  139.         }
  140.         else
  141.         {
  142.           if (++c2 >= 3)
  143.             break;
  144.         }
  145.       }
  146.       if (c3 == 'q')
  147.         is_qp = 1;
  148.       else if (c3 == 'b')
  149.         is_base64 = 1;
  150.     }
  151.     else
  152.       *dst++ = c1;
  153.   }
  154.   *dst = '';
  155. }