1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker * _ _ ____ _
3*6236dae4SAndroid Build Coastguard Worker * Project ___| | | | _ \| |
4*6236dae4SAndroid Build Coastguard Worker * / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker * | (__| |_| | _ <| |___
6*6236dae4SAndroid Build Coastguard Worker * \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker *
8*6236dae4SAndroid Build Coastguard Worker * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9*6236dae4SAndroid Build Coastguard Worker *
10*6236dae4SAndroid Build Coastguard Worker * This software is licensed as described in the file COPYING, which
11*6236dae4SAndroid Build Coastguard Worker * you should have received as part of this distribution. The terms
12*6236dae4SAndroid Build Coastguard Worker * are also available at https://curl.se/docs/copyright.html.
13*6236dae4SAndroid Build Coastguard Worker *
14*6236dae4SAndroid Build Coastguard Worker * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15*6236dae4SAndroid Build Coastguard Worker * copies of the Software, and permit persons to whom the Software is
16*6236dae4SAndroid Build Coastguard Worker * furnished to do so, under the terms of the COPYING file.
17*6236dae4SAndroid Build Coastguard Worker *
18*6236dae4SAndroid Build Coastguard Worker * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19*6236dae4SAndroid Build Coastguard Worker * KIND, either express or implied.
20*6236dae4SAndroid Build Coastguard Worker *
21*6236dae4SAndroid Build Coastguard Worker * SPDX-License-Identifier: curl
22*6236dae4SAndroid Build Coastguard Worker *
23*6236dae4SAndroid Build Coastguard Worker *
24*6236dae4SAndroid Build Coastguard Worker ***************************************************************************/
25*6236dae4SAndroid Build Coastguard Worker
26*6236dae4SAndroid Build Coastguard Worker /* CL interface program to curl cli tool. */
27*6236dae4SAndroid Build Coastguard Worker
28*6236dae4SAndroid Build Coastguard Worker #include <stdio.h>
29*6236dae4SAndroid Build Coastguard Worker #include <stdlib.h>
30*6236dae4SAndroid Build Coastguard Worker
31*6236dae4SAndroid Build Coastguard Worker #include <milib.h>
32*6236dae4SAndroid Build Coastguard Worker #include <miptrnam.h>
33*6236dae4SAndroid Build Coastguard Worker #include <mih/callpgmv.h>
34*6236dae4SAndroid Build Coastguard Worker
35*6236dae4SAndroid Build Coastguard Worker #ifndef CURLPGM
36*6236dae4SAndroid Build Coastguard Worker #define CURLPGM "CURL"
37*6236dae4SAndroid Build Coastguard Worker #endif
38*6236dae4SAndroid Build Coastguard Worker
39*6236dae4SAndroid Build Coastguard Worker /* Variable-length string, with 16-bit length. */
40*6236dae4SAndroid Build Coastguard Worker struct vary2 {
41*6236dae4SAndroid Build Coastguard Worker short len;
42*6236dae4SAndroid Build Coastguard Worker char string[5000];
43*6236dae4SAndroid Build Coastguard Worker };
44*6236dae4SAndroid Build Coastguard Worker
45*6236dae4SAndroid Build Coastguard Worker /* Arguments from CL command. */
46*6236dae4SAndroid Build Coastguard Worker struct arguments {
47*6236dae4SAndroid Build Coastguard Worker char *pgm; /* Program name. */
48*6236dae4SAndroid Build Coastguard Worker struct vary2 *cmdargs; /* Command line arguments. */
49*6236dae4SAndroid Build Coastguard Worker };
50*6236dae4SAndroid Build Coastguard Worker
51*6236dae4SAndroid Build Coastguard Worker static int
is_ifs(char c)52*6236dae4SAndroid Build Coastguard Worker is_ifs(char c)
53*6236dae4SAndroid Build Coastguard Worker {
54*6236dae4SAndroid Build Coastguard Worker return c == ' ' || c == '\t' || c == '\r' || c == '\n';
55*6236dae4SAndroid Build Coastguard Worker }
56*6236dae4SAndroid Build Coastguard Worker
57*6236dae4SAndroid Build Coastguard Worker static int
parse_command_line(const char * cmdargs,size_t len,size_t * argc,char ** argv,size_t * argsize,char * argbuf)58*6236dae4SAndroid Build Coastguard Worker parse_command_line(const char *cmdargs, size_t len,
59*6236dae4SAndroid Build Coastguard Worker size_t *argc, char **argv,
60*6236dae4SAndroid Build Coastguard Worker size_t *argsize, char *argbuf)
61*6236dae4SAndroid Build Coastguard Worker {
62*6236dae4SAndroid Build Coastguard Worker const char *endline = cmdargs + len;
63*6236dae4SAndroid Build Coastguard Worker char quote = '\0';
64*6236dae4SAndroid Build Coastguard Worker int inarg = 0;
65*6236dae4SAndroid Build Coastguard Worker
66*6236dae4SAndroid Build Coastguard Worker *argc = 0;
67*6236dae4SAndroid Build Coastguard Worker *argsize = 0;
68*6236dae4SAndroid Build Coastguard Worker
69*6236dae4SAndroid Build Coastguard Worker while(cmdargs < endline) {
70*6236dae4SAndroid Build Coastguard Worker char c = *cmdargs++;
71*6236dae4SAndroid Build Coastguard Worker
72*6236dae4SAndroid Build Coastguard Worker if(!inarg) {
73*6236dae4SAndroid Build Coastguard Worker /* Skip argument separator. */
74*6236dae4SAndroid Build Coastguard Worker if(is_ifs(c))
75*6236dae4SAndroid Build Coastguard Worker continue;
76*6236dae4SAndroid Build Coastguard Worker
77*6236dae4SAndroid Build Coastguard Worker /* Start a new argument. */
78*6236dae4SAndroid Build Coastguard Worker ++*argc;
79*6236dae4SAndroid Build Coastguard Worker if(argv)
80*6236dae4SAndroid Build Coastguard Worker *argv++ = argbuf;
81*6236dae4SAndroid Build Coastguard Worker inarg = 1;
82*6236dae4SAndroid Build Coastguard Worker }
83*6236dae4SAndroid Build Coastguard Worker
84*6236dae4SAndroid Build Coastguard Worker /* Check for quoting end. */
85*6236dae4SAndroid Build Coastguard Worker if(quote && quote == c) {
86*6236dae4SAndroid Build Coastguard Worker quote = '\0';
87*6236dae4SAndroid Build Coastguard Worker continue;
88*6236dae4SAndroid Build Coastguard Worker }
89*6236dae4SAndroid Build Coastguard Worker
90*6236dae4SAndroid Build Coastguard Worker /* Check for backslash-escaping. */
91*6236dae4SAndroid Build Coastguard Worker if(quote != '\'' && c == '\\') {
92*6236dae4SAndroid Build Coastguard Worker if(cmdargs >= endline) {
93*6236dae4SAndroid Build Coastguard Worker fputs("Trailing backslash in command\n", stderr);
94*6236dae4SAndroid Build Coastguard Worker return -1;
95*6236dae4SAndroid Build Coastguard Worker }
96*6236dae4SAndroid Build Coastguard Worker c = *cmdargs++;
97*6236dae4SAndroid Build Coastguard Worker }
98*6236dae4SAndroid Build Coastguard Worker else if(!quote && is_ifs(c)) { /* Check for end of argument. */
99*6236dae4SAndroid Build Coastguard Worker inarg = 0;
100*6236dae4SAndroid Build Coastguard Worker c = '\0'; /* Will store a string terminator. */
101*6236dae4SAndroid Build Coastguard Worker }
102*6236dae4SAndroid Build Coastguard Worker
103*6236dae4SAndroid Build Coastguard Worker /* Store argument character and count it. */
104*6236dae4SAndroid Build Coastguard Worker if(argbuf)
105*6236dae4SAndroid Build Coastguard Worker *argbuf++ = c;
106*6236dae4SAndroid Build Coastguard Worker ++*argsize;
107*6236dae4SAndroid Build Coastguard Worker }
108*6236dae4SAndroid Build Coastguard Worker
109*6236dae4SAndroid Build Coastguard Worker if(quote) {
110*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "Unterminated quote: %c\n", quote);
111*6236dae4SAndroid Build Coastguard Worker return -1;
112*6236dae4SAndroid Build Coastguard Worker }
113*6236dae4SAndroid Build Coastguard Worker
114*6236dae4SAndroid Build Coastguard Worker /* Terminate last argument. */
115*6236dae4SAndroid Build Coastguard Worker if(inarg) {
116*6236dae4SAndroid Build Coastguard Worker if(argbuf)
117*6236dae4SAndroid Build Coastguard Worker *argbuf = '\0';
118*6236dae4SAndroid Build Coastguard Worker ++*argsize;
119*6236dae4SAndroid Build Coastguard Worker }
120*6236dae4SAndroid Build Coastguard Worker
121*6236dae4SAndroid Build Coastguard Worker /* Terminate argument list. */
122*6236dae4SAndroid Build Coastguard Worker if(argv)
123*6236dae4SAndroid Build Coastguard Worker *argv = NULL;
124*6236dae4SAndroid Build Coastguard Worker
125*6236dae4SAndroid Build Coastguard Worker return 0;
126*6236dae4SAndroid Build Coastguard Worker }
127*6236dae4SAndroid Build Coastguard Worker
128*6236dae4SAndroid Build Coastguard Worker
129*6236dae4SAndroid Build Coastguard Worker int
main(int argsc,struct arguments * args)130*6236dae4SAndroid Build Coastguard Worker main(int argsc, struct arguments *args)
131*6236dae4SAndroid Build Coastguard Worker {
132*6236dae4SAndroid Build Coastguard Worker size_t argc;
133*6236dae4SAndroid Build Coastguard Worker char **argv;
134*6236dae4SAndroid Build Coastguard Worker size_t argsize;
135*6236dae4SAndroid Build Coastguard Worker int i;
136*6236dae4SAndroid Build Coastguard Worker int exitcode;
137*6236dae4SAndroid Build Coastguard Worker char library[11];
138*6236dae4SAndroid Build Coastguard Worker
139*6236dae4SAndroid Build Coastguard Worker /* Extract current program library name. */
140*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < 10; i++) {
141*6236dae4SAndroid Build Coastguard Worker char c = args->pgm[i];
142*6236dae4SAndroid Build Coastguard Worker
143*6236dae4SAndroid Build Coastguard Worker if(!c || c == '/')
144*6236dae4SAndroid Build Coastguard Worker break;
145*6236dae4SAndroid Build Coastguard Worker
146*6236dae4SAndroid Build Coastguard Worker library[i] = c;
147*6236dae4SAndroid Build Coastguard Worker }
148*6236dae4SAndroid Build Coastguard Worker library[i] = '\0';
149*6236dae4SAndroid Build Coastguard Worker
150*6236dae4SAndroid Build Coastguard Worker /* Measure arguments size. */
151*6236dae4SAndroid Build Coastguard Worker exitcode = parse_command_line(args->cmdargs->string, args->cmdargs->len,
152*6236dae4SAndroid Build Coastguard Worker &argc, NULL, &argsize, NULL);
153*6236dae4SAndroid Build Coastguard Worker
154*6236dae4SAndroid Build Coastguard Worker if(!exitcode) {
155*6236dae4SAndroid Build Coastguard Worker /* Allocate space for parsed arguments. */
156*6236dae4SAndroid Build Coastguard Worker argv = (char **) malloc((argc + 1) * sizeof(*argv) + argsize);
157*6236dae4SAndroid Build Coastguard Worker if(!argv) {
158*6236dae4SAndroid Build Coastguard Worker fputs("Memory allocation error\n", stderr);
159*6236dae4SAndroid Build Coastguard Worker exitcode = -2;
160*6236dae4SAndroid Build Coastguard Worker }
161*6236dae4SAndroid Build Coastguard Worker else {
162*6236dae4SAndroid Build Coastguard Worker _SYSPTR pgmptr = rslvsp(WLI_PGM, (char *) CURLPGM, library, _AUTH_NONE);
163*6236dae4SAndroid Build Coastguard Worker _LU_Work_Area_T *luwrka = (_LU_Work_Area_T *) _LUWRKA();
164*6236dae4SAndroid Build Coastguard Worker
165*6236dae4SAndroid Build Coastguard Worker parse_command_line(args->cmdargs->string, args->cmdargs->len,
166*6236dae4SAndroid Build Coastguard Worker &argc, argv, &argsize, (char *) (argv + argc + 1));
167*6236dae4SAndroid Build Coastguard Worker
168*6236dae4SAndroid Build Coastguard Worker /* Call program. */
169*6236dae4SAndroid Build Coastguard Worker _CALLPGMV((void *) &pgmptr, argv, argc);
170*6236dae4SAndroid Build Coastguard Worker exitcode = luwrka->LU_RC;
171*6236dae4SAndroid Build Coastguard Worker
172*6236dae4SAndroid Build Coastguard Worker free(argv);
173*6236dae4SAndroid Build Coastguard Worker }
174*6236dae4SAndroid Build Coastguard Worker }
175*6236dae4SAndroid Build Coastguard Worker
176*6236dae4SAndroid Build Coastguard Worker return exitcode;
177*6236dae4SAndroid Build Coastguard Worker }
178