178 lines
4.1 KiB
C
178 lines
4.1 KiB
C
|
/***************************************************************************
|
||
|
* _ _ ____ _
|
||
|
* Project ___| | | | _ \| |
|
||
|
* / __| | | | |_) | |
|
||
|
* | (__| |_| | _ <| |___
|
||
|
* \___|\___/|_| \_\_____|
|
||
|
*
|
||
|
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, 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 <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
#include <milib.h>
|
||
|
#include <miptrnam.h>
|
||
|
#include <mih/callpgmv.h>
|
||
|
|
||
|
#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;
|
||
|
}
|