$search
00001 /* 00002 * wpa_supplicant/hostapd / Internal implementation of OS specific functions 00003 * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 * 00014 * This file is an example of operating system specific wrapper functions. 00015 * This version implements many of the functions internally, so it can be used 00016 * to fill in missing functions from the target system C libraries. 00017 * 00018 * Some of the functions are using standard C library calls in order to keep 00019 * this file in working condition to allow the functions to be tested on a 00020 * Linux target. Please note that OS_NO_C_LIB_DEFINES needs to be defined for 00021 * this file to work correctly. Note that these implementations are only 00022 * examples and are not optimized for speed. 00023 */ 00024 00025 #include "includes.h" 00026 00027 #undef OS_REJECT_C_LIB_FUNCTIONS 00028 #include "os.h" 00029 00030 void os_sleep(os_time_t sec, os_time_t usec) 00031 { 00032 if (sec) 00033 sleep(sec); 00034 if (usec) 00035 usleep(usec); 00036 } 00037 00038 00039 int os_get_time(struct os_time *t) 00040 { 00041 int res; 00042 struct timeval tv; 00043 res = gettimeofday(&tv, NULL); 00044 t->sec = tv.tv_sec; 00045 t->usec = tv.tv_usec; 00046 return res; 00047 } 00048 00049 00050 int os_mktime(int year, int month, int day, int hour, int min, int sec, 00051 os_time_t *t) 00052 { 00053 struct tm tm; 00054 00055 if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 || 00056 hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 || 00057 sec > 60) 00058 return -1; 00059 00060 os_memset(&tm, 0, sizeof(tm)); 00061 tm.tm_year = year - 1900; 00062 tm.tm_mon = month - 1; 00063 tm.tm_mday = day; 00064 tm.tm_hour = hour; 00065 tm.tm_min = min; 00066 tm.tm_sec = sec; 00067 00068 *t = (os_time_t) mktime(&tm); 00069 return 0; 00070 } 00071 00072 00073 int os_daemonize(const char *pid_file) 00074 { 00075 if (daemon(0, 0)) { 00076 perror("daemon"); 00077 return -1; 00078 } 00079 00080 if (pid_file) { 00081 FILE *f = fopen(pid_file, "w"); 00082 if (f) { 00083 fprintf(f, "%u\n", getpid()); 00084 fclose(f); 00085 } 00086 } 00087 00088 return -0; 00089 } 00090 00091 00092 void os_daemonize_terminate(const char *pid_file) 00093 { 00094 if (pid_file) 00095 unlink(pid_file); 00096 } 00097 00098 00099 int os_get_random(unsigned char *buf, size_t len) 00100 { 00101 FILE *f; 00102 size_t rc; 00103 00104 f = fopen("/dev/urandom", "rb"); 00105 if (f == NULL) { 00106 printf("Could not open /dev/urandom.\n"); 00107 return -1; 00108 } 00109 00110 rc = fread(buf, 1, len, f); 00111 fclose(f); 00112 00113 return rc != len ? -1 : 0; 00114 } 00115 00116 00117 unsigned long os_random(void) 00118 { 00119 return random(); 00120 } 00121 00122 00123 char * os_rel2abs_path(const char *rel_path) 00124 { 00125 char *buf = NULL, *cwd, *ret; 00126 size_t len = 128, cwd_len, rel_len, ret_len; 00127 00128 if (rel_path[0] == '/') 00129 return os_strdup(rel_path); 00130 00131 for (;;) { 00132 buf = os_malloc(len); 00133 if (buf == NULL) 00134 return NULL; 00135 cwd = getcwd(buf, len); 00136 if (cwd == NULL) { 00137 os_free(buf); 00138 if (errno != ERANGE) { 00139 return NULL; 00140 } 00141 len *= 2; 00142 } else { 00143 break; 00144 } 00145 } 00146 00147 cwd_len = strlen(cwd); 00148 rel_len = strlen(rel_path); 00149 ret_len = cwd_len + 1 + rel_len + 1; 00150 ret = os_malloc(ret_len); 00151 if (ret) { 00152 os_memcpy(ret, cwd, cwd_len); 00153 ret[cwd_len] = '/'; 00154 os_memcpy(ret + cwd_len + 1, rel_path, rel_len); 00155 ret[ret_len - 1] = '\0'; 00156 } 00157 os_free(buf); 00158 return ret; 00159 } 00160 00161 00162 int os_program_init(void) 00163 { 00164 return 0; 00165 } 00166 00167 00168 void os_program_deinit(void) 00169 { 00170 } 00171 00172 00173 int os_setenv(const char *name, const char *value, int overwrite) 00174 { 00175 return setenv(name, value, overwrite); 00176 } 00177 00178 00179 int os_unsetenv(const char *name) 00180 { 00181 #if defined(__FreeBSD__) || defined(__NetBSD__) 00182 unsetenv(name); 00183 return 0; 00184 #else 00185 return unsetenv(name); 00186 #endif 00187 } 00188 00189 00190 char * os_readfile(const char *name, size_t *len) 00191 { 00192 FILE *f; 00193 char *buf; 00194 00195 f = fopen(name, "rb"); 00196 if (f == NULL) 00197 return NULL; 00198 00199 fseek(f, 0, SEEK_END); 00200 *len = ftell(f); 00201 fseek(f, 0, SEEK_SET); 00202 00203 buf = os_malloc(*len); 00204 if (buf == NULL) { 00205 fclose(f); 00206 return NULL; 00207 } 00208 00209 if (fread(buf, 1, *len, f) != *len) { 00210 fclose(f); 00211 os_free(buf); 00212 return NULL; 00213 } 00214 00215 fclose(f); 00216 00217 return buf; 00218 } 00219 00220 00221 void * os_zalloc(size_t size) 00222 { 00223 void *n = os_malloc(size); 00224 if (n) 00225 os_memset(n, 0, size); 00226 return n; 00227 } 00228 00229 00230 void * os_malloc(size_t size) 00231 { 00232 return malloc(size); 00233 } 00234 00235 00236 void * os_realloc(void *ptr, size_t size) 00237 { 00238 return realloc(ptr, size); 00239 } 00240 00241 00242 void os_free(void *ptr) 00243 { 00244 free(ptr); 00245 } 00246 00247 00248 void * os_memcpy(void *dest, const void *src, size_t n) 00249 { 00250 char *d = dest; 00251 const char *s = src; 00252 while (n--) 00253 *d++ = *s++; 00254 return dest; 00255 } 00256 00257 00258 void * os_memmove(void *dest, const void *src, size_t n) 00259 { 00260 if (dest < src) 00261 os_memcpy(dest, src, n); 00262 else { 00263 /* overlapping areas */ 00264 char *d = (char *) dest + n; 00265 const char *s = (const char *) src + n; 00266 while (n--) 00267 *--d = *--s; 00268 } 00269 return dest; 00270 } 00271 00272 00273 void * os_memset(void *s, int c, size_t n) 00274 { 00275 char *p = s; 00276 while (n--) 00277 *p++ = c; 00278 return s; 00279 } 00280 00281 00282 int os_memcmp(const void *s1, const void *s2, size_t n) 00283 { 00284 const unsigned char *p1 = s1, *p2 = s2; 00285 00286 if (n == 0) 00287 return 0; 00288 00289 while (*p1 == *p2) { 00290 p1++; 00291 p2++; 00292 n--; 00293 if (n == 0) 00294 return 0; 00295 } 00296 00297 return *p1 - *p2; 00298 } 00299 00300 00301 char * os_strdup(const char *s) 00302 { 00303 char *res; 00304 size_t len; 00305 if (s == NULL) 00306 return NULL; 00307 len = os_strlen(s); 00308 res = os_malloc(len + 1); 00309 if (res) 00310 os_memcpy(res, s, len + 1); 00311 return res; 00312 } 00313 00314 00315 size_t os_strlen(const char *s) 00316 { 00317 const char *p = s; 00318 while (*p) 00319 p++; 00320 return p - s; 00321 } 00322 00323 00324 int os_strcasecmp(const char *s1, const char *s2) 00325 { 00326 /* 00327 * Ignoring case is not required for main functionality, so just use 00328 * the case sensitive version of the function. 00329 */ 00330 return os_strcmp(s1, s2); 00331 } 00332 00333 00334 int os_strncasecmp(const char *s1, const char *s2, size_t n) 00335 { 00336 /* 00337 * Ignoring case is not required for main functionality, so just use 00338 * the case sensitive version of the function. 00339 */ 00340 return os_strncmp(s1, s2, n); 00341 } 00342 00343 00344 char * os_strchr(const char *s, int c) 00345 { 00346 while (*s) { 00347 if (*s == c) 00348 return (char *) s; 00349 s++; 00350 } 00351 return NULL; 00352 } 00353 00354 00355 char * os_strrchr(const char *s, int c) 00356 { 00357 const char *p = s; 00358 while (*p) 00359 p++; 00360 p--; 00361 while (p >= s) { 00362 if (*p == c) 00363 return (char *) p; 00364 p--; 00365 } 00366 return NULL; 00367 } 00368 00369 00370 int os_strcmp(const char *s1, const char *s2) 00371 { 00372 while (*s1 == *s2) { 00373 if (*s1 == '\0') 00374 break; 00375 s1++; 00376 s2++; 00377 } 00378 00379 return *s1 - *s2; 00380 } 00381 00382 00383 int os_strncmp(const char *s1, const char *s2, size_t n) 00384 { 00385 if (n == 0) 00386 return 0; 00387 00388 while (*s1 == *s2) { 00389 if (*s1 == '\0') 00390 break; 00391 s1++; 00392 s2++; 00393 n--; 00394 if (n == 0) 00395 return 0; 00396 } 00397 00398 return *s1 - *s2; 00399 } 00400 00401 00402 char * os_strncpy(char *dest, const char *src, size_t n) 00403 { 00404 char *d = dest; 00405 00406 while (n--) { 00407 *d = *src; 00408 if (*src == '\0') 00409 break; 00410 d++; 00411 src++; 00412 } 00413 00414 return dest; 00415 } 00416 00417 00418 size_t os_strlcpy(char *dest, const char *src, size_t siz) 00419 { 00420 const char *s = src; 00421 size_t left = siz; 00422 00423 if (left) { 00424 /* Copy string up to the maximum size of the dest buffer */ 00425 while (--left != 0) { 00426 if ((*dest++ = *s++) == '\0') 00427 break; 00428 } 00429 } 00430 00431 if (left == 0) { 00432 /* Not enough room for the string; force NUL-termination */ 00433 if (siz != 0) 00434 *dest = '\0'; 00435 while (*s++) 00436 ; /* determine total src string length */ 00437 } 00438 00439 return s - src - 1; 00440 } 00441 00442 00443 char * os_strstr(const char *haystack, const char *needle) 00444 { 00445 size_t len = os_strlen(needle); 00446 while (*haystack) { 00447 if (os_strncmp(haystack, needle, len) == 0) 00448 return (char *) haystack; 00449 haystack++; 00450 } 00451 00452 return NULL; 00453 } 00454 00455 00456 int os_snprintf(char *str, size_t size, const char *format, ...) 00457 { 00458 va_list ap; 00459 int ret; 00460 00461 /* See http://www.ijs.si/software/snprintf/ for portable 00462 * implementation of snprintf. 00463 */ 00464 00465 va_start(ap, format); 00466 ret = vsnprintf(str, size, format, ap); 00467 va_end(ap); 00468 if (size > 0) 00469 str[size - 1] = '\0'; 00470 return ret; 00471 }