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