|
@@ -0,0 +1,176 @@
|
|
|
+/***************************************************************************
|
|
|
+ * _ _ ____ _
|
|
|
+ * 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>
|
|
|
+
|
|
|
+
|
|
|
+/* Variable-length string, with 16-bit length. */
|
|
|
+typedef struct {
|
|
|
+ short len;
|
|
|
+ char string[5000];
|
|
|
+} vary2;
|
|
|
+
|
|
|
+
|
|
|
+/* Arguments from CL command. */
|
|
|
+typedef struct {
|
|
|
+ char * pgm; /* Program name. */
|
|
|
+ vary2 * cmdargs; /* Command line arguments. */
|
|
|
+} 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, 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 *) "CURL", 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;
|
|
|
+}
|