home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / p / pktxl31.zip / PKTXL.C < prev    next >
Text File  |  1992-05-22  |  22KB  |  1,146 lines

  1. /* PKTXL.C  Översättning av PKT-filer mellan olika teckenuppsättningar. */
  2. /* (c) 1989, 1990 Nils Hammar */
  3.  
  4. /* VMS is a trademark of Digital Equipment Corporation. */
  5. /* FOSSIL is a Fido-Opus-Seadog .... */
  6.  
  7. /*    The program may be used by anyone, as long as the source of the program
  8.     is declared. If the source is used in commercial programs, the
  9.     information about the source must be included in the documentation.
  10.     This program is primary written for Microsoft C 6.00, but should be
  11.     possible to implement in other environments with minor efforts.
  12. */
  13.  
  14. /*    This program is currently only possible to compile under
  15.     Microsoft C. It is possible to use Turbo C, but then the program
  16.     will not allow wildcards in the input filenames.
  17. */
  18.  
  19. /*    This declaration allows the case conversion to be customized.
  20.     Do not customize characters 'A' to 'Z'. It is possible to add
  21.     characters too.
  22. */
  23.  
  24. #define VERSION        "3.1"
  25. #define UPPERCASE    "ÉABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖÜÆÇÑ"
  26. #define LOWERCASE    "éabcdefghijklmnopqrstuvwxyzåäöüæçñ"
  27.  
  28. #define INCL_DOS
  29. #include <os2.h>
  30.  
  31. #include <stdio.h>
  32.  
  33. #ifdef __TURBOC__
  34. #include <dos.h>
  35. #include <stdlib.h>
  36. #else
  37. #ifdef MSDOS
  38. #include <stdlib.h>
  39. #include <conio.h>
  40. #include <dos.h>
  41. #else
  42. #include <curses.h>
  43. #endif /* MSDOS */
  44. #endif /* __TURBOC__ */
  45.  
  46. #include <time.h>
  47. #include <string.h>
  48. #include <malloc.h>
  49. #include <direct.h>
  50. #include <time.h>
  51.  
  52. #ifndef __TURBOC__
  53. #ifndef MSDOS
  54. #include <unistd.h>
  55. #endif /* MSDOS */
  56. #endif /* __TURBOC__ */
  57.  
  58. int        direntry(struct FILEINFO    *, char *, int);
  59. void        dtidkonv(unsigned int, unsigned int, char *);
  60. unsigned char    transchar(unsigned char, int, int);
  61. int        xlatetexts(FILE *, FILE *, int, int);
  62. int        dirlist(char *, char *);
  63. void        xlatefile(char *, char*, int, int);
  64. int        space(int, int);
  65. int        trema(int, int);
  66. int        dollar(int, int);
  67. int        cedilla(int, int);
  68. int        minus(int, int);
  69. int        dot(int, int);
  70. int        slash(int, int);
  71. int        caret(int, int);
  72. int        greek(int, int);
  73. int        trademark(int, int);
  74. int        subcompstr(char *, char *);
  75. void        addkludge(FILE *, int);
  76. void        upper(char *, char *);
  77. int        identify(char *);
  78.  
  79. typedef struct
  80. {
  81.     unsigned int    orignode, destnode, year, month, day, hour, minute,
  82.                 second, baud, idcode, orignet, destnet;
  83.     unsigned char    pcode, serialno, password[20];
  84.     unsigned int    origzone, destzone;
  85.     unsigned char    filler[8];
  86. } packheader;
  87.  
  88. typedef struct
  89. {
  90.     unsigned int    idcode, orignode, destnode, orignet, destnet,
  91.             attribute, cost;
  92. } packmessage;
  93.  
  94. struct FILEINFO
  95. {
  96.     char        rsvd[21];
  97.     char        attr;
  98.     unsigned int    time;
  99.     unsigned int    date;
  100.     long        size;
  101.     char        name[13];
  102.     char        nill;
  103. };
  104.  
  105. packmessage    packmsg;
  106. packheader    packhd;
  107. int        opt, nolf, nosoft;
  108.  
  109. /*    On the following lines is it possible to customize the translation
  110.     of the national language characters.
  111.     Current translation is for Swedish terminals.
  112.     Observe that \ must be typed \\ which will make some confusion.
  113.     The only line that have to be modified is the 7-bit line.
  114.     The other lines are fixed. All places with a blank means no
  115.     translation.
  116.     Here follows some translation tables for 7-bit.
  117.     These translations is for CodePage 437, which will give some
  118.     problems with some languages.
  119.  
  120. */
  121.  
  122. unsigned char    *teckenset[11]={
  123.         /* 7-bit Swedish charset */
  124.         "}{|][\\~^@`                              # ",
  125.         /* 8-bit IBM-PC */
  126.         "åäöÅÄÖüÜÉéÇçâàêëèïî æÆôòûùÿ¢£¥ƒáíóúñÑ∞°ß#₧",
  127.         /* 8-bit ISO 8859 */
  128.         "σΣ÷┼─╓ⁿ▄╔Θ╟τΓαΩδΦ∩ε∞µ╞⌠≥√∙²óúÑ ßφ≤·±╤≈░▀# ",
  129.         /* 8-bit MacIntosh */
  130.         "îèÜüÇàƒåâÄé ëêÉæÅòöô╛«Öÿ₧¥╪óú┤─çÆù£û ░íº# ",
  131.         /* 7-bit French charset (one char excluded.) */
  132.         "         { \\ @  }        |            [ # ",
  133.         /* 7-bit German charset (one char excluded.) */
  134.         " {| [\\}]                               ~# ",
  135.         /* 7-bit English (British) charset */
  136.         "                            #              ",
  137.         /* 7-bit Danish charset (Not really. CP437 does not
  138.            support Danish characters, we use the Swedish ones) */
  139.         "} |] \\              {[                  # ",
  140.         /* 7-bit Italian charset */
  141.         "         ]   {  }  ~   | `            [ # ",
  142.         /* 7-bit Spanish charset (Not fully translated
  143.            due to the CP437 limitations.) */
  144.         "                                   |\\    #",
  145.         /* 7-bit Japanese charset */
  146.         "                             \\            "},
  147.  
  148. /*        "åäöÅÄÖüÜÉéÇçâàêëèïî æÆôòûùÿ¢£¥ƒáíóúñÑ∞°ß#₧", */
  149.  
  150. /*    Umlaut is a special character conversion which is often used
  151.     in germany. This conversion is not always the best, but
  152.     it will make the texts more readable if converting from
  153.     "wrong" character set. */
  154.  
  155.         *umlaut[43]={
  156.         "aa", "ae", "oe", "AA", "AE", "OE", "ue", "UE", "E", "e",
  157.         "C", "c", "a", "a", "e", "e", "e", "i", "i", "i", "ae", "AE",
  158.         "o", "o", "u", "u", "ye", "c", "L", "Y", "f", "a", "i", "o",
  159.         "u", "n", "N", "", "", "ss", "#", "Pt"};
  160.  
  161.  
  162. int    main(argc, argv)
  163. int    argc;
  164. char    *argv[];
  165. {
  166.     char    tmp[160],
  167.         *sortarea,
  168.         inmail[160],
  169.         tmp1[160],
  170.         tmp2[160],
  171.         outmail[160],
  172.         indir[160],
  173.         args[20][160],
  174.         *env;
  175.     int    i, n, z, j, fromcharset, tocharset;
  176.     long    tid1, tid2;
  177.  
  178.     fprintf(stderr, "\n\nPKTXL - Packet translator version ");
  179.     fprintf(stderr, VERSION);
  180.     fprintf(stderr, "\n(C) 1990,1991,1992 Nils Hammar\n");
  181.     fprintf(stderr, "Free to use in non-commercial applications.\n\n");
  182.  
  183.     if (argc < 5)
  184.     {
  185.         printf("Syntax : PKTXL infile outfile fromcharset tocharset\n");
  186.         exit(9);
  187.     }
  188.  
  189.     opt=0;        /* != 0 if a new charset kludge is added. */
  190.     nolf=0;        /* != 0 if all LF chars is to be removed. */
  191.     nosoft=0;    /* != 0 if all SoftCR is to be removed. */
  192.  
  193.     i=0;
  194.     while(i<20) *args[i++]=0;
  195.  
  196.     i=1;
  197.     j=1;
  198.     while(i<=argc)
  199.     {
  200.         if (*argv[i] != '-')
  201.         {
  202.             strcpy(args[j], argv[i]);
  203.             j++;
  204.         }
  205.  
  206.         upper(tmp1, argv[i]);
  207.         if (subcompstr("-KLUDGE", tmp1) == 0) opt=-1;
  208.         if (subcompstr("-NOLF", tmp1) == 0) nolf=-1;
  209.         if (subcompstr("-NOSOFT", tmp1) == 0) nosoft=-1;
  210.         if (subcompstr("-K", tmp1) == 0) opt=-1;
  211.         if (subcompstr("-L", tmp1) == 0) nolf=-1;
  212.         if (subcompstr("-S", tmp1) == 0) nosoft=-1;
  213.  
  214.         i++;
  215.     }
  216.  
  217.     time(&tid1);
  218.  
  219.     strcpy(inmail, args[1]);
  220.     strcpy(indir, inmail);
  221.  
  222.  
  223. /*    Check environment area for configuration parameters. */
  224.  
  225.     env=getenv("PKTXL");
  226.  
  227.     if (env != NULL)
  228.     {
  229.         i=0;
  230.         while(*(env + i) != 0)
  231.         {
  232.             if (subcompstr("-KLUDGE", (env + i)) == 0) opt=-1;
  233.             if (subcompstr("-NOLF", (env + i)) == 0) nolf=-1;
  234.             if (subcompstr("-NOSOFT", (env + i)) == 0) nosoft=-1;
  235.             i++;
  236.         }
  237.     }
  238.  
  239.     if (opt != 0)
  240.         printf("Replacing character set kludge\n");
  241.     else
  242.         printf("Removing character set kludge\n");
  243.  
  244.     if (nolf != 0)
  245.         printf("Removing LF\n");
  246.     else
  247.         printf("Leaving LF:s unchanged\n");
  248.  
  249.     if (nosoft != 0)
  250.         printf("Removing SoftCR\n");
  251.     else
  252.         printf("Leaving SoftCR:s unchanged\n");
  253.  
  254.     n=strlen(inmail);
  255.  
  256.     while(n > 0 && *(indir + n) != '\\') n--;
  257.     if (n != 0) *(indir + n + 1)=0;
  258.     else *indir=0;
  259.  
  260. /*    if (*(inmail+n-1) != '\\')
  261.     {
  262.         *(inmail+n)='\\';
  263.         *(inmail+n+1)=0;
  264.     } */
  265.  
  266.     strcpy(outmail, args[2]);
  267.     n=strlen(outmail);
  268.     if (*(outmail+n-1)!='\\')
  269.     {
  270.         *(outmail+n)='\\';
  271.         *(outmail+n+1)=0;
  272.     }
  273.  
  274.     fromcharset=atoi(args[3]);
  275.     tocharset=atoi(args[4]);
  276.  
  277.     if (fromcharset < 0 || fromcharset > 10)
  278.     {
  279.         printf("Illegal from character set.\n");
  280.         exit(9);
  281.     }
  282.  
  283.     if (tocharset < -1 || tocharset > 10)
  284.     {
  285.         printf("Illegal to character set.\n");
  286.         exit(9);
  287.     }
  288.  
  289.     printf("Translation from character set %d to character set %d\n",
  290.         fromcharset, tocharset);
  291.  
  292.     printf("Input files in  : %s\n", indir);
  293.     printf("Output files in : %s\n", outmail);
  294.  
  295. /*    Ladda texter. */
  296.  
  297. #ifdef MSDOS
  298.     sortarea=halloc(65535L, sizeof(char));
  299. #else
  300.     sortarea=calloc(65535L, sizeof(char));
  301. #endif
  302.  
  303.     strcpy(tmp, inmail);
  304.  
  305.     n=dirlist(tmp, sortarea);
  306.  
  307.     printf("Files = %d\n", n);
  308.  
  309.     for(j=0;j<n;j++)
  310.     {
  311.         i=0;
  312.         z=0;
  313.  
  314.         strcpy(tmp, (sortarea + j*45));
  315.  
  316. /*        printf("File(%d)=\"%s\"\n", j, tmp); */
  317.  
  318.         while(*(tmp + i) > ' ')
  319.         {
  320. /*             Om det är ett bibliotek. */
  321.             if (*tmp == ' ') z=1;
  322.             i++;
  323.         }
  324.  
  325.         *(tmp+i)=0;
  326.  
  327.         sprintf(tmp1, "%s%s", indir, tmp);
  328.         sprintf(tmp2, "%s%s", outmail, tmp);
  329.  
  330.         if (strlen(tmp) > 0 && z == 0)
  331.         {
  332.             printf("Converts from file \"%s\" to file \"%s\"\n",
  333.                 tmp1, tmp2);
  334.             xlatefile(tmp1, tmp2, fromcharset, tocharset);
  335.         }
  336.     }
  337.  
  338. #ifdef MSDOS
  339.     hfree(sortarea);
  340. #else
  341.     free(sortarea);
  342. #endif
  343.  
  344.     time(&tid2);
  345.  
  346.     printf("Execution time %ld seconds\n", tid2-tid1);
  347.  
  348.     return(0);
  349. }
  350.  
  351. /*    Compare the first part of 'string' with 'compval' */
  352.  
  353. int    subcompstr(compval, string)
  354. char    *compval, *string;
  355. {
  356.     int    i;
  357.  
  358.     if (strlen(compval) > strlen(string)) return(-1);
  359.  
  360.     i=0;
  361.     while( *(compval + i) == *(string + i) && *(compval + i) != 0) i++;
  362.  
  363.     if (*(compval + i) == 0) return(0);
  364.  
  365.     return(1);
  366. }
  367.  
  368. /*    Convert lower case to upper case. */
  369.  
  370. void    upper(outbuff, inbuff)
  371. char    *outbuff, *inbuff;
  372. {
  373.     char    upcase[256], lowcase[256];
  374.     int    i;
  375.  
  376.     strcpy(upcase, UPPERCASE);
  377.     strcpy(lowcase, LOWERCASE);
  378.  
  379.     while(*inbuff != 0)
  380.     {
  381.         i=0;
  382.         while(*(lowcase + i) != *inbuff && *(lowcase + i) !=0) i++;
  383.         if (*(lowcase + i) !=0) *outbuff=*(upcase + i);
  384.         else *outbuff=*inbuff;
  385.  
  386.         outbuff++;
  387.         inbuff++;
  388.     }
  389.     *outbuff=0;
  390. }
  391.  
  392. /*    Convert DOS time to ISO text format. (YYYY-MM-DD HH:MM:SS) */
  393.  
  394. void        dtidkonv(tid, dat, uttid)
  395. unsigned int    tid, dat;
  396. char        *uttid;
  397. {
  398.     unsigned int    yr, mon, day, hr, min, sec, tdat, ttid;
  399.  
  400.     tdat=dat;
  401.     ttid=tid;
  402.  
  403.     yr=tdat/512;
  404.     tdat=tdat-yr*512;
  405.  
  406.     mon=tdat/32;
  407.     day=tdat-mon*32;
  408.  
  409.     hr=ttid/2048;
  410.     ttid=ttid-hr*2048;
  411.  
  412.     min=ttid/32;
  413.     sec=(ttid-min*32)*2;    
  414.  
  415.     sprintf(uttid, "%4d-%02d-%02d %02d:%02d:%02d",
  416.         yr+1980, mon, day, hr, min, sec);
  417. }
  418.  
  419. #ifndef OS2
  420. /* Lägg till strängen srcs till strängen apps samt returnera det nya
  421.    strängslutet    */
  422.  
  423. char    *appst(register char *apps, register char *srcs)
  424. {
  425.     while( *srcs != 0)
  426.     {
  427.         *(apps++) = *(srcs++);
  428.     }
  429.     return( apps);
  430. }
  431.  
  432. int    direntry(dta, name, times)
  433. struct FILEINFO    *dta;
  434. char        *name;
  435. int        times;
  436. {
  437.     union REGS    r;
  438.  
  439.     r.x.dx = FP_OFF(dta);
  440.     r.h.ah = 0x1a;
  441.     intdos (&r, &r);
  442.     r.x.bx = 0;
  443.     r.x.cx = ~0x08;
  444.     r.x.dx = FP_OFF(name);
  445.     r.x.si = 0;
  446.     r.x.di = 0;
  447.  
  448.     if (times == 0)
  449.     {
  450.         r.h.ah = 0x4e;
  451.         intdos (&r, &r);
  452.         dta->nill = '\0';
  453.         if (r.x.cflag != 0)
  454.         {
  455.             dta->name[0] = '\0';
  456.             return (1);
  457.         }
  458.         return (0);
  459.     }
  460.     else
  461.     {
  462.         r.h.ah = 0x4f;
  463.         intdos (&r, &r);
  464.         dta->nill = '\0';
  465.         if (r.x.cflag != 0)
  466.         {
  467.             dta->name[0] = '\0';
  468.             return (1);
  469.         }
  470.         return (0);
  471.     }
  472. }
  473.  
  474. int    sort_function(const void * a, const void * b)
  475. {
  476.     return(strcmp(a, b));
  477. }
  478.  
  479. int    dirlist(namn, sortarea)
  480. char    *namn, *sortarea;
  481. {
  482.     struct FILEINFO dta[1];
  483.     char        slask[30], tmp[30];
  484.     int        z, i, j, n;
  485.  
  486.     i=0;
  487.     j=0;
  488.     z=direntry(dta, namn, i);
  489.     if (z != 0) printf("No directory.\n");
  490.  
  491.     strcpy(sortarea, "");
  492.  
  493.     while (z == 0)
  494.     {
  495.         if (strcmp(dta->name, ".") != 0 &&
  496.             strcmp(dta->name, "..") != 0 &&
  497.             ('É' != *dta->name ||
  498.             (dta->attr & 16) == 0))
  499.         {
  500.             dtidkonv(dta->time, dta->date, slask);
  501.  
  502.             strcpy(tmp, dta->name);
  503.  
  504.             n=0;
  505.             while(*(tmp+n) != 0) n++;
  506.             while(n<13)
  507.             {
  508.                 *(tmp+n)=' ';
  509.                 n++;
  510.                 *(tmp+n)=0;
  511.             }
  512.  
  513.             if ((dta->attr & 16) != 0)
  514.                 sprintf((sortarea + j*45), " Filarea %s", tmp);
  515.             else
  516.                 sprintf((sortarea + j*45),"%s%9ld %s",
  517.                     tmp, dta->size, slask);
  518.  
  519.             j++;
  520.             strcpy((sortarea + j*45), "");
  521.         }
  522.  
  523.         i++;
  524.         z=direntry(dta, namn, i);
  525.     }
  526.  
  527. #ifdef __TURBOC__
  528.     qsort(sortarea, j, 45, sort_function);
  529. #else
  530.     qsort(sortarea, j, 45, strcmp);
  531. #endif
  532.  
  533.     return(j);
  534. }
  535.  
  536. #else
  537.  
  538. int    dirlist(namn, sortarea)
  539. char    *namn, *sortarea;
  540. {
  541.     char            path[80];
  542.     unsigned        count=1;
  543.     int            rc, j;
  544.     struct _FILEFINDBUF    buff;
  545.     unsigned short         handle=0xffff;
  546.  
  547.     rc=DosFindFirst(namn, &handle, 0x0000, &buff,
  548.         sizeof(buff), &count, 0L);
  549.  
  550.     if (rc)
  551.     {
  552.         if (rc == 18)
  553.         {
  554.             DosFindClose(handle);
  555.             return(0);
  556.         }
  557.  
  558.         printf("Error in the directory handling.\n");
  559.         exit(9);
  560.     }
  561.  
  562.     j=0;
  563.  
  564.     if ((buff.attrFile & 0x0010) != 0)
  565.     {
  566.         sprintf(sortarea, " Filarea %s", buff.achName);
  567.     }
  568.     else
  569.     {
  570.         sprintf(sortarea,"%s%9ld %02d-%02d-%02d %02d:%02d",
  571.             buff.achName, buff.cbFile,
  572.             buff.fdateLastWrite.year,
  573.             buff.fdateLastWrite.month,
  574.             buff.fdateLastWrite.day,
  575.             buff.ftimeLastWrite.hours,
  576.             buff.ftimeLastWrite.minutes);
  577.  
  578.     }
  579.  
  580. /*    printf("%s\n", sortarea); */
  581.     j++;
  582.  
  583.     while(TRUE)
  584.     {
  585.         rc=DosFindNext(handle, &buff, sizeof(buff), &count);
  586.         if (rc)
  587.         {
  588.             if (rc == 18)
  589.             {
  590.                 DosFindClose(handle);
  591.                 qsort(sortarea, j, 45, strcmp);
  592.                 return(j);
  593.             }
  594.  
  595.             perror("Fel i hanteringen.\n");
  596.             exit(9);
  597.         }
  598.  
  599.         if ((buff.attrFile & 0x0010) != 0)
  600.         {
  601.             sprintf((sortarea + j*45), " Filarea %s",
  602.                 buff.achName);
  603.         }
  604.         else
  605.         {
  606.             sprintf((sortarea + j*45),
  607.                 "%s%9ld %02d-%02d-%02d %02d:%02d",
  608.                 buff.achName, buff.cbFile,
  609.                 buff.fdateLastWrite.year,
  610.                 buff.fdateLastWrite.month,
  611.                 buff.fdateLastWrite.day,
  612.                 buff.ftimeLastWrite.hours,
  613.                 buff.ftimeLastWrite.minutes);
  614.         }
  615. /*        printf("%s\n", (sortarea+j*45)); */
  616.         j++;
  617.     }
  618. }
  619.  
  620. #endif
  621.  
  622. unsigned char    transchar(c, from, to)
  623. unsigned char    c;
  624. int        from, to;
  625. {
  626.     int    i;
  627.     unsigned char    cx;
  628.  
  629.     i=0;
  630.  
  631.     while (*(teckenset[from] + i) != c && *(teckenset[from] + i) != 0) i++;
  632.  
  633. /*    If translating to the "umlaut" multi-byte format. */
  634.  
  635.     if (to < 0)
  636.     {
  637.         if (*(teckenset[from] + i) == c &&
  638.             *(teckenset[from] + i) != ' ')
  639.             return((unsigned char)(i+1));
  640.  
  641.         return(0);
  642.     }
  643.  
  644.     if (*(teckenset[from] + i) == c && *(teckenset[from] + i) != ' ')
  645.         return(*(teckenset[to] + i));
  646.  
  647.      cx=c;
  648.  
  649.     return(cx);
  650. }
  651.  
  652. void    addkludge(g1, tocharset)
  653. FILE    *g1;
  654. int    tocharset;
  655. {
  656.     fputc(1, g1);
  657.  
  658.     switch (tocharset)
  659.     {
  660.         case -1 : fputs("CHARSET: UMLAUT", g1);
  661.               break;
  662.  
  663.         case 0  : fputs("CHRS: SWEDISH 1", g1);
  664.               break;
  665.  
  666.         case 1  : fputs("CHRS: IBMPC 2", g1);
  667.               break;
  668.  
  669.         case 2  : fputs("CHRS: LATIN-1 2", g1);
  670.               break;
  671.  
  672.         case 3  : fputs("CHRS: MAC 2", g1);
  673.               break;
  674.  
  675.         case 4  : fputs("CHRS: FRENCH 1", g1);
  676.               break;
  677.  
  678.         case 5  : fputs("CHRS: GERMAN 1", g1);
  679.               break;
  680.  
  681.         case 6  : fputs("CHRS: UK 1", g1);
  682.               break;
  683.  
  684.         case 7  : fputs("CHARSET: NORWEG 1", g1);
  685.               break;
  686.  
  687.         case 8  : fputs("CHRS: ITALIAN 1", g1);
  688.               break;
  689.  
  690.         case 9  : fputs("CHRS: SPANISH 1", g1);
  691.               break;
  692.  
  693.         case 10 : fputs("CHARSET: JAPANESE", g1);
  694.               break;
  695.     }
  696.  
  697.     fputc(13, g1);
  698. }
  699.  
  700. int    identify(id)
  701. char    *id;
  702. {
  703.     char    ident[80];
  704.     int    fromcharset;
  705.  
  706. /*    This routine checks the identifier even it it was lower case. */
  707.  
  708.     upper(ident, id);
  709.  
  710.     if (subcompstr("ISO-11", ident) == 0)
  711.         fromcharset=0;
  712.  
  713.     if (subcompstr("SWEDISH", ident) == 0)
  714.         fromcharset=0;
  715.  
  716.     if (subcompstr("FINNISH", ident) == 0)
  717.         fromcharset=0;
  718.  
  719.     if (subcompstr("CP437", ident) == 0)
  720.         fromcharset=1;
  721.  
  722.     if (subcompstr("IBM", ident) == 0)
  723.         fromcharset=1;
  724.  
  725.     if (subcompstr("PC-8", ident) == 0)
  726.         fromcharset=1;
  727.  
  728.     if (subcompstr("ISO 8859-1", ident) == 0)
  729.         fromcharset=2;
  730.  
  731.     if (subcompstr("ISO8859-1", ident) == 0)
  732.         fromcharset=2;
  733.  
  734.     if (subcompstr("ISO LATIN-1", ident) == 0)
  735.         fromcharset=2;
  736.  
  737.     if (subcompstr("LATIN-1", ident) == 0)
  738.         fromcharset=2;
  739.  
  740.     if (subcompstr("ISO-6", ident) == 0)
  741.         fromcharset=2;
  742.  
  743.     if (subcompstr("AMIGA", ident) == 0)
  744.         fromcharset=2;
  745.  
  746.     if (subcompstr("I51", ident) == 0)
  747.         fromcharset=2;
  748.  
  749.     if (subcompstr("MAC", ident) == 0)
  750.         fromcharset=3;
  751.  
  752.     if (subcompstr("FRENCH", ident) == 0)
  753.         fromcharset=4;
  754.  
  755.     if (subcompstr("ISO-69", ident) == 0)
  756.         fromcharset=4;
  757.  
  758.     if (subcompstr("GERMAN", ident) == 0)
  759.         fromcharset=5;
  760.  
  761.     if (subcompstr("ISO-21", ident) == 0)
  762.         fromcharset=5;
  763.  
  764.     if (subcompstr("BRITISH", ident) == 0)
  765.         fromcharset=6;
  766.  
  767.     if (subcompstr("UK", ident) == 0)
  768.         fromcharset=6;
  769.  
  770.     if (subcompstr("ISO-60", ident) == 0)
  771.         fromcharset=7;
  772.  
  773.     if (subcompstr("DANISH", ident) == 0)
  774.         fromcharset=7;
  775.  
  776.     if (subcompstr("NORWEG", ident) == 0)
  777.         fromcharset=7;
  778.  
  779.     if (subcompstr("ITALIAN", ident) == 0)
  780.         fromcharset=8;
  781.  
  782.     if (subcompstr("SPANISH", ident) == 0)
  783.         fromcharset=9;
  784.  
  785.     if (subcompstr("JAPAN", ident) == 0)
  786.         fromcharset=10;
  787.  
  788.     return(fromcharset);
  789. }
  790.  
  791. int    xlatetexts(f, g1, fromcharset, tocharset)
  792. FILE    *f, *g1;
  793. int    fromcharset, tocharset;
  794. {
  795.     int        c, n, c1, i, i0, j, k, characters, noout;
  796.     unsigned char    *textarea, ident[80], output[160];
  797.  
  798. /*    Check if the file is a type-2 file. */
  799.  
  800.     if (packmsg.idcode != 0x0002)
  801.     {
  802.         printf("Idcode : %d\n", packmsg.idcode);
  803.         printf("Illegal packet type\n");
  804.         return(1);
  805.     }
  806.  
  807. #ifdef MSDOS
  808.     textarea=halloc(65535L, sizeof(char));
  809. #else
  810.     textarea=calloc(65535L, sizeof(char));
  811. #endif
  812.  
  813.     fwrite((char *) &packmsg, sizeof(packmsg), 1, g1);
  814.  
  815. /*    The header field is not translated. */
  816.  
  817. /*    Date. */
  818.  
  819.     while((c=fgetc(f)) > 0) fputc(c, g1);
  820.     fputc(0, g1);
  821.  
  822. /*    To user: */
  823.  
  824.     while((c=fgetc(f)) > 0) fputc(c, g1);
  825.     fputc(0, g1);
  826.  
  827. /*    From user: */
  828.  
  829.     while((c=fgetc(f)) > 0) fputc(c, g1);
  830.     fputc(0, g1);
  831.  
  832. /*    Subject:
  833.     This line is only translated to an equally sized format.
  834. */
  835.  
  836.     while((c=fgetc(f)) > 0)
  837.     {
  838.         c1=c;
  839.         if (fromcharset >= 0 && tocharset >= 0)
  840.             c1=(int)transchar((unsigned char) c,
  841.                 fromcharset, tocharset);
  842.  
  843.         fputc(c1, g1);
  844.     }
  845.     fputc(0, g1);
  846.  
  847. /*    Start with reading in the text as is in a buffer. */
  848.  
  849.     n=0;
  850.     i=0;
  851.  
  852.     while((c=fgetc(f)) != 0)
  853.      {
  854.         *(textarea + i++)=(unsigned char)c;
  855.     }
  856.     *(textarea+i)=0;
  857.  
  858.     characters=i+1;
  859.  
  860.     i=0;
  861.     k=1;
  862.     i0=0;
  863.  
  864.     if (subcompstr("AREA:", textarea) == 0)
  865.     {
  866.         k=0;
  867. /*        printf("Area: found!\n"); */
  868.     }
  869.  
  870.     while(i < characters)
  871.     {
  872.         noout=0;
  873.         c=*(textarea + i);
  874.  
  875. /*        if (k < 2)
  876.         {
  877.             printf("%c", c);
  878.             if (c == 13) printf("\n"); 
  879.         }
  880. */
  881.         if (k == 1 && c != 10 &&
  882.             tocharset >= -1 && tocharset <= 10 &&
  883.             fromcharset >= 0 && fromcharset <= 10)
  884.         {
  885.             if (opt != 0)
  886.             {
  887.                 addkludge(g1, tocharset);
  888.                 fputc(1, g1);
  889.                 fputs("XL: ", g1);
  890.                 fputs(VERSION, g1);
  891.                 fputc(13, g1);
  892.             }
  893.  
  894. /*            printf("*Kludges*\n"); */
  895.             k=2;
  896.         }
  897.  
  898. /*        Kludges översätts inte. */
  899.         if (c == 1)
  900.         {
  901.             n=1;
  902.  
  903. /*    Check both the CHARSET and the CHRS kludge. Since
  904.     they can contain almost the same information, they may be
  905.     handled with the same identification function.
  906. */
  907.  
  908. /*    Check the CHARSET kludge. */
  909.  
  910.             if (subcompstr("CHARSET", (textarea + i + 1)) == 0)
  911.             {
  912.                 i=i+8;
  913.                 j=0;
  914.  
  915.                 while(*(textarea + i) == ':' ||
  916.                     *(textarea + i) == ' ')
  917.                 {
  918.                     i++;
  919.                 }
  920.  
  921.                 while(*(textarea + i) != 13 &&
  922.                     *(textarea + i) != 0)
  923.                 {
  924.                     *(ident + j)=*(textarea + i);
  925.                     i++;
  926.                     j++;
  927.                 }
  928.                 *(ident + j)=0;
  929.  
  930.                 printf("Old CHARSET: %s\n", ident);
  931.  
  932.                 j=identify(ident);
  933.                 if (j>-10) fromcharset=j;
  934.  
  935.                 n=0;
  936.                 i++;
  937.                 c=*(textarea + i);
  938.                 if (c == 10)
  939.                 {
  940.                     i++;
  941.                     c=*(textarea + i);
  942.                 }
  943.  
  944.                 i--;
  945.                 noout=-1;
  946.             }
  947.  
  948. /*    Check the CHRS kludge. */
  949.  
  950.             if (subcompstr("CHRS", (textarea + i + 1)) == 0)
  951.             {
  952.                 i=i+5;
  953.                 j=0;
  954.  
  955.                 while(*(textarea + i) == ':' ||
  956.                     *(textarea + i) == ' ')
  957.                 {
  958.                     i++;
  959.                 }
  960.  
  961.                 while(*(textarea + i) != 13 &&
  962.                     *(textarea + i) != 0)
  963.                 {
  964.                     *(ident + j)=*(textarea + i);
  965.                     i++;
  966.                     j++;
  967.                 }
  968.                 *(ident + j)=0;
  969.  
  970.                 printf("Old CHRS: %s\n", ident);
  971.  
  972.                 j=identify(ident);
  973.                 if (j>-10) fromcharset=j;
  974.  
  975.                 n=0;
  976.                 i++;
  977.                 c=*(textarea + i);
  978.                 if (c == 10)
  979.                 {
  980.                     i++;
  981.                     c=*(textarea + i);
  982.                 }
  983.  
  984.                 i--;
  985.                 noout=-1;
  986.             }
  987.  
  988.  
  989. /*    Check the I51 kludge. */
  990.  
  991.             if (subcompstr("I51", (textarea + i + 1)) == 0 &&
  992.                 fromcharset >= 0)
  993.             {
  994.                 i=i+4;
  995.                 fromcharset=2;
  996.  
  997.                 c=*(textarea + i);
  998.  
  999.                 if (c == 13)
  1000.                 {
  1001.                     i++;
  1002.                     c=*(textarea + i);
  1003.                 }
  1004.  
  1005.                 if (c == 10)
  1006.                 {
  1007.                     i++;
  1008.                     c=*(textarea + i);
  1009.                 }
  1010.  
  1011.                 i--;
  1012.                 noout=-1;
  1013.             }
  1014.         }
  1015.  
  1016. /*        Återställning till översättning vid HARD CR. */
  1017.         if (c == 13)
  1018.         {
  1019.             n=0;
  1020.             j=0;
  1021.             if (k == 0) k=1;
  1022.         }
  1023.  
  1024.         c1=c;
  1025. /*    If translation was allowed, we are translating the text now. */
  1026.  
  1027.         if (n == 0) c=(int)transchar((unsigned char)c,
  1028.             fromcharset, tocharset);
  1029.  
  1030. /*    If we are translating byte by byte to a non-"umlaut" format
  1031.     we only write the character returned by the translation routine.
  1032.     Otherwise the character is an index to the umlaut table.
  1033. */
  1034.  
  1035.         if (noout == 0 && (c1 != 10 || nolf == 0) &&
  1036.             (c1 != 0x8d || nosoft == 0))
  1037.         {
  1038.             if (tocharset >= 0 || n != 0)
  1039.             {
  1040.                 output[i0]=(unsigned char)c;
  1041.                 i0++;
  1042. /*                fputc(c, g1); */
  1043.             }
  1044.             else
  1045.             {
  1046.                 if (c == 0)
  1047.                 {
  1048.                     output[i0]=(unsigned char)c1;
  1049.                     i0++;
  1050. /*                    fputc(c1, g1); */
  1051.                 }
  1052.                 else
  1053.                 {
  1054.                     strcat((output + i0), umlaut[c-1]);
  1055.                     i0=i0+strlen(umlaut[c-1]);
  1056. /*                    fputs(umlaut[c-1], g1); */
  1057.                 }
  1058.             }
  1059.  
  1060.             if (i0 > 120 || c == 13)
  1061.             {
  1062.                 fwrite(output, sizeof(char), i0, g1);
  1063.                 i0=0;
  1064.             }
  1065.         }
  1066.  
  1067.         i++;
  1068.     }
  1069.  
  1070.     if (i0 > 0) fwrite(output, sizeof(char), i0, g1);
  1071.  
  1072. #ifdef MSDOS
  1073.     hfree(textarea);
  1074. #else
  1075.     free(textarea);
  1076. #endif
  1077.  
  1078.     return(0);
  1079. }
  1080.  
  1081. void    xlatefile(filnamn1, filnamn2, fromcharset, tocharset)
  1082. char    *filnamn1, *filnamn2;
  1083. int    fromcharset, tocharset;
  1084. {
  1085.     FILE    *f, *g1;
  1086.     char    tmp[80];
  1087.     int    z;
  1088.  
  1089. #ifdef MSDOS
  1090.     if ((g1=fopen(filnamn2, "wb")) == NULL)
  1091. #else
  1092.     if ((g1=fopen(filnamn2, "w")) == NULL)
  1093. #endif
  1094.     {
  1095.         sprintf(tmp, "Can't open file %s for writing", filnamn2);
  1096.         perror(tmp);
  1097.         return;
  1098.     }
  1099.  
  1100.  
  1101. #ifdef MSDOS
  1102.     if ((f=fopen(filnamn1, "rb")) == NULL)
  1103. #else
  1104.     if ((f=fopen(filnamn1, "r")) == NULL)
  1105. #endif
  1106.     {
  1107.         sprintf(tmp, "Can't open file %s for reading", filnamn1);
  1108.         perror(tmp);
  1109.         fclose(g1);
  1110.         return;
  1111.     }
  1112.  
  1113.     fseek(f, 0L, SEEK_SET);
  1114.  
  1115.     if (fread((char *) &packhd, sizeof(packheader), 1, f) != 0)
  1116.     {
  1117.         printf("PKT-file created at node : %d/%d\n",
  1118.             packhd.orignet, packhd.orignode);
  1119.  
  1120.         if (packhd.idcode != 0x0002)
  1121.         {
  1122.             printf("Unknown packet type\n");
  1123.             fclose(f);
  1124.             fclose(g1);
  1125.             return;
  1126.         }
  1127.  
  1128.         fwrite((char *) &packhd, sizeof(packheader), 1, g1);
  1129.  
  1130.         z=0;
  1131.         while(fread((char *) &packmsg, sizeof(packmsg), 1, f) != 0
  1132.             && z==0)
  1133.         {
  1134.             z=xlatetexts(f, g1, fromcharset, tocharset);
  1135.         }
  1136.  
  1137. /*    Terminate file with extra 0x00:s */
  1138.  
  1139.         fputc(0, g1);
  1140.         fputc(0, g1);
  1141.         fputc(0, g1);
  1142.     }
  1143.     fclose(f);
  1144.     fclose(g1);
  1145. }
  1146.