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
os_sleep(os_time_t sec,os_time_t usec)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
os_get_time(struct os_time * t)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
os_get_reltime(struct os_reltime * t)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
os_mktime(int year,int month,int day,int hour,int min,int sec,os_time_t * t)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
os_gmtime(os_time_t t,struct os_tm * tm)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
os_daemonize(const char * pid_file)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
os_daemonize_terminate(const char * pid_file)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
os_get_random(unsigned char * buf,size_t len)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
os_random(void)1426d49e1aeSJan Lentfer unsigned long os_random(void)
1436d49e1aeSJan Lentfer {
1446d49e1aeSJan Lentfer return random();
1456d49e1aeSJan Lentfer }
1466d49e1aeSJan Lentfer
1476d49e1aeSJan Lentfer
os_rel2abs_path(const char * rel_path)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
os_program_init(void)1876d49e1aeSJan Lentfer int os_program_init(void)
1886d49e1aeSJan Lentfer {
1896d49e1aeSJan Lentfer return 0;
1906d49e1aeSJan Lentfer }
1916d49e1aeSJan Lentfer
1926d49e1aeSJan Lentfer
os_program_deinit(void)1936d49e1aeSJan Lentfer void os_program_deinit(void)
1946d49e1aeSJan Lentfer {
1956d49e1aeSJan Lentfer }
1966d49e1aeSJan Lentfer
1976d49e1aeSJan Lentfer
os_setenv(const char * name,const char * value,int overwrite)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
os_unsetenv(const char * name)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
os_readfile(const char * name,size_t * len)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
os_fdatasync(FILE * stream)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
os_zalloc(size_t size)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
os_malloc(size_t size)2616d49e1aeSJan Lentfer void * os_malloc(size_t size)
2626d49e1aeSJan Lentfer {
2636d49e1aeSJan Lentfer return malloc(size);
2646d49e1aeSJan Lentfer }
2656d49e1aeSJan Lentfer
2666d49e1aeSJan Lentfer
os_realloc(void * ptr,size_t size)2676d49e1aeSJan Lentfer void * os_realloc(void *ptr, size_t size)
2686d49e1aeSJan Lentfer {
2696d49e1aeSJan Lentfer return realloc(ptr, size);
2706d49e1aeSJan Lentfer }
2716d49e1aeSJan Lentfer
2726d49e1aeSJan Lentfer
os_free(void * ptr)2736d49e1aeSJan Lentfer void os_free(void *ptr)
2746d49e1aeSJan Lentfer {
2756d49e1aeSJan Lentfer free(ptr);
2766d49e1aeSJan Lentfer }
2776d49e1aeSJan Lentfer
2786d49e1aeSJan Lentfer
os_memcpy(void * dest,const void * src,size_t n)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
os_memmove(void * dest,const void * src,size_t n)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
os_memset(void * s,int c,size_t n)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
os_memcmp(const void * s1,const void * s2,size_t n)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
os_strdup(const char * s)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
os_strlen(const char * s)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
os_strcasecmp(const char * s1,const char * s2)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
os_strncasecmp(const char * s1,const char * s2,size_t n)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
os_strchr(const char * s,int c)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
os_strrchr(const char * s,int c)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
os_strcmp(const char * s1,const char * s2)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
os_strncmp(const char * s1,const char * s2,size_t n)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
os_strlcpy(char * dest,const char * src,size_t siz)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
os_memcmp_const(const void * a,const void * b,size_t len)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
os_strstr(const char * haystack,const char * needle)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
os_snprintf(char * str,size_t size,const char * format,...)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
os_exec(const char * program,const char * arg,int wait_completion)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