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