Home | History | Annotate | Download | only in utils
      1 /*
      2  * wpa_supplicant/hostapd / Internal implementation of OS specific functions
      3  * Copyright (c) 2005-2006, Jouni Malinen <j (at) 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 int os_memcmp_const(const void *a, const void *b, size_t len)
    467 {
    468 	const u8 *aa = a;
    469 	const u8 *bb = b;
    470 	size_t i;
    471 	u8 res;
    472 
    473 	for (res = 0, i = 0; i < len; i++)
    474 		res |= aa[i] ^ bb[i];
    475 
    476 	return res;
    477 }
    478 
    479 
    480 char * os_strstr(const char *haystack, const char *needle)
    481 {
    482 	size_t len = os_strlen(needle);
    483 	while (*haystack) {
    484 		if (os_strncmp(haystack, needle, len) == 0)
    485 			return (char *) haystack;
    486 		haystack++;
    487 	}
    488 
    489 	return NULL;
    490 }
    491 
    492 
    493 int os_snprintf(char *str, size_t size, const char *format, ...)
    494 {
    495 	va_list ap;
    496 	int ret;
    497 
    498 	/* See http://www.ijs.si/software/snprintf/ for portable
    499 	 * implementation of snprintf.
    500 	 */
    501 
    502 	va_start(ap, format);
    503 	ret = vsnprintf(str, size, format, ap);
    504 	va_end(ap);
    505 	if (size > 0)
    506 		str[size - 1] = '\0';
    507 	return ret;
    508 }
    509