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