(root)/
libxml2-2.12.3/
os400/
xmlcatlgcl.c
       1  /**
       2  ***     XMLCATALOG command response program.
       3  ***
       4  ***     See Copyright for the status of this software.
       5  ***
       6  ***     Author: Patrick Monnerat <pm@datasphere.ch>, DATASPHERE S.A.
       7  **/
       8  
       9  #include <stdio.h>
      10  #include <stdlib.h>
      11  #include <string.h>
      12  #include <qshell.h>
      13  
      14  
      15  /* Variable-length string, with 16-bit length. */
      16  typedef struct {
      17          short           len;
      18          char            string[5000];
      19  }               vary2;
      20  
      21  
      22  /* Variable-length string, with 32-bit length. */
      23  typedef struct {
      24          int             len;
      25          char            string[5000];
      26  }               vary4;
      27  
      28  
      29  /* Multiple occurrence parameter list. */
      30  #define paramlist(itemsize, itemtype)                                   \
      31          _Packed struct {                                                \
      32                  short           len;                                    \
      33                  _Packed union {                                         \
      34                           char           _pad[itemsize];                 \
      35                          itemtype        param;                          \
      36                  }               item[1];                                \
      37          }
      38  
      39  /* Add element list structure. */
      40  typedef struct {
      41          short           elcount;        /* Element count (=3). */
      42          paramlist(16, char) type;       /* vary2(16). */
      43          paramlist(256, char) origin;    /* vary2(256). */
      44          paramlist(256, char) replace;   /* vary2(256). */
      45  }               addelement;
      46  
      47  /* SGML add element list structure. */
      48  typedef struct {
      49          short           elcount;        /* Element count (=3). */
      50          paramlist(256, char) catalog;   /* vary2(256). */
      51          paramlist(256, char) ident;     /* vary2(256). */
      52  }               sgmladdelement;
      53  
      54  
      55  /* Arguments from CL command. */
      56  typedef struct {
      57          char *          pgm;            /* Program name. */
      58          vary2 *         instmf;         /* Input catalog file name. */
      59          vary2 *         kind;           /* Catalog kind. */
      60          vary2 *         outstmf;        /* Output catalog file name. */
      61          vary2 *         convert;        /* Convert SGML to XML. */
      62          vary2 *         superupd;       /* --no-super-update. */
      63          vary2 *         verbose;        /* Verbose output. */
      64          paramlist(256 + 2, vary2) * delete; /* Identifiers to delete. */
      65          paramlist(2, unsigned short) * add; /* Items to add. */
      66          paramlist(2, unsigned short) * sgmladd; /* SGML items to add. */
      67          paramlist(256 + 2, vary2) * resolve; /* Identifiers to resolve. */
      68          paramlist(5000 + 2, vary2) * catalog; /* Additional catalog files. */
      69  }               arguments;
      70  
      71  
      72  /* Definition of QSHELL program. */
      73  extern void     qshell(vary4 * cmd);
      74  #pragma linkage(qshell, OS)
      75  #pragma map(qshell, "QSHELL/QZSHQSHC")
      76  
      77  /* Macro to handle displacements. */
      78  #define OFFSETBY(t, p, n)       ((t *) (((char *) (p)) + (n)))
      79  
      80  
      81  static void
      82  vary4nappend(vary4 * dst, const char * src, size_t len)
      83  
      84  {
      85          if (len > sizeof(dst->string) - dst->len)
      86                  len = sizeof(dst->string) - dst->len;
      87  
      88          if (len) {
      89                  memcpy(dst->string + dst->len, src, len);
      90                  dst->len += len;
      91                  }
      92  }
      93  
      94  
      95  static void
      96  vary4append(vary4 * dst, const char * src)
      97  
      98  {
      99          vary4nappend(dst, src, strlen(src));
     100  }
     101  
     102  
     103  static void
     104  vary4arg(vary4 * dst, const char * arg)
     105  
     106  {
     107          vary4nappend(dst, " ", 1);
     108          vary4append(dst, arg);
     109  }
     110  
     111  
     112  static void
     113  vary4varg(vary4 * dst, vary2 * arg)
     114  
     115  {
     116          vary4nappend(dst, " ", 1);
     117          vary4nappend(dst, arg->string, arg->len);
     118  }
     119  
     120  
     121  static void
     122  vary4vescape(vary4 * dst, vary2 * arg)
     123  
     124  {
     125          int i;
     126  
     127          for (i = 0; i < arg->len; i++)
     128                  if (arg->string[i] == '\'')
     129                          vary4nappend(dst, "'\"'\"'", 5);
     130                  else
     131                          vary4nappend(dst, arg->string + i, 1);
     132  }
     133  
     134  
     135  static void
     136  vary4vargquote(vary4 * dst, vary2 * arg)
     137  
     138  {
     139          vary4nappend(dst, " '", 2);
     140          vary4vescape(dst, arg);
     141          vary4nappend(dst, "'", 1);
     142  }
     143  
     144  
     145  int
     146  main(int argsc, arguments * args)
     147  
     148  {
     149          vary4 cmd;
     150          int i;
     151          char c;
     152          addelement * aelp;
     153          sgmladdelement * saelp;
     154  
     155          /* Specify additional catalogs. */
     156          cmd.len = 0;
     157          if (args->catalog->len) {
     158                  for (i = 0; i < args->catalog->len &&
     159                              !args->catalog->item[i].param.len; i++)
     160                          ;
     161  
     162                  vary4append(&cmd, "XML_CATALOG_FILES=");
     163                  if (i < args->catalog->len) {
     164                          c = '\'';
     165                          for (i = 0; i < args->catalog->len; i++) {
     166                                  if (!args->catalog->item[i].param.len)
     167                                          continue;
     168                                  vary4nappend(&cmd, &c, 1);
     169                                  c = ' ';
     170                                  vary4vescape(&cmd,
     171                                              &args->catalog->item[i].param);
     172                                  }
     173                          vary4nappend(&cmd, "'", 1);
     174                          }
     175                  vary4nappend(&cmd, " ", 1);
     176                  }
     177  
     178          /* find length of library name. */
     179          for (i = 0; i < 10 && args->pgm[i] && args->pgm[i] != '/'; i++)
     180                  ;
     181  
     182          /* Store program name in command buffer. */
     183          vary4append(&cmd, "/QSYS.LIB/");
     184          vary4nappend(&cmd, args->pgm, i);
     185          vary4append(&cmd, ".LIB/XMLCATALOG.PGM");
     186  
     187          /* Map command arguments to standard xmlcatalog argument vector. */
     188          if (args->kind && args->kind->len)
     189                  vary4varg(&cmd, args->kind);
     190  
     191          if (args->verbose && args->verbose->len)
     192                  vary4varg(&cmd, args->verbose);
     193  
     194          if (args->delete)
     195                  for (i = 0; i < args->delete->len; i++) {
     196                          vary4arg(&cmd, "--del");
     197                          vary4vargquote(&cmd, &args->delete->item[i].param);
     198                          }
     199  
     200          if (args->kind && args->kind->len) {
     201                  /* Process SGML-specific parameters. */
     202                  if (args->superupd && args->superupd->len)
     203                          vary4varg(&cmd, args->superupd);
     204  
     205                  if (args->sgmladd)
     206                          for (i = 0; i < args->sgmladd->len; i++) {
     207                                  saelp = OFFSETBY(sgmladdelement, args->sgmladd,
     208                                                  args->sgmladd->item[i].param);
     209                                  if (!((vary2 *) &saelp->catalog)->len)
     210                                          continue;
     211                                  vary4arg(&cmd, "--add");
     212                                  vary4vargquote(&cmd, (vary2 *) &saelp->catalog);
     213                                  vary4vargquote(&cmd, (vary2 *) &saelp->ident);
     214                                  }
     215                  }
     216          else {
     217                  /* Process XML-specific parameters. */
     218                  if (args->convert && args->convert->len)
     219                          vary4varg(&cmd, args->convert);
     220  
     221                  if (args->add)
     222                          for (i = 0; i < args->add->len; i++) {
     223                                  aelp = OFFSETBY(addelement, args->add,
     224                                                  args->add->item[i].param);
     225                                  if (!((vary2 *) &aelp->origin)->len)
     226                                          continue;
     227                                  vary4arg(&cmd, "--add");
     228                                  vary4varg(&cmd, (vary2 *) &aelp->type);
     229                                  vary4vargquote(&cmd, (vary2 *) &aelp->origin);
     230                                  vary4vargquote(&cmd, (vary2 *) &aelp->replace);
     231                                  }
     232                  }
     233  
     234          /* Avoid INSTMF(*NEW) and OUTSMTF(*INSTMF). */
     235          if (args->outstmf && args->outstmf->len && !args->outstmf->string[0])
     236                  if (args->instmf && args->instmf->len)
     237                          args->outstmf = args->instmf;
     238                  else
     239                          args->outstmf = NULL;
     240  
     241          /* If INSTMF(*NEW) and OUTSTMF(somepath), Use --create --noout and
     242             somepath as (unexisting) input file. */
     243          if (args->outstmf && args->outstmf->len)
     244                  if (!args->instmf || !args->instmf->len) {
     245                          vary4arg(&cmd, "--create");
     246                          vary4arg(&cmd, "--noout");
     247                          args->instmf = args->outstmf;
     248                          args->outstmf = NULL;
     249                          }
     250  
     251          /* If output to input file, use --noout option. */
     252          if (args->instmf && args->outstmf && args->instmf->len &&
     253              args->instmf->len == args->outstmf->len &&
     254              !strncmp(args->instmf->string, args->outstmf->string,
     255                       args->instmf->len)) {
     256                  vary4arg(&cmd, "--noout");
     257                  args->outstmf = NULL;
     258                  }
     259  
     260          /* If no input file create catalog, else specify the input file name. */
     261          /* Specify the input file name: my be a dummy one. */
     262          if (!args->instmf || !args->instmf->len) {
     263                  vary4arg(&cmd, "--create -");
     264                  vary4arg(&cmd, ".dmyxmlcatalog");
     265                  }
     266          else {
     267                  vary4arg(&cmd, "-");
     268                  vary4vargquote(&cmd, args->instmf);
     269                  }
     270  
     271          /* Query entities. */
     272  
     273          if (args->resolve)
     274                  for (i = 0; i < args->resolve->len; i++)
     275                          vary4vargquote(&cmd, &args->resolve->item[i].param);
     276  
     277          /* Redirect output if requested. */
     278          if (args->outstmf && args->outstmf->len) {
     279                  vary4arg(&cmd, ">");
     280                  vary4vargquote(&cmd, args->outstmf);
     281                  }
     282  
     283          /* Execute the shell command. */
     284          qshell(&cmd);
     285  
     286          /* Terminate. */
     287          exit(0);
     288  }