2001-08-17 05:46:24 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2002-06-30 12:48:44 +00:00
|
|
|
#include "../config.h"
|
2001-08-17 05:46:24 +00:00
|
|
|
#include "libs.h"
|
2002-06-30 12:48:44 +00:00
|
|
|
#include "memwatch.h"
|
2001-08-17 05:46:24 +00:00
|
|
|
#include "structs.h"
|
|
|
|
#include "clcomm.h"
|
|
|
|
#include "common.h"
|
|
|
|
|
|
|
|
|
|
|
|
/* QP-Decode code by T.Tanaka <tt@efnet.com> */
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|