16d49e1aeSJan Lentfer /* 26d49e1aeSJan Lentfer * wpa_supplicant/hostapd / Internal implementation of OS specific functions 36d49e1aeSJan Lentfer * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi> 46d49e1aeSJan Lentfer * 53ff40c12SJohn Marino * This software may be distributed under the terms of the BSD license. 63ff40c12SJohn Marino * See README for more details. 76d49e1aeSJan Lentfer * 86d49e1aeSJan Lentfer * This file is an example of operating system specific wrapper functions. 96d49e1aeSJan Lentfer * This version implements many of the functions internally, so it can be used 106d49e1aeSJan Lentfer * to fill in missing functions from the target system C libraries. 116d49e1aeSJan Lentfer * 126d49e1aeSJan Lentfer * Some of the functions are using standard C library calls in order to keep 136d49e1aeSJan Lentfer * this file in working condition to allow the functions to be tested on a 146d49e1aeSJan Lentfer * Linux target. Please note that OS_NO_C_LIB_DEFINES needs to be defined for 156d49e1aeSJan Lentfer * this file to work correctly. Note that these implementations are only 166d49e1aeSJan Lentfer * examples and are not optimized for speed. 176d49e1aeSJan Lentfer */ 186d49e1aeSJan Lentfer 196d49e1aeSJan Lentfer #include "includes.h" 20*a1157835SDaniel Fojt #include <time.h> 21*a1157835SDaniel Fojt #include <sys/wait.h> 226d49e1aeSJan Lentfer 236d49e1aeSJan Lentfer #undef OS_REJECT_C_LIB_FUNCTIONS 24*a1157835SDaniel Fojt #include "common.h" 256d49e1aeSJan Lentfer 266d49e1aeSJan Lentfer void os_sleep(os_time_t sec, os_time_t usec) 276d49e1aeSJan Lentfer { 286d49e1aeSJan Lentfer if (sec) 296d49e1aeSJan Lentfer sleep(sec); 306d49e1aeSJan Lentfer if (usec) 316d49e1aeSJan Lentfer usleep(usec); 326d49e1aeSJan Lentfer } 336d49e1aeSJan Lentfer 346d49e1aeSJan Lentfer 356d49e1aeSJan Lentfer int os_get_time(struct os_time *t) 366d49e1aeSJan Lentfer { 376d49e1aeSJan Lentfer int res; 386d49e1aeSJan Lentfer struct timeval tv; 396d49e1aeSJan Lentfer res = gettimeofday(&tv, NULL); 406d49e1aeSJan Lentfer t->sec = tv.tv_sec; 416d49e1aeSJan Lentfer t->usec = tv.tv_usec; 426d49e1aeSJan Lentfer return res; 436d49e1aeSJan Lentfer } 446d49e1aeSJan Lentfer 456d49e1aeSJan Lentfer 463ff40c12SJohn Marino int os_get_reltime(struct os_reltime *t) 473ff40c12SJohn Marino { 483ff40c12SJohn Marino int res; 493ff40c12SJohn Marino struct timeval tv; 503ff40c12SJohn Marino res = gettimeofday(&tv, NULL); 513ff40c12SJohn Marino t->sec = tv.tv_sec; 523ff40c12SJohn Marino t->usec = tv.tv_usec; 533ff40c12SJohn Marino return res; 543ff40c12SJohn Marino } 553ff40c12SJohn Marino 563ff40c12SJohn Marino 576d49e1aeSJan Lentfer int os_mktime(int year, int month, int day, int hour, int min, int sec, 586d49e1aeSJan Lentfer os_time_t *t) 596d49e1aeSJan Lentfer { 606d49e1aeSJan Lentfer struct tm tm; 616d49e1aeSJan Lentfer 626d49e1aeSJan Lentfer if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 || 636d49e1aeSJan Lentfer hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 || 646d49e1aeSJan Lentfer sec > 60) 656d49e1aeSJan Lentfer return -1; 666d49e1aeSJan Lentfer 676d49e1aeSJan Lentfer os_memset(&tm, 0, sizeof(tm)); 686d49e1aeSJan Lentfer tm.tm_year = year - 1900; 696d49e1aeSJan Lentfer tm.tm_mon = month - 1; 706d49e1aeSJan Lentfer tm.tm_mday = day; 716d49e1aeSJan Lentfer tm.tm_hour = hour; 726d49e1aeSJan Lentfer tm.tm_min = min; 736d49e1aeSJan Lentfer tm.tm_sec = sec; 746d49e1aeSJan Lentfer 756d49e1aeSJan Lentfer *t = (os_time_t) mktime(&tm); 766d49e1aeSJan Lentfer return 0; 776d49e1aeSJan Lentfer } 786d49e1aeSJan Lentfer 796d49e1aeSJan Lentfer 803ff40c12SJohn Marino int os_gmtime(os_time_t t, struct os_tm *tm) 813ff40c12SJohn Marino { 823ff40c12SJohn Marino struct tm *tm2; 833ff40c12SJohn Marino time_t t2 = t; 843ff40c12SJohn Marino 853ff40c12SJohn Marino tm2 = gmtime(&t2); 863ff40c12SJohn Marino if (tm2 == NULL) 873ff40c12SJohn Marino return -1; 883ff40c12SJohn Marino tm->sec = tm2->tm_sec; 893ff40c12SJohn Marino tm->min = tm2->tm_min; 903ff40c12SJohn Marino tm->hour = tm2->tm_hour; 913ff40c12SJohn Marino tm->day = tm2->tm_mday; 923ff40c12SJohn Marino tm->month = tm2->tm_mon + 1; 933ff40c12SJohn Marino tm->year = tm2->tm_year + 1900; 943ff40c12SJohn Marino return 0; 953ff40c12SJohn Marino } 963ff40c12SJohn Marino 973ff40c12SJohn Marino 986d49e1aeSJan Lentfer int os_daemonize(const char *pid_file) 996d49e1aeSJan Lentfer { 1006d49e1aeSJan Lentfer if (daemon(0, 0)) { 101*a1157835SDaniel Fojt wpa_printf(MSG_ERROR, "daemon: %s", strerror(errno)); 1026d49e1aeSJan Lentfer return -1; 1036d49e1aeSJan Lentfer } 1046d49e1aeSJan Lentfer 1056d49e1aeSJan Lentfer if (pid_file) { 1066d49e1aeSJan Lentfer FILE *f = fopen(pid_file, "w"); 1076d49e1aeSJan Lentfer if (f) { 1086d49e1aeSJan Lentfer fprintf(f, "%u\n", getpid()); 1096d49e1aeSJan Lentfer fclose(f); 1106d49e1aeSJan Lentfer } 1116d49e1aeSJan Lentfer } 1126d49e1aeSJan Lentfer 1136d49e1aeSJan Lentfer return -0; 1146d49e1aeSJan Lentfer } 1156d49e1aeSJan Lentfer 1166d49e1aeSJan Lentfer 1176d49e1aeSJan Lentfer void os_daemonize_terminate(const char *pid_file) 1186d49e1aeSJan Lentfer { 1196d49e1aeSJan Lentfer if (pid_file) 1206d49e1aeSJan Lentfer unlink(pid_file); 1216d49e1aeSJan Lentfer } 1226d49e1aeSJan Lentfer 1236d49e1aeSJan Lentfer 1246d49e1aeSJan Lentfer int os_get_random(unsigned char *buf, size_t len) 1256d49e1aeSJan Lentfer { 1266d49e1aeSJan Lentfer FILE *f; 1276d49e1aeSJan Lentfer size_t rc; 1286d49e1aeSJan Lentfer 1296d49e1aeSJan Lentfer f = fopen("/dev/urandom", "rb"); 1306d49e1aeSJan Lentfer if (f == NULL) { 1316d49e1aeSJan Lentfer printf("Could not open /dev/urandom.\n"); 1326d49e1aeSJan Lentfer return -1; 1336d49e1aeSJan Lentfer } 1346d49e1aeSJan Lentfer 1356d49e1aeSJan Lentfer rc = fread(buf, 1, len, f); 1366d49e1aeSJan Lentfer fclose(f); 1376d49e1aeSJan Lentfer 1386d49e1aeSJan Lentfer return rc != len ? -1 : 0; 1396d49e1aeSJan Lentfer } 1406d49e1aeSJan Lentfer 1416d49e1aeSJan Lentfer 1426d49e1aeSJan Lentfer unsigned long os_random(void) 1436d49e1aeSJan Lentfer { 1446d49e1aeSJan Lentfer return random(); 1456d49e1aeSJan Lentfer } 1466d49e1aeSJan Lentfer 1476d49e1aeSJan Lentfer 1486d49e1aeSJan Lentfer char * os_rel2abs_path(const char *rel_path) 1496d49e1aeSJan Lentfer { 1506d49e1aeSJan Lentfer char *buf = NULL, *cwd, *ret; 1516d49e1aeSJan Lentfer size_t len = 128, cwd_len, rel_len, ret_len; 1526d49e1aeSJan Lentfer 1536d49e1aeSJan Lentfer if (rel_path[0] == '/') 1546d49e1aeSJan Lentfer return os_strdup(rel_path); 1556d49e1aeSJan Lentfer 1566d49e1aeSJan Lentfer for (;;) { 1576d49e1aeSJan Lentfer buf = os_malloc(len); 1586d49e1aeSJan Lentfer if (buf == NULL) 1596d49e1aeSJan Lentfer return NULL; 1606d49e1aeSJan Lentfer cwd = getcwd(buf, len); 1616d49e1aeSJan Lentfer if (cwd == NULL) { 1626d49e1aeSJan Lentfer os_free(buf); 1636d49e1aeSJan Lentfer if (errno != ERANGE) { 1646d49e1aeSJan Lentfer return NULL; 1656d49e1aeSJan Lentfer } 1666d49e1aeSJan Lentfer len *= 2; 1676d49e1aeSJan Lentfer } else { 1686d49e1aeSJan Lentfer break; 1696d49e1aeSJan Lentfer } 1706d49e1aeSJan Lentfer } 1716d49e1aeSJan Lentfer 172*a1157835SDaniel Fojt cwd_len = os_strlen(cwd); 173*a1157835SDaniel Fojt rel_len = os_strlen(rel_path); 1746d49e1aeSJan Lentfer ret_len = cwd_len + 1 + rel_len + 1; 1756d49e1aeSJan Lentfer ret = os_malloc(ret_len); 1766d49e1aeSJan Lentfer if (ret) { 1776d49e1aeSJan Lentfer os_memcpy(ret, cwd, cwd_len); 1786d49e1aeSJan Lentfer ret[cwd_len] = '/'; 1796d49e1aeSJan Lentfer os_memcpy(ret + cwd_len + 1, rel_path, rel_len); 1806d49e1aeSJan Lentfer ret[ret_len - 1] = '\0'; 1816d49e1aeSJan Lentfer } 1826d49e1aeSJan Lentfer os_free(buf); 1836d49e1aeSJan Lentfer return ret; 1846d49e1aeSJan Lentfer } 1856d49e1aeSJan Lentfer 1866d49e1aeSJan Lentfer 1876d49e1aeSJan Lentfer int os_program_init(void) 1886d49e1aeSJan Lentfer { 1896d49e1aeSJan Lentfer return 0; 1906d49e1aeSJan Lentfer } 1916d49e1aeSJan Lentfer 1926d49e1aeSJan Lentfer 1936d49e1aeSJan Lentfer void os_program_deinit(void) 1946d49e1aeSJan Lentfer { 1956d49e1aeSJan Lentfer } 1966d49e1aeSJan Lentfer 1976d49e1aeSJan Lentfer 1986d49e1aeSJan Lentfer int os_setenv(const char *name, const char *value, int overwrite) 1996d49e1aeSJan Lentfer { 2006d49e1aeSJan Lentfer return setenv(name, value, overwrite); 2016d49e1aeSJan Lentfer } 2026d49e1aeSJan Lentfer 2036d49e1aeSJan Lentfer 2046d49e1aeSJan Lentfer int os_unsetenv(const char *name) 2056d49e1aeSJan Lentfer { 2066d49e1aeSJan Lentfer #if defined(__FreeBSD__) || defined(__NetBSD__) 2076d49e1aeSJan Lentfer unsetenv(name); 2086d49e1aeSJan Lentfer return 0; 2096d49e1aeSJan Lentfer #else 2106d49e1aeSJan Lentfer return unsetenv(name); 2116d49e1aeSJan Lentfer #endif 2126d49e1aeSJan Lentfer } 2136d49e1aeSJan Lentfer 2146d49e1aeSJan Lentfer 2156d49e1aeSJan Lentfer char * os_readfile(const char *name, size_t *len) 2166d49e1aeSJan Lentfer { 2176d49e1aeSJan Lentfer FILE *f; 2186d49e1aeSJan Lentfer char *buf; 2196d49e1aeSJan Lentfer 2206d49e1aeSJan Lentfer f = fopen(name, "rb"); 2216d49e1aeSJan Lentfer if (f == NULL) 2226d49e1aeSJan Lentfer return NULL; 2236d49e1aeSJan Lentfer 2246d49e1aeSJan Lentfer fseek(f, 0, SEEK_END); 2256d49e1aeSJan Lentfer *len = ftell(f); 2266d49e1aeSJan Lentfer fseek(f, 0, SEEK_SET); 2276d49e1aeSJan Lentfer 2286d49e1aeSJan Lentfer buf = os_malloc(*len); 2296d49e1aeSJan Lentfer if (buf == NULL) { 2306d49e1aeSJan Lentfer fclose(f); 2316d49e1aeSJan Lentfer return NULL; 2326d49e1aeSJan Lentfer } 2336d49e1aeSJan Lentfer 2343ff40c12SJohn Marino if (fread(buf, 1, *len, f) != *len) { 2353ff40c12SJohn Marino fclose(f); 2363ff40c12SJohn Marino os_free(buf); 2373ff40c12SJohn Marino return NULL; 2383ff40c12SJohn Marino } 2393ff40c12SJohn Marino 2406d49e1aeSJan Lentfer fclose(f); 2416d49e1aeSJan Lentfer 2426d49e1aeSJan Lentfer return buf; 2436d49e1aeSJan Lentfer } 2446d49e1aeSJan Lentfer 2456d49e1aeSJan Lentfer 246*a1157835SDaniel Fojt int os_fdatasync(FILE *stream) 247*a1157835SDaniel Fojt { 248*a1157835SDaniel Fojt return 0; 249*a1157835SDaniel Fojt } 250*a1157835SDaniel Fojt 251*a1157835SDaniel Fojt 2526d49e1aeSJan Lentfer void * os_zalloc(size_t size) 2536d49e1aeSJan Lentfer { 2546d49e1aeSJan Lentfer void *n = os_malloc(size); 2556d49e1aeSJan Lentfer if (n) 2566d49e1aeSJan Lentfer os_memset(n, 0, size); 2576d49e1aeSJan Lentfer return n; 2586d49e1aeSJan Lentfer } 2596d49e1aeSJan Lentfer 2606d49e1aeSJan Lentfer 2616d49e1aeSJan Lentfer void * os_malloc(size_t size) 2626d49e1aeSJan Lentfer { 2636d49e1aeSJan Lentfer return malloc(size); 2646d49e1aeSJan Lentfer } 2656d49e1aeSJan Lentfer 2666d49e1aeSJan Lentfer 2676d49e1aeSJan Lentfer void * os_realloc(void *ptr, size_t size) 2686d49e1aeSJan Lentfer { 2696d49e1aeSJan Lentfer return realloc(ptr, size); 2706d49e1aeSJan Lentfer } 2716d49e1aeSJan Lentfer 2726d49e1aeSJan Lentfer 2736d49e1aeSJan Lentfer void os_free(void *ptr) 2746d49e1aeSJan Lentfer { 2756d49e1aeSJan Lentfer free(ptr); 2766d49e1aeSJan Lentfer } 2776d49e1aeSJan Lentfer 2786d49e1aeSJan Lentfer 2796d49e1aeSJan Lentfer void * os_memcpy(void *dest, const void *src, size_t n) 2806d49e1aeSJan Lentfer { 2816d49e1aeSJan Lentfer char *d = dest; 2826d49e1aeSJan Lentfer const char *s = src; 2836d49e1aeSJan Lentfer while (n--) 2846d49e1aeSJan Lentfer *d++ = *s++; 2856d49e1aeSJan Lentfer return dest; 2866d49e1aeSJan Lentfer } 2876d49e1aeSJan Lentfer 2886d49e1aeSJan Lentfer 2896d49e1aeSJan Lentfer void * os_memmove(void *dest, const void *src, size_t n) 2906d49e1aeSJan Lentfer { 2916d49e1aeSJan Lentfer if (dest < src) 2926d49e1aeSJan Lentfer os_memcpy(dest, src, n); 2936d49e1aeSJan Lentfer else { 2946d49e1aeSJan Lentfer /* overlapping areas */ 2956d49e1aeSJan Lentfer char *d = (char *) dest + n; 2966d49e1aeSJan Lentfer const char *s = (const char *) src + n; 2976d49e1aeSJan Lentfer while (n--) 2986d49e1aeSJan Lentfer *--d = *--s; 2996d49e1aeSJan Lentfer } 3006d49e1aeSJan Lentfer return dest; 3016d49e1aeSJan Lentfer } 3026d49e1aeSJan Lentfer 3036d49e1aeSJan Lentfer 3046d49e1aeSJan Lentfer void * os_memset(void *s, int c, size_t n) 3056d49e1aeSJan Lentfer { 3066d49e1aeSJan Lentfer char *p = s; 3076d49e1aeSJan Lentfer while (n--) 3086d49e1aeSJan Lentfer *p++ = c; 3096d49e1aeSJan Lentfer return s; 3106d49e1aeSJan Lentfer } 3116d49e1aeSJan Lentfer 3126d49e1aeSJan Lentfer 3136d49e1aeSJan Lentfer int os_memcmp(const void *s1, const void *s2, size_t n) 3146d49e1aeSJan Lentfer { 3156d49e1aeSJan Lentfer const unsigned char *p1 = s1, *p2 = s2; 3166d49e1aeSJan Lentfer 3176d49e1aeSJan Lentfer if (n == 0) 3186d49e1aeSJan Lentfer return 0; 3196d49e1aeSJan Lentfer 3206d49e1aeSJan Lentfer while (*p1 == *p2) { 3216d49e1aeSJan Lentfer p1++; 3226d49e1aeSJan Lentfer p2++; 3236d49e1aeSJan Lentfer n--; 3246d49e1aeSJan Lentfer if (n == 0) 3256d49e1aeSJan Lentfer return 0; 3266d49e1aeSJan Lentfer } 3276d49e1aeSJan Lentfer 3286d49e1aeSJan Lentfer return *p1 - *p2; 3296d49e1aeSJan Lentfer } 3306d49e1aeSJan Lentfer 3316d49e1aeSJan Lentfer 3326d49e1aeSJan Lentfer char * os_strdup(const char *s) 3336d49e1aeSJan Lentfer { 3346d49e1aeSJan Lentfer char *res; 3356d49e1aeSJan Lentfer size_t len; 3366d49e1aeSJan Lentfer if (s == NULL) 3376d49e1aeSJan Lentfer return NULL; 3386d49e1aeSJan Lentfer len = os_strlen(s); 3396d49e1aeSJan Lentfer res = os_malloc(len + 1); 3406d49e1aeSJan Lentfer if (res) 3416d49e1aeSJan Lentfer os_memcpy(res, s, len + 1); 3426d49e1aeSJan Lentfer return res; 3436d49e1aeSJan Lentfer } 3446d49e1aeSJan Lentfer 3456d49e1aeSJan Lentfer 3466d49e1aeSJan Lentfer size_t os_strlen(const char *s) 3476d49e1aeSJan Lentfer { 3486d49e1aeSJan Lentfer const char *p = s; 3496d49e1aeSJan Lentfer while (*p) 3506d49e1aeSJan Lentfer p++; 3516d49e1aeSJan Lentfer return p - s; 3526d49e1aeSJan Lentfer } 3536d49e1aeSJan Lentfer 3546d49e1aeSJan Lentfer 3556d49e1aeSJan Lentfer int os_strcasecmp(const char *s1, const char *s2) 3566d49e1aeSJan Lentfer { 3576d49e1aeSJan Lentfer /* 3586d49e1aeSJan Lentfer * Ignoring case is not required for main functionality, so just use 3596d49e1aeSJan Lentfer * the case sensitive version of the function. 3606d49e1aeSJan Lentfer */ 3616d49e1aeSJan Lentfer return os_strcmp(s1, s2); 3626d49e1aeSJan Lentfer } 3636d49e1aeSJan Lentfer 3646d49e1aeSJan Lentfer 3656d49e1aeSJan Lentfer int os_strncasecmp(const char *s1, const char *s2, size_t n) 3666d49e1aeSJan Lentfer { 3676d49e1aeSJan Lentfer /* 3686d49e1aeSJan Lentfer * Ignoring case is not required for main functionality, so just use 3696d49e1aeSJan Lentfer * the case sensitive version of the function. 3706d49e1aeSJan Lentfer */ 3716d49e1aeSJan Lentfer return os_strncmp(s1, s2, n); 3726d49e1aeSJan Lentfer } 3736d49e1aeSJan Lentfer 3746d49e1aeSJan Lentfer 3756d49e1aeSJan Lentfer char * os_strchr(const char *s, int c) 3766d49e1aeSJan Lentfer { 3776d49e1aeSJan Lentfer while (*s) { 3786d49e1aeSJan Lentfer if (*s == c) 3796d49e1aeSJan Lentfer return (char *) s; 3806d49e1aeSJan Lentfer s++; 3816d49e1aeSJan Lentfer } 3826d49e1aeSJan Lentfer return NULL; 3836d49e1aeSJan Lentfer } 3846d49e1aeSJan Lentfer 3856d49e1aeSJan Lentfer 3866d49e1aeSJan Lentfer char * os_strrchr(const char *s, int c) 3876d49e1aeSJan Lentfer { 3886d49e1aeSJan Lentfer const char *p = s; 3896d49e1aeSJan Lentfer while (*p) 3906d49e1aeSJan Lentfer p++; 3916d49e1aeSJan Lentfer p--; 3926d49e1aeSJan Lentfer while (p >= s) { 3936d49e1aeSJan Lentfer if (*p == c) 3946d49e1aeSJan Lentfer return (char *) p; 3956d49e1aeSJan Lentfer p--; 3966d49e1aeSJan Lentfer } 3976d49e1aeSJan Lentfer return NULL; 3986d49e1aeSJan Lentfer } 3996d49e1aeSJan Lentfer 4006d49e1aeSJan Lentfer 4016d49e1aeSJan Lentfer int os_strcmp(const char *s1, const char *s2) 4026d49e1aeSJan Lentfer { 4036d49e1aeSJan Lentfer while (*s1 == *s2) { 4046d49e1aeSJan Lentfer if (*s1 == '\0') 4056d49e1aeSJan Lentfer break; 4066d49e1aeSJan Lentfer s1++; 4076d49e1aeSJan Lentfer s2++; 4086d49e1aeSJan Lentfer } 4096d49e1aeSJan Lentfer 4106d49e1aeSJan Lentfer return *s1 - *s2; 4116d49e1aeSJan Lentfer } 4126d49e1aeSJan Lentfer 4136d49e1aeSJan Lentfer 4146d49e1aeSJan Lentfer int os_strncmp(const char *s1, const char *s2, size_t n) 4156d49e1aeSJan Lentfer { 4166d49e1aeSJan Lentfer if (n == 0) 4176d49e1aeSJan Lentfer return 0; 4186d49e1aeSJan Lentfer 4196d49e1aeSJan Lentfer while (*s1 == *s2) { 4206d49e1aeSJan Lentfer if (*s1 == '\0') 4216d49e1aeSJan Lentfer break; 4226d49e1aeSJan Lentfer s1++; 4236d49e1aeSJan Lentfer s2++; 4246d49e1aeSJan Lentfer n--; 4256d49e1aeSJan Lentfer if (n == 0) 4266d49e1aeSJan Lentfer return 0; 4276d49e1aeSJan Lentfer } 4286d49e1aeSJan Lentfer 4296d49e1aeSJan Lentfer return *s1 - *s2; 4306d49e1aeSJan Lentfer } 4316d49e1aeSJan Lentfer 4326d49e1aeSJan Lentfer 4336d49e1aeSJan Lentfer size_t os_strlcpy(char *dest, const char *src, size_t siz) 4346d49e1aeSJan Lentfer { 4356d49e1aeSJan Lentfer const char *s = src; 4366d49e1aeSJan Lentfer size_t left = siz; 4376d49e1aeSJan Lentfer 4386d49e1aeSJan Lentfer if (left) { 4396d49e1aeSJan Lentfer /* Copy string up to the maximum size of the dest buffer */ 4406d49e1aeSJan Lentfer while (--left != 0) { 4416d49e1aeSJan Lentfer if ((*dest++ = *s++) == '\0') 4426d49e1aeSJan Lentfer break; 4436d49e1aeSJan Lentfer } 4446d49e1aeSJan Lentfer } 4456d49e1aeSJan Lentfer 4466d49e1aeSJan Lentfer if (left == 0) { 4476d49e1aeSJan Lentfer /* Not enough room for the string; force NUL-termination */ 4486d49e1aeSJan Lentfer if (siz != 0) 4496d49e1aeSJan Lentfer *dest = '\0'; 4506d49e1aeSJan Lentfer while (*s++) 4516d49e1aeSJan Lentfer ; /* determine total src string length */ 4526d49e1aeSJan Lentfer } 4536d49e1aeSJan Lentfer 4546d49e1aeSJan Lentfer return s - src - 1; 4556d49e1aeSJan Lentfer } 4566d49e1aeSJan Lentfer 4576d49e1aeSJan Lentfer 458*a1157835SDaniel Fojt int os_memcmp_const(const void *a, const void *b, size_t len) 459*a1157835SDaniel Fojt { 460*a1157835SDaniel Fojt const u8 *aa = a; 461*a1157835SDaniel Fojt const u8 *bb = b; 462*a1157835SDaniel Fojt size_t i; 463*a1157835SDaniel Fojt u8 res; 464*a1157835SDaniel Fojt 465*a1157835SDaniel Fojt for (res = 0, i = 0; i < len; i++) 466*a1157835SDaniel Fojt res |= aa[i] ^ bb[i]; 467*a1157835SDaniel Fojt 468*a1157835SDaniel Fojt return res; 469*a1157835SDaniel Fojt } 470*a1157835SDaniel Fojt 471*a1157835SDaniel Fojt 4726d49e1aeSJan Lentfer char * os_strstr(const char *haystack, const char *needle) 4736d49e1aeSJan Lentfer { 4746d49e1aeSJan Lentfer size_t len = os_strlen(needle); 4756d49e1aeSJan Lentfer while (*haystack) { 4766d49e1aeSJan Lentfer if (os_strncmp(haystack, needle, len) == 0) 4776d49e1aeSJan Lentfer return (char *) haystack; 4786d49e1aeSJan Lentfer haystack++; 4796d49e1aeSJan Lentfer } 4806d49e1aeSJan Lentfer 4816d49e1aeSJan Lentfer return NULL; 4826d49e1aeSJan Lentfer } 4836d49e1aeSJan Lentfer 4846d49e1aeSJan Lentfer 4856d49e1aeSJan Lentfer int os_snprintf(char *str, size_t size, const char *format, ...) 4866d49e1aeSJan Lentfer { 4876d49e1aeSJan Lentfer va_list ap; 4886d49e1aeSJan Lentfer int ret; 4896d49e1aeSJan Lentfer 4906d49e1aeSJan Lentfer /* See http://www.ijs.si/software/snprintf/ for portable 4916d49e1aeSJan Lentfer * implementation of snprintf. 4926d49e1aeSJan Lentfer */ 4936d49e1aeSJan Lentfer 4946d49e1aeSJan Lentfer va_start(ap, format); 4956d49e1aeSJan Lentfer ret = vsnprintf(str, size, format, ap); 4966d49e1aeSJan Lentfer va_end(ap); 4976d49e1aeSJan Lentfer if (size > 0) 4986d49e1aeSJan Lentfer str[size - 1] = '\0'; 4996d49e1aeSJan Lentfer return ret; 5006d49e1aeSJan Lentfer } 501*a1157835SDaniel Fojt 502*a1157835SDaniel Fojt 503*a1157835SDaniel Fojt int os_exec(const char *program, const char *arg, int wait_completion) 504*a1157835SDaniel Fojt { 505*a1157835SDaniel Fojt pid_t pid; 506*a1157835SDaniel Fojt int pid_status; 507*a1157835SDaniel Fojt 508*a1157835SDaniel Fojt pid = fork(); 509*a1157835SDaniel Fojt if (pid < 0) { 510*a1157835SDaniel Fojt wpa_printf(MSG_ERROR, "fork: %s", strerror(errno)); 511*a1157835SDaniel Fojt return -1; 512*a1157835SDaniel Fojt } 513*a1157835SDaniel Fojt 514*a1157835SDaniel Fojt if (pid == 0) { 515*a1157835SDaniel Fojt /* run the external command in the child process */ 516*a1157835SDaniel Fojt const int MAX_ARG = 30; 517*a1157835SDaniel Fojt char *_program, *_arg, *pos; 518*a1157835SDaniel Fojt char *argv[MAX_ARG + 1]; 519*a1157835SDaniel Fojt int i; 520*a1157835SDaniel Fojt 521*a1157835SDaniel Fojt _program = os_strdup(program); 522*a1157835SDaniel Fojt _arg = os_strdup(arg); 523*a1157835SDaniel Fojt 524*a1157835SDaniel Fojt argv[0] = _program; 525*a1157835SDaniel Fojt 526*a1157835SDaniel Fojt i = 1; 527*a1157835SDaniel Fojt pos = _arg; 528*a1157835SDaniel Fojt while (i < MAX_ARG && pos && *pos) { 529*a1157835SDaniel Fojt while (*pos == ' ') 530*a1157835SDaniel Fojt pos++; 531*a1157835SDaniel Fojt if (*pos == '\0') 532*a1157835SDaniel Fojt break; 533*a1157835SDaniel Fojt argv[i++] = pos; 534*a1157835SDaniel Fojt pos = os_strchr(pos, ' '); 535*a1157835SDaniel Fojt if (pos) 536*a1157835SDaniel Fojt *pos++ = '\0'; 537*a1157835SDaniel Fojt } 538*a1157835SDaniel Fojt argv[i] = NULL; 539*a1157835SDaniel Fojt 540*a1157835SDaniel Fojt execv(program, argv); 541*a1157835SDaniel Fojt wpa_printf(MSG_ERROR, "execv: %s", strerror(errno)); 542*a1157835SDaniel Fojt os_free(_program); 543*a1157835SDaniel Fojt os_free(_arg); 544*a1157835SDaniel Fojt exit(0); 545*a1157835SDaniel Fojt return -1; 546*a1157835SDaniel Fojt } 547*a1157835SDaniel Fojt 548*a1157835SDaniel Fojt if (wait_completion) { 549*a1157835SDaniel Fojt /* wait for the child process to complete in the parent */ 550*a1157835SDaniel Fojt waitpid(pid, &pid_status, 0); 551*a1157835SDaniel Fojt } 552*a1157835SDaniel Fojt 553*a1157835SDaniel Fojt return 0; 554*a1157835SDaniel Fojt } 555