home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / EUROSET.ZIP / FOLD.C < prev    next >
C/C++ Source or Header  |  1994-01-27  |  12KB  |  374 lines

  1. /* fold.c  1994 jan 03  [gh]
  2. +-----------------------------------------------------------------------------
  3. | Abstract:
  4. |    Fold character sets.
  5. |
  6. | Authorship:
  7. |    Copyright (c) 1994 Gisle Hannemyr.
  8. |    Permission is granted to hack, make and distribute copies of this program
  9. |    as long as this copyright notice is not removed.
  10. |    Flames, bug reports, comments and improvements to:
  11. |       snail: Gisle Hannemyr, Brageveien 3A, 0452 Oslo, Norway
  12. |       email: X400:  gisle.hannemyr@nr.no
  13. |              Inet: gisle@ifi.uio.no, gisle@oslonett.no
  14. |              UUCP: ...!mcsun!ifi!gisle
  15. |
  16. | Usage:
  17. |    The following 5 character sets are enumerated in fold.h:
  18. |    ISO646IRV  -- ISO 646 International Reference version (ISO-IR-2)
  19. |       ISO646N    -- ISO 646 Norwegian/Danish version (ISO-IR-60)
  20. |    ISOL1       -- ISO 8859/1 (ISO Latin 1).
  21. |    CP850       -- IBM codepage 850
  22. |    MAC       -- Apple MacIntosh default character set.
  23. |    To set up a particular conversion, first call the function initfold
  24. |    with your input character set and output character set.
  25. |
  26. |    Example: to set up the module to convert from IBM CP 850 to Macintosh,
  27. |
  28. |       initfold(CP850, MAC);
  29. |
  30. |    then, too actually fold, the following two functions are provided:
  31. |
  32. |    To fold one charcter:
  33. |
  34. |       unsigned int foldchar(cc)
  35. |
  36. |    To fold all the character in a text buffer terminated by '\0':
  37. |
  38. |       void foldbuffer(buf)
  39. |
  40. |
  41. | History:
  42. |    1.0 94 jan 03 [gh] Wrote it.
  43. +---------------------------------------------------------------------------*/
  44.  
  45. #include <stdio.h>
  46. #include <string.h>
  47. #include <ctype.h>
  48. #include "fold.h"
  49.  
  50. /*---( defines )------------------------------------------------------------*/
  51.  
  52. #define INTEROR  -3    /* Indices into table doing the actual concersion.  */
  53. #define NS72ISO  -2    /* The negative values denote special semantics.    */
  54. #define NOTHING  -1    /* All conversions is either to or from Latin 1.    */
  55. #define ISO2AS7   0
  56. #define ISO2NS7   1
  57. #define ISO2IBM   2
  58. #define IBM2ISO   3
  59. #define ISO2MAC   4
  60. #define MAC2ISO   5
  61.  
  62. #define NOTIMPL   0
  63. #define UNCODED   1
  64. #define ENCODED   2
  65.  
  66. static int Encoding = UNCODED;
  67. static int Charset  = ISOL1;
  68.  
  69.  
  70. /*---( constants )----------------------------------------------------------*/
  71.  
  72. static int  ITab, OTab;
  73.  
  74. static unsigned char FoldTables[6][128] = {
  75.    { 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* ISO2AS7 */
  76.      32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* ISO 646 IRV */
  77.      32, 33, 63, 76, 36, 89,124, 63, 34, 99, 97, 34,126, 45,114, 45,
  78.      42, 63, 50, 51, 39,117, 63, 42, 44, 49,111, 34, 63, 63, 63, 63,
  79.      65, 65, 65, 65, 65, 65, 65, 67, 69, 69, 69, 69, 73, 73, 73, 73,
  80.      68, 78, 79, 79, 79, 79, 79,120, 79, 85, 85, 85, 85, 89, 63, 63,
  81.      97, 97, 97, 97, 97, 97, 97, 99,101,101,101,101,105,105,105,105,
  82.     100,110,111,111,111,111,111, 47,111,117,117,117,117,121, 63,121},
  83.    { 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* ISO2NS7 */
  84.      32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* ISO 646 Norsk */
  85.      32, 33, 63, 76, 36, 89,124, 63, 34, 99, 97, 34,126, 45,114, 45,
  86.      42, 63, 50, 51, 39,117, 63, 42, 44, 49,111, 34, 63, 63, 63, 63,
  87.      65, 65, 65, 65, 91, 93, 91, 67, 69, 69, 69, 69, 73, 73, 73, 73,
  88.      68, 78, 79, 79, 79, 79, 92,120, 92, 85, 85, 85, 85, 89, 63, 63,
  89.      97, 97, 97, 97,123,125,123, 99,101,101,101,101,105,105,105,105,
  90.     100,110,111,111,111,111,124, 47,124,117,117,117,117,121, 63,121},
  91.    { 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* ISO2IBM */
  92.      32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* CP850   */
  93.      32,173,189,156,207,190,221,245,249,184,166,174,170, 45,169,238,
  94.     248,241,253,252,239,230,244,250, 44,251,167,175,172,171,243,168,
  95.     183,181,182,199,142,143,146,128,212,144,210,211,222,214,215,216,
  96.     209,165,227,224,226,229,153,158,157,235,233,234,154,237,232,225,
  97.     133,160,131,198,132,134,145,135,138,130,136,137,141,161,140,139,
  98.     208,164,149,162,147,228,148,246,155,151,163,150,129,236,231,152},
  99.    {199,252,233,226,228,224,229,231,234,235,232,239,238,236,196,197, /* IBM2ISO */
  100.     201,230,198,244,246,242,251,249,255,214,220,248,163,216,215,102, /* CP850   */
  101.     225,237,243,250,241,209,170,186,191,174,172,189,188,161,171,187,
  102.      35, 35, 35,124, 43,193,194,192,169, 43,124, 43, 43,162,165, 43,
  103.      43, 43, 43, 43, 45, 43,227,195, 43, 43, 43, 43, 43, 45, 43,164,
  104.     240,208,202,203,200,105,205,206,207, 43, 43, 35, 45,166,204, 45,
  105.     211,223,212,210,245,213,181,254,222,218,219,217,253,221,175,180,
  106.      45,177, 61,190,182,167,247, 45,176,168,183,185,179,178,183, 32},
  107.    { 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* ISO2MAC */
  108.      32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
  109.     202,193,162,163,192,180,124,164,172,169,187,199,194, 45,168, 45,
  110.     161,177, 50, 51,171,181,166,165, 44, 49,188,200,192,192,192,192,
  111.     203, 65, 65,204,128,129,174,130, 69,131, 69, 69, 73, 73, 73, 73,
  112.      68,132, 79, 79, 79,205,133,120,175, 85, 85, 85,134, 89,192,167,
  113.     136,135,137,139,138,140,190,141,143,142,144,145,147,146,148,149,
  114.     182,150,152,151,153,155,154,214,191,157,156,158,159,121,192,216},
  115.    {196,197,199,201,209,214,220,225,224,226,228,227,229,231,233,232, /* MAC2ISO */
  116.     234,235,237,236,238,239,241,243,242,244,246,245,250,249,251,252,
  117.     191,176,162,163,167,183,182,223,174,169,191,180,168,191,198,216,
  118.     191,177,191,191,165,181,240,191,191,191,191,170,186,191,230,248,
  119.     191,161,172,191,191,191,191,171,187,191,160,192,195,213,191,191,
  120.      45, 45, 34, 34, 39, 39,247,191,255,191,191,191,191,191,191,191,
  121.     191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
  122.     191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191}
  123. }; /*  FoldTables */
  124.  
  125.  
  126. /*---( init )---------------------------------------------------------------*/
  127.  
  128. /*
  129. | Abs: Explicitly initialize both input an output tables.
  130. | Sef: Selects input and output table (ITab & OTab).
  131. | Ret: TRUE if OK, else FALSE.
  132. */
  133. int initfold(iset, oset)
  134. int iset, oset;
  135. {
  136.     if (iset == oset) {  /* Don't fold */
  137.     ITab = OTab = NOTHING;
  138.     return(1);
  139.     } /* if (equal) */
  140.  
  141.     switch (iset) {
  142.       case ISO646IRV : ITab = NOTHING;    break;
  143.       case ISO646N   : ITab = NS72ISO;    break;
  144.       case ISOL1     : ITab = NOTHING;    break;
  145.       case CP850     : ITab = IBM2ISO;    break;
  146.       case MAC         : ITab = MAC2ISO;    break;
  147.       default        : ITab = INTEROR;
  148.     } /* switch */
  149.  
  150.     switch (oset) {
  151.       case ISO646IRV : OTab = ISO2AS7;    break;
  152.       case ISO646N   : OTab = ISO2NS7;    break;
  153.       case ISOL1     : OTab = NOTHING;    break;
  154.       case CP850     : OTab = ISO2IBM;    break;
  155.       case MAC         : OTab = ISO2MAC;    break;
  156.       default        : OTab = INTEROR;    break;
  157.     } /* switch */
  158.  
  159.     if ((ITab == INTEROR) || (OTab == INTEROR)) return(0);
  160.     else                    return(1);
  161. } /* initfold */
  162.  
  163.  
  164. /*
  165. | Abs: Initialize output table (we'll get input from headers.
  166. | Des: When importing messages, this only depends upon what your system
  167. |      considers default character encoding.
  168. | Sef: Selects output table ( & OTab).
  169. | Ret: TRUE if OK, else FALSE.
  170. */
  171. int initout(oset)
  172. int oset;
  173. {
  174.     switch (oset) {
  175.       case ISO646IRV : OTab = ISO2AS7;    break;
  176.       case ISO646N   : OTab = ISO2NS7;    break;
  177.       case ISOL1     : OTab = NOTHING;    break;
  178.       case CP850     : OTab = ISO2IBM;    break;
  179.       case MAC         : OTab = ISO2MAC;    break;
  180.       default        : OTab = INTEROR;    break;
  181.     } /* switch */
  182.  
  183.     if (OTab == INTEROR) return(0);
  184.     else         return(1);
  185. } /* initout */
  186.  
  187.  
  188. /*
  189. | Abs: Explicitly initialize input table by parsing headers.
  190. | Des: Assumes output table already known.
  191. | Sef: Selects input table (ITab).
  192. | Ret: TRUE if OK, else FALSE.
  193. */
  194. int inithead(head)
  195. unsigned char *head;
  196. {
  197.     int wasnl;
  198.     unsigned char hline[512];
  199.     unsigned char *ss, *dd;
  200.  
  201.     if (!head) return(0);
  202.     ss = head;;
  203.  
  204.     Encoding = UNCODED;
  205.     wasnl = 1;
  206.     while (*ss) {
  207.     if (wasnl) {
  208.         if ((*ss == 'c') || (*ss == 'C')) {
  209.         dd = hline;
  210.         while (*ss && (*ss != '\n')) {
  211.             if (*ss != '"') *dd++ = tolower(*ss);
  212.             ss++;
  213.         }
  214.         ss++;
  215.         *dd = '\0';
  216.         printf("[%s]", hline);
  217.         if (!strncmp(hline, "content-transfer-encoding:", 26)) {
  218.             dd = hline+26;
  219.             while (isspace(*dd)) dd++;
  220.             if (!strncmp(dd, "quoted-printable", 16)) Encoding = ENCODED;
  221.             else if ((*dd == '7') || (*dd == '8'))    Encoding = UNCODED;
  222.             else                      Encoding = NOTIMPL;
  223.             fputs(dd, stdout);
  224.             fputc('\n', stdout);
  225.         } else if (!strncmp(hline, "content-type:", 13)) {
  226.             if (dd = (unsigned char *)strstr(hline, "charset=")) {
  227.             dd += 8;
  228.             if      (!strncmp(dd, "us-ascii",    8)) Charset = ISO646IRV;
  229.             else if (!strncmp(dd, "iso-8859-1", 10)) Charset = ISO646IRV;
  230.             else if (!strncmp(dd, "x-iso-ir-60",11)) Charset = ISO646N;
  231.             else                                     Charset = CSETNONE;
  232.             fputs(dd, stdout);
  233.             fputc('\n', stdout);
  234.             }
  235.         } else fputs("huh?\n", stdout);
  236.  
  237.         } else {
  238.         if (*ss != '\r') wasnl = 0;
  239.         ss++;
  240.         }
  241.     } else {
  242.         if      (*ss == '\n') wasnl = 1;
  243.         else if (*ss != '\r') wasnl = 0;
  244.         ss++;
  245.     }
  246.     } /* while */
  247.  
  248.     printf(">>> CharSet: %2d, Encoding: %2d\n", Charset, Encoding);
  249.  
  250.     switch (Charset) {
  251.       case ISO646IRV : ITab = NOTHING;    break;
  252.       case ISO646N   : ITab = NS72ISO;    break;
  253.       case ISOL1     : ITab = NOTHING;    break;
  254.       case CP850     : ITab = IBM2ISO;    break;
  255.       case MAC         : ITab = MAC2ISO;    break;
  256.       default        : ITab = INTEROR;
  257.     } /* switch */
  258.  
  259.     printf(">>> IP: %2d OP: %2d\n", ITab, OTab);
  260.  
  261.     if (ITab == OTab) {  /* Don't fold */
  262.     ITab = OTab = NOTHING;
  263.     return(1);
  264.     } /* if (equal) */
  265.  
  266.     if ((ITab == INTEROR) || (OTab == INTEROR)) return(0);
  267.     else                    return(1);
  268. } /* inithead */
  269.  
  270.  
  271. /*---( fold )---------------------------------------------------------------*/
  272.  
  273. /*
  274. | Abs: Fold one charcter.
  275. */
  276. unsigned int foldchar(cc)
  277. unsigned int cc;
  278. {
  279.     if (ITab == -2) {
  280.     if (((cc >= 91) && (cc <= 93)) || ((cc >= 123) && (cc <= 125))) {
  281.         if      ( 91 == cc) cc = 198;
  282.         else if ( 92 == cc) cc = 216;
  283.         else if ( 93 == cc) cc = 195;
  284.         else if (123 == cc) cc = 230;
  285.         else if (124 == cc) cc = 248;
  286.         else if (125 == cc) cc = 229;
  287.     } /* if (Norwegian/Danish) */
  288.     } else
  289.     if ((cc >= 128) && (ITab >=  0)) cc = FoldTables[ITab][cc - 128];
  290.     if ((cc >= 128) && (OTab >=  0)) cc = FoldTables[OTab][cc - 128];
  291.     return(cc);
  292. } /* foldchar */
  293.  
  294.  
  295. /*
  296. | Abs: Fold all the character in a text buffer terminated by '\0'.
  297. */
  298. void foldbuffer(buf)
  299. unsigned char *buf;
  300. {
  301.     int ii;
  302.  
  303.     if (!buf) return;
  304.     ii = 0;
  305.     while (buf[ii]) {
  306.     buf[ii] = foldchar(buf[ii]);
  307.     ii++;
  308.     } /* while */
  309. } /* foldbuffer */
  310.  
  311.  
  312. /*---( mime )---------------------------------------------------------------*/
  313.  
  314. /*
  315. | Abs: Remove MIME codes in buffer
  316. | Des: The ceasar rotate is based upon gnus implementation, and do a ROT13
  317. |      for A-Z, a-z, and a ROT47 for the 94 characters between 161 and 254
  318. |      (inclusive).
  319. */
  320. void unmimebuffer(buf)
  321. unsigned char *buf;
  322. {
  323.     int cc;
  324.     unsigned char *ss, *dd;
  325.  
  326.     if (!buf) return;
  327.     if (Encoding != ENCODED) return;;
  328.  
  329.     dd = ss = buf;
  330.     while (*ss) {
  331.     if (*ss == '=') {
  332.         ss++;
  333.         if (!*ss) break;
  334.         if ('\n' == *ss) { ss++; continue; }
  335.         cc  = isdigit(*ss) ? (*ss - '0') : (*ss - 55);
  336.         cc *= 0x10;
  337.         ss++;
  338.         cc += isdigit(*ss) ? (*ss - '0') : (*ss - 55);
  339.         *dd = cc;
  340.     } else *dd = *ss;
  341.     dd++; ss++;
  342.     } /* while */
  343.     *dd = '\0';
  344. } /* unmimebuffer */
  345.  
  346.  
  347. /*---( split )--------------------------------------------------------------*/
  348.  
  349. /*
  350. | Abs: Separate headers from the message.
  351. | Ret: Pointer to the start of the message body.
  352. */
  353. unsigned char *splitbody(buf)
  354. unsigned char *buf;
  355. {
  356.     int wasnl;
  357.     unsigned char *ss;
  358.  
  359.     ss = buf;
  360.     wasnl = 0;
  361.     while (*ss) {
  362.     if (*ss == '\n') {
  363.         if (wasnl) {
  364.         *ss++ = '\0';
  365.         return(ss);
  366.         } else wasnl++;
  367.     } else if (*ss != '\r') wasnl = 0;
  368.     ss++;
  369.     } /* while */
  370.     return(NULL);
  371. } /* splitbody */
  372.  
  373. /* EOF */
  374.