This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
deb-mbse/lib/mime.c

267 lines
7.1 KiB
C
Raw Normal View History

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.
*****************************************************************************/
#include "libs.h"
#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;
}