xref: /dflybsd-src/contrib/wpa_supplicant/src/utils/os_internal.c (revision 6d49e1aea1f916afb9e202b8d2ad09cfab6e48c3)
1*6d49e1aeSJan Lentfer /*
2*6d49e1aeSJan Lentfer  * wpa_supplicant/hostapd / Internal implementation of OS specific functions
3*6d49e1aeSJan Lentfer  * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
4*6d49e1aeSJan Lentfer  *
5*6d49e1aeSJan Lentfer  * This program is free software; you can redistribute it and/or modify
6*6d49e1aeSJan Lentfer  * it under the terms of the GNU General Public License version 2 as
7*6d49e1aeSJan Lentfer  * published by the Free Software Foundation.
8*6d49e1aeSJan Lentfer  *
9*6d49e1aeSJan Lentfer  * Alternatively, this software may be distributed under the terms of BSD
10*6d49e1aeSJan Lentfer  * license.
11*6d49e1aeSJan Lentfer  *
12*6d49e1aeSJan Lentfer  * See README and COPYING for more details.
13*6d49e1aeSJan Lentfer  *
14*6d49e1aeSJan Lentfer  * This file is an example of operating system specific  wrapper functions.
15*6d49e1aeSJan Lentfer  * This version implements many of the functions internally, so it can be used
16*6d49e1aeSJan Lentfer  * to fill in missing functions from the target system C libraries.
17*6d49e1aeSJan Lentfer  *
18*6d49e1aeSJan Lentfer  * Some of the functions are using standard C library calls in order to keep
19*6d49e1aeSJan Lentfer  * this file in working condition to allow the functions to be tested on a
20*6d49e1aeSJan Lentfer  * Linux target. Please note that OS_NO_C_LIB_DEFINES needs to be defined for
21*6d49e1aeSJan Lentfer  * this file to work correctly. Note that these implementations are only
22*6d49e1aeSJan Lentfer  * examples and are not optimized for speed.
23*6d49e1aeSJan Lentfer  */
24*6d49e1aeSJan Lentfer 
25*6d49e1aeSJan Lentfer #include "includes.h"
26*6d49e1aeSJan Lentfer 
27*6d49e1aeSJan Lentfer #undef OS_REJECT_C_LIB_FUNCTIONS
28*6d49e1aeSJan Lentfer #include "os.h"
29*6d49e1aeSJan Lentfer 
30*6d49e1aeSJan Lentfer void os_sleep(os_time_t sec, os_time_t usec)
31*6d49e1aeSJan Lentfer {
32*6d49e1aeSJan Lentfer 	if (sec)
33*6d49e1aeSJan Lentfer 		sleep(sec);
34*6d49e1aeSJan Lentfer 	if (usec)
35*6d49e1aeSJan Lentfer 		usleep(usec);
36*6d49e1aeSJan Lentfer }
37*6d49e1aeSJan Lentfer 
38*6d49e1aeSJan Lentfer 
39*6d49e1aeSJan Lentfer int os_get_time(struct os_time *t)
40*6d49e1aeSJan Lentfer {
41*6d49e1aeSJan Lentfer 	int res;
42*6d49e1aeSJan Lentfer 	struct timeval tv;
43*6d49e1aeSJan Lentfer 	res = gettimeofday(&tv, NULL);
44*6d49e1aeSJan Lentfer 	t->sec = tv.tv_sec;
45*6d49e1aeSJan Lentfer 	t->usec = tv.tv_usec;
46*6d49e1aeSJan Lentfer 	return res;
47*6d49e1aeSJan Lentfer }
48*6d49e1aeSJan Lentfer 
49*6d49e1aeSJan Lentfer 
50*6d49e1aeSJan Lentfer int os_mktime(int year, int month, int day, int hour, int min, int sec,
51*6d49e1aeSJan Lentfer 	      os_time_t *t)
52*6d49e1aeSJan Lentfer {
53*6d49e1aeSJan Lentfer 	struct tm tm;
54*6d49e1aeSJan Lentfer 
55*6d49e1aeSJan Lentfer 	if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ||
56*6d49e1aeSJan Lentfer 	    hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 ||
57*6d49e1aeSJan Lentfer 	    sec > 60)
58*6d49e1aeSJan Lentfer 		return -1;
59*6d49e1aeSJan Lentfer 
60*6d49e1aeSJan Lentfer 	os_memset(&tm, 0, sizeof(tm));
61*6d49e1aeSJan Lentfer 	tm.tm_year = year - 1900;
62*6d49e1aeSJan Lentfer 	tm.tm_mon = month - 1;
63*6d49e1aeSJan Lentfer 	tm.tm_mday = day;
64*6d49e1aeSJan Lentfer 	tm.tm_hour = hour;
65*6d49e1aeSJan Lentfer 	tm.tm_min = min;
66*6d49e1aeSJan Lentfer 	tm.tm_sec = sec;
67*6d49e1aeSJan Lentfer 
68*6d49e1aeSJan Lentfer 	*t = (os_time_t) mktime(&tm);
69*6d49e1aeSJan Lentfer 	return 0;
70*6d49e1aeSJan Lentfer }
71*6d49e1aeSJan Lentfer 
72*6d49e1aeSJan Lentfer 
73*6d49e1aeSJan Lentfer int os_daemonize(const char *pid_file)
74*6d49e1aeSJan Lentfer {
75*6d49e1aeSJan Lentfer 	if (daemon(0, 0)) {
76*6d49e1aeSJan Lentfer 		perror("daemon");
77*6d49e1aeSJan Lentfer 		return -1;
78*6d49e1aeSJan Lentfer 	}
79*6d49e1aeSJan Lentfer 
80*6d49e1aeSJan Lentfer 	if (pid_file) {
81*6d49e1aeSJan Lentfer 		FILE *f = fopen(pid_file, "w");
82*6d49e1aeSJan Lentfer 		if (f) {
83*6d49e1aeSJan Lentfer 			fprintf(f, "%u\n", getpid());
84*6d49e1aeSJan Lentfer 			fclose(f);
85*6d49e1aeSJan Lentfer 		}
86*6d49e1aeSJan Lentfer 	}
87*6d49e1aeSJan Lentfer 
88*6d49e1aeSJan Lentfer 	return -0;
89*6d49e1aeSJan Lentfer }
90*6d49e1aeSJan Lentfer 
91*6d49e1aeSJan Lentfer 
92*6d49e1aeSJan Lentfer void os_daemonize_terminate(const char *pid_file)
93*6d49e1aeSJan Lentfer {
94*6d49e1aeSJan Lentfer 	if (pid_file)
95*6d49e1aeSJan Lentfer 		unlink(pid_file);
96*6d49e1aeSJan Lentfer }
97*6d49e1aeSJan Lentfer 
98*6d49e1aeSJan Lentfer 
99*6d49e1aeSJan Lentfer int os_get_random(unsigned char *buf, size_t len)
100*6d49e1aeSJan Lentfer {
101*6d49e1aeSJan Lentfer 	FILE *f;
102*6d49e1aeSJan Lentfer 	size_t rc;
103*6d49e1aeSJan Lentfer 
104*6d49e1aeSJan Lentfer 	f = fopen("/dev/urandom", "rb");
105*6d49e1aeSJan Lentfer 	if (f == NULL) {
106*6d49e1aeSJan Lentfer 		printf("Could not open /dev/urandom.\n");
107*6d49e1aeSJan Lentfer 		return -1;
108*6d49e1aeSJan Lentfer 	}
109*6d49e1aeSJan Lentfer 
110*6d49e1aeSJan Lentfer 	rc = fread(buf, 1, len, f);
111*6d49e1aeSJan Lentfer 	fclose(f);
112*6d49e1aeSJan Lentfer 
113*6d49e1aeSJan Lentfer 	return rc != len ? -1 : 0;
114*6d49e1aeSJan Lentfer }
115*6d49e1aeSJan Lentfer 
116*6d49e1aeSJan Lentfer 
117*6d49e1aeSJan Lentfer unsigned long os_random(void)
118*6d49e1aeSJan Lentfer {
119*6d49e1aeSJan Lentfer 	return random();
120*6d49e1aeSJan Lentfer }
121*6d49e1aeSJan Lentfer 
122*6d49e1aeSJan Lentfer 
123*6d49e1aeSJan Lentfer char * os_rel2abs_path(const char *rel_path)
124*6d49e1aeSJan Lentfer {
125*6d49e1aeSJan Lentfer 	char *buf = NULL, *cwd, *ret;
126*6d49e1aeSJan Lentfer 	size_t len = 128, cwd_len, rel_len, ret_len;
127*6d49e1aeSJan Lentfer 
128*6d49e1aeSJan Lentfer 	if (rel_path[0] == '/')
129*6d49e1aeSJan Lentfer 		return os_strdup(rel_path);
130*6d49e1aeSJan Lentfer 
131*6d49e1aeSJan Lentfer 	for (;;) {
132*6d49e1aeSJan Lentfer 		buf = os_malloc(len);
133*6d49e1aeSJan Lentfer 		if (buf == NULL)
134*6d49e1aeSJan Lentfer 			return NULL;
135*6d49e1aeSJan Lentfer 		cwd = getcwd(buf, len);
136*6d49e1aeSJan Lentfer 		if (cwd == NULL) {
137*6d49e1aeSJan Lentfer 			os_free(buf);
138*6d49e1aeSJan Lentfer 			if (errno != ERANGE) {
139*6d49e1aeSJan Lentfer 				return NULL;
140*6d49e1aeSJan Lentfer 			}
141*6d49e1aeSJan Lentfer 			len *= 2;
142*6d49e1aeSJan Lentfer 		} else {
143*6d49e1aeSJan Lentfer 			break;
144*6d49e1aeSJan Lentfer 		}
145*6d49e1aeSJan Lentfer 	}
146*6d49e1aeSJan Lentfer 
147*6d49e1aeSJan Lentfer 	cwd_len = strlen(cwd);
148*6d49e1aeSJan Lentfer 	rel_len = strlen(rel_path);
149*6d49e1aeSJan Lentfer 	ret_len = cwd_len + 1 + rel_len + 1;
150*6d49e1aeSJan Lentfer 	ret = os_malloc(ret_len);
151*6d49e1aeSJan Lentfer 	if (ret) {
152*6d49e1aeSJan Lentfer 		os_memcpy(ret, cwd, cwd_len);
153*6d49e1aeSJan Lentfer 		ret[cwd_len] = '/';
154*6d49e1aeSJan Lentfer 		os_memcpy(ret + cwd_len + 1, rel_path, rel_len);
155*6d49e1aeSJan Lentfer 		ret[ret_len - 1] = '\0';
156*6d49e1aeSJan Lentfer 	}
157*6d49e1aeSJan Lentfer 	os_free(buf);
158*6d49e1aeSJan Lentfer 	return ret;
159*6d49e1aeSJan Lentfer }
160*6d49e1aeSJan Lentfer 
161*6d49e1aeSJan Lentfer 
162*6d49e1aeSJan Lentfer int os_program_init(void)
163*6d49e1aeSJan Lentfer {
164*6d49e1aeSJan Lentfer 	return 0;
165*6d49e1aeSJan Lentfer }
166*6d49e1aeSJan Lentfer 
167*6d49e1aeSJan Lentfer 
168*6d49e1aeSJan Lentfer void os_program_deinit(void)
169*6d49e1aeSJan Lentfer {
170*6d49e1aeSJan Lentfer }
171*6d49e1aeSJan Lentfer 
172*6d49e1aeSJan Lentfer 
173*6d49e1aeSJan Lentfer int os_setenv(const char *name, const char *value, int overwrite)
174*6d49e1aeSJan Lentfer {
175*6d49e1aeSJan Lentfer 	return setenv(name, value, overwrite);
176*6d49e1aeSJan Lentfer }
177*6d49e1aeSJan Lentfer 
178*6d49e1aeSJan Lentfer 
179*6d49e1aeSJan Lentfer int os_unsetenv(const char *name)
180*6d49e1aeSJan Lentfer {
181*6d49e1aeSJan Lentfer #if defined(__FreeBSD__) || defined(__NetBSD__)
182*6d49e1aeSJan Lentfer 	unsetenv(name);
183*6d49e1aeSJan Lentfer 	return 0;
184*6d49e1aeSJan Lentfer #else
185*6d49e1aeSJan Lentfer 	return unsetenv(name);
186*6d49e1aeSJan Lentfer #endif
187*6d49e1aeSJan Lentfer }
188*6d49e1aeSJan Lentfer 
189*6d49e1aeSJan Lentfer 
190*6d49e1aeSJan Lentfer char * os_readfile(const char *name, size_t *len)
191*6d49e1aeSJan Lentfer {
192*6d49e1aeSJan Lentfer 	FILE *f;
193*6d49e1aeSJan Lentfer 	char *buf;
194*6d49e1aeSJan Lentfer 
195*6d49e1aeSJan Lentfer 	f = fopen(name, "rb");
196*6d49e1aeSJan Lentfer 	if (f == NULL)
197*6d49e1aeSJan Lentfer 		return NULL;
198*6d49e1aeSJan Lentfer 
199*6d49e1aeSJan Lentfer 	fseek(f, 0, SEEK_END);
200*6d49e1aeSJan Lentfer 	*len = ftell(f);
201*6d49e1aeSJan Lentfer 	fseek(f, 0, SEEK_SET);
202*6d49e1aeSJan Lentfer 
203*6d49e1aeSJan Lentfer 	buf = os_malloc(*len);
204*6d49e1aeSJan Lentfer 	if (buf == NULL) {
205*6d49e1aeSJan Lentfer 		fclose(f);
206*6d49e1aeSJan Lentfer 		return NULL;
207*6d49e1aeSJan Lentfer 	}
208*6d49e1aeSJan Lentfer 
209*6d49e1aeSJan Lentfer 	fread(buf, 1, *len, f);
210*6d49e1aeSJan Lentfer 	fclose(f);
211*6d49e1aeSJan Lentfer 
212*6d49e1aeSJan Lentfer 	return buf;
213*6d49e1aeSJan Lentfer }
214*6d49e1aeSJan Lentfer 
215*6d49e1aeSJan Lentfer 
216*6d49e1aeSJan Lentfer void * os_zalloc(size_t size)
217*6d49e1aeSJan Lentfer {
218*6d49e1aeSJan Lentfer 	void *n = os_malloc(size);
219*6d49e1aeSJan Lentfer 	if (n)
220*6d49e1aeSJan Lentfer 		os_memset(n, 0, size);
221*6d49e1aeSJan Lentfer 	return n;
222*6d49e1aeSJan Lentfer }
223*6d49e1aeSJan Lentfer 
224*6d49e1aeSJan Lentfer 
225*6d49e1aeSJan Lentfer void * os_malloc(size_t size)
226*6d49e1aeSJan Lentfer {
227*6d49e1aeSJan Lentfer 	return malloc(size);
228*6d49e1aeSJan Lentfer }
229*6d49e1aeSJan Lentfer 
230*6d49e1aeSJan Lentfer 
231*6d49e1aeSJan Lentfer void * os_realloc(void *ptr, size_t size)
232*6d49e1aeSJan Lentfer {
233*6d49e1aeSJan Lentfer 	return realloc(ptr, size);
234*6d49e1aeSJan Lentfer }
235*6d49e1aeSJan Lentfer 
236*6d49e1aeSJan Lentfer 
237*6d49e1aeSJan Lentfer void os_free(void *ptr)
238*6d49e1aeSJan Lentfer {
239*6d49e1aeSJan Lentfer 	free(ptr);
240*6d49e1aeSJan Lentfer }
241*6d49e1aeSJan Lentfer 
242*6d49e1aeSJan Lentfer 
243*6d49e1aeSJan Lentfer void * os_memcpy(void *dest, const void *src, size_t n)
244*6d49e1aeSJan Lentfer {
245*6d49e1aeSJan Lentfer 	char *d = dest;
246*6d49e1aeSJan Lentfer 	const char *s = src;
247*6d49e1aeSJan Lentfer 	while (n--)
248*6d49e1aeSJan Lentfer 		*d++ = *s++;
249*6d49e1aeSJan Lentfer 	return dest;
250*6d49e1aeSJan Lentfer }
251*6d49e1aeSJan Lentfer 
252*6d49e1aeSJan Lentfer 
253*6d49e1aeSJan Lentfer void * os_memmove(void *dest, const void *src, size_t n)
254*6d49e1aeSJan Lentfer {
255*6d49e1aeSJan Lentfer 	if (dest < src)
256*6d49e1aeSJan Lentfer 		os_memcpy(dest, src, n);
257*6d49e1aeSJan Lentfer 	else {
258*6d49e1aeSJan Lentfer 		/* overlapping areas */
259*6d49e1aeSJan Lentfer 		char *d = (char *) dest + n;
260*6d49e1aeSJan Lentfer 		const char *s = (const char *) src + n;
261*6d49e1aeSJan Lentfer 		while (n--)
262*6d49e1aeSJan Lentfer 			*--d = *--s;
263*6d49e1aeSJan Lentfer 	}
264*6d49e1aeSJan Lentfer 	return dest;
265*6d49e1aeSJan Lentfer }
266*6d49e1aeSJan Lentfer 
267*6d49e1aeSJan Lentfer 
268*6d49e1aeSJan Lentfer void * os_memset(void *s, int c, size_t n)
269*6d49e1aeSJan Lentfer {
270*6d49e1aeSJan Lentfer 	char *p = s;
271*6d49e1aeSJan Lentfer 	while (n--)
272*6d49e1aeSJan Lentfer 		*p++ = c;
273*6d49e1aeSJan Lentfer 	return s;
274*6d49e1aeSJan Lentfer }
275*6d49e1aeSJan Lentfer 
276*6d49e1aeSJan Lentfer 
277*6d49e1aeSJan Lentfer int os_memcmp(const void *s1, const void *s2, size_t n)
278*6d49e1aeSJan Lentfer {
279*6d49e1aeSJan Lentfer 	const unsigned char *p1 = s1, *p2 = s2;
280*6d49e1aeSJan Lentfer 
281*6d49e1aeSJan Lentfer 	if (n == 0)
282*6d49e1aeSJan Lentfer 		return 0;
283*6d49e1aeSJan Lentfer 
284*6d49e1aeSJan Lentfer 	while (*p1 == *p2) {
285*6d49e1aeSJan Lentfer 		p1++;
286*6d49e1aeSJan Lentfer 		p2++;
287*6d49e1aeSJan Lentfer 		n--;
288*6d49e1aeSJan Lentfer 		if (n == 0)
289*6d49e1aeSJan Lentfer 			return 0;
290*6d49e1aeSJan Lentfer 	}
291*6d49e1aeSJan Lentfer 
292*6d49e1aeSJan Lentfer 	return *p1 - *p2;
293*6d49e1aeSJan Lentfer }
294*6d49e1aeSJan Lentfer 
295*6d49e1aeSJan Lentfer 
296*6d49e1aeSJan Lentfer char * os_strdup(const char *s)
297*6d49e1aeSJan Lentfer {
298*6d49e1aeSJan Lentfer 	char *res;
299*6d49e1aeSJan Lentfer 	size_t len;
300*6d49e1aeSJan Lentfer 	if (s == NULL)
301*6d49e1aeSJan Lentfer 		return NULL;
302*6d49e1aeSJan Lentfer 	len = os_strlen(s);
303*6d49e1aeSJan Lentfer 	res = os_malloc(len + 1);
304*6d49e1aeSJan Lentfer 	if (res)
305*6d49e1aeSJan Lentfer 		os_memcpy(res, s, len + 1);
306*6d49e1aeSJan Lentfer 	return res;
307*6d49e1aeSJan Lentfer }
308*6d49e1aeSJan Lentfer 
309*6d49e1aeSJan Lentfer 
310*6d49e1aeSJan Lentfer size_t os_strlen(const char *s)
311*6d49e1aeSJan Lentfer {
312*6d49e1aeSJan Lentfer 	const char *p = s;
313*6d49e1aeSJan Lentfer 	while (*p)
314*6d49e1aeSJan Lentfer 		p++;
315*6d49e1aeSJan Lentfer 	return p - s;
316*6d49e1aeSJan Lentfer }
317*6d49e1aeSJan Lentfer 
318*6d49e1aeSJan Lentfer 
319*6d49e1aeSJan Lentfer int os_strcasecmp(const char *s1, const char *s2)
320*6d49e1aeSJan Lentfer {
321*6d49e1aeSJan Lentfer 	/*
322*6d49e1aeSJan Lentfer 	 * Ignoring case is not required for main functionality, so just use
323*6d49e1aeSJan Lentfer 	 * the case sensitive version of the function.
324*6d49e1aeSJan Lentfer 	 */
325*6d49e1aeSJan Lentfer 	return os_strcmp(s1, s2);
326*6d49e1aeSJan Lentfer }
327*6d49e1aeSJan Lentfer 
328*6d49e1aeSJan Lentfer 
329*6d49e1aeSJan Lentfer int os_strncasecmp(const char *s1, const char *s2, size_t n)
330*6d49e1aeSJan Lentfer {
331*6d49e1aeSJan Lentfer 	/*
332*6d49e1aeSJan Lentfer 	 * Ignoring case is not required for main functionality, so just use
333*6d49e1aeSJan Lentfer 	 * the case sensitive version of the function.
334*6d49e1aeSJan Lentfer 	 */
335*6d49e1aeSJan Lentfer 	return os_strncmp(s1, s2, n);
336*6d49e1aeSJan Lentfer }
337*6d49e1aeSJan Lentfer 
338*6d49e1aeSJan Lentfer 
339*6d49e1aeSJan Lentfer char * os_strchr(const char *s, int c)
340*6d49e1aeSJan Lentfer {
341*6d49e1aeSJan Lentfer 	while (*s) {
342*6d49e1aeSJan Lentfer 		if (*s == c)
343*6d49e1aeSJan Lentfer 			return (char *) s;
344*6d49e1aeSJan Lentfer 		s++;
345*6d49e1aeSJan Lentfer 	}
346*6d49e1aeSJan Lentfer 	return NULL;
347*6d49e1aeSJan Lentfer }
348*6d49e1aeSJan Lentfer 
349*6d49e1aeSJan Lentfer 
350*6d49e1aeSJan Lentfer char * os_strrchr(const char *s, int c)
351*6d49e1aeSJan Lentfer {
352*6d49e1aeSJan Lentfer 	const char *p = s;
353*6d49e1aeSJan Lentfer 	while (*p)
354*6d49e1aeSJan Lentfer 		p++;
355*6d49e1aeSJan Lentfer 	p--;
356*6d49e1aeSJan Lentfer 	while (p >= s) {
357*6d49e1aeSJan Lentfer 		if (*p == c)
358*6d49e1aeSJan Lentfer 			return (char *) p;
359*6d49e1aeSJan Lentfer 		p--;
360*6d49e1aeSJan Lentfer 	}
361*6d49e1aeSJan Lentfer 	return NULL;
362*6d49e1aeSJan Lentfer }
363*6d49e1aeSJan Lentfer 
364*6d49e1aeSJan Lentfer 
365*6d49e1aeSJan Lentfer int os_strcmp(const char *s1, const char *s2)
366*6d49e1aeSJan Lentfer {
367*6d49e1aeSJan Lentfer 	while (*s1 == *s2) {
368*6d49e1aeSJan Lentfer 		if (*s1 == '\0')
369*6d49e1aeSJan Lentfer 			break;
370*6d49e1aeSJan Lentfer 		s1++;
371*6d49e1aeSJan Lentfer 		s2++;
372*6d49e1aeSJan Lentfer 	}
373*6d49e1aeSJan Lentfer 
374*6d49e1aeSJan Lentfer 	return *s1 - *s2;
375*6d49e1aeSJan Lentfer }
376*6d49e1aeSJan Lentfer 
377*6d49e1aeSJan Lentfer 
378*6d49e1aeSJan Lentfer int os_strncmp(const char *s1, const char *s2, size_t n)
379*6d49e1aeSJan Lentfer {
380*6d49e1aeSJan Lentfer 	if (n == 0)
381*6d49e1aeSJan Lentfer 		return 0;
382*6d49e1aeSJan Lentfer 
383*6d49e1aeSJan Lentfer 	while (*s1 == *s2) {
384*6d49e1aeSJan Lentfer 		if (*s1 == '\0')
385*6d49e1aeSJan Lentfer 			break;
386*6d49e1aeSJan Lentfer 		s1++;
387*6d49e1aeSJan Lentfer 		s2++;
388*6d49e1aeSJan Lentfer 		n--;
389*6d49e1aeSJan Lentfer 		if (n == 0)
390*6d49e1aeSJan Lentfer 			return 0;
391*6d49e1aeSJan Lentfer 	}
392*6d49e1aeSJan Lentfer 
393*6d49e1aeSJan Lentfer 	return *s1 - *s2;
394*6d49e1aeSJan Lentfer }
395*6d49e1aeSJan Lentfer 
396*6d49e1aeSJan Lentfer 
397*6d49e1aeSJan Lentfer char * os_strncpy(char *dest, const char *src, size_t n)
398*6d49e1aeSJan Lentfer {
399*6d49e1aeSJan Lentfer 	char *d = dest;
400*6d49e1aeSJan Lentfer 
401*6d49e1aeSJan Lentfer 	while (n--) {
402*6d49e1aeSJan Lentfer 		*d = *src;
403*6d49e1aeSJan Lentfer 		if (*src == '\0')
404*6d49e1aeSJan Lentfer 			break;
405*6d49e1aeSJan Lentfer 		d++;
406*6d49e1aeSJan Lentfer 		src++;
407*6d49e1aeSJan Lentfer 	}
408*6d49e1aeSJan Lentfer 
409*6d49e1aeSJan Lentfer 	return dest;
410*6d49e1aeSJan Lentfer }
411*6d49e1aeSJan Lentfer 
412*6d49e1aeSJan Lentfer 
413*6d49e1aeSJan Lentfer size_t os_strlcpy(char *dest, const char *src, size_t siz)
414*6d49e1aeSJan Lentfer {
415*6d49e1aeSJan Lentfer 	const char *s = src;
416*6d49e1aeSJan Lentfer 	size_t left = siz;
417*6d49e1aeSJan Lentfer 
418*6d49e1aeSJan Lentfer 	if (left) {
419*6d49e1aeSJan Lentfer 		/* Copy string up to the maximum size of the dest buffer */
420*6d49e1aeSJan Lentfer 		while (--left != 0) {
421*6d49e1aeSJan Lentfer 			if ((*dest++ = *s++) == '\0')
422*6d49e1aeSJan Lentfer 				break;
423*6d49e1aeSJan Lentfer 		}
424*6d49e1aeSJan Lentfer 	}
425*6d49e1aeSJan Lentfer 
426*6d49e1aeSJan Lentfer 	if (left == 0) {
427*6d49e1aeSJan Lentfer 		/* Not enough room for the string; force NUL-termination */
428*6d49e1aeSJan Lentfer 		if (siz != 0)
429*6d49e1aeSJan Lentfer 			*dest = '\0';
430*6d49e1aeSJan Lentfer 		while (*s++)
431*6d49e1aeSJan Lentfer 			; /* determine total src string length */
432*6d49e1aeSJan Lentfer 	}
433*6d49e1aeSJan Lentfer 
434*6d49e1aeSJan Lentfer 	return s - src - 1;
435*6d49e1aeSJan Lentfer }
436*6d49e1aeSJan Lentfer 
437*6d49e1aeSJan Lentfer 
438*6d49e1aeSJan Lentfer char * os_strstr(const char *haystack, const char *needle)
439*6d49e1aeSJan Lentfer {
440*6d49e1aeSJan Lentfer 	size_t len = os_strlen(needle);
441*6d49e1aeSJan Lentfer 	while (*haystack) {
442*6d49e1aeSJan Lentfer 		if (os_strncmp(haystack, needle, len) == 0)
443*6d49e1aeSJan Lentfer 			return (char *) haystack;
444*6d49e1aeSJan Lentfer 		haystack++;
445*6d49e1aeSJan Lentfer 	}
446*6d49e1aeSJan Lentfer 
447*6d49e1aeSJan Lentfer 	return NULL;
448*6d49e1aeSJan Lentfer }
449*6d49e1aeSJan Lentfer 
450*6d49e1aeSJan Lentfer 
451*6d49e1aeSJan Lentfer int os_snprintf(char *str, size_t size, const char *format, ...)
452*6d49e1aeSJan Lentfer {
453*6d49e1aeSJan Lentfer 	va_list ap;
454*6d49e1aeSJan Lentfer 	int ret;
455*6d49e1aeSJan Lentfer 
456*6d49e1aeSJan Lentfer 	/* See http://www.ijs.si/software/snprintf/ for portable
457*6d49e1aeSJan Lentfer 	 * implementation of snprintf.
458*6d49e1aeSJan Lentfer 	 */
459*6d49e1aeSJan Lentfer 
460*6d49e1aeSJan Lentfer 	va_start(ap, format);
461*6d49e1aeSJan Lentfer 	ret = vsnprintf(str, size, format, ap);
462*6d49e1aeSJan Lentfer 	va_end(ap);
463*6d49e1aeSJan Lentfer 	if (size > 0)
464*6d49e1aeSJan Lentfer 		str[size - 1] = '\0';
465*6d49e1aeSJan Lentfer 	return ret;
466*6d49e1aeSJan Lentfer }
467