summaryrefslogtreecommitdiffstats
path: root/Utilities/cmlibuv/src/unix/ibmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmlibuv/src/unix/ibmi.c')
-rw-r--r--Utilities/cmlibuv/src/unix/ibmi.c264
1 files changed, 238 insertions, 26 deletions
diff --git a/Utilities/cmlibuv/src/unix/ibmi.c b/Utilities/cmlibuv/src/unix/ibmi.c
index c7e1051..e4c5122 100644
--- a/Utilities/cmlibuv/src/unix/ibmi.c
+++ b/Utilities/cmlibuv/src/unix/ibmi.c
@@ -56,6 +56,7 @@
#include <sys/vnode.h>
#include <as400_protos.h>
+#include <as400_types.h>
typedef struct {
@@ -98,24 +99,91 @@ typedef struct {
} SSTS0200;
+typedef struct {
+ char header[208];
+ unsigned char loca_adapter_address[12];
+} LIND0500;
+
+
+typedef struct {
+ int bytes_provided;
+ int bytes_available;
+ char msgid[7];
+} errcode_s;
+
+
+static const unsigned char e2a[256] = {
+ 0, 1, 2, 3, 156, 9, 134, 127, 151, 141, 142, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 157, 133, 8, 135, 24, 25, 146, 143, 28, 29, 30, 31,
+ 128, 129, 130, 131, 132, 10, 23, 27, 136, 137, 138, 139, 140, 5, 6, 7,
+ 144, 145, 22, 147, 148, 149, 150, 4, 152, 153, 154, 155, 20, 21, 158, 26,
+ 32, 160, 161, 162, 163, 164, 165, 166, 167, 168, 91, 46, 60, 40, 43, 33,
+ 38, 169, 170, 171, 172, 173, 174, 175, 176, 177, 93, 36, 42, 41, 59, 94,
+ 45, 47, 178, 179, 180, 181, 182, 183, 184, 185, 124, 44, 37, 95, 62, 63,
+ 186, 187, 188, 189, 190, 191, 192, 193, 194, 96, 58, 35, 64, 39, 61, 34,
+ 195, 97, 98, 99, 100, 101, 102, 103, 104, 105, 196, 197, 198, 199, 200, 201,
+ 202, 106, 107, 108, 109, 110, 111, 112, 113, 114, 203, 204, 205, 206, 207, 208,
+ 209, 126, 115, 116, 117, 118, 119, 120, 121, 122, 210, 211, 212, 213, 214, 215,
+ 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231,
+ 123, 65, 66, 67, 68, 69, 70, 71, 72, 73, 232, 233, 234, 235, 236, 237,
+ 125, 74, 75, 76, 77, 78, 79, 80, 81, 82, 238, 239, 240, 241, 242, 243,
+ 92, 159, 83, 84, 85, 86, 87, 88, 89, 90, 244, 245, 246, 247, 248, 249,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 250, 251, 252, 253, 254, 255};
+
+
+static const unsigned char a2e[256] = {
+ 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31,
+ 64, 79, 127, 123, 91, 108, 80, 125, 77, 93, 92, 78, 107, 96, 75, 97,
+ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 122, 94, 76, 126, 110, 111,
+ 124, 193, 194, 195, 196, 197, 198, 199, 200, 201, 209, 210, 211, 212, 213, 214,
+ 215, 216, 217, 226, 227, 228, 229, 230, 231, 232, 233, 74, 224, 90, 95, 109,
+ 121, 129, 130, 131, 132, 133, 134, 135, 136, 137, 145, 146, 147, 148, 149, 150,
+ 151, 152, 153, 162, 163, 164, 165, 166, 167, 168, 169, 192, 106, 208, 161, 7,
+ 32, 33, 34, 35, 36, 21, 6, 23, 40, 41, 42, 43, 44, 9, 10, 27,
+ 48, 49, 26, 51, 52, 53, 54, 8, 56, 57, 58, 59, 4, 20, 62, 225,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 98, 99, 100, 101, 102, 103, 104, 105, 112, 113, 114, 115, 116, 117,
+ 118, 119, 120, 128, 138, 139, 140, 141, 142, 143, 144, 154, 155, 156, 157, 158,
+ 159, 160, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183,
+ 184, 185, 186, 187, 188, 189, 190, 191, 202, 203, 204, 205, 206, 207, 218, 219,
+ 220, 221, 222, 223, 234, 235, 236, 237, 238, 239, 250, 251, 252, 253, 254, 255};
+
+
+static void iconv_e2a(unsigned char src[], unsigned char dst[], size_t length) {
+ size_t i;
+ for (i = 0; i < length; i++)
+ dst[i] = e2a[src[i]];
+}
+
+
+static void iconv_a2e(const char* src, unsigned char dst[], size_t length) {
+ size_t srclen;
+ size_t i;
+
+ srclen = strlen(src);
+ if (srclen > length)
+ abort();
+ for (i = 0; i < srclen; i++)
+ dst[i] = a2e[src[i]];
+ /* padding the remaining part with spaces */
+ for (; i < length; i++)
+ dst[i] = a2e[' '];
+}
+
+
static int get_ibmi_system_status(SSTS0200* rcvr) {
/* rcvrlen is input parameter 2 to QWCRSSTS */
unsigned int rcvrlen = sizeof(*rcvr);
+ unsigned char format[8], reset_status[10];
- /* format is input parameter 3 to QWCRSSTS ("SSTS0200" in EBCDIC) */
- unsigned char format[] = {0xE2, 0xE2, 0xE3, 0xE2, 0xF0, 0xF2, 0xF0, 0xF0};
-
- /* reset_status is input parameter 4 to QWCRSSTS ("*NO " in EBCDIC) */
- unsigned char reset_status[] = {
- 0x5C, 0xD5, 0xD6, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
- };
+ /* format is input parameter 3 to QWCRSSTS */
+ iconv_a2e("SSTS0200", format, sizeof(format));
+ /* reset_status is input parameter 4 */
+ iconv_a2e("*NO", reset_status, sizeof(reset_status));
/* errcode is input parameter 5 to QWCRSSTS */
- struct _errcode {
- int bytes_provided;
- int bytes_available;
- char msgid[7];
- } errcode;
+ errcode_s errcode;
/* qwcrssts_pointer is the 16-byte tagged system pointer to QWCRSSTS */
ILEpointer __attribute__((aligned(16))) qwcrssts_pointer;
@@ -145,7 +213,7 @@ static int get_ibmi_system_status(SSTS0200* rcvr) {
qwcrssts_argv[5] = NULL;
/* Call the IBM i QWCRSSTS API from PASE */
- rc = _PGMCALL(&qwcrssts_pointer, (void**)&qwcrssts_argv, 0);
+ rc = _PGMCALL(&qwcrssts_pointer, qwcrssts_argv, 0);
return rc;
}
@@ -157,19 +225,7 @@ uint64_t uv_get_free_memory(void) {
if (get_ibmi_system_status(&rcvr))
return 0;
- /* The amount of main storage, in kilobytes, in the system. */
- uint64_t main_storage_size = rcvr.main_storage_size;
-
- /* The current amount of storage in use for temporary objects.
- * in millions (M) of bytes.
- */
- uint64_t current_unprotected_storage_used =
- rcvr.current_unprotected_storage_used * 1024ULL;
-
- uint64_t free_storage_size =
- (main_storage_size - current_unprotected_storage_used) * 1024ULL;
-
- return free_storage_size < 0 ? 0 : free_storage_size;
+ return (uint64_t)rcvr.main_storage_size * 1024ULL;
}
@@ -248,3 +304,159 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
return 0;
}
+
+static int get_ibmi_physical_address(const char* line, char (*phys_addr)[6]) {
+ LIND0500 rcvr;
+ /* rcvrlen is input parameter 2 to QDCRLIND */
+ unsigned int rcvrlen = sizeof(rcvr);
+ unsigned char format[8], line_name[10];
+ unsigned char mac_addr[sizeof(rcvr.loca_adapter_address)];
+ int c[6];
+
+ /* format is input parameter 3 to QDCRLIND */
+ iconv_a2e("LIND0500", format, sizeof(format));
+
+ /* line_name is input parameter 4 to QDCRLIND */
+ iconv_a2e(line, line_name, sizeof(line_name));
+
+ /* err is input parameter 5 to QDCRLIND */
+ errcode_s err;
+
+ /* qwcrssts_pointer is the 16-byte tagged system pointer to QDCRLIND */
+ ILEpointer __attribute__((aligned(16))) qdcrlind_pointer;
+
+ /* qwcrssts_argv is the array of argument pointers to QDCRLIND */
+ void* qdcrlind_argv[6];
+
+ /* Set the IBM i pointer to the QSYS/QDCRLIND *PGM object */
+ int rc = _RSLOBJ2(&qdcrlind_pointer, RSLOBJ_TS_PGM, "QDCRLIND", "QSYS");
+
+ if (rc != 0)
+ return rc;
+
+ /* initialize the QDCRLIND returned info structure */
+ memset(&rcvr, 0, sizeof(rcvr));
+
+ /* initialize the QDCRLIND error code structure */
+ memset(&err, 0, sizeof(err));
+ err.bytes_provided = sizeof(err);
+
+ /* initialize the array of argument pointers for the QDCRLIND API */
+ qdcrlind_argv[0] = &rcvr;
+ qdcrlind_argv[1] = &rcvrlen;
+ qdcrlind_argv[2] = &format;
+ qdcrlind_argv[3] = &line_name;
+ qdcrlind_argv[4] = &err;
+ qdcrlind_argv[5] = NULL;
+
+ /* Call the IBM i QDCRLIND API from PASE */
+ rc = _PGMCALL(&qdcrlind_pointer, qdcrlind_argv, 0);
+ if (rc != 0)
+ return rc;
+
+ /* convert ebcdic loca_adapter_address to ascii first */
+ iconv_e2a(rcvr.loca_adapter_address, mac_addr,
+ sizeof(rcvr.loca_adapter_address));
+
+ /* convert loca_adapter_address(char[12]) to phys_addr(char[6]) */
+ int r = sscanf(mac_addr, "%02x%02x%02x%02x%02x%02x",
+ &c[0], &c[1], &c[2], &c[3], &c[4], &c[5]);
+
+ if (r == ARRAY_SIZE(c)) {
+ (*phys_addr)[0] = c[0];
+ (*phys_addr)[1] = c[1];
+ (*phys_addr)[2] = c[2];
+ (*phys_addr)[3] = c[3];
+ (*phys_addr)[4] = c[4];
+ (*phys_addr)[5] = c[5];
+ } else {
+ memset(*phys_addr, 0, sizeof(*phys_addr));
+ rc = -1;
+ }
+ return rc;
+}
+
+
+int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
+ uv_interface_address_t* address;
+ struct ifaddrs_pase *ifap = NULL, *cur;
+ int inet6, r = 0;
+
+ *count = 0;
+ *addresses = NULL;
+
+ if (Qp2getifaddrs(&ifap))
+ return UV_ENOSYS;
+
+ /* The first loop to get the size of the array to be allocated */
+ for (cur = ifap; cur; cur = cur->ifa_next) {
+ if (!(cur->ifa_addr->sa_family == AF_INET6 ||
+ cur->ifa_addr->sa_family == AF_INET))
+ continue;
+
+ if (!(cur->ifa_flags & IFF_UP && cur->ifa_flags & IFF_RUNNING))
+ continue;
+
+ (*count)++;
+ }
+
+ if (*count == 0) {
+ Qp2freeifaddrs(ifap);
+ return 0;
+ }
+
+ /* Alloc the return interface structs */
+ *addresses = uv__calloc(*count, sizeof(**addresses));
+ if (*addresses == NULL) {
+ Qp2freeifaddrs(ifap);
+ return UV_ENOMEM;
+ }
+ address = *addresses;
+
+ /* The second loop to fill in the array */
+ for (cur = ifap; cur; cur = cur->ifa_next) {
+ if (!(cur->ifa_addr->sa_family == AF_INET6 ||
+ cur->ifa_addr->sa_family == AF_INET))
+ continue;
+
+ if (!(cur->ifa_flags & IFF_UP && cur->ifa_flags & IFF_RUNNING))
+ continue;
+
+ address->name = uv__strdup(cur->ifa_name);
+
+ inet6 = (cur->ifa_addr->sa_family == AF_INET6);
+
+ if (inet6) {
+ address->address.address6 = *((struct sockaddr_in6*)cur->ifa_addr);
+ address->netmask.netmask6 = *((struct sockaddr_in6*)cur->ifa_netmask);
+ address->netmask.netmask6.sin6_family = AF_INET6;
+ } else {
+ address->address.address4 = *((struct sockaddr_in*)cur->ifa_addr);
+ address->netmask.netmask4 = *((struct sockaddr_in*)cur->ifa_netmask);
+ address->netmask.netmask4.sin_family = AF_INET;
+ }
+ address->is_internal = cur->ifa_flags & IFF_LOOPBACK ? 1 : 0;
+ if (!address->is_internal) {
+ int rc = get_ibmi_physical_address(address->name, &address->phys_addr);
+ if (rc != 0)
+ r = rc;
+ }
+
+ address++;
+ }
+
+ Qp2freeifaddrs(ifap);
+ return r;
+}
+
+
+void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) {
+ int i;
+
+ for (i = 0; i < count; ++i) {
+ uv__free(addresses[i].name);
+ }
+
+ uv__free(addresses);
+}
+