1b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat/**
2b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat***     QADRT/QADRTMAIN2 substitution program.
3b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat***     This is needed because the IBM-provided QADRTMAIN2 does not
4b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat***     properly translate arguments by default or if no locale is provided.
5b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat***
6b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat***     See Copyright for the status of this software.
7b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat***
8b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat***     Author: Patrick Monnerat <pm@datasphere.ch>, DATASPHERE S.A.
9b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat**/
10b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
11b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat#include <stdlib.h>
12b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat#include <string.h>
13b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat#include <iconv.h>
14b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat#include <errno.h>
15b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat#include <locale.h>
16b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
17b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat/* Do not use qadrt.h since it defines unneeded static procedures. */
18b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monneratextern void     QadrtInit(void);
19b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monneratextern int      QadrtFreeConversionTable(void);
20b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monneratextern int      QadrtFreeEnviron(void);
21b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monneratextern char *   setlocale_a(int, const char *);
22b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
23b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
24b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat/* The ASCII main program. */
25b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monneratextern int      main_a(int argc, char * * argv);
26b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
27b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat/* Global values of original EBCDIC arguments. */
28b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monneratint             ebcdic_argc;
29b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monneratchar * *        ebcdic_argv;
30b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
31b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
32b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monneratint
33b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monneratmain(int argc, char * * argv)
34b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
35b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat{
36b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        int i;
37b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        int j;
38b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        iconv_t cd;
39b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        size_t bytecount = 0;
40b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        char * inbuf;
41b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        char * outbuf;
42b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        size_t inbytesleft;
43b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        size_t outbytesleft;
44b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        char dummybuf[128];
45b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        char tocode[32];
46b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        char fromcode[32];
47b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
48b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        ebcdic_argc = argc;
49b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        ebcdic_argv = argv;
50b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
51b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        /* Build the encoding converter. */
52b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        strncpy(tocode, "IBMCCSID01208", sizeof tocode);
53b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        strncpy(fromcode, "IBMCCSID000000000010", sizeof fromcode);
54b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        cd = iconv_open(tocode, fromcode);
55b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
56b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        /* Measure the arguments. */
57b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        for (i = 0; i < argc; i++) {
58b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat                inbuf = argv[i];
59b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat                do {
60b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat                        inbytesleft = 0;
61b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat                        outbuf = dummybuf;
62b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat                        outbytesleft = sizeof dummybuf;
63b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat                        j = iconv(cd,
64b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat                                  &inbuf, &inbytesleft, &outbuf, &outbytesleft);
65b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat                        bytecount += outbuf - dummybuf;
66b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat                } while (j == -1 && errno == E2BIG);
67b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat                /* Reset the shift state. */
68b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat                iconv(cd, NULL, &inbytesleft, &outbuf, &outbytesleft);
69b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat                }
70b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
71b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        /* Allocate memory for the ASCII arguments and vector. */
72b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        argv = (char * *) malloc((argc + 1) * sizeof *argv + bytecount);
73b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
74b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        /* Build the vector and convert argument encoding. */
75b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        outbuf = (char *) (argv + argc + 1);
76b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        outbytesleft = bytecount;
77b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
78b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        for (i = 0; i < argc; i++) {
79b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat                argv[i] = outbuf;
80b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat                inbuf = ebcdic_argv[i];
81b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat                inbytesleft = 0;
82b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat                iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
83b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat                iconv(cd, NULL, &inbytesleft, &outbuf, &outbytesleft);
84b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat                }
85b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
86b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        iconv_close(cd);
87b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        argv[argc] = NULL;
88b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
89b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        /* Try setting the locale regardless of QADRT_ENV_LOCALE. */
90b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        setlocale_a(LC_ALL, "");
91b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
92b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        /* Call the program. */
93b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        i = main_a(argc, argv);
94b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
95b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        /* Clean-up allocated items. */
96b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        free((char *) argv);
97b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        QadrtFreeConversionTable();
98b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        QadrtFreeEnviron();
99b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat
100b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        /* Terminate. */
101b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat        return i;
102b1682bdb93f473bc82c5e8cde4fcfb01dc8165bfPatrick Monnerat}
103