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