home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
PROG_C
/
EUROSET.ZIP
/
FOLD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-27
|
12KB
|
374 lines
/* fold.c 1994 jan 03 [gh]
+-----------------------------------------------------------------------------
| Abstract:
| Fold character sets.
|
| Authorship:
| Copyright (c) 1994 Gisle Hannemyr.
| Permission is granted to hack, make and distribute copies of this program
| as long as this copyright notice is not removed.
| Flames, bug reports, comments and improvements to:
| snail: Gisle Hannemyr, Brageveien 3A, 0452 Oslo, Norway
| email: X400: gisle.hannemyr@nr.no
| Inet: gisle@ifi.uio.no, gisle@oslonett.no
| UUCP: ...!mcsun!ifi!gisle
|
| Usage:
| The following 5 character sets are enumerated in fold.h:
| ISO646IRV -- ISO 646 International Reference version (ISO-IR-2)
| ISO646N -- ISO 646 Norwegian/Danish version (ISO-IR-60)
| ISOL1 -- ISO 8859/1 (ISO Latin 1).
| CP850 -- IBM codepage 850
| MAC -- Apple MacIntosh default character set.
| To set up a particular conversion, first call the function initfold
| with your input character set and output character set.
|
| Example: to set up the module to convert from IBM CP 850 to Macintosh,
|
| initfold(CP850, MAC);
|
| then, too actually fold, the following two functions are provided:
|
| To fold one charcter:
|
| unsigned int foldchar(cc)
|
| To fold all the character in a text buffer terminated by '\0':
|
| void foldbuffer(buf)
|
|
| History:
| 1.0 94 jan 03 [gh] Wrote it.
+---------------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "fold.h"
/*---( defines )------------------------------------------------------------*/
#define INTEROR -3 /* Indices into table doing the actual concersion. */
#define NS72ISO -2 /* The negative values denote special semantics. */
#define NOTHING -1 /* All conversions is either to or from Latin 1. */
#define ISO2AS7 0
#define ISO2NS7 1
#define ISO2IBM 2
#define IBM2ISO 3
#define ISO2MAC 4
#define MAC2ISO 5
#define NOTIMPL 0
#define UNCODED 1
#define ENCODED 2
static int Encoding = UNCODED;
static int Charset = ISOL1;
/*---( constants )----------------------------------------------------------*/
static int ITab, OTab;
static unsigned char FoldTables[6][128] = {
{ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* ISO2AS7 */
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* ISO 646 IRV */
32, 33, 63, 76, 36, 89,124, 63, 34, 99, 97, 34,126, 45,114, 45,
42, 63, 50, 51, 39,117, 63, 42, 44, 49,111, 34, 63, 63, 63, 63,
65, 65, 65, 65, 65, 65, 65, 67, 69, 69, 69, 69, 73, 73, 73, 73,
68, 78, 79, 79, 79, 79, 79,120, 79, 85, 85, 85, 85, 89, 63, 63,
97, 97, 97, 97, 97, 97, 97, 99,101,101,101,101,105,105,105,105,
100,110,111,111,111,111,111, 47,111,117,117,117,117,121, 63,121},
{ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* ISO2NS7 */
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* ISO 646 Norsk */
32, 33, 63, 76, 36, 89,124, 63, 34, 99, 97, 34,126, 45,114, 45,
42, 63, 50, 51, 39,117, 63, 42, 44, 49,111, 34, 63, 63, 63, 63,
65, 65, 65, 65, 91, 93, 91, 67, 69, 69, 69, 69, 73, 73, 73, 73,
68, 78, 79, 79, 79, 79, 92,120, 92, 85, 85, 85, 85, 89, 63, 63,
97, 97, 97, 97,123,125,123, 99,101,101,101,101,105,105,105,105,
100,110,111,111,111,111,124, 47,124,117,117,117,117,121, 63,121},
{ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* ISO2IBM */
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* CP850 */
32,173,189,156,207,190,221,245,249,184,166,174,170, 45,169,238,
248,241,253,252,239,230,244,250, 44,251,167,175,172,171,243,168,
183,181,182,199,142,143,146,128,212,144,210,211,222,214,215,216,
209,165,227,224,226,229,153,158,157,235,233,234,154,237,232,225,
133,160,131,198,132,134,145,135,138,130,136,137,141,161,140,139,
208,164,149,162,147,228,148,246,155,151,163,150,129,236,231,152},
{199,252,233,226,228,224,229,231,234,235,232,239,238,236,196,197, /* IBM2ISO */
201,230,198,244,246,242,251,249,255,214,220,248,163,216,215,102, /* CP850 */
225,237,243,250,241,209,170,186,191,174,172,189,188,161,171,187,
35, 35, 35,124, 43,193,194,192,169, 43,124, 43, 43,162,165, 43,
43, 43, 43, 43, 45, 43,227,195, 43, 43, 43, 43, 43, 45, 43,164,
240,208,202,203,200,105,205,206,207, 43, 43, 35, 45,166,204, 45,
211,223,212,210,245,213,181,254,222,218,219,217,253,221,175,180,
45,177, 61,190,182,167,247, 45,176,168,183,185,179,178,183, 32},
{ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* ISO2MAC */
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
202,193,162,163,192,180,124,164,172,169,187,199,194, 45,168, 45,
161,177, 50, 51,171,181,166,165, 44, 49,188,200,192,192,192,192,
203, 65, 65,204,128,129,174,130, 69,131, 69, 69, 73, 73, 73, 73,
68,132, 79, 79, 79,205,133,120,175, 85, 85, 85,134, 89,192,167,
136,135,137,139,138,140,190,141,143,142,144,145,147,146,148,149,
182,150,152,151,153,155,154,214,191,157,156,158,159,121,192,216},
{196,197,199,201,209,214,220,225,224,226,228,227,229,231,233,232, /* MAC2ISO */
234,235,237,236,238,239,241,243,242,244,246,245,250,249,251,252,
191,176,162,163,167,183,182,223,174,169,191,180,168,191,198,216,
191,177,191,191,165,181,240,191,191,191,191,170,186,191,230,248,
191,161,172,191,191,191,191,171,187,191,160,192,195,213,191,191,
45, 45, 34, 34, 39, 39,247,191,255,191,191,191,191,191,191,191,
191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191}
}; /* FoldTables */
/*---( init )---------------------------------------------------------------*/
/*
| Abs: Explicitly initialize both input an output tables.
| Sef: Selects input and output table (ITab & OTab).
| Ret: TRUE if OK, else FALSE.
*/
int initfold(iset, oset)
int iset, oset;
{
if (iset == oset) { /* Don't fold */
ITab = OTab = NOTHING;
return(1);
} /* if (equal) */
switch (iset) {
case ISO646IRV : ITab = NOTHING; break;
case ISO646N : ITab = NS72ISO; break;
case ISOL1 : ITab = NOTHING; break;
case CP850 : ITab = IBM2ISO; break;
case MAC : ITab = MAC2ISO; break;
default : ITab = INTEROR;
} /* switch */
switch (oset) {
case ISO646IRV : OTab = ISO2AS7; break;
case ISO646N : OTab = ISO2NS7; break;
case ISOL1 : OTab = NOTHING; break;
case CP850 : OTab = ISO2IBM; break;
case MAC : OTab = ISO2MAC; break;
default : OTab = INTEROR; break;
} /* switch */
if ((ITab == INTEROR) || (OTab == INTEROR)) return(0);
else return(1);
} /* initfold */
/*
| Abs: Initialize output table (we'll get input from headers.
| Des: When importing messages, this only depends upon what your system
| considers default character encoding.
| Sef: Selects output table ( & OTab).
| Ret: TRUE if OK, else FALSE.
*/
int initout(oset)
int oset;
{
switch (oset) {
case ISO646IRV : OTab = ISO2AS7; break;
case ISO646N : OTab = ISO2NS7; break;
case ISOL1 : OTab = NOTHING; break;
case CP850 : OTab = ISO2IBM; break;
case MAC : OTab = ISO2MAC; break;
default : OTab = INTEROR; break;
} /* switch */
if (OTab == INTEROR) return(0);
else return(1);
} /* initout */
/*
| Abs: Explicitly initialize input table by parsing headers.
| Des: Assumes output table already known.
| Sef: Selects input table (ITab).
| Ret: TRUE if OK, else FALSE.
*/
int inithead(head)
unsigned char *head;
{
int wasnl;
unsigned char hline[512];
unsigned char *ss, *dd;
if (!head) return(0);
ss = head;;
Encoding = UNCODED;
wasnl = 1;
while (*ss) {
if (wasnl) {
if ((*ss == 'c') || (*ss == 'C')) {
dd = hline;
while (*ss && (*ss != '\n')) {
if (*ss != '"') *dd++ = tolower(*ss);
ss++;
}
ss++;
*dd = '\0';
printf("[%s]", hline);
if (!strncmp(hline, "content-transfer-encoding:", 26)) {
dd = hline+26;
while (isspace(*dd)) dd++;
if (!strncmp(dd, "quoted-printable", 16)) Encoding = ENCODED;
else if ((*dd == '7') || (*dd == '8')) Encoding = UNCODED;
else Encoding = NOTIMPL;
fputs(dd, stdout);
fputc('\n', stdout);
} else if (!strncmp(hline, "content-type:", 13)) {
if (dd = (unsigned char *)strstr(hline, "charset=")) {
dd += 8;
if (!strncmp(dd, "us-ascii", 8)) Charset = ISO646IRV;
else if (!strncmp(dd, "iso-8859-1", 10)) Charset = ISO646IRV;
else if (!strncmp(dd, "x-iso-ir-60",11)) Charset = ISO646N;
else Charset = CSETNONE;
fputs(dd, stdout);
fputc('\n', stdout);
}
} else fputs("huh?\n", stdout);
} else {
if (*ss != '\r') wasnl = 0;
ss++;
}
} else {
if (*ss == '\n') wasnl = 1;
else if (*ss != '\r') wasnl = 0;
ss++;
}
} /* while */
printf(">>> CharSet: %2d, Encoding: %2d\n", Charset, Encoding);
switch (Charset) {
case ISO646IRV : ITab = NOTHING; break;
case ISO646N : ITab = NS72ISO; break;
case ISOL1 : ITab = NOTHING; break;
case CP850 : ITab = IBM2ISO; break;
case MAC : ITab = MAC2ISO; break;
default : ITab = INTEROR;
} /* switch */
printf(">>> IP: %2d OP: %2d\n", ITab, OTab);
if (ITab == OTab) { /* Don't fold */
ITab = OTab = NOTHING;
return(1);
} /* if (equal) */
if ((ITab == INTEROR) || (OTab == INTEROR)) return(0);
else return(1);
} /* inithead */
/*---( fold )---------------------------------------------------------------*/
/*
| Abs: Fold one charcter.
*/
unsigned int foldchar(cc)
unsigned int cc;
{
if (ITab == -2) {
if (((cc >= 91) && (cc <= 93)) || ((cc >= 123) && (cc <= 125))) {
if ( 91 == cc) cc = 198;
else if ( 92 == cc) cc = 216;
else if ( 93 == cc) cc = 195;
else if (123 == cc) cc = 230;
else if (124 == cc) cc = 248;
else if (125 == cc) cc = 229;
} /* if (Norwegian/Danish) */
} else
if ((cc >= 128) && (ITab >= 0)) cc = FoldTables[ITab][cc - 128];
if ((cc >= 128) && (OTab >= 0)) cc = FoldTables[OTab][cc - 128];
return(cc);
} /* foldchar */
/*
| Abs: Fold all the character in a text buffer terminated by '\0'.
*/
void foldbuffer(buf)
unsigned char *buf;
{
int ii;
if (!buf) return;
ii = 0;
while (buf[ii]) {
buf[ii] = foldchar(buf[ii]);
ii++;
} /* while */
} /* foldbuffer */
/*---( mime )---------------------------------------------------------------*/
/*
| Abs: Remove MIME codes in buffer
| Des: The ceasar rotate is based upon gnus implementation, and do a ROT13
| for A-Z, a-z, and a ROT47 for the 94 characters between 161 and 254
| (inclusive).
*/
void unmimebuffer(buf)
unsigned char *buf;
{
int cc;
unsigned char *ss, *dd;
if (!buf) return;
if (Encoding != ENCODED) return;;
dd = ss = buf;
while (*ss) {
if (*ss == '=') {
ss++;
if (!*ss) break;
if ('\n' == *ss) { ss++; continue; }
cc = isdigit(*ss) ? (*ss - '0') : (*ss - 55);
cc *= 0x10;
ss++;
cc += isdigit(*ss) ? (*ss - '0') : (*ss - 55);
*dd = cc;
} else *dd = *ss;
dd++; ss++;
} /* while */
*dd = '\0';
} /* unmimebuffer */
/*---( split )--------------------------------------------------------------*/
/*
| Abs: Separate headers from the message.
| Ret: Pointer to the start of the message body.
*/
unsigned char *splitbody(buf)
unsigned char *buf;
{
int wasnl;
unsigned char *ss;
ss = buf;
wasnl = 0;
while (*ss) {
if (*ss == '\n') {
if (wasnl) {
*ss++ = '\0';
return(ss);
} else wasnl++;
} else if (*ss != '\r') wasnl = 0;
ss++;
} /* while */
return(NULL);
} /* splitbody */
/* EOF */