diff --git a/os400/initscript.sh b/os400/initscript.sh new file mode 100644 index 0000000..1d47a1d --- /dev/null +++ b/os400/initscript.sh @@ -0,0 +1,243 @@ +#!/bin/sh + + +setenv() + +{ + # Define and export. + + eval ${1}="${2}" + export ${1} +} + + +case "${SCRIPTDIR}" in +/*) ;; +*) SCRIPTDIR="`pwd`/${SCRIPTDIR}" +esac + +while true +do case "${SCRIPTDIR}" in + */.) SCRIPTDIR="${SCRIPTDIR%/.}";; + *) break;; + esac +done + +# The script directory is supposed to be in $TOPDIR/os400. + +TOPDIR=`dirname "${SCRIPTDIR}"` +export SCRIPTDIR TOPDIR + +# Extract the SONAME from the library makefile. + +SONAME=`sed -e '/^VERSION=/!d' -e 's/^.* \([0-9]*\):.*$/\1/' -e 'q' \ + < "${TOPDIR}/src/Makefile.am"` +export SONAME + + +################################################################################ +# +# Tunable configuration parameters. +# +################################################################################ + +setenv TARGETLIB 'LIBSSH2' # Target OS/400 program library. +setenv STATBNDDIR 'LIBSSH2_A' # Static binding directory. +setenv DYNBNDDIR 'LIBSSH2' # Dynamic binding directory. +setenv SRVPGM "LIBSSH2.${SONAME}" # Service program. +setenv TGTCCSID '500' # Target CCSID of objects. +setenv DEBUG '*ALL' # Debug level. +setenv OPTIMIZE '10' # Optimisation level +setenv OUTPUT '*NONE' # Compilation output option. +setenv TGTRLS 'V5R3M0' # Target OS release. +setenv IFSDIR '/libssh2' # Installation IFS directory. + +# Define ZLIB availability and locations. + +setenv WITH_ZLIB 0 # Define to 1 to enable. +setenv ZLIB_INCLUDE '/zlib/include' # ZLIB include IFS directory. +setenv ZLIB_LIB 'ZLIB' # ZLIB library. +setenv ZLIB_BNDDIR 'ZLIB_A' # ZLIB binding directory. + + +################################################################################ + +# Need to get the version definitions. + +LIBSSH2_VERSION=`grep '^#define *LIBSSH2_VERSION ' \ + "${TOPDIR}/include/libssh2.h" | + sed 's/.*"\(.*\)".*/\1/'` +LIBSSH2_VERSION_MAJOR=`grep '^#define *LIBSSH2_VERSION_MAJOR ' \ + "${TOPDIR}/include/libssh2.h" | + sed 's/^#define *LIBSSH2_VERSION_MAJOR *\([^ ]*\).*/\1/'` +LIBSSH2_VERSION_MINOR=`grep '^#define *LIBSSH2_VERSION_MINOR ' \ + "${TOPDIR}/include/libssh2.h" | + sed 's/^#define *LIBSSH2_VERSION_MINOR *\([^ ]*\).*/\1/'` +LIBSSH2_VERSION_PATCH=`grep '^#define *LIBSSH2_VERSION_PATCH ' \ + "${TOPDIR}/include/libssh2.h" | + sed 's/^#define *LIBSSH2_VERSION_PATCH *\([^ ]*\).*/\1/'` +LIBSSH2_VERSION_NUM=`grep '^#define *LIBSSH2_VERSION_NUM ' \ + "${TOPDIR}/include/libssh2.h" | + sed 's/^#define *LIBSSH2_VERSION_NUM *0x\([^ ]*\).*/\1/'` +LIBSSH2_TIMESTAMP=`grep '^#define *LIBSSH2_TIMESTAMP ' \ + "${TOPDIR}/include/libssh2.h" | + sed 's/.*"\(.*\)".*/\1/'` +export LIBSSH2_VERSION +export LIBSSH2_VERSION_MAJOR LIBSSH2_VERSION_MINOR LIBSSH2_VERSION_PATCH +export LIBSSH2_VERSION_NUM LIBSSH2_TIMESTAMP + +################################################################################ +# +# OS/400 specific definitions. +# +################################################################################ + +LIBIFSNAME="/QSYS.LIB/${TARGETLIB}.LIB" + + +################################################################################ +# +# Procedures. +# +################################################################################ + +# action_needed dest [src] +# +# dest is an object to build +# if specified, src is an object on which dest depends. +# +# exit 0 (succeeds) if some action has to be taken, else 1. + +action_needed() + +{ + [ ! -e "${1}" ] && return 0 + [ "${2}" ] || return 1 + [ "${1}" -ot "${2}" ] && return 0 + return 1 +} + + +# canonicalize_path path +# +# Return canonicalized path as: +# - Absolute +# - No . or .. component. + +canonicalize_path() + +{ + if expr "${1}" : '^/' > /dev/null + then P="${1}" + else P="`pwd`/${1}" + fi + + R= + IFSSAVE="${IFS}" + IFS="/" + + for C in ${P} + do IFS="${IFSSAVE}" + case "${C}" in + .) ;; + ..) R=`expr "${R}" : '^\(.*/\)..*'` + ;; + ?*) R="${R}${C}/" + ;; + *) ;; + esac + done + + IFS="${IFSSAVE}" + echo "/`expr "${R}" : '^\(.*\)/'`" +} + + +# make_module module_name source_name [additional_definitions] +# +# Compile source name into ASCII module if needed. +# As side effect, append the module name to variable MODULES. +# Set LINK to "YES" if the module has been compiled. + +make_module() + +{ + MODULES="${MODULES} ${1}" + MODIFSNAME="${LIBIFSNAME}/${1}.MODULE" + action_needed "${MODIFSNAME}" "${2}" || return 0; + SRCDIR=`dirname \`canonicalize_path "${2}"\`` + + # #pragma convert has to be in the source file itself, i.e. + # putting it in an include file makes it only active + # for that include file. + # Thus we build a temporary file with the pragma prepended to + # the source file and we compile that temporary file. + + echo "#line 1 \"${2}\"" > __tmpsrcf.c + echo "#pragma convert(819)" >> __tmpsrcf.c + echo "#line 1" >> __tmpsrcf.c + cat "${2}" >> __tmpsrcf.c + CMD="CRTCMOD MODULE(${TARGETLIB}/${1}) SRCSTMF('__tmpsrcf.c')" +# CMD="${CMD} SYSIFCOPT(*IFS64IO) OPTION(*INCDIRFIRST *SHOWINC *SHOWSYS)" + CMD="${CMD} SYSIFCOPT(*IFS64IO) OPTION(*INCDIRFIRST)" + CMD="${CMD} LOCALETYPE(*LOCALE)" + CMD="${CMD} INCDIR('${TOPDIR}/os400/include'" + CMD="${CMD} '/QIBM/ProdData/qadrt/include' '${TOPDIR}/include'" + CMD="${CMD} '${TOPDIR}/os400' '${SRCDIR}'" + + if [ "${WITH_ZLIB}" != "0" ] + then CMD="${CMD} '${ZLIB_INCLUDE}'" + fi + + CMD="${CMD} ${INCLUDES})" + CMD="${CMD} TGTCCSID(${TGTCCSID}) TGTRLS(${TGTRLS})" + CMD="${CMD} OUTPUT(${OUTPUT})" + CMD="${CMD} OPTIMIZE(${OPTIMIZE})" + CMD="${CMD} DBGVIEW(${DEBUG})" + + DEFINES="${3}" + + if [ "${WITH_ZLIB}" != "0" ] + then DEFINES="${DEFINES} HAVE_LIBZ LIBSSH2_HAVE_ZLIB" + fi + + if [ "${DEFINES}" ] + then CMD="${CMD} DEFINE(${DEFINES})" + fi + + system "${CMD}" + rm -f __tmpsrcf.c + LINK=YES +} + + +# Determine DB2 object name from IFS name. + +db2_name() + +{ + if [ "${2}" = 'nomangle' ] + then basename "${1}" | + tr 'a-z-' 'A-Z_' | + sed -e 's/\..*//;s/^\(.\).*\(.........\)$/\1\2/' + else basename "${1}" | + tr 'a-z-' 'A-Z_' | + sed -e 's/\..*//;s/^LIBSSH2_/SSH2_/' \ + -e 's/^\(.\).*\(.........\)$/\1\2/' \ + -e 's/^SPUBLICKEY$/SSH2_PKEY/' + fi +} + + +# Copy stream replacing version info. + +versioned_copy() + +{ + sed -e "s/@LIBSSH2_VERSION@/${LIBSSH2_VERSION}/g" \ + -e "s/@LIBSSH2_VERSION_MAJOR@/${LIBSSH2_VERSION_MAJOR}/g" \ + -e "s/@LIBSSH2_VERSION_MINOR@/${LIBSSH2_VERSION_MINOR}/g" \ + -e "s/@LIBSSH2_VERSION_PATCH@/${LIBSSH2_VERSION_PATCH}/g" \ + -e "s/@LIBSSH2_VERSION_NUM@/${LIBSSH2_VERSION_NUM}/g" \ + -e "s/@LIBSSH2_TIMESTAMP@/${LIBSSH2_TIMESTAMP}/g" +} diff --git a/os400/make-include.sh b/os400/make-include.sh new file mode 100644 index 0000000..d44980f --- /dev/null +++ b/os400/make-include.sh @@ -0,0 +1,56 @@ +#!/bin/sh +# +# Installation of the header files in the OS/400 library. +# + +SCRIPTDIR=`dirname "${0}"` +. "${SCRIPTDIR}/initscript.sh" +cd "${TOPDIR}/include" + + +# Create the OS/400 source program file for the header files. + +SRCPF="${LIBIFSNAME}/H.FILE" + +if action_needed "${SRCPF}" +then CMD="CRTSRCPF FILE(${TARGETLIB}/H) RCDLEN(112)" + CMD="${CMD} CCSID(${TGTCCSID}) TEXT('libssh2: Header files')" + system "${CMD}" +fi + + +# Create the IFS directory for the header files. + +IFSINCLUDE="${IFSDIR}/include" + +if action_needed "${IFSINCLUDE}" +then mkdir -p "${IFSINCLUDE}" +fi + + +copy_hfile() + +{ + destfile="${1}" + srcfile="${2}" + shift + shift + sed -e '1i\ +#pragma datamodel(P128)\ +' "${@}" -e '$a\ +#pragma datamodel(pop)\ +' < "${srcfile}" > "${destfile}" +} + +# Copy the header files. + +for HFILE in *.h +do DEST="${SRCPF}/`db2_name \"${HFILE}\"`.MBR" + + if action_needed "${DEST}" "${HFILE}" + then copy_hfile "${DEST}" "${HFILE}" + IFSDEST="${IFSINCLUDE}/`basename \"${HFILE}\"`" + rm -f "${IFSDEST}" + ln -s "${DEST}" "${IFSDEST}" + fi +done diff --git a/os400/make-rpg.sh b/os400/make-rpg.sh new file mode 100644 index 0000000..c8a2647 --- /dev/null +++ b/os400/make-rpg.sh @@ -0,0 +1,92 @@ +#!/bin/sh +# +# Installation of the ILE/RPG header files in the OS/400 library. +# + +SCRIPTDIR=`dirname "${0}"` +. "${SCRIPTDIR}/initscript.sh" +cd "${TOPDIR}/os400/libssh2rpg" + + +# Create the OS/400 source program file for the ILE/RPG header files. + +SRCPF="${LIBIFSNAME}/LIBSSH2RPG.FILE" + +if action_needed "${SRCPF}" +then CMD="CRTSRCPF FILE(${TARGETLIB}/LIBSSH2RPG) RCDLEN(112)" + CMD="${CMD} CCSID(${TGTCCSID}) TEXT('libssh2: ILE/RPG header files')" + system "${CMD}" +fi + + +# Map file names to DB2 name syntax. + +for HFILE in *.rpgle *.rpgle.in +do NAME="`basename \"${HFILE}\" .in`" + VAR="`basename \"${NAME}\" .rpgle`" + VAL="`db2_name \"${NAME}\"`" + + eval "VAR_${VAR}=\"${VAL}\"" + echo "${VAR} s/${VAR}/${VAL}/g" +done > tmpsubstfile1 + +# Order substitution commands so that a prefix appears after all +# file names beginning with the prefix. + +sort -r tmpsubstfile1 | sed 's/^[^ ]*[ ]*//' > tmpsubstfile2 + + +change_include() + +{ + sed -e '\#^....../include *"libssh2rpg/#{' \ + -e 's///' \ + -e 's/".*//' \ + -f tmpsubstfile2 \ + -e 's#.*# /include libssh2rpg,&#' \ + -e '}' +} + + +# Create the IFS directory for the ILE/RPG header files. + +RPGIFSDIR="${IFSDIR}/include/libssh2rpg" + +if action_needed "${RPGIFSDIR}" +then mkdir -p "${RPGIFSDIR}" +fi + +# Copy the header files to IFS ILE/RPG include directory. +# Copy them with include path editing to the DB2 library. + +for HFILE in *.rpgle *.rpgle.in +do IFSCMD="cat \"${HFILE}\"" + DB2CMD="change_include < \"${HFILE}\"" + IFSFILE="`basename \"${HFILE}\" .in`" + + case "${HFILE}" in + + *.in) IFSCMD="${IFSCMD} | versioned_copy" + DB2CMD="${DB2CMD} | versioned_copy" + ;; + esac + + IFSDEST="${RPGIFSDIR}/${IFSFILE}" + + if action_needed "${IFSDEST}" "${HFILE}" + then eval "${IFSCMD}" > "${IFSDEST}" + fi + + eval DB2MBR="\"\${VAR_`basename \"${IFSDEST}\" .rpgle`}\"" + DB2DEST="${SRCPF}/${DB2MBR}.MBR" + + if action_needed "${DB2DEST}" "${HFILE}" + then eval "${DB2CMD}" | change_include > tmphdrfile + + # Need to translate to target CCSID. + + CMD="CPY OBJ('`pwd`/tmphdrfile') TOOBJ('${DB2DEST}')" + CMD="${CMD} TOCCSID(${TGTCCSID}) DTAFMT(*TEXT) REPLACE(*YES)" + system "${CMD}" + fi +done diff --git a/os400/make-src.sh b/os400/make-src.sh new file mode 100644 index 0000000..ef1b999 --- /dev/null +++ b/os400/make-src.sh @@ -0,0 +1,206 @@ +#!/bin/sh +# +# libssh2 compilation script for the OS/400. +# + +SCRIPTDIR=`dirname "${0}"` +. "${SCRIPTDIR}/initscript.sh" +cd "${TOPDIR}/src" + + +# Function to extract external prototypes from header files. +# Input: concatenated header files. +# Output: external prototypes, one per (long) line. + +extproto() +{ + sed -e 'x;G;s/^\n//;s/\n/ /g' \ + -e 's#[[:space:]]*/\*[^*]*\(\*\([^/*][^*]*\)\{0,1\}\)*\*/[[:space:]]*##g' \ + -e 'h' \ + -e '/\/\*/!{' \ + -e '/^#/{s/^.*[^\\]$//;h;d' \ + -e '}' \ + -e 's/\\$//' \ + -e ':loop1' \ + -e '/;/{' \ + -e 's/^[^;]*;//;x;s/;.*//' \ + -e '/^[[:space:]]*LIBSSH2_API[[:space:]].*(/{' \ + -e 's/^[[:space:]]*LIBSSH2_API[[:space:]]*//' \ + -e 's/[[:space:]]*$//' \ + -e 's/[[:space:]][[:space:]]*/ /g' \ + -e 'p' \ + -e '}' \ + -e 'g;bloop1' \ + -e '}' \ + -e '}' \ + -n +} + +# Need to have IFS access to the mih/modasa header file. + +if action_needed modasa.mih '/QSYS.LIB/QSYSINC.LIB/MIH.FILE/MODASA.MBR' +then rm -f modasa.mih + ln -s '/QSYS.LIB/QSYSINC.LIB/MIH.FILE/MODASA.MBR' modasa.mih +fi + + +# Create and compile the identification source file. + +echo '#pragma comment(user, "libssh2 version '"${LIBSSH2_VERSION}"'")' > os400.c +echo '#pragma comment(user, __DATE__)' >> os400.c +echo '#pragma comment(user, __TIME__)' >> os400.c +echo '#pragma comment(copyright, "See COPYING file. OS/400 version by P. Monnerat")' >> os400.c +make_module OS400 os400.c +LINK= # No need to rebuild service program yet. +MODULES= + + +# Generate the procedures implementing macros. + +if action_needed macros.c "${TOPDIR}/os400/macros.h" +then ( + echo '#include "libssh2_publickey.h"' + echo '#include "libssh2_sftp.h"' + extproto < "${TOPDIR}/os400/macros.h" | + sed -e 'h;s/^[^(]*[ *]\([^ (]*\) *(.*/\1/' \ + -e 's/.*/#pragma map(_&, "&")/;p' \ + -e 'g;s/^\([^(]*[ *]\)\([^ (]*\)\( *(.*\)/\1_\2\3 {/;p' \ + -e 'g;s/^[^(]*(\(.*\))$/,\1,/;s/[^A-Za-z0-9_,]/ /g' \ + -e 's/ *,/,/g;s/,[^,]* \([^ ,]*\)/,\1/g' \ + -e 's/ //g;s/^,void,$/,,/' \ + -e 's/^,\(.*\),$/(\1); }/;s/,/, /g' \ + -e 'x;s/(.*//;s/ *$//;G;s/\n//g' \ + -e 's/^void\([ *]\)/\1/;s/^ *//' \ + -e 's/^[^(]*[ *]\([A-Za-z][A-Za-z0-9_]* *(\)/return \1/' \ + -e 's/.*/ &/' + ) > macros.c +fi + +# Get source list. + +cat ../Makefile.inc ../Makefile.os400qc3.inc | + 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' \ + > tmpscript.sh +. ./tmpscript.sh + + +# Compile the sources into modules. + +INCLUDES="'`pwd`'" + +for SRC in "${SCRIPTDIR}/os400sys.c" ${CSOURCES} ${CRYPTO_CSOURCES} macros.c +do MODULE=`db2_name "${SRC}"` + make_module "${MODULE}" "${SRC}" +done + + +# If needed, (re)create the static binding directory. + +if action_needed "${LIBIFSNAME}/${STATBNDDIR}.BNDDIR" +then LINK=YES +fi + +if [ "${LINK}" ] +then rm -rf "${LIBIFSNAME}/${STATBNDDIR}.BNDDIR" + CMD="CRTBNDDIR BNDDIR(${TARGETLIB}/${STATBNDDIR})" + CMD="${CMD} TEXT('libssh2 API static binding directory')" + system "${CMD}" + + for MODULE in ${MODULES} + do CMD="ADDBNDDIRE BNDDIR(${TARGETLIB}/${STATBNDDIR})" + CMD="${CMD} OBJ((${TARGETLIB}/${MODULE} *MODULE))" + system "${CMD}" + done + +# V6R1M0 does not list system service program QC3PBEXT in the +# implicit binding directory: thus we add it here in ours. + + CMD="ADDBNDDIRE BNDDIR(${TARGETLIB}/${STATBNDDIR})" + CMD="${CMD} OBJ((QSYS/QC3PBEXT *SRVPGM))" + system "${CMD}" +fi + + +# The exportation file for service program creation must be in a DB2 +# source file, so make sure it exists. + +if action_needed "${LIBIFSNAME}/TOOLS.FILE" +then CMD="CRTSRCPF FILE(${TARGETLIB}/TOOLS) RCDLEN(112)" + CMD="${CMD} TEXT('libssh2: build tools')" + system "${CMD}" +fi + + +# Gather the list of symbols to export. + +EXPORTS=`cat "${TOPDIR}"/include/*.h "${TOPDIR}"/os400/macros.h | + extproto | + sed -e 's/(.*//;s/[^A-Za-z0-9_]/ /g;s/ *$//;s/^.* //'` + +# Create the service program exportation file in DB2 member if needed. + +BSF="${LIBIFSNAME}/TOOLS.FILE/BNDSRC.MBR" + +if action_needed "${BSF}" Makefile.am +then LINK=YES +fi + +if [ "${LINK}" ] +then echo " STRPGMEXP PGMLVL(*CURRENT) SIGNATURE('LIBSSH2_${SONAME}')" \ + > "${BSF}" + for EXPORT in ${EXPORTS} + do echo ' EXPORT SYMBOL("'"${EXPORT}"'")' >> "${BSF}" + done + + echo ' ENDPGMEXP' >> "${BSF}" +fi + + +# Build the service program if needed. + +if action_needed "${LIBIFSNAME}/${SRVPGM}.SRVPGM" +then LINK=YES +fi + +if [ "${LINK}" ] +then CMD="CRTSRVPGM SRVPGM(${TARGETLIB}/${SRVPGM})" + CMD="${CMD} SRCFILE(${TARGETLIB}/TOOLS) SRCMBR(BNDSRC)" + CMD="${CMD} MODULE(${TARGETLIB}/OS400)" + CMD="${CMD} BNDDIR(${TARGETLIB}/${STATBNDDIR}" + if [ "${WITH_ZLIB}" != 0 ] + then CMD="${CMD} ${ZLIB_LIB}/${ZLIB_BNDDIR}" + liblist -a "${ZLIB_LIB}" + fi + CMD="${CMD})" + CMD="${CMD} BNDSRVPGM(QADRTTS)" + CMD="${CMD} TEXT('libssh2 API library')" + CMD="${CMD} TGTRLS(${TGTRLS})" + system "${CMD}" + LINK=YES +fi + + +# If needed, (re)create the dynamic binding directory. + +if action_needed "${LIBIFSNAME}/${DYNBNDDIR}.BNDDIR" +then LINK=YES +fi + +if [ "${LINK}" ] +then rm -rf "${LIBIFSNAME}/${DYNBNDDIR}.BNDDIR" + CMD="CRTBNDDIR BNDDIR(${TARGETLIB}/${DYNBNDDIR})" + CMD="${CMD} TEXT('libssh2 API dynamic binding directory')" + system "${CMD}" + CMD="ADDBNDDIRE BNDDIR(${TARGETLIB}/${DYNBNDDIR})" + CMD="${CMD} OBJ((*LIBL/${SRVPGM} *SRVPGM))" + system "${CMD}" +fi diff --git a/os400/make.sh b/os400/make.sh new file mode 100644 index 0000000..0c9e3de --- /dev/null +++ b/os400/make.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# +# libssh2 compilation script for the OS/400. +# +# +# This is a shell script since make is not a standard component of OS/400. + +SCRIPTDIR=`dirname "${0}"` +. "${SCRIPTDIR}/initscript.sh" +cd "${TOPDIR}" + + +# Create the OS/400 library if it does not exist. + +if action_needed "${LIBIFSNAME}" +then CMD="CRTLIB LIB(${TARGETLIB}) TEXT('libssh2: SSH2 protocol API')" + system "${CMD}" +fi + + +# Create the DOCS source file if it does not exist. + +if action_needed "${LIBIFSNAME}/DOCS.FILE" +then CMD="CRTSRCPF FILE(${TARGETLIB}/DOCS) RCDLEN(240)" + CMD="${CMD} CCSID(${TGTCCSID}) TEXT('Documentation texts')" + system "${CMD}" +fi + + +# Copy some documentation files if needed. + +for TEXT in "${TOPDIR}/COPYING" "${SCRIPTDIR}/README400" \ + "${TOPDIR}/NEWS" "${TOPDIR}/README" "${TOPDIR}/docs/AUTHORS" \ + "${TOPDIR}/docs/BINDINGS" +do MEMBER="${LIBIFSNAME}/DOCS.FILE/`db2_name \"${TEXT}\"`.MBR" + + if action_needed "${MEMBER}" "${TEXT}" + then CMD="CPY OBJ('${TEXT}') TOOBJ('${MEMBER}') TOCCSID(${TGTCCSID})" + CMD="${CMD} DTAFMT(*TEXT) REPLACE(*YES)" + system "${CMD}" + fi +done + + +# Build in each directory. + +for SUBDIR in include rpg src +do "${SCRIPTDIR}/make-${SUBDIR}.sh" +done