quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

curlcl.c (4185B)


      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  * SPDX-License-Identifier: curl
     22  *
     23  *
     24  ***************************************************************************/
     25 
     26 /* CL interface program to curl cli tool. */
     27 
     28 #include <stdio.h>
     29 #include <stdlib.h>
     30 
     31 #include <milib.h>
     32 #include <miptrnam.h>
     33 #include <mih/callpgmv.h>
     34 
     35 #ifndef CURLPGM
     36 #define CURLPGM "CURL"
     37 #endif
     38 
     39 /* Variable-length string, with 16-bit length. */
     40 struct vary2 {
     41   short len;
     42   char  string[5000];
     43 };
     44 
     45 /* Arguments from CL command. */
     46 struct arguments {
     47   char         *pgm;            /* Program name. */
     48   struct vary2 *cmdargs;        /* Command line arguments. */
     49 };
     50 
     51 static int
     52 is_ifs(char c)
     53 {
     54   return c == ' ' || c == '\t' || c == '\r' || c == '\n';
     55 }
     56 
     57 static int
     58 parse_command_line(const char *cmdargs, size_t len,
     59                    size_t *argc, char **argv,
     60                    size_t *argsize, char *argbuf)
     61 {
     62   const char *endline = cmdargs + len;
     63   char quote = '\0';
     64   int inarg = 0;
     65 
     66   *argc = 0;
     67   *argsize = 0;
     68 
     69   while(cmdargs < endline) {
     70     char c = *cmdargs++;
     71 
     72     if(!inarg) {
     73       /* Skip argument separator. */
     74       if(is_ifs(c))
     75         continue;
     76 
     77       /* Start a new argument. */
     78       ++*argc;
     79       if(argv)
     80         *argv++ = argbuf;
     81       inarg = 1;
     82     }
     83 
     84     /* Check for quoting end. */
     85     if(quote && quote == c) {
     86       quote = '\0';
     87       continue;
     88     }
     89 
     90     /* Check for backslash-escaping. */
     91     if(quote != '\'' && c == '\\') {
     92       if(cmdargs >= endline) {
     93         fputs("Trailing backslash in command\n", stderr);
     94         return -1;
     95       }
     96       c = *cmdargs++;
     97     }
     98     else if(!quote && is_ifs(c)) {      /* Check for end of argument. */
     99       inarg = 0;
    100       c = '\0';         /* Will store a string terminator. */
    101     }
    102 
    103     /* Store argument character and count it. */
    104     if(argbuf)
    105       *argbuf++ = c;
    106     ++*argsize;
    107   }
    108 
    109   if(quote) {
    110     fprintf(stderr, "Unterminated quote: %c\n", quote);
    111     return -1;
    112   }
    113 
    114   /* Terminate last argument. */
    115   if(inarg) {
    116     if(argbuf)
    117       *argbuf = '\0';
    118     ++*argsize;
    119   }
    120 
    121   /* Terminate argument list. */
    122   if(argv)
    123     *argv = NULL;
    124 
    125   return 0;
    126 }
    127 
    128 
    129 int
    130 main(int argsc, struct arguments *args)
    131 {
    132   size_t argc;
    133   char **argv;
    134   size_t argsize;
    135   int i;
    136   int exitcode;
    137   char library[11];
    138 
    139   /* Extract current program library name. */
    140   for(i = 0; i < 10; i++) {
    141     char c = args->pgm[i];
    142 
    143     if(!c || c == '/')
    144       break;
    145 
    146     library[i] = c;
    147   }
    148   library[i] = '\0';
    149 
    150   /* Measure arguments size. */
    151   exitcode = parse_command_line(args->cmdargs->string, args->cmdargs->len,
    152                                 &argc, NULL, &argsize, NULL);
    153 
    154   if(!exitcode) {
    155     /* Allocate space for parsed arguments. */
    156     argv = (char **) malloc((argc + 1) * sizeof(*argv) + argsize);
    157     if(!argv) {
    158       fputs("Memory allocation error\n", stderr);
    159       exitcode = -2;
    160     }
    161     else {
    162       _SYSPTR pgmptr = rslvsp(WLI_PGM, (char *) CURLPGM, library, _AUTH_NONE);
    163       _LU_Work_Area_T *luwrka = (_LU_Work_Area_T *) _LUWRKA();
    164 
    165       parse_command_line(args->cmdargs->string, args->cmdargs->len,
    166                          &argc, argv, &argsize, (char *) (argv + argc + 1));
    167 
    168       /* Call program. */
    169       _CALLPGMV((void *) &pgmptr, argv, argc);
    170       exitcode = luwrka->LU_RC;
    171 
    172       free(argv);
    173     }
    174   }
    175 
    176   return exitcode;
    177 }