xref: /netbsd-src/external/mit/libuv/dist/src/unix/ibmi.c (revision 5f2f42719cd62ff11fd913b40b7ce19f07c4fd25)
10e552da7Schristos /* Copyright libuv project contributors. All rights reserved.
20e552da7Schristos  *
30e552da7Schristos  * Permission is hereby granted, free of charge, to any person obtaining a copy
40e552da7Schristos  * of this software and associated documentation files (the "Software"), to
50e552da7Schristos  * deal in the Software without restriction, including without limitation the
60e552da7Schristos  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
70e552da7Schristos  * sell copies of the Software, and to permit persons to whom the Software is
80e552da7Schristos  * furnished to do so, subject to the following conditions:
90e552da7Schristos  *
100e552da7Schristos  * The above copyright notice and this permission notice shall be included in
110e552da7Schristos  * all copies or substantial portions of the Software.
120e552da7Schristos  *
130e552da7Schristos  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
140e552da7Schristos  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
150e552da7Schristos  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
160e552da7Schristos  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
170e552da7Schristos  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
180e552da7Schristos  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
190e552da7Schristos  * IN THE SOFTWARE.
200e552da7Schristos  */
210e552da7Schristos 
220e552da7Schristos #include "uv.h"
230e552da7Schristos #include "internal.h"
240e552da7Schristos 
250e552da7Schristos #include <stdio.h>
260e552da7Schristos #include <stdint.h>
270e552da7Schristos #include <stdlib.h>
280e552da7Schristos #include <string.h>
290e552da7Schristos #include <errno.h>
300e552da7Schristos 
310e552da7Schristos #include <sys/types.h>
320e552da7Schristos #include <sys/socket.h>
330e552da7Schristos #include <sys/ioctl.h>
340e552da7Schristos #include <net/if.h>
350e552da7Schristos #include <netinet/in.h>
360e552da7Schristos #include <arpa/inet.h>
370e552da7Schristos 
380e552da7Schristos #include <sys/time.h>
390e552da7Schristos #include <unistd.h>
400e552da7Schristos #include <fcntl.h>
410e552da7Schristos #include <utmp.h>
420e552da7Schristos #include <libgen.h>
430e552da7Schristos 
440e552da7Schristos #include <sys/protosw.h>
450e552da7Schristos #include <procinfo.h>
460e552da7Schristos #include <sys/proc.h>
470e552da7Schristos #include <sys/procfs.h>
480e552da7Schristos 
490e552da7Schristos #include <ctype.h>
500e552da7Schristos 
510e552da7Schristos #include <sys/mntctl.h>
520e552da7Schristos #include <sys/vmount.h>
530e552da7Schristos #include <limits.h>
540e552da7Schristos #include <strings.h>
550e552da7Schristos #include <sys/vnode.h>
560e552da7Schristos 
570e552da7Schristos #include <as400_protos.h>
580e552da7Schristos #include <as400_types.h>
590e552da7Schristos 
60*5f2f4271Schristos char* original_exepath = NULL;
61*5f2f4271Schristos uv_mutex_t process_title_mutex;
62*5f2f4271Schristos uv_once_t process_title_mutex_once = UV_ONCE_INIT;
630e552da7Schristos 
640e552da7Schristos typedef struct {
650e552da7Schristos   int bytes_available;
660e552da7Schristos   int bytes_returned;
670e552da7Schristos   char current_date_and_time[8];
680e552da7Schristos   char system_name[8];
690e552da7Schristos   char elapsed_time[6];
700e552da7Schristos   char restricted_state_flag;
710e552da7Schristos   char reserved;
720e552da7Schristos   int percent_processing_unit_used;
730e552da7Schristos   int jobs_in_system;
740e552da7Schristos   int percent_permanent_addresses;
750e552da7Schristos   int percent_temporary_addresses;
760e552da7Schristos   int system_asp;
770e552da7Schristos   int percent_system_asp_used;
780e552da7Schristos   int total_auxiliary_storage;
790e552da7Schristos   int current_unprotected_storage_used;
800e552da7Schristos   int maximum_unprotected_storage_used;
810e552da7Schristos   int percent_db_capability;
820e552da7Schristos   int main_storage_size;
830e552da7Schristos   int number_of_partitions;
840e552da7Schristos   int partition_identifier;
850e552da7Schristos   int reserved1;
860e552da7Schristos   int current_processing_capacity;
870e552da7Schristos   char processor_sharing_attribute;
880e552da7Schristos   char reserved2[3];
890e552da7Schristos   int number_of_processors;
900e552da7Schristos   int active_jobs_in_system;
910e552da7Schristos   int active_threads_in_system;
920e552da7Schristos   int maximum_jobs_in_system;
930e552da7Schristos   int percent_temporary_256mb_segments_used;
940e552da7Schristos   int percent_temporary_4gb_segments_used;
950e552da7Schristos   int percent_permanent_256mb_segments_used;
960e552da7Schristos   int percent_permanent_4gb_segments_used;
970e552da7Schristos   int percent_current_interactive_performance;
980e552da7Schristos   int percent_uncapped_cpu_capacity_used;
990e552da7Schristos   int percent_shared_processor_pool_used;
1000e552da7Schristos   long main_storage_size_long;
1010e552da7Schristos } SSTS0200;
1020e552da7Schristos 
1030e552da7Schristos 
1040e552da7Schristos typedef struct {
1050e552da7Schristos   char header[208];
1060e552da7Schristos   unsigned char loca_adapter_address[12];
1070e552da7Schristos } LIND0500;
1080e552da7Schristos 
1090e552da7Schristos 
1100e552da7Schristos typedef struct {
1110e552da7Schristos   int bytes_provided;
1120e552da7Schristos   int bytes_available;
1130e552da7Schristos   char msgid[7];
1140e552da7Schristos } errcode_s;
1150e552da7Schristos 
1160e552da7Schristos 
1170e552da7Schristos static const unsigned char e2a[256] = {
1180e552da7Schristos     0, 1, 2, 3, 156, 9, 134, 127, 151, 141, 142, 11, 12, 13, 14, 15,
1190e552da7Schristos     16, 17, 18, 19, 157, 133, 8, 135, 24, 25, 146, 143, 28, 29, 30, 31,
1200e552da7Schristos     128, 129, 130, 131, 132, 10, 23, 27, 136, 137, 138, 139, 140, 5, 6, 7,
1210e552da7Schristos     144, 145, 22, 147, 148, 149, 150, 4, 152, 153, 154, 155, 20, 21, 158, 26,
1220e552da7Schristos     32, 160, 161, 162, 163, 164, 165, 166, 167, 168, 91, 46, 60, 40, 43, 33,
1230e552da7Schristos     38, 169, 170, 171, 172, 173, 174, 175, 176, 177, 93, 36, 42, 41, 59, 94,
1240e552da7Schristos     45, 47, 178, 179, 180, 181, 182, 183, 184, 185, 124, 44, 37, 95, 62, 63,
1250e552da7Schristos     186, 187, 188, 189, 190, 191, 192, 193, 194, 96, 58, 35, 64, 39, 61, 34,
1260e552da7Schristos     195, 97, 98, 99, 100, 101, 102, 103, 104, 105, 196, 197, 198, 199, 200, 201,
1270e552da7Schristos     202, 106, 107, 108, 109, 110, 111, 112, 113, 114, 203, 204, 205, 206, 207, 208,
1280e552da7Schristos     209, 126, 115, 116, 117, 118, 119, 120, 121, 122, 210, 211, 212, 213, 214, 215,
1290e552da7Schristos     216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231,
1300e552da7Schristos     123, 65, 66, 67, 68, 69, 70, 71, 72, 73, 232, 233, 234, 235, 236, 237,
1310e552da7Schristos     125, 74, 75, 76, 77, 78, 79, 80, 81, 82, 238, 239, 240, 241, 242, 243,
1320e552da7Schristos     92, 159, 83, 84, 85, 86, 87, 88, 89, 90, 244, 245, 246, 247, 248, 249,
1330e552da7Schristos     48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 250, 251, 252, 253, 254, 255};
1340e552da7Schristos 
1350e552da7Schristos 
1360e552da7Schristos static const unsigned char a2e[256] = {
1370e552da7Schristos     0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15,
1380e552da7Schristos     16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31,
1390e552da7Schristos     64, 79, 127, 123, 91, 108, 80, 125, 77, 93, 92, 78, 107, 96, 75, 97,
1400e552da7Schristos     240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 122, 94, 76, 126, 110, 111,
1410e552da7Schristos     124, 193, 194, 195, 196, 197, 198, 199, 200, 201, 209, 210, 211, 212, 213, 214,
1420e552da7Schristos     215, 216, 217, 226, 227, 228, 229, 230, 231, 232, 233, 74, 224, 90, 95, 109,
1430e552da7Schristos     121, 129, 130, 131, 132, 133, 134, 135, 136, 137, 145, 146, 147, 148, 149, 150,
1440e552da7Schristos     151, 152, 153, 162, 163, 164, 165, 166, 167, 168, 169, 192, 106, 208, 161, 7,
1450e552da7Schristos     32, 33, 34, 35, 36, 21, 6, 23, 40, 41, 42, 43, 44, 9, 10, 27,
1460e552da7Schristos     48, 49, 26, 51, 52, 53, 54, 8, 56, 57, 58, 59, 4, 20, 62, 225,
1470e552da7Schristos     65, 66, 67, 68, 69, 70, 71, 72, 73, 81, 82, 83, 84, 85, 86, 87,
1480e552da7Schristos     88, 89, 98, 99, 100, 101, 102, 103, 104, 105, 112, 113, 114, 115, 116, 117,
1490e552da7Schristos     118, 119, 120, 128, 138, 139, 140, 141, 142, 143, 144, 154, 155, 156, 157, 158,
1500e552da7Schristos     159, 160, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183,
1510e552da7Schristos     184, 185, 186, 187, 188, 189, 190, 191, 202, 203, 204, 205, 206, 207, 218, 219,
1520e552da7Schristos     220, 221, 222, 223, 234, 235, 236, 237, 238, 239, 250, 251, 252, 253, 254, 255};
1530e552da7Schristos 
1540e552da7Schristos 
iconv_e2a(unsigned char src[],unsigned char dst[],size_t length)1550e552da7Schristos static void iconv_e2a(unsigned char src[], unsigned char dst[], size_t length) {
1560e552da7Schristos   size_t i;
1570e552da7Schristos   for (i = 0; i < length; i++)
1580e552da7Schristos     dst[i] = e2a[src[i]];
1590e552da7Schristos }
1600e552da7Schristos 
1610e552da7Schristos 
iconv_a2e(const char * src,unsigned char dst[],size_t length)1620e552da7Schristos static void iconv_a2e(const char* src, unsigned char dst[], size_t length) {
1630e552da7Schristos   size_t srclen;
1640e552da7Schristos   size_t i;
1650e552da7Schristos 
1660e552da7Schristos   srclen = strlen(src);
1670e552da7Schristos   if (srclen > length)
168*5f2f4271Schristos     srclen = length;
1690e552da7Schristos   for (i = 0; i < srclen; i++)
1700e552da7Schristos     dst[i] = a2e[src[i]];
1710e552da7Schristos   /* padding the remaining part with spaces */
1720e552da7Schristos   for (; i < length; i++)
1730e552da7Schristos     dst[i] = a2e[' '];
1740e552da7Schristos }
1750e552da7Schristos 
init_process_title_mutex_once(void)176*5f2f4271Schristos void init_process_title_mutex_once(void) {
177*5f2f4271Schristos   uv_mutex_init(&process_title_mutex);
178*5f2f4271Schristos }
1790e552da7Schristos 
get_ibmi_system_status(SSTS0200 * rcvr)1800e552da7Schristos static int get_ibmi_system_status(SSTS0200* rcvr) {
1810e552da7Schristos   /* rcvrlen is input parameter 2 to QWCRSSTS */
1820e552da7Schristos   unsigned int rcvrlen = sizeof(*rcvr);
1830e552da7Schristos   unsigned char format[8], reset_status[10];
1840e552da7Schristos 
1850e552da7Schristos   /* format is input parameter 3 to QWCRSSTS */
1860e552da7Schristos   iconv_a2e("SSTS0200", format, sizeof(format));
1870e552da7Schristos   /* reset_status is input parameter 4 */
1880e552da7Schristos   iconv_a2e("*NO", reset_status, sizeof(reset_status));
1890e552da7Schristos 
1900e552da7Schristos   /* errcode is input parameter 5 to QWCRSSTS */
1910e552da7Schristos   errcode_s errcode;
1920e552da7Schristos 
1930e552da7Schristos   /* qwcrssts_pointer is the 16-byte tagged system pointer to QWCRSSTS */
1940e552da7Schristos   ILEpointer __attribute__((aligned(16))) qwcrssts_pointer;
1950e552da7Schristos 
1960e552da7Schristos   /* qwcrssts_argv is the array of argument pointers to QWCRSSTS */
1970e552da7Schristos   void* qwcrssts_argv[6];
1980e552da7Schristos 
1990e552da7Schristos   /* Set the IBM i pointer to the QSYS/QWCRSSTS *PGM object */
2000e552da7Schristos   int rc = _RSLOBJ2(&qwcrssts_pointer, RSLOBJ_TS_PGM, "QWCRSSTS", "QSYS");
2010e552da7Schristos 
2020e552da7Schristos   if (rc != 0)
2030e552da7Schristos     return rc;
2040e552da7Schristos 
2050e552da7Schristos   /* initialize the QWCRSSTS returned info structure */
2060e552da7Schristos   memset(rcvr, 0, sizeof(*rcvr));
2070e552da7Schristos 
2080e552da7Schristos   /* initialize the QWCRSSTS error code structure */
2090e552da7Schristos   memset(&errcode, 0, sizeof(errcode));
2100e552da7Schristos   errcode.bytes_provided = sizeof(errcode);
2110e552da7Schristos 
2120e552da7Schristos   /* initialize the array of argument pointers for the QWCRSSTS API */
2130e552da7Schristos   qwcrssts_argv[0] = rcvr;
2140e552da7Schristos   qwcrssts_argv[1] = &rcvrlen;
2150e552da7Schristos   qwcrssts_argv[2] = &format;
2160e552da7Schristos   qwcrssts_argv[3] = &reset_status;
2170e552da7Schristos   qwcrssts_argv[4] = &errcode;
2180e552da7Schristos   qwcrssts_argv[5] = NULL;
2190e552da7Schristos 
2200e552da7Schristos   /* Call the IBM i QWCRSSTS API from PASE */
2210e552da7Schristos   rc = _PGMCALL(&qwcrssts_pointer, qwcrssts_argv, 0);
2220e552da7Schristos 
2230e552da7Schristos   return rc;
2240e552da7Schristos }
2250e552da7Schristos 
2260e552da7Schristos 
uv_get_free_memory(void)2270e552da7Schristos uint64_t uv_get_free_memory(void) {
2280e552da7Schristos   SSTS0200 rcvr;
2290e552da7Schristos 
2300e552da7Schristos   if (get_ibmi_system_status(&rcvr))
2310e552da7Schristos     return 0;
2320e552da7Schristos 
2330e552da7Schristos   return (uint64_t)rcvr.main_storage_size * 1024ULL;
2340e552da7Schristos }
2350e552da7Schristos 
2360e552da7Schristos 
uv_get_total_memory(void)2370e552da7Schristos uint64_t uv_get_total_memory(void) {
2380e552da7Schristos   SSTS0200 rcvr;
2390e552da7Schristos 
2400e552da7Schristos   if (get_ibmi_system_status(&rcvr))
2410e552da7Schristos     return 0;
2420e552da7Schristos 
2430e552da7Schristos   return (uint64_t)rcvr.main_storage_size * 1024ULL;
2440e552da7Schristos }
2450e552da7Schristos 
2460e552da7Schristos 
uv_get_constrained_memory(void)2470e552da7Schristos uint64_t uv_get_constrained_memory(void) {
2480e552da7Schristos   return 0;  /* Memory constraints are unknown. */
2490e552da7Schristos }
2500e552da7Schristos 
2510e552da7Schristos 
uv_loadavg(double avg[3])2520e552da7Schristos void uv_loadavg(double avg[3]) {
2530e552da7Schristos   SSTS0200 rcvr;
2540e552da7Schristos 
2550e552da7Schristos   if (get_ibmi_system_status(&rcvr)) {
2560e552da7Schristos     avg[0] = avg[1] = avg[2] = 0;
2570e552da7Schristos     return;
2580e552da7Schristos   }
2590e552da7Schristos 
2600e552da7Schristos   /* The average (in tenths) of the elapsed time during which the processing
2610e552da7Schristos    * units were in use. For example, a value of 411 in binary would be 41.1%.
2620e552da7Schristos    * This percentage could be greater than 100% for an uncapped partition.
2630e552da7Schristos    */
2640e552da7Schristos   double processing_unit_used_percent =
2650e552da7Schristos     rcvr.percent_processing_unit_used / 1000.0;
2660e552da7Schristos 
2670e552da7Schristos   avg[0] = avg[1] = avg[2] = processing_unit_used_percent;
2680e552da7Schristos }
2690e552da7Schristos 
2700e552da7Schristos 
uv_resident_set_memory(size_t * rss)2710e552da7Schristos int uv_resident_set_memory(size_t* rss) {
2720e552da7Schristos   *rss = 0;
2730e552da7Schristos   return 0;
2740e552da7Schristos }
2750e552da7Schristos 
2760e552da7Schristos 
uv_uptime(double * uptime)2770e552da7Schristos int uv_uptime(double* uptime) {
2780e552da7Schristos   return UV_ENOSYS;
2790e552da7Schristos }
2800e552da7Schristos 
2810e552da7Schristos 
uv_cpu_info(uv_cpu_info_t ** cpu_infos,int * count)2820e552da7Schristos int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
2830e552da7Schristos   unsigned int numcpus, idx = 0;
2840e552da7Schristos   uv_cpu_info_t* cpu_info;
2850e552da7Schristos 
2860e552da7Schristos   *cpu_infos = NULL;
2870e552da7Schristos   *count = 0;
2880e552da7Schristos 
2890e552da7Schristos   numcpus = sysconf(_SC_NPROCESSORS_ONLN);
2900e552da7Schristos 
2910e552da7Schristos   *cpu_infos = uv__malloc(numcpus * sizeof(uv_cpu_info_t));
2920e552da7Schristos   if (!*cpu_infos) {
2930e552da7Schristos     return UV_ENOMEM;
2940e552da7Schristos   }
2950e552da7Schristos 
2960e552da7Schristos   cpu_info = *cpu_infos;
2970e552da7Schristos   for (idx = 0; idx < numcpus; idx++) {
2980e552da7Schristos     cpu_info->speed = 0;
2990e552da7Schristos     cpu_info->model = uv__strdup("unknown");
3000e552da7Schristos     cpu_info->cpu_times.user = 0;
3010e552da7Schristos     cpu_info->cpu_times.sys = 0;
3020e552da7Schristos     cpu_info->cpu_times.idle = 0;
3030e552da7Schristos     cpu_info->cpu_times.irq = 0;
3040e552da7Schristos     cpu_info->cpu_times.nice = 0;
3050e552da7Schristos     cpu_info++;
3060e552da7Schristos   }
3070e552da7Schristos   *count = numcpus;
3080e552da7Schristos 
3090e552da7Schristos   return 0;
3100e552da7Schristos }
3110e552da7Schristos 
3120e552da7Schristos 
get_ibmi_physical_address(const char * line,char (* phys_addr)[6])3130e552da7Schristos static int get_ibmi_physical_address(const char* line, char (*phys_addr)[6]) {
3140e552da7Schristos   LIND0500 rcvr;
3150e552da7Schristos   /* rcvrlen is input parameter 2 to QDCRLIND */
3160e552da7Schristos   unsigned int rcvrlen = sizeof(rcvr);
3170e552da7Schristos   unsigned char format[8], line_name[10];
3180e552da7Schristos   unsigned char mac_addr[sizeof(rcvr.loca_adapter_address)];
3190e552da7Schristos   int c[6];
3200e552da7Schristos 
3210e552da7Schristos   /* format is input parameter 3 to QDCRLIND */
3220e552da7Schristos   iconv_a2e("LIND0500", format, sizeof(format));
3230e552da7Schristos 
3240e552da7Schristos   /* line_name is input parameter 4 to QDCRLIND */
3250e552da7Schristos   iconv_a2e(line, line_name, sizeof(line_name));
3260e552da7Schristos 
3270e552da7Schristos   /* err is input parameter 5 to QDCRLIND */
3280e552da7Schristos   errcode_s err;
3290e552da7Schristos 
3300e552da7Schristos   /* qwcrssts_pointer is the 16-byte tagged system pointer to QDCRLIND */
3310e552da7Schristos   ILEpointer __attribute__((aligned(16))) qdcrlind_pointer;
3320e552da7Schristos 
3330e552da7Schristos   /* qwcrssts_argv is the array of argument pointers to QDCRLIND */
3340e552da7Schristos   void* qdcrlind_argv[6];
3350e552da7Schristos 
3360e552da7Schristos   /* Set the IBM i pointer to the QSYS/QDCRLIND *PGM object */
3370e552da7Schristos   int rc = _RSLOBJ2(&qdcrlind_pointer, RSLOBJ_TS_PGM, "QDCRLIND", "QSYS");
3380e552da7Schristos 
3390e552da7Schristos   if (rc != 0)
3400e552da7Schristos     return rc;
3410e552da7Schristos 
3420e552da7Schristos   /* initialize the QDCRLIND returned info structure */
3430e552da7Schristos   memset(&rcvr, 0, sizeof(rcvr));
3440e552da7Schristos 
3450e552da7Schristos   /* initialize the QDCRLIND error code structure */
3460e552da7Schristos   memset(&err, 0, sizeof(err));
3470e552da7Schristos   err.bytes_provided = sizeof(err);
3480e552da7Schristos 
3490e552da7Schristos   /* initialize the array of argument pointers for the QDCRLIND API */
3500e552da7Schristos   qdcrlind_argv[0] = &rcvr;
3510e552da7Schristos   qdcrlind_argv[1] = &rcvrlen;
3520e552da7Schristos   qdcrlind_argv[2] = &format;
3530e552da7Schristos   qdcrlind_argv[3] = &line_name;
3540e552da7Schristos   qdcrlind_argv[4] = &err;
3550e552da7Schristos   qdcrlind_argv[5] = NULL;
3560e552da7Schristos 
3570e552da7Schristos   /* Call the IBM i QDCRLIND API from PASE */
3580e552da7Schristos   rc = _PGMCALL(&qdcrlind_pointer, qdcrlind_argv, 0);
3590e552da7Schristos   if (rc != 0)
3600e552da7Schristos     return rc;
3610e552da7Schristos 
362*5f2f4271Schristos   if (err.bytes_available > 0) {
363*5f2f4271Schristos     return -1;
364*5f2f4271Schristos   }
365*5f2f4271Schristos 
3660e552da7Schristos   /* convert ebcdic loca_adapter_address to ascii first */
3670e552da7Schristos   iconv_e2a(rcvr.loca_adapter_address, mac_addr,
3680e552da7Schristos             sizeof(rcvr.loca_adapter_address));
3690e552da7Schristos 
3700e552da7Schristos   /* convert loca_adapter_address(char[12]) to phys_addr(char[6]) */
3710e552da7Schristos   int r = sscanf(mac_addr, "%02x%02x%02x%02x%02x%02x",
3720e552da7Schristos                 &c[0], &c[1], &c[2], &c[3], &c[4], &c[5]);
3730e552da7Schristos 
3740e552da7Schristos   if (r == ARRAY_SIZE(c)) {
3750e552da7Schristos     (*phys_addr)[0] = c[0];
3760e552da7Schristos     (*phys_addr)[1] = c[1];
3770e552da7Schristos     (*phys_addr)[2] = c[2];
3780e552da7Schristos     (*phys_addr)[3] = c[3];
3790e552da7Schristos     (*phys_addr)[4] = c[4];
3800e552da7Schristos     (*phys_addr)[5] = c[5];
3810e552da7Schristos   } else {
3820e552da7Schristos     memset(*phys_addr, 0, sizeof(*phys_addr));
3830e552da7Schristos     rc = -1;
3840e552da7Schristos   }
3850e552da7Schristos   return rc;
3860e552da7Schristos }
3870e552da7Schristos 
3880e552da7Schristos 
uv_interface_addresses(uv_interface_address_t ** addresses,int * count)3890e552da7Schristos int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
3900e552da7Schristos   uv_interface_address_t* address;
3910e552da7Schristos   struct ifaddrs_pase *ifap = NULL, *cur;
3920e552da7Schristos   int inet6, r = 0;
3930e552da7Schristos 
3940e552da7Schristos   *count = 0;
3950e552da7Schristos   *addresses = NULL;
3960e552da7Schristos 
3970e552da7Schristos   if (Qp2getifaddrs(&ifap))
3980e552da7Schristos     return UV_ENOSYS;
3990e552da7Schristos 
4000e552da7Schristos   /* The first loop to get the size of the array to be allocated */
4010e552da7Schristos   for (cur = ifap; cur; cur = cur->ifa_next) {
4020e552da7Schristos     if (!(cur->ifa_addr->sa_family == AF_INET6 ||
4030e552da7Schristos           cur->ifa_addr->sa_family == AF_INET))
4040e552da7Schristos       continue;
4050e552da7Schristos 
4060e552da7Schristos     if (!(cur->ifa_flags & IFF_UP && cur->ifa_flags & IFF_RUNNING))
4070e552da7Schristos       continue;
4080e552da7Schristos 
4090e552da7Schristos     (*count)++;
4100e552da7Schristos   }
4110e552da7Schristos 
4120e552da7Schristos   if (*count == 0) {
4130e552da7Schristos     Qp2freeifaddrs(ifap);
4140e552da7Schristos     return 0;
4150e552da7Schristos   }
4160e552da7Schristos 
4170e552da7Schristos   /* Alloc the return interface structs */
4180e552da7Schristos   *addresses = uv__calloc(*count, sizeof(**addresses));
4190e552da7Schristos   if (*addresses == NULL) {
4200e552da7Schristos     Qp2freeifaddrs(ifap);
4210e552da7Schristos     return UV_ENOMEM;
4220e552da7Schristos   }
4230e552da7Schristos   address = *addresses;
4240e552da7Schristos 
4250e552da7Schristos   /* The second loop to fill in the array */
4260e552da7Schristos   for (cur = ifap; cur; cur = cur->ifa_next) {
4270e552da7Schristos     if (!(cur->ifa_addr->sa_family == AF_INET6 ||
4280e552da7Schristos           cur->ifa_addr->sa_family == AF_INET))
4290e552da7Schristos       continue;
4300e552da7Schristos 
4310e552da7Schristos     if (!(cur->ifa_flags & IFF_UP && cur->ifa_flags & IFF_RUNNING))
4320e552da7Schristos       continue;
4330e552da7Schristos 
4340e552da7Schristos     address->name = uv__strdup(cur->ifa_name);
4350e552da7Schristos 
4360e552da7Schristos     inet6 = (cur->ifa_addr->sa_family == AF_INET6);
4370e552da7Schristos 
4380e552da7Schristos     if (inet6) {
4390e552da7Schristos       address->address.address6 = *((struct sockaddr_in6*)cur->ifa_addr);
4400e552da7Schristos       address->netmask.netmask6 = *((struct sockaddr_in6*)cur->ifa_netmask);
4410e552da7Schristos       address->netmask.netmask6.sin6_family = AF_INET6;
4420e552da7Schristos     } else {
4430e552da7Schristos       address->address.address4 = *((struct sockaddr_in*)cur->ifa_addr);
4440e552da7Schristos       address->netmask.netmask4 = *((struct sockaddr_in*)cur->ifa_netmask);
4450e552da7Schristos       address->netmask.netmask4.sin_family = AF_INET;
4460e552da7Schristos     }
4470e552da7Schristos     address->is_internal = cur->ifa_flags & IFF_LOOPBACK ? 1 : 0;
4480e552da7Schristos     if (!address->is_internal) {
449*5f2f4271Schristos       int rc = -1;
450*5f2f4271Schristos       size_t name_len = strlen(address->name);
451*5f2f4271Schristos       /* To get the associated MAC address, we must convert the address to a
452*5f2f4271Schristos        * line description. Normally, the name field contains the line
453*5f2f4271Schristos        * description name, but for VLANs it has the VLAN appended with a
454*5f2f4271Schristos        * period. Since object names can also contain periods and numbers, there
455*5f2f4271Schristos        * is no way to know if a returned name is for a VLAN or not. eg.
456*5f2f4271Schristos        * *LIND ETH1.1 and *LIND ETH1, VLAN 1 both have the same name: ETH1.1
457*5f2f4271Schristos        *
458*5f2f4271Schristos        * Instead, we apply the same heuristic used by some of the XPF ioctls:
459*5f2f4271Schristos        * - names > 10 *must* contain a VLAN
460*5f2f4271Schristos        * - assume names <= 10 do not contain a VLAN and try directly
461*5f2f4271Schristos        * - if >10 or QDCRLIND returned an error, try to strip off a VLAN
462*5f2f4271Schristos        *   and try again
463*5f2f4271Schristos        * - if we still get an error or couldn't find a period, leave the MAC as
464*5f2f4271Schristos        *   00:00:00:00:00:00
465*5f2f4271Schristos        */
466*5f2f4271Schristos       if (name_len <= 10) {
467*5f2f4271Schristos         /* Assume name does not contain a VLAN ID */
468*5f2f4271Schristos         rc = get_ibmi_physical_address(address->name, &address->phys_addr);
469*5f2f4271Schristos       }
470*5f2f4271Schristos 
471*5f2f4271Schristos       if (name_len > 10 || rc != 0) {
472*5f2f4271Schristos         /* The interface name must contain a VLAN ID suffix. Attempt to strip
473*5f2f4271Schristos          * it off so we can get the line description to pass to QDCRLIND.
474*5f2f4271Schristos          */
475*5f2f4271Schristos         char* temp_name = uv__strdup(address->name);
476*5f2f4271Schristos         char* dot = strrchr(temp_name, '.');
477*5f2f4271Schristos         if (dot != NULL) {
478*5f2f4271Schristos           *dot = '\0';
479*5f2f4271Schristos           if (strlen(temp_name) <= 10) {
480*5f2f4271Schristos             rc = get_ibmi_physical_address(temp_name, &address->phys_addr);
481*5f2f4271Schristos           }
482*5f2f4271Schristos         }
483*5f2f4271Schristos         uv__free(temp_name);
484*5f2f4271Schristos       }
4850e552da7Schristos     }
4860e552da7Schristos 
4870e552da7Schristos     address++;
4880e552da7Schristos   }
4890e552da7Schristos 
4900e552da7Schristos   Qp2freeifaddrs(ifap);
4910e552da7Schristos   return r;
4920e552da7Schristos }
4930e552da7Schristos 
4940e552da7Schristos 
uv_free_interface_addresses(uv_interface_address_t * addresses,int count)4950e552da7Schristos void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) {
4960e552da7Schristos   int i;
4970e552da7Schristos 
4980e552da7Schristos   for (i = 0; i < count; ++i) {
4990e552da7Schristos     uv__free(addresses[i].name);
5000e552da7Schristos   }
5010e552da7Schristos 
5020e552da7Schristos   uv__free(addresses);
5030e552da7Schristos }
504*5f2f4271Schristos 
uv_setup_args(int argc,char ** argv)505*5f2f4271Schristos char** uv_setup_args(int argc, char** argv) {
506*5f2f4271Schristos   char exepath[UV__PATH_MAX];
507*5f2f4271Schristos   char* s;
508*5f2f4271Schristos   size_t size;
509*5f2f4271Schristos 
510*5f2f4271Schristos   if (argc > 0) {
511*5f2f4271Schristos     /* Use argv[0] to determine value for uv_exepath(). */
512*5f2f4271Schristos     size = sizeof(exepath);
513*5f2f4271Schristos     if (uv__search_path(argv[0], exepath, &size) == 0) {
514*5f2f4271Schristos       uv_once(&process_title_mutex_once, init_process_title_mutex_once);
515*5f2f4271Schristos       uv_mutex_lock(&process_title_mutex);
516*5f2f4271Schristos       original_exepath = uv__strdup(exepath);
517*5f2f4271Schristos       uv_mutex_unlock(&process_title_mutex);
518*5f2f4271Schristos     }
519*5f2f4271Schristos   }
520*5f2f4271Schristos 
521*5f2f4271Schristos   return argv;
522*5f2f4271Schristos }
523*5f2f4271Schristos 
uv_set_process_title(const char * title)524*5f2f4271Schristos int uv_set_process_title(const char* title) {
525*5f2f4271Schristos   return 0;
526*5f2f4271Schristos }
527*5f2f4271Schristos 
uv_get_process_title(char * buffer,size_t size)528*5f2f4271Schristos int uv_get_process_title(char* buffer, size_t size) {
529*5f2f4271Schristos   if (buffer == NULL || size == 0)
530*5f2f4271Schristos     return UV_EINVAL;
531*5f2f4271Schristos 
532*5f2f4271Schristos   buffer[0] = '\0';
533*5f2f4271Schristos   return 0;
534*5f2f4271Schristos }
535*5f2f4271Schristos 
uv__process_title_cleanup(void)536*5f2f4271Schristos void uv__process_title_cleanup(void) {
537*5f2f4271Schristos }
538