qp_conv.c
上传用户:minyiyu
上传日期:2018-12-24
资源大小:864k
文件大小:4k
- /* ----------------------------------------------------- */
- /* QP code : "0123456789ABCDEF" */
- /* ----------------------------------------------------- */
- static int
- qp_code(x)
- register int x;
- {
- if (x >= '0' && x <= '9')
- return x - '0';
- if (x >= 'a' && x <= 'f')
- return x - 'a' + 10;
- if (x >= 'A' && x <= 'F')
- return x - 'A' + 10;
- return -1;
- }
- /* ------------------------------------------------------------------ */
- /* BASE64 : */
- /* "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" */
- /* ------------------------------------------------------------------ */
- static int
- base64_code(x)
- register int x;
- {
- if (x >= 'A' && x <= 'Z')
- return x - 'A';
- if (x >= 'a' && x <= 'z')
- return x - 'a' + 26;
- if (x >= '0' && x <= '9')
- return x - '0' + 52;
- if (x == '+')
- return 62;
- if (x == '/')
- return 63;
- return -1;
- }
- int
- ignorestr(str)
- char *str;
- {
- char *s;
- for (s = str; *s != ' '; s++) {
- if (!isalnum(*s) && !ispunct(*s) && !isspace(*s))
- return 1;
- }
- return 0;
- }
- /* ----------------------------------------------------- */
- /* judge & decode QP / BASE64 */
- /* ----------------------------------------------------- */
- void
- str_decode(dst, src)
- register unsigned char *dst, *src;
- {
- register int is_qp, is_base64, is_done;
- register int c1, c2, c3, c4;
- char *dsttmp;
- char *srctmp;
- char srcbuf[256];
- int pos;
- if (ignorestr(src)) {
- strcpy(dst, src);
- return;
- }
- memcpy(srcbuf, src, 256);
- dsttmp = dst;
- srctmp = src;
- pos = (int) src - (int) srctmp;
- for (is_done = is_qp = is_base64 = 0; c1 = *src; src++) {
- pos = (int) src - (int) srctmp;
- if (pos > 254) {
- memcpy(dsttmp, srcbuf, 256);
- return;
- }
- if (c1 == '?' && src[1] == '=') {
- src++;
- continue;
- } else if (c1 == 'n') { /* chuan: multi line encoding */
- src++;
- is_done = is_qp = is_base64 = 0;
- continue;
- } else if (is_qp && c1 == '=') {
- pos = (int) src - (int) srctmp;
- if (pos > 254) {
- memcpy(dsttmp, srcbuf, 256);
- return;
- }
- c1 = *++src;
- pos = (int) src - (int) srctmp;
- if (pos > 254) {
- memcpy(dsttmp, srcbuf, 256);
- return;
- }
- c2 = *++src;
- *dst++ = (qp_code(c1) << 4) | qp_code(c2);
- } else if (is_base64 && !is_done) {
- while (isspace(c1)) {
- pos = (int) src - (int) srctmp;
- if (pos > 254) {
- memcpy(dsttmp, srcbuf, 256);
- return;
- }
- c1 = *++src;
- }
- if (!c1)
- break;
- do {
- pos = (int) src - (int) srctmp;
- if (pos > 254) {
- memcpy(dsttmp, srcbuf, 256);
- return;
- }
- c2 = *++src;
- } while (isspace(c2));
- if (!c2)
- break;
- do {
- pos = (int) src - (int) srctmp;
- if (pos > 254) {
- memcpy(dsttmp, srcbuf, 256);
- return;
- }
- c3 = *++src;
- } while (isspace(c3));
- if (!c3)
- break;
- do {
- pos = (int) src - (int) srctmp;
- if (pos > 254) {
- memcpy(dsttmp, srcbuf, 256);
- return;
- }
- c4 = *++src;
- } while (isspace(c4));
- if (!c4)
- break;
- if (c1 == '=' || c2 == '=') {
- is_done = 1;
- continue;
- }
- c2 = base64_code(c2);
- *dst++ = (base64_code(c1) << 2) | ((c2 & 0x30) >> 4);
- if (c3 == '=')
- is_done = 1;
- else {
- c3 = base64_code(c3);
- *dst++ = ((c2 & 0xF) << 4) | ((c3 & 0x3c) >> 2);
- if (c4 == '=')
- is_done = 1;
- else {
- *dst++ = ((c3 & 0x03) << 6) | base64_code(c4);
- }
- }
- } else if ((c1 == '=') && (src[1] == '?')) {
- /* c2 : qmarks, c3 : code_kind */
- c2 = c3 = 0;
- for (;;) {
- pos = (int) src - (int) srctmp;
- if (pos > 254) {
- memcpy(dsttmp, srcbuf, 256);
- return;
- }
- c1 = *++src;
- if (c1 != '?') {
- if (c2 == 2)
- c3 = c1 | 0x20;
- } else {
- if (++c2 >= 3)
- break;
- }
- }
- if (c3 == 'q')
- is_qp = 1;
- else if (c3 == 'b')
- is_base64 = 1;
- } else
- *dst++ = c1;
- }
- *dst = ' ';
- }