/***************************************************************************** * * File ..................: mime.c * Purpose ...............: Common library * Last modification date : 25-Aug-2000 * ***************************************************************************** * Copyright (C) 1997-2000 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 * 1971 BV IJmuiden * the Netherlands * * This file is part of MBSE BBS. * * This BBS is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * MBSE BBS is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MBSE BBS; see the file COPYING. If not, write to the Free * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. *****************************************************************************/ #include "../config.h" #include "libs.h" #include "memwatch.h" #include "structs.h" #include "clcomm.h" #include "common.h" /* QP-Decode code by T.Tanaka */ /* QP-Encode inspired from sendmail code of Berkley */ /* XD() converts hexadecimal digit to decimal */ #define XD(c) ( (((c) >= '0') && ((c) <= '9')) ? (c) - '0' : \ (((c) >= 'A') && ((c) <= 'F')) ? (c) - 'A' + 10 : \ (((c) >= 'a') && ((c) <= 'f')) ? (c) - 'a' + 10 : 0) /* chars to be converted in qp_encode() */ char badchars[] = "\001\002\003\004\005\006\007" \ "\010\011\012\013\014\015\016\017" \ "\020\021\022\023\024\025\026\027" \ "\030\031\032\033\034\035\036\037" \ "\177" \ "\200\201\202\203\204\205\206\207" \ "\210\211\212\213\214\215\216\217" \ "\220\221\222\223\224\225\226\227" \ "\230\231\232\233\234\235\236\237" \ "\240\241\242\243\244\245\246\247" \ "\250\251\252\253\254\255\256\257" \ "\260\261\262\263\264\265\266\267" \ "\270\271\272\273\274\275\276\277" \ "\300\301\302\303\304\305\306\307" \ "\310\311\312\313\314\315\316\317" \ "\320\321\322\323\324\325\326\327" \ "\330\331\332\333\334\335\336\337" \ "\340\341\342\343\344\345\346\347" \ "\350\351\352\353\354\355\356\357" \ "\360\361\362\363\364\365\366\367" \ "\370\371\372\373\374\375\376\377"; char badchars2[] = "!\"#$@[\\]^`{|}~()<>,;:/_"; char Base16Code[] = "0123456789ABCDEF"; char Base64Code[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /* returns numeric value from a Base64Code[] digit */ static int index_hex[128] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,0x3e, -1, -1, -1,0x3f, 0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b, 0x3c,0x3d, -1, -1, -1, -1, -1, -1, -1,0x00,0x01,0x02,0x03,0x04,0x05,0x06, 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16, 0x17,0x18,0x19, -1, -1, -1, -1, -1, -1,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20, 0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28, 0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30, 0x31,0x32,0x33, -1, -1, -1, -1, -1 }; char *qp_decode(char *s) { static char *buf; char *p, *q; if (buf) free(buf); if ((buf = malloc(strlen(s) + 1 * sizeof(char))) == NULL) { WriteError("qp_decode: out of memory:string too long:\"%s\"", s); return s; } for (p = s, q = buf; *p != '\0';) { if (*p == '=') { ++p; if (*p == '\0') { /* ends with "=(null)" */ *q++ = '='; break; } else if (*p == '\n') break; else if (isxdigit(*p) && isxdigit(*(p + 1))) { *q++ = 16 * XD(*p) + XD(*(p + 1)); ++p; ++p; } else { /* "=1x" "=5(null)" "=G\n" "=0=" etc. */ *q++ = '='; *q++ = *p++; } } else *q++ = *p++; } *q = '\0'; return buf; } char *qp_encode(char *s, int mode) { static char *buf; char *p, *q; int linelen = 0; if (buf) free(buf); if ((buf = malloc(3 * strlen(s) + 1 * sizeof(char))) == NULL) { WriteError("qp_encode: out of memory:string too long:\"%s\"", s); return s; } for (p = s, q = buf; *p != '\0';) { if (*p == '\n') { *q++ = *p++; linelen = 0; } else if ((mode == 1) && (*p == ' ')) { *q++ = '_'; p++; linelen += 1; } else if (*p == ' ' || *p == '\t') { if ((linelen > 72) && (*(p+1) != '\n')) { *q++ = *p++; *q++ = '='; *q++ = '\n'; linelen = 0; } else if (*(p+1) == '\n') { *q++ = *p++; *q++ = '='; *q++ = *p++; linelen = 0; } else { *q++ = *p++; linelen += 1; } } else if ((strchr(badchars,*p)) || (*p == '=') || ((mode==1) && (strchr(badchars2,*p)))) { if (linelen > 72) { *q++ = '\n'; linelen = 0; } *q++ = '='; *q++ = Base16Code[(*p >> 4) & 0x0f]; *q++ = Base16Code[*p & 0x0f]; linelen += 3; p++; } else { *q++ = *p++; linelen++; } } *q = '\0'; return buf; } /* * Base64 stores 3 bytes of 8bits into 4 bytes of six bits (the 2 remaining * bits are left to 0). * * AAAAAAAA BBBBBBBB CCCCCCCC --> 00AAAAAA 00AABBBB 00BBBBCC 00CCCCCC * */ char *b64_decode(char *s) { static char *buf; static char buf2[4]; char *p, *q; int i,t; if (buf) free(buf); if ((buf = malloc(3 * strlen(s) + 1 * sizeof(char))) == NULL) { WriteError("b64_decode:out of memory:string too long:\"%s\"", s); return s; } for (p = s, q = buf; *p != '\0';) { for (i = 0; i < 4; i++) buf2[i]=0x40; for (i = 0;((i < 4) && (*p != '\0'));) { t = (index_hex[(unsigned int)*p]); if (*p == '=') buf2[i++]=0x40; else if (t != -1) buf2[i++]=(char)t; p++; } if ((buf2[0] < 0x40) && (buf2[1] < 0x40)) *q++=(((buf2[0] & 0x3f) << 2) | ((buf2[1] >> 4) & 0x03)); if ((buf2[1] < 0x40) && (buf2[2] < 0x40)) *q++=(((buf2[1] & 0x0f) << 4) | ((buf2[2] >> 2) & 0x0f)); if ((buf2[2] < 0x40) && (buf2[3] < 0x40)) *q++=(((buf2[2] & 0x03) << 6) | (buf2[3] & 0x3f)); } *q = '\0'; return buf; } char *b64_encode(char *s) { static char *buf; static char buf2[3]; char *p, *q; int i; if (buf) free(buf); if ((buf = malloc(3 * strlen(s) + 1 * sizeof(char))) == NULL) { WriteError("b64_encode:out of memory:string too long:\"%s\"", s); return s; } for (p = s, q = buf; *p != '\0';) { for (i = 0; ((i < 3) && (*p != '\0')); ) buf2[i++] = *p++; *q++=Base64Code[((buf2[0] >> 2) & 0x3f)]; *q++=Base64Code[(((buf2[0] & 0x03) << 4) | ((buf2[1] >> 4) & 0x0f))]; if (i<2) *q++='='; else *q++=Base64Code[(((buf2[1] & 0x0f) << 2) | ((buf2[2] >> 6) & 0x03))]; if (i<3) *q++='='; else *q++=Base64Code[(buf2[2] & 0x3f)]; } *q = '\0'; return buf; }