Skip to content

Commit

Permalink
os400: implement CLI tool
Browse files Browse the repository at this point in the history
This is provided as a QADRT (ascii) program, a link to it in the IFS and
a minimal CL command.

Closes #11547
  • Loading branch information
monnerat authored and bagder committed Aug 30, 2023
1 parent b137634 commit 6f8d9cc
Show file tree
Hide file tree
Showing 11 changed files with 472 additions and 41 deletions.
3 changes: 3 additions & 0 deletions lib/setup-os400.h
Expand Up @@ -34,6 +34,9 @@
/* No OS/400 header file defines u_int32_t. */
typedef unsigned long u_int32_t;

/* OS/400 has no idea of a tty! */
#define isatty(fd) 0


/* System API wrapper prototypes & definitions to support ASCII parameters. */

Expand Down
5 changes: 4 additions & 1 deletion packages/Makefile.am
Expand Up @@ -28,6 +28,8 @@ EXTRA_DIST = README.md \
OS400/rpg-examples \
OS400/ccsidcurl.c \
OS400/ccsidcurl.h \
OS400/curlcl.c \
OS400/curlmain.c \
OS400/curl.inc.in \
OS400/initscript.sh \
OS400/make-include.sh \
Expand All @@ -36,7 +38,8 @@ EXTRA_DIST = README.md \
OS400/make-tests.sh \
OS400/makefile.sh \
OS400/os400sys.c \
OS400/os400sys.h
OS400/os400sys.h \
OS400/curl.cmd

CHECKSRC = $(CS_$(V))
CS_0 = @echo " RUN " $@;
Expand Down
13 changes: 13 additions & 0 deletions packages/OS400/README.OS400
Expand Up @@ -374,3 +374,16 @@ _ Since V7R4M0, procedure overloading is used to emulate limited "vararg-like"
is provided for that purpose: this allows storing a long value in the
curl_forms array. Please note the form API is deprecated and the MIME API
should be used instead.


CLI tool:

The build system provides it as a bound program, an IFS link to it and a
simple CL command. The latter however is not able to provide a different
parameter for each option since there are too many of those; instead,
parameters are entered in a single field subject to quoting and escaping, in
the same form as expected by the standard CLI program.
Care must be taken about the program output encoding: by default, it is sent
to the standard output and is thus subject to transcoding. It is therefore
recommended to use option "--output" to redirect output to a specific IFS file.
Similar problems may occur about the standard input encoding.
32 changes: 32 additions & 0 deletions packages/OS400/curl.cmd
@@ -0,0 +1,32 @@
/*****************************************************************************/
/* _ _ ____ _ */
/* 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 */
/* */
/* */
/*****************************************************************************/

/* Use program CURLCL as interface to the curl command line tool */

CMD PROMPT('File transfer utility')

PARM KWD(CMDARGS) TYPE(*CHAR) LEN(5000) VARY(*YES *INT2) +
CASE(*MIXED) EXPR(*YES) MIN(1) +
PROMPT('Curl command arguments')
176 changes: 176 additions & 0 deletions packages/OS400/curlcl.c
@@ -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;
}
123 changes: 123 additions & 0 deletions packages/OS400/curlmain.c
@@ -0,0 +1,123 @@
/***************************************************************************
* _ _ ____ _
* 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
*
*
***************************************************************************/

/*
* QADRT/QADRTMAIN2 substitution program.
* This is needed because the IBM-provided QADRTMAIN2 does not
* properly translate arguments by default or if no locale is provided.
*/

#include <stdlib.h>
#include <string.h>
#include <iconv.h>
#include <errno.h>
#include <locale.h>

/* Do not use qadrt.h since it defines unneeded static procedures. */
extern void QadrtInit(void);
extern int QadrtFreeConversionTable(void);
extern int QadrtFreeEnviron(void);
extern char * setlocale_a(int, const char *);


/* The ASCII main program. */
extern int main_a(int argc, char * * argv);

/* Global values of original EBCDIC arguments. */
int ebcdic_argc;
char ** ebcdic_argv;


int
main(int argc, char **argv)

{
int i;
int j;
iconv_t cd;
size_t bytecount = 0;
char * inbuf;
char * outbuf;
size_t inbytesleft;
size_t outbytesleft;
char dummybuf[128];
char tocode[32];
char fromcode[32];

ebcdic_argc = argc;
ebcdic_argv = argv;

/* Build the encoding converter. */
strncpy(tocode, "IBMCCSID01208", sizeof tocode); /* Use UTF-8. */
strncpy(fromcode, "IBMCCSID000000000010", sizeof fromcode);
cd = iconv_open(tocode, fromcode);

/* Measure the arguments. */
for(i = 0; i < argc; i++) {
inbuf = argv[i];
do {
inbytesleft = 0;
outbuf = dummybuf;
outbytesleft = sizeof dummybuf;
j = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
bytecount += outbuf - dummybuf;
} while(j == -1 && errno == E2BIG);

/* Reset the shift state. */
iconv(cd, NULL, &inbytesleft, &outbuf, &outbytesleft);
}

/* Allocate memory for the ASCII arguments and vector. */
argv = (char **) malloc((argc + 1) * sizeof *argv + bytecount);

/* Build the vector and convert argument encoding. */
outbuf = (char *) (argv + argc + 1);
outbytesleft = bytecount;

for(i = 0; i < argc; i++) {
argv[i] = outbuf;
inbuf = ebcdic_argv[i];
inbytesleft = 0;
iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
iconv(cd, NULL, &inbytesleft, &outbuf, &outbytesleft);
}

iconv_close(cd);
argv[argc] = NULL;

/* Try setting the locale regardless of QADRT_ENV_LOCALE. */
setlocale_a(LC_ALL, "");

/* Call the program. */
i = main_a(argc, argv);

/* Clean-up allocated items. */
free((char *) argv);
QadrtFreeConversionTable();
QadrtFreeEnviron();

/* Terminate. */
return i;
}

0 comments on commit 6f8d9cc

Please sign in to comment.