/***************************************************************************1* _ _ ____ _2* Project ___| | | | _ \| |3* / __| | | | |_) | |4* | (__| |_| | _ <| |___5* \___|\___/|_| \_\_____|6*7* Copyright (C) Daniel Stenberg, <[email protected]>, et al.8*9* This software is licensed as described in the file COPYING, which10* you should have received as part of this distribution. The terms11* are also available at https://curl.se/docs/copyright.html.12*13* You may opt to use, copy, modify, merge, publish, distribute and/or sell14* copies of the Software, and permit persons to whom the Software is15* furnished to do so, under the terms of the COPYING file.16*17* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY18* KIND, either express or implied.19*20* SPDX-License-Identifier: curl21*22*23***************************************************************************/2425/* CL interface program to curl cli tool. */2627#include <stdio.h>28#include <stdlib.h>2930#include <milib.h>31#include <miptrnam.h>32#include <mih/callpgmv.h>3334#ifndef CURLPGM35#define CURLPGM "CURL"36#endif3738/* Variable-length string, with 16-bit length. */39struct vary2 {40short len;41char string[5000];42};4344/* Arguments from CL command. */45struct arguments {46char *pgm; /* Program name. */47struct vary2 *cmdargs; /* Command line arguments. */48};4950static int51is_ifs(char c)52{53return c == ' ' || c == '\t' || c == '\r' || c == '\n';54}5556static int57parse_command_line(const char *cmdargs, size_t len,58size_t *argc, char **argv,59size_t *argsize, char *argbuf)60{61const char *endline = cmdargs + len;62char quote = '\0';63int inarg = 0;6465*argc = 0;66*argsize = 0;6768while(cmdargs < endline) {69char c = *cmdargs++;7071if(!inarg) {72/* Skip argument separator. */73if(is_ifs(c))74continue;7576/* Start a new argument. */77++*argc;78if(argv)79*argv++ = argbuf;80inarg = 1;81}8283/* Check for quoting end. */84if(quote && quote == c) {85quote = '\0';86continue;87}8889/* Check for backslash-escaping. */90if(quote != '\'' && c == '\\') {91if(cmdargs >= endline) {92fputs("Trailing backslash in command\n", stderr);93return -1;94}95c = *cmdargs++;96}97else if(!quote && is_ifs(c)) { /* Check for end of argument. */98inarg = 0;99c = '\0'; /* Will store a string terminator. */100}101102/* Store argument character and count it. */103if(argbuf)104*argbuf++ = c;105++*argsize;106}107108if(quote) {109/* !checksrc! disable BANNEDFUNC 1 */110fprintf(stderr, "Unterminated quote: %c\n", quote);111return -1;112}113114/* Terminate last argument. */115if(inarg) {116if(argbuf)117*argbuf = '\0';118++*argsize;119}120121/* Terminate argument list. */122if(argv)123*argv = NULL;124125return 0;126}127128129int130main(int argsc, struct arguments *args)131{132size_t argc;133char **argv;134size_t argsize;135int i;136int exitcode;137char library[11];138139/* Extract current program library name. */140for(i = 0; i < 10; i++) {141char c = args->pgm[i];142143if(!c || c == '/')144break;145146library[i] = c;147}148library[i] = '\0';149150/* Measure arguments size. */151exitcode = parse_command_line(args->cmdargs->string, args->cmdargs->len,152&argc, NULL, &argsize, NULL);153154if(!exitcode) {155/* Allocate space for parsed arguments. */156argv = (char **) malloc((argc + 1) * sizeof(*argv) + argsize);157if(!argv) {158fputs("Memory allocation error\n", stderr);159exitcode = -2;160}161else {162_SYSPTR pgmptr = rslvsp(WLI_PGM, (char *) CURLPGM, library, _AUTH_NONE);163_LU_Work_Area_T *luwrka = (_LU_Work_Area_T *) _LUWRKA();164165parse_command_line(args->cmdargs->string, args->cmdargs->len,166&argc, argv, &argsize, (char *) (argv + argc + 1));167168/* Call program. */169_CALLPGMV((void *) &pgmptr, argv, argc);170exitcode = luwrka->LU_RC;171172free(argv);173}174}175176return exitcode;177}178179180