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 }