/*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | * / __| | | | |_) | | * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * * Copyright (C) Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is * furnished to do so, under the terms of the COPYING file. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * * SPDX-License-Identifier: curl * * ***************************************************************************/ /* CL interface program to curl cli tool. */ #include #include #include #include #include #ifndef CURLPGM #define CURLPGM "CURL" #endif /* Variable-length string, with 16-bit length. */ struct vary2 { short len; char string[5000]; }; /* Arguments from CL command. */ struct arguments { char *pgm; /* Program name. */ struct vary2 *cmdargs; /* Command line arguments. */ }; static int is_ifs(char c) { return c == ' ' || c == '\t' || c == '\r' || c == '\n'; } static int parse_command_line(const char *cmdargs, size_t len, size_t *argc, char **argv, size_t *argsize, char *argbuf) { const char *endline = cmdargs + len; char quote = '\0'; int inarg = 0; *argc = 0; *argsize = 0; while(cmdargs < endline) { char c = *cmdargs++; if(!inarg) { /* Skip argument separator. */ if(is_ifs(c)) continue; /* Start a new argument. */ ++*argc; if(argv) *argv++ = argbuf; inarg = 1; } /* Check for quoting end. */ if(quote && quote == c) { quote = '\0'; continue; } /* Check for backslash-escaping. */ if(quote != '\'' && c == '\\') { if(cmdargs >= endline) { fputs("Trailing backslash in command\n", stderr); return -1; } c = *cmdargs++; } else if(!quote && is_ifs(c)) { /* Check for end of argument. */ inarg = 0; c = '\0'; /* Will store a string terminator. */ } /* Store argument character and count it. */ if(argbuf) *argbuf++ = c; ++*argsize; } if(quote) { fprintf(stderr, "Unterminated quote: %c\n", quote); return -1; } /* Terminate last argument. */ if(inarg) { if(argbuf) *argbuf = '\0'; ++*argsize; } /* Terminate argument list. */ if(argv) *argv = NULL; return 0; } int main(int argsc, struct arguments *args) { size_t argc; char **argv; size_t argsize; int i; int exitcode; char library[11]; /* Extract current program library name. */ for(i = 0; i < 10; i++) { char c = args->pgm[i]; if(!c || c == '/') break; library[i] = c; } library[i] = '\0'; /* Measure arguments size. */ exitcode = parse_command_line(args->cmdargs->string, args->cmdargs->len, &argc, NULL, &argsize, NULL); if(!exitcode) { /* Allocate space for parsed arguments. */ argv = (char **) malloc((argc + 1) * sizeof(*argv) + argsize); if(!argv) { fputs("Memory allocation error\n", stderr); exitcode = -2; } else { _SYSPTR pgmptr = rslvsp(WLI_PGM, (char *) CURLPGM, library, _AUTH_NONE); _LU_Work_Area_T *luwrka = (_LU_Work_Area_T *) _LUWRKA(); parse_command_line(args->cmdargs->string, args->cmdargs->len, &argc, argv, &argsize, (char *) (argv + argc + 1)); /* Call program. */ _CALLPGMV((void *) &pgmptr, argv, argc); exitcode = luwrka->LU_RC; free(argv); } } return exitcode; }