This is provided as a QADRT (ascii) program, a link to it in the IFS and
a minimal CL command.

Closes #11547
This commit is contained in:
Patrick Monnerat 2023-08-29 13:32:39 +02:00 коммит произвёл Daniel Stenberg
Родитель b137634ba3
Коммит 6f8d9cc4e9
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 5CC908FDB71E12C2
11 изменённых файлов: 471 добавлений и 40 удалений

Просмотреть файл

@ -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. */

Просмотреть файл

@ -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 \
@ -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 " $@;

Просмотреть файл

@ -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
packages/OS400/curl.cmd Normal file
Просмотреть файл

@ -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
packages/OS400/curlcl.c Normal file
Просмотреть файл

@ -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
packages/OS400/curlmain.c Normal file
Просмотреть файл

@ -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;
}

Просмотреть файл

@ -80,7 +80,6 @@ setenv OUTPUT '*NONE' # Compilation output option.
setenv TGTRLS '*CURRENT' # Target OS release.
setenv IFSDIR '/curl' # Installation IFS directory.
setenv QADRTDIR '/QIBM/ProdData/qadrt' # QADRT IFS directory.
setenv QADRTLIB 'QADRT' # QADRT object library.
# Define ZLIB availability and locations.
@ -236,7 +235,7 @@ make_module()
CMD="${CMD} OPTIMIZE(${OPTIMIZE})"
CMD="${CMD} DBGVIEW(${DEBUG})"
DEFINES="${3} BUILDING_LIBCURL 'qadrt_use_inline'"
DEFINES="${3} 'qadrt_use_inline'"
if [ "${WITH_ZLIB}" != "0" ]
then DEFINES="${DEFINES} HAVE_LIBZ"
@ -270,6 +269,7 @@ db2_name()
tr 'a-z-' 'A-Z_' |
sed -e 's/\..*//' \
-e 's/^CURL_*/C/' \
-e 's/^TOOL_*/T/' \
-e 's/^\(.\).*\(.........\)$/\1\2/'
fi
}
@ -288,3 +288,26 @@ versioned_copy()
-e "s/@LIBCURL_TIMESTAMP@/${LIBCURL_TIMESTAMP}/g" \
< "${1}" > "${2}"
}
# Get definitions from a make file.
# The `sed' statement works as follows:
# - Join \nl-separated lines.
# - Retain only lines that begins with "identifier =".
# - Turn these lines into shell variable assignments.
get_make_vars()
{
eval "`sed -e ': begin' \
-e '/\\\\$/{' \
-e 'N' \
-e 's/\\\\\\n/ /' \
-e 'b begin' \
-e '}' \
-e '/^[A-Za-z_][A-Za-z0-9_]*[[:space:]]*=/!d' \
-e 's/[[:space:]]*=[[:space:]]*/=/' \
-e 's/=\\(.*[^[:space:]]\\)[[:space:]]*$/=\\"\\1\\"/' \
-e 's/\\\$(\\([^)]*\\))/\${\\1}/g' \
< \"${1}\"`"
}

Просмотреть файл

@ -44,37 +44,26 @@ echo '#pragma comment(user, "libcurl version '"${LIBCURL_VERSION}"'")' > os400.c
echo '#pragma comment(user, __DATE__)' >> os400.c
echo '#pragma comment(user, __TIME__)' >> os400.c
echo '#pragma comment(copyright, "Copyright (C) Daniel Stenberg et al. OS/400 version by P. Monnerat")' >> os400.c
make_module OS400 os400.c
make_module OS400 os400.c BUILDING_LIBCURL
LINK= # No need to rebuild service program yet.
MODULES=
# Get source list.
# Get source list (CSOURCES variable).
sed -e ':begin' \
-e '/\\$/{' \
-e 's/\\$/ /' \
-e 'N' \
-e 'bbegin' \
-e '}' \
-e 's/\n//g' \
-e 's/[[:space:]]*$//' \
-e 's/^\([A-Za-z][A-Za-z0-9_]*\)[[:space:]]*=[[:space:]]*\(.*\)/\1="\2"/' \
-e 's/\$(\([A-Za-z][A-Za-z0-9_]*\))/${\1}/g' \
< Makefile.inc > tmpscript.sh
. ./tmpscript.sh
get_make_vars Makefile.inc
# Compile the sources into modules.
INCLUDES="'`pwd`'"
make_module OS400SYS "${SCRIPTDIR}/os400sys.c"
make_module CCSIDCURL "${SCRIPTDIR}/ccsidcurl.c"
make_module OS400SYS "${SCRIPTDIR}/os400sys.c" BUILDING_LIBCURL
make_module CCSIDCURL "${SCRIPTDIR}/ccsidcurl.c" BUILDING_LIBCURL
for SRC in ${CSOURCES}
do MODULE=`db2_name "${SRC}"`
make_module "${MODULE}" "${SRC}"
make_module "${MODULE}" "${SRC}" BUILDING_LIBCURL
done

Просмотреть файл

