summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Monnerat <patrick@monnerat.net>2023-04-18 03:04:32 +0200
committerJay Satiro <raysatiro@yahoo.com>2023-04-18 16:14:00 -0400
commit7c142d05718d591fa1c8b3c418539c822702ddf5 (patch)
treed4fd265126d224a5eb1652fb196a87356721f23f
parent59ce2620a90b76670d99f7d1b2abda56bc6ce522 (diff)
downloadcurl-7c142d05718d591fa1c8b3c418539c822702ddf5.tar.gz
OS400: provide ILE/RPG usage examples
Closes https://github.com/curl/curl/pull/10994
-rw-r--r--packages/Makefile.am1
-rwxr-xr-xpackages/OS400/makefile.sh30
-rw-r--r--packages/OS400/rpg-examples/HEADERAPI146
-rw-r--r--packages/OS400/rpg-examples/HTTPPOST129
-rw-r--r--packages/OS400/rpg-examples/INMEMORY159
-rw-r--r--packages/OS400/rpg-examples/SIMPLE1108
-rw-r--r--packages/OS400/rpg-examples/SIMPLE2108
-rw-r--r--packages/OS400/rpg-examples/SMTPSRCMBR239
8 files changed, 920 insertions, 0 deletions
diff --git a/packages/Makefile.am b/packages/Makefile.am
index 4347f51da..1da49f68b 100644
--- a/packages/Makefile.am
+++ b/packages/Makefile.am
@@ -25,6 +25,7 @@ SUBDIRS = vms
EXTRA_DIST = README.md \
OS400/README.OS400 \
+ OS400/rpg-examples \
OS400/ccsidcurl.c \
OS400/ccsidcurl.h \
OS400/chkstrings.c \
diff --git a/packages/OS400/makefile.sh b/packages/OS400/makefile.sh
index e8a7e7c8d..70399cb99 100755
--- a/packages/OS400/makefile.sh
+++ b/packages/OS400/makefile.sh
@@ -71,6 +71,36 @@ do MEMBER="`basename \"${TEXT}\" .OS400`"
done
+# Create the RPGXAMPLES source file if it does not exist.
+
+if action_needed "${LIBIFSNAME}/RPGXAMPLES.FILE"
+then CMD="CRTSRCPF FILE(${TARGETLIB}/RPGXAMPLES) RCDLEN(240)"
+ CMD="${CMD} CCSID(${TGTCCSID}) TEXT('ILE/RPG examples')"
+ CLcommand "${CMD}"
+fi
+
+
+# Copy RPG examples if needed.
+
+for EXAMPLE in "${SCRIPTDIR}/rpg-examples"/*
+do MEMBER="`basename \"${EXAMPLE}\"`"
+ IFSMEMBER="${LIBIFSNAME}/RPGXAMPLES.FILE/`db2_name \"${MEMBER}\"`.MBR"
+
+ [ -e "${EXAMPLE}" ] || continue
+
+ if action_needed "${IFSMEMBER}" "${EXAMPLE}"
+ then CMD="CPY OBJ('${EXAMPLE}') TOOBJ('${IFSMEMBER}')"
+ CMD="${CMD} TOCCSID(${TGTCCSID}) DTAFMT(*TEXT) REPLACE(*YES)"
+ CLcommand "${CMD}"
+ MBRTEXT=`sed -e '1!d;/^ \*/!d;s/^ *\* *//' \
+ -e 's/ *$//;s/'"'"'/&&/g' < "${EXAMPLE}"`
+ CMD="CHGPFM FILE(${TARGETLIB}/RPGXAMPLES) MBR(${MEMBER})"
+ CMD="${CMD} SRCTYPE(RPGLE) TEXT('${MBRTEXT}')"
+ CLcommand "${CMD}"
+ fi
+done
+
+
# Build in each directory.
# for SUBDIR in include lib src tests
diff --git a/packages/OS400/rpg-examples/HEADERAPI b/packages/OS400/rpg-examples/HEADERAPI
new file mode 100644
index 000000000..2c2407ea2
--- /dev/null
+++ b/packages/OS400/rpg-examples/HEADERAPI
@@ -0,0 +1,146 @@
+ * Curl header API: extract headers post transfer
+ *
+ h DFTACTGRP(*NO) ACTGRP(*NEW)
+ h OPTION(*NOSHOWCPY)
+ h BNDDIR('CURL')
+ *
+ **************************************************************************
+ * _ _ ____ _
+ * 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
+ *
+ **************************************************************************
+ *
+ /include H,CURL.INC
+ *
+ * Extract headers post transfer with the header API.
+ *
+ d pi
+ d url 120
+ *
+ d urllen s 10u 0 URL length
+ *
+ **************************************************************************
+
+ urllen = trimmed_length(url: %len(url));
+
+ // Do the curl stuff.
+
+ curl_global_init(CURL_GLOBAL_ALL);
+ main();
+ curl_global_cleanup();
+ *inlr = *on; // Exit
+ *
+ **************************************************************************
+ * Main procedure: do the curl job.
+ **************************************************************************
+ *
+ p main b
+ d main pi
+ *
+ d h s * Easy handle
+ d result s like(CURLcode) Curl return code
+ d inz(CURLE_OUT_OF_MEMORY)
+ d header ds likeds(curl_header) based(hp)
+ d strp1 s * Work string pointer
+ d strp2 s * Work string pointer
+ d inout s 52 For error display
+
+ // Create and fill curl handle.
+
+ h = curl_easy_init();
+ if h <> *NULL;
+ curl_easy_setopt_ccsid(h: CURLOPT_URL: %subst(url: 1: urllen): 0);
+ curl_easy_setopt(h: CURLOPT_FOLLOWLOCATION: 1);
+ curl_easy_setopt(h: CURLOPT_WRITEFUNCTION: %paddr(in_data_cb)); // Ignore input data
+
+ // Perform the request.
+
+ result = curl_easy_perform(h);
+ endif;
+
+ // Check for error and report if some.
+
+ if result <> CURLE_OK;
+ inout = %str(curl_easy_strerror_ccsid(result: 0));
+ dsply '' '*EXT' inout;
+ else;
+ if curl_easy_header_ccsid(h: 'Content-Type': 0: CURLH_HEADER: -1:
+ hp: 0) = CURLHE_OK;
+ strp2 = curl_to_ccsid(header.value: 0);
+ inout = 'Content-Type: ' + %str(strp2);
+ dsply inout;
+ curl_free(strp2);
+ endif;
+ dsply ' All server headers:';
+ hp = *NULL;
+ dow *on;
+ hp = curl_easy_nextheader(h: CURLH_HEADER: -1: hp);
+ if hp = *NULL;
+ leave;
+ endif;
+ strp1 = curl_to_ccsid(header.name: 0);
+ strp2 = curl_to_ccsid(header.value: 0);
+ inout = %str(strp1) + ': ' + %str(strp2) +
+ ' (' + %char(header.amount) + ')';
+ curl_free(strp2);
+ curl_free(strp1);
+ dsply inout;
+ enddo;
+ inout = 'Done';
+ dsply '' '*EXT' inout;
+ curl_easy_cleanup(h); // Release handle
+ endif;
+ p main e
+ *
+ **************************************************************************
+ * Dummy data input callback procedure.
+ **************************************************************************
+ *
+ p in_data_cb b
+ d in_data_cb pi 10u 0
+ d ptr * value Input data pointer
+ d size 10u 0 value Data element size
+ d nmemb 10u 0 value Data element count
+ d userdata * value User data pointer
+ *
+ return size * nmemb;
+ p in_data_cb e
+ *
+ **************************************************************************
+ * Get the length of right-trimmed string
+ **************************************************************************
+ *
+ p trimmed_length b
+ d trimmed_length pi 10u 0
+ d string 999999 const options(*varsize)
+ d length 10u 0 value
+ *
+ d len s 10u 0
+ *
+ len = %scan(X'00': string: 1: length); // Limit to zero-terminated string
+ if len = 0;
+ len = length + 1;
+ endif;
+ if len <= 1;
+ return 0;
+ endif;
+ return %checkr(' ': string: len - 1); // Trim right
+ p trimmed_length e
diff --git a/packages/OS400/rpg-examples/HTTPPOST b/packages/OS400/rpg-examples/HTTPPOST
new file mode 100644
index 000000000..21202ebe0
--- /dev/null
+++ b/packages/OS400/rpg-examples/HTTPPOST
@@ -0,0 +1,129 @@
+ * Curl MIME post data and display response
+ *
+ h DFTACTGRP(*NO) ACTGRP(*NEW)
+ h OPTION(*NOSHOWCPY)
+ h BNDDIR('CURL')
+ *
+ **************************************************************************
+ * _ _ ____ _
+ * 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
+ *
+ **************************************************************************
+ *
+ /include H,CURL.INC
+ *
+ * Example to HTTP POST data using the MIME API. Displays the response.
+ *
+ d pi
+ d userinput 120 User data to post
+ *
+ d url c 'http://httpbin.org/anything'
+ *
+ *
+ d inputlen s 10u 0 User input length
+ **************************************************************************
+
+ inputlen = trimmed_length(userinput: %len(userinput));
+
+ // Do the curl stuff.
+
+ curl_global_init(CURL_GLOBAL_ALL);
+ main();
+ curl_global_cleanup();
+ *inlr = *on; // Exit
+ *
+ **************************************************************************
+ * Main procedure: do the curl job.
+ **************************************************************************
+ *
+ p main b
+ d main pi
+ *
+ d h s * Easy handle
+ d result s like(CURLcode) Curl return code
+ d inz(CURLE_OUT_OF_MEMORY)
+ d errmsgp s * Error string pointer
+ d response s 52 For error display
+ d mime s * MIME handle
+ d mimepart s * MIME part handle
+ d parthdrs s * inz(*NULL) Part headers
+
+ // Create and fill curl handle.
+
+ h = curl_easy_init();
+ if h <> *NULL;
+ curl_easy_setopt_ccsid(h: CURLOPT_URL: url: 0);
+ curl_easy_setopt(h: CURLOPT_FOLLOWLOCATION: 1);
+ mime = curl_mime_init(h);
+ mimepart = curl_mime_addpart(mime);
+ curl_mime_name_ccsid(mimepart: 'autofield': 0);
+ curl_mime_data_ccsid(mimepart: 'program-generated value':
+ CURL_ZERO_TERMINATED: 0);
+ mimepart = curl_mime_addpart(mime);
+ curl_mime_name_ccsid(mimepart: 'userfield': 0);
+ curl_mime_data_ccsid(mimepart: %subst(userinput: 1: inputlen):
+ CURL_ZERO_TERMINATED: 0);
+ mimepart = curl_mime_addpart(mime);
+ curl_mime_name_ccsid(mimepart: 'ebcdicfield': 0);
+ curl_mime_data(mimepart: %subst(userinput: 1: inputlen): inputlen);
+ curl_mime_encoder_ccsid(mimepart: 'base64': 0);
+ // Avoid server to convert base64 to text.
+ parthdrs = curl_slist_append_ccsid(parthdrs:
+ 'Content-Transfer-Encoding: bit': 0);
+ curl_mime_headers(mimepart: parthdrs: 1);
+ curl_easy_setopt(h: CURLOPT_MIMEPOST: mime);
+
+ // Perform the request.
+
+ result = curl_easy_perform(h);
+ curl_mime_free(mime);
+ curl_easy_cleanup(h); // Release handle
+ endif;
+
+ // Check for error and report if some.
+
+ if result <> CURLE_OK;
+ errmsgp = curl_easy_strerror_ccsid(result: 0);
+ response = %str(errmsgp);
+ dsply '' '*EXT' response;
+ endif;
+ p main e
+ *
+ **************************************************************************
+ * Get the length of right-trimmed string
+ **************************************************************************
+ *
+ p trimmed_length b
+ d trimmed_length pi 10u 0
+ d string 999999 const options(*varsize)
+ d length 10u 0 value
+ *
+ d len s 10u 0
+ *
+ len = %scan(X'00': string: 1: length); // Limit to zero-terminated string
+ if len = 0;
+ len = length + 1;
+ endif;
+ if len <= 1;
+ return 0;
+ endif;
+ return %checkr(' ': string: len - 1); // Trim right
+ p trimmed_length e
diff --git a/packages/OS400/rpg-examples/INMEMORY b/packages/OS400/rpg-examples/INMEMORY
new file mode 100644
index 000000000..e6f43abc8
--- /dev/null
+++ b/packages/OS400/rpg-examples/INMEMORY
@@ -0,0 +1,159 @@
+ * Curl get in memory and count HTML tags
+ *
+ h DFTACTGRP(*NO) ACTGRP(*NEW)
+ h OPTION(*NOSHOWCPY)
+ h BNDDIR('CURL')
+ *
+ **************************************************************************
+ * _ _ ____ _
+ * 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
+ *
+ **************************************************************************
+ *
+ /include H,CURL.INC
+ *
+ * Example to request the URL given as command line parameter and count
+ * HTML tags in its response.
+ *
+ d pi
+ d url 120
+ *
+ d countdata ds qualified based(###dummyptr) User data type
+ d tagcount 10u 0 Tag counter
+ d tagopen n Possible opening tag
+ *
+ d urllen s 10u 0 URL length
+ *
+ **************************************************************************
+
+ urllen = trimmed_length(url: %len(url));
+
+ // Do the curl stuff.
+
+ curl_global_init(CURL_GLOBAL_ALL);
+ main();
+ curl_global_cleanup();
+ *inlr = *on; // Exit
+ *
+ **************************************************************************
+ * Main procedure: do the curl job.
+ **************************************************************************
+ *
+ p main b
+ d main pi
+ *
+ d h s * Easy handle
+ d result s like(CURLcode) Curl return code
+ d inz(CURLE_OUT_OF_MEMORY)
+ d errmsgp s * Error string pointer
+ d response s 52 For error display
+ d counter ds likeds(countdata) HTML tag counter
+
+ counter.tagcount = 0;
+ counter.tagopen = *off;
+
+ // Create and fill curl handle.
+
+ h = curl_easy_init();
+ if h <> *NULL;
+ curl_easy_setopt_ccsid(h: CURLOPT_URL: %subst(url: 1: urllen): 0);
+ curl_easy_setopt(h: CURLOPT_FOLLOWLOCATION: 1);
+ curl_easy_setopt(h: CURLOPT_WRITEFUNCTION: %paddr(in_data_cb));
+ curl_easy_setopt(h: CURLOPT_WRITEDATA: %addr(counter));
+
+ // Perform the request.
+
+ result = curl_easy_perform(h);
+ curl_easy_cleanup(h); // Release handle
+ endif;
+
+ // Check for error and report if some.
+
+ if result <> CURLE_OK;
+ errmsgp = curl_easy_strerror_ccsid(result: 0);
+ response = %str(errmsgp);
+ dsply '' '*EXT' response;
+ else;
+ // Display the tag count.
+
+ response = 'Tag count: ' + %char(counter.tagcount);
+ dsply '' '*EXT' response;
+ endif;
+ p main e
+ *
+ **************************************************************************
+ * Data input callback procedure.
+ **************************************************************************
+ *
+ p in_data_cb b
+ d in_data_cb pi 10u 0
+ d ptr * value Input data pointer
+ d size 10u 0 value Data element size
+ d nmemb 10u 0 value Data element count
+ d userdata * value User data pointer
+ *
+ d counter ds likeds(countdata) based(userdata) HTML tag counter
+ d ebcdata s * EBCDIC data pointer
+ d chars s 1 based(ebcdata) dim(1000000)
+ d i s 10u 0 Character position
+ *
+ size = size * nmemb; // The size in bytes.
+ ebcdata = curl_to_ccsid(%str(ptr: size): 0); // Convert to EBCDIC.
+ i = 1;
+ dow i <= size;
+ if counter.tagopen; // Did we see '<' ?
+ counter.tagopen = *off;
+ if chars(i) <> '/'; // Reject closing tag.
+ counter.tagcount = counter.tagcount + 1; // Count this tag.
+ endif;
+ else;
+ i = %scan('<': %str(ebcdata): i); // Search next possible tag.
+ if i = 0;
+ leave;
+ endif;
+ counter.tagopen = *on; // Found one: flag it.
+ endif;
+ i = i + 1;
+ enddo;
+ curl_free(ebcdata);
+ return size;
+ p in_data_cb e
+ *
+ **************************************************************************
+ * Get the length of right-trimmed string
+ **************************************************************************
+ *
+ p trimmed_length b
+ d trimmed_length pi 10u 0
+ d string 999999 const options(*varsize)
+ d length 10u 0 value
+ *
+ d len s 10u 0
+ *
+ len = %scan(X'00': string: 1: length); // Limit to zero-terminated string
+ if len = 0;
+ len = length + 1;
+ endif;
+ if len <= 1;
+ return 0;
+ endif;
+ return %checkr(' ': string: len - 1); // Trim right
+ p trimmed_length e
diff --git a/packages/OS400/rpg-examples/SIMPLE1 b/packages/OS400/rpg-examples/SIMPLE1
new file mode 100644
index 000000000..52c0c93e8
--- /dev/null
+++ b/packages/OS400/rpg-examples/SIMPLE1
@@ -0,0 +1,108 @@
+ * Curl simple URL request
+ *
+ h DFTACTGRP(*NO) ACTGRP(*NEW)
+ h OPTION(*NOSHOWCPY)
+ h BNDDIR('CURL')
+ *
+ **************************************************************************
+ * _ _ ____ _
+ * 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
+ *
+ **************************************************************************
+ *
+ /include H,CURL.INC
+ *
+ * Simple example to request the URL given as command line parameter and
+ * output its response.
+ *
+ d pi
+ d url 120
+ *
+ d urllen s 10u 0 URL length
+ *
+ **************************************************************************
+ *
+ c eval urllen = trimmed_length(url: %len(url))
+ *
+ * Do the curl stuff.
+ *
+ c callp curl_global_init(CURL_GLOBAL_ALL)
+ c callp main
+ c callp curl_global_cleanup()
+ c seton lr Exit
+ *
+ **************************************************************************
+ * Main procedure: do the curl job.
+ **************************************************************************
+ *
+ p main b
+ d main pi
+ *
+ d h s * Easy handle
+ d result s like(CURLcode) Curl return code
+ d inz(CURLE_OUT_OF_MEMORY)
+ d errmsgp s * Error string pointer
+ d response s 52 For error display
+ *
+ * Create and fill curl handle.
+ *
+ c eval h = curl_easy_init()
+ c if h <> *NULL
+ c callp curl_easy_setopt_ccsid(h: CURLOPT_URL:
+ c %subst(url: 1: urllen): 0)
+ c callp curl_easy_setopt_long(h:
+ c CURLOPT_FOLLOWLOCATION: 1)
+ *
+ * Perform the request.
+ *
+ c eval result = curl_easy_perform(h)
+ c callp curl_easy_cleanup(h) Release handle
+ c endif
+ *
+ * Check for error and report if some.
+ *
+ c if result <> CURLE_OK
+ c eval errmsgp = curl_easy_strerror_ccsid(result: 0)
+ c eval response = %str(errmsgp)
+ c dsply response
+ c endif
+ p main e
+ *
+ **************************************************************************
+ * Get the length of right-trimmed string
+ **************************************************************************
+ *
+ p trimmed_length b
+ d trimmed_length pi 10u 0
+ d string 999999 const options(*varsize)
+ d length 10u 0 value
+ *
+ d len s 10u 0
+ *
+ c eval len = %scan(X'00': string: 1: length) Limit 0-terminated
+ c if len = 0
+ c eval len = length + 1
+ c endif
+ c if len <= 1
+ c return 0
+ c endif
+ c return %checkr(' ': string: len - 1) Trim right
+ p trimmed_length e
diff --git a/packages/OS400/rpg-examples/SIMPLE2 b/packages/OS400/rpg-examples/SIMPLE2
new file mode 100644
index 000000000..493c91ee2
--- /dev/null
+++ b/packages/OS400/rpg-examples/SIMPLE2
@@ -0,0 +1,108 @@
+ * Curl simple URL request (free-format RPG)
+ *
+ ctl-opt dftactgrp(*NO) actgrp(*NEW)
+ option(*NOSHOWCPY)
+ bnddir('CURL');
+ *
+ **************************************************************************
+ * _ _ ____ _
+ * 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
+ *
+ **************************************************************************
+
+ /include H,CURL.INC
+
+ * Simple free-format RPG program to request the URL given as command line
+ * parameter and output its response.
+
+ dcl-pi *N;
+ url char(120);
+ end-pi;
+
+ dcl-s urllen int(10); // URL length
+
+ **************************************************************************
+
+ urllen = trimmed_length(url: %len(url));
+
+ // Do the curl stuff.
+
+ curl_global_init(CURL_GLOBAL_ALL);
+ main();
+ curl_global_cleanup();
+ *inlr = *on; // Exit
+
+ **************************************************************************
+ * Main procedure: do the curl job.
+ **************************************************************************
+
+ dcl-proc main;
+ dcl-pi *N end-pi;
+
+ dcl-s h pointer; // Easy handle
+ dcl-s result like(CURLcode) inz(CURLE_OUT_OF_MEMORY); // Curl return code
+ dcl-s errmsgp pointer; // Error string pointer
+ dcl-s response char(52); // For error display
+
+ // Create and fill curl handle.
+
+ h = curl_easy_init();
+ if h <> *NULL;
+ curl_easy_setopt_ccsid(h: CURLOPT_URL: %subst(url: 1: urllen):
+ 0);
+ curl_easy_setopt(h: CURLOPT_FOLLOWLOCATION: 1);
+
+ // Perform the request.
+
+ result = curl_easy_perform(h);
+ curl_easy_cleanup(h); // Release handle
+ endif;
+
+ // Check for error and report if some.
+
+ if result <> CURLE_OK;
+ errmsgp = curl_easy_strerror_ccsid(result: 0);
+ response = %str(errmsgp);
+ dsply '' '*EXT' response;
+ endif;
+ end-proc;
+ *
+ **************************************************************************
+ * Get the length of right-trimmed string
+ **************************************************************************
+ *
+ dcl-proc trimmed_length;
+ dcl-pi *N uns(10);
+ string char(9999999) const options(*varsize);
+ length uns(10) value;
+ end-pi;
+
+ dcl-s len uns(10);
+
+ len = %scan(X'00': string: 1: length); // Limit to zero-terminated string
+ if len = 0;
+ len = length + 1;
+ endif;
+ if len <= 1;
+ return 0;
+ endif;
+ return %checkr(' ': string: len - 1); // Trim right
+ end-proc;
diff --git a/packages/OS400/rpg-examples/SMTPSRCMBR b/packages/OS400/rpg-examples/SMTPSRCMBR
new file mode 100644
index 000000000..88f4fd25c
--- /dev/null
+++ b/packages/OS400/rpg-examples/SMTPSRCMBR
@@ -0,0 +1,239 @@
+ * Curl SMTP send source member as attachment
+ *
+ h DFTACTGRP(*NO) ACTGRP(*NEW)
+ h OPTION(*NOSHOWCPY)
+ h BNDDIR('CURL')
+ *
+ **************************************************************************
+ * _ _ ____ _
+ * 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
+ *
+ **************************************************************************
+ *
+ /include H,CURL.INC
+ *
+ * Example to SMTP send source member as attachment via SMTP.
+ *
+ fRPGXAMPLESif e disk extmbr(program_name)
+ f rename(RPGXAMPLES: record)
+ d pi
+ d url 60 SMTP server URL
+ d recipient_mail 40 Recipient mail addr
+ *
+ d program_name c 'SMTPSRCMBR' Member name to send
+ d sender_name c 'Curl' Sender name
+ d sender_mail c 'curl@example.com' Sender e-mail
+ d recipient_name c 'WIMC' Recipient name
+ d crlf c X'0D25'
+ *
+ d urllen s 10u 0 URL length
+ d rcptmlen s 10u 0 Recipient mail len
+ *
+ **************************************************************************
+
+ urllen = trimmed_length(url: %len(url));
+ rcptmlen = trimmed_length(recipient_mail: %len(recipient_mail));
+
+ // Do the curl stuff.
+
+ curl_global_init(CURL_GLOBAL_ALL);
+ main();
+ curl_global_cleanup();
+ *inlr = *on; // Exit
+ *
+ **************************************************************************
+ * Main procedure: do the curl job.
+ **************************************************************************
+ *
+ p main b
+ d main pi
+ *
+ d h s * Easy handle
+ d result s like(CURLcode) Curl return code
+ d inz(CURLE_OUT_OF_MEMORY)
+ d errmsgp s * Error string pointer
+ d response s 52 For error display
+ d headers s * inz(*NULL) Mail headers
+ d rcpts s * inz(*NULL) List of recipients
+ d mime s * Mail MIME structure
+ d mimepart s * Mail part
+
+ // Create and fill curl handle.
+
+ h = curl_easy_init();
+ if h <> *NULL;
+ rcpts = curl_slist_append_ccsid(rcpts:
+ %subst(recipient_mail: 1: rcptmlen): 0);
+ headers = curl_slist_append_ccsid(headers: 'From: ' + sender_name +
+ ' <' + sender_mail + '>':
+ 0);
+ headers = curl_slist_append_ccsid(headers: 'To: ' + recipient_name +
+ ' <' + %subst(recipient_mail: 1: rcptmlen) + '>': 0);
+ headers = curl_slist_append_ccsid(headers: 'Subject: An ILE/RPG ' +
+ 'source program': 0);
+ headers = curl_slist_append_ccsid(headers: 'Date: ' + mail_date():
+ 0);
+ curl_easy_setopt_ccsid(h: CURLOPT_URL: %subst(url: 1: urllen): 0);
+ curl_easy_setopt_ccsid(h: CURLOPT_MAIL_FROM: sender_mail: 0);
+ curl_easy_setopt(h: CURLOPT_MAIL_RCPT: rcpts);
+ curl_easy_setopt(h: CURLOPT_HTTPHEADER: headers);
+ mime = curl_mime_init(h);
+ mimepart = curl_mime_addpart(mime);
+ curl_mime_data_ccsid(mimepart: 'Please find the ILE/RPG program ' +
+ program_name + ' source code in ' +
+ 'attachment.' + crlf:
+ CURL_ZERO_TERMINATED: 0);
+ mimepart = curl_mime_addpart(mime);
+ curl_mime_data_cb(mimepart: -1: %paddr(out_data_cb): *NULL: *NULL:
+ *NULL);
+ curl_mime_filename_ccsid(mimepart: program_name: 0);
+ curl_mime_encoder_ccsid(mimepart: 'quoted-printable': 0);
+ curl_easy_setopt(h: CURLOPT_MIMEPOST: mime);
+
+ // Perform the request.
+
+ setll *start RPGXAMPLES;
+ result = curl_easy_perform(h);
+
+ // Cleanup.
+
+ curl_mime_free(mime);
+ curl_slist_free_all(headers);
+ curl_slist_free_all(rcpts);
+ curl_easy_cleanup(h); // Release handle
+ endif;
+
+ // Check for error and report if some.
+
+ if result <> CURLE_OK;
+ errmsgp = curl_easy_strerror_ccsid(result: 0);
+ response = %str(errmsgp);
+ dsply '' '*EXT' response;
+ else;
+ response = 'Mail sent';
+ dsply '' '*EXT' response;
+ endif;
+ p main e
+ *
+ **************************************************************************
+ * Attachment data callback procedure.
+ **************************************************************************
+ *
+ p out_data_cb b
+ d out_data_cb pi 10u 0
+ d ptr * value Output data pointer
+ d size 10u 0 value Data element size
+ d nmemb 10u 0 value Data element count
+ d userdata * value User data pointer
+ *
+ d buffer s 9999999 based(ptr) Output buffer
+ d line s 9999999 based(lineptr) ASCII line pointer
+ d linelen s 10u 0
+ d i s 10u 0 Buffer position
+ *
+ size = size * nmemb; // The size in bytes.
+ i = 0;
+ dow size - i >= %len(SRCDTA) + %len(crlf) and not %eof(RPGXAMPLES);
+ read record;
+ lineptr = curl_from_ccsid(%trimr(SRCDTA) + crlf: 0);
+ linelen = %scan(X'00': line) - 1;
+ %subst(buffer: i + 1: linelen) = %str(lineptr);
+ curl_free(lineptr);
+ i = i + linelen;
+ enddo;
+ return i;
+ p out_data_cb e
+ *
+ **************************************************************************
+ * Mail-formatted date procedure.
+ **************************************************************************
+ *
+ p mail_date b
+ d mail_date pi 50 varying
+ *
+ d sysval ds qualified To retrieve timezone
+ d numsysval 10u 0
+ d offset 10u 0
+ d 100
+ *
+ d get_sysval pr extpgm('QWCRSVAL')
+ d outdata likeds(sysval)
+ d outsize 10u 0 const
+ d numsysval 10u 0 const
+ d name 10 const
+ d errcode 10000 options(*varsize)
+ *
+ d now ds qualified
+ d ts z
+ d year 4s 0 overlay(ts: 1)
+ d month 2s 0 overlay(ts: 6)
+ d day 2s 0 overlay(ts: 9)
+ d hour 2s 0 overlay(ts: 12)
+ d minute 2 overlay(ts: 15)
+ d second 2 overlay(ts: 18)
+ *
+ d sysvalinfo ds qualified based(sysvalinfoptr)
+ d name 10
+ d type 1
+ d status 1
+ d length 10u 0
+ d value 99999
+ *
+ d qusec ds qualified
+ d 10u 0 inz(0)
+ *
+ d weekday s 10u 0
+ *
+ now.ts = %timestamp(*SYS);
+ get_sysval(sysval: %len(sysval): 1: 'QUTCOFFSET': qusec);
+ sysvalinfoptr = %addr(sysval) + sysval.offset;
+ weekday = %rem(%diff(now.ts: %timestamp('2001-01-01-00.00.00.000000'):
+ *DAYS): 7);
+ return %subst('MonTueWedThuFriSatSun': 3 * weekday + 1: 3) + ', ' +
+ %char(now.day) + ' ' +
+ %subst('JanFebMarAprMayJunJulAugSepOctNovDec':
+ 3 * now.month - 2: 3) + ' ' +
+ %char(now.year) + ' ' +
+ %char(now.hour) + ':' + now.minute + ':' + now.second + ' ' +
+ %subst(sysvalinfo.value: 1: sysvalinfo.length);
+ p mail_date e
+ *
+ **************************************************************************
+ * Get the length of right-trimmed string
+ **************************************************************************
+ *
+ p trimmed_length b
+ d trimmed_length pi 10u 0
+ d string 999999 const options(*varsize)
+ d length 10u 0 value
+ *
+ d addrdiff s 10i 0
+ d len s 10u 0
+ *
+ len = %scan(X'00': string: 1: length); // Limit to zero-terminated string
+ if len = 0;
+ len = length + 1;
+ endif;
+ if len <= 1;
+ return 0;
+ endif;
+ return %checkr(' ': string: len - 1); // Trim right
+ p trimmed_length e