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