@ -23,5 +23,76 @@
#
###########################################################################
#
#
# Not implemented yet on OS/400.
# Command line interface tool compilation script for the OS/400.
SCRIPTDIR=`dirname "${0}"`
. "${SCRIPTDIR}/initscript.sh"
cd "${TOPDIR}/src"
# Get source lists.
# CURL_CFILES are in the current directory.
# CURLX_CFILES are in the lib directory and need to be recompiled because
# some function names change using macros.
get_make_vars Makefile.inc
# Compile the sources into modules.
LINK=
MODULES=
INCLUDES="'${TOPDIR}/lib'"
for SRC in ${CURLX_CFILES}
do MODULE=`db2_name "${SRC}"`
MODULE=`db2_name "X${MODULE}"`
make_module "${MODULE}" "${SRC}"
done
for SRC in ${CURL_CFILES}
do MODULE=`db2_name "${SRC}"`
make_module "${MODULE}" "${SRC}"
done
# Link modules into program.
MODULES="`echo \"${MODULES}\" | sed \"s/[^ ][^ ]*/${TARGETLIB}\/&/g\"`"
CMD="CRTPGM PGM(${TARGETLIB}/CURL)"
CMD="${CMD} ENTMOD(${TARGETLIB}/CURLMAIN)"
CMD="${CMD} MODULE(${MODULES})"
CMD="${CMD} BNDSRVPGM(${TARGETLIB}/${SRVPGM} QADRTTS)"
CMD="${CMD} TGTRLS(${TGTRLS})"
CLcommand "${CMD}"
# Create the IFS command.
IFSBIN="${IFSDIR}/bin"
if action_needed "${IFSBIN}"
then mkdir -p "${IFSBIN}"
fi
rm -f "${IFSBIN}/curl"
ln -s "/QSYS.LIB/${TARGETLIB}.LIB/CURL.PGM" "${IFSBIN}/curl"
# Create the CL interface program.
if action_needed "${LIBIFSNAME}/CURLCL.PGM" "${SCRIPTDIR}/curlcl.c"
then CMD="CRTBNDC PGM(${TARGETLIB}/CURLCL)"
CMD="${CMD} SRCSTMF('${SCRIPTDIR}/curlcl.c')"
CMD="${CMD} TGTCCSID(${TGTCCSID})"
CLcommand "${CMD}"
fi
# Create the CL command.
if action_needed "${LIBIFSNAME}/CURL.CMD" "${SCRIPTDIR}/curl.cmd"
then CMD="CRTCMD CMD(${TARGETLIB}/CURL) PGM(${TARGETLIB}/CURLCL)"
CMD="${CMD} SRCSTMF('${SCRIPTDIR}/curl.cmd')"
CLcommand "${CMD}"
fi

Просмотреть файл

@ -40,24 +40,8 @@ cd "${TOPDIR}/tests"
cd libtest
# Get definitions from the Makefile.inc file.
# The `sed' statement works as follows:
# _ Join \nl-separated lines.
# _ Retain only lines that begins with "identifier =".
# _ Turn these lines into shell variable assignments.
eval "`sed -e ': begin' \
-e '/\\\\$/{' \
-e 'N' \
-e 's/\\\\\\n/ /' \
-e 'b begin' \
-e '}' \
-e '/^[A-Za-z_][A-Za-z0-9_]*[[:space:]]*[=]/b keep' \
-e 'd' \
-e ': keep' \
-e 's/[[:space:]]*=[[:space:]]*/=/' \
-e 's/=\\(.*[^[:space:]]\\)[[:space:]]*$/=\\"\\1\\"/' \
-e 's/\\$(\\([^)]*\\))/${\\1}/g' \
< Makefile.inc`"
get_make_vars Makefile.inc
# Special case: redefine chkhostname compilation parameters.
@ -128,7 +112,7 @@ do DB2PGM=`db2_name "${PGM}"`
MODULES="`echo \"${MODULES}\" |
sed \"s/[^ ][^ ]*/${TARGETLIB}\/&/g\"`"
CMD="CRTPGM PGM(${TARGETLIB}/${DB2PGM})"
CMD="${CMD} ENTMOD(${QADRTLIB}/QADRTMAIN2)"
CMD="${CMD} ENTMOD(${TARGETLIB}/CURLMAIN)"
CMD="${CMD} MODULE(${MODULES})"
CMD="${CMD} BNDSRVPGM(${TARGETLIB}/${SRVPGM} QADRTTS)"
CMD="${CMD} TGTRLS(${TGTRLS})"

Просмотреть файл

@ -101,6 +101,20 @@ do MEMBER="`basename \"${EXAMPLE}\"`"
done
# Compile the QADRTMAIN2 replacement module.
if action_needed "${LIBIFSNAME}/CURLMAIN.MODULE" "${SCRIPTDIR}/curlmain.c"
then CMD="CRTCMOD MODULE(${TARGETLIB}/CURLMAIN)"
CMD="${CMD} SRCSTMF('${SCRIPTDIR}/curlmain.c')"
CMD="${CMD} SYSIFCOPT(*IFS64IO) LOCALETYPE(*LOCALE) FLAG(10)"
CMD="${CMD} TGTCCSID(${TGTCCSID}) TGTRLS(${TGTRLS})"
CMD="${CMD} OUTPUT(${OUTPUT})"
CMD="${CMD} OPTIMIZE(${OPTIMIZE})"
CMD="${CMD} DBGVIEW(${DEBUG})"
CLcommand "${CMD}"
fi
# Build in each directory.
# for SUBDIR in include lib src tests