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 * 5*3ff40c12SJohn Marino * This software may be distributed under the terms of the BSD license. 6*3ff40c12SJohn 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" 206d49e1aeSJan Lentfer 216d49e1aeSJan Lentfer #undef OS_REJECT_C_LIB_FUNCTIONS 226d49e1aeSJan Lentfer #include "os.h" 236d49e1aeSJan Lentfer 246d49e1aeSJan Lentfer void os_sleep(os_time_t sec, os_time_t usec) 256d49e1aeSJan Lentfer { 266d49e1aeSJan Lentfer if (sec) 276d49e1aeSJan Lentfer sleep(sec); 286d49e1aeSJan Lentfer if (usec) 296d49e1aeSJan Lentfer usleep(usec); 306d49e1aeSJan Lentfer } 316d49e1aeSJan Lentfer 326d49e1aeSJan Lentfer 336d49e1aeSJan Lentfer int os_get_time(struct os_time *t) 346d49e1aeSJan Lentfer { 356d49e1aeSJan Lentfer int res; 366d49e1aeSJan Lentfer struct timeval tv; 376d49e1aeSJan Lentfer res = gettimeofday(&tv, NULL); 386d49e1aeSJan Lentfer t->sec = tv.tv_sec; 396d49e1aeSJan Lentfer t->usec = tv.tv_usec; 406d49e1aeSJan Lentfer return res; 416d49e1aeSJan Lentfer } 426d49e1aeSJan Lentfer 436d49e1aeSJan Lentfer 44*3ff40c12SJohn Marino int os_get_reltime(struct os_reltime *t) 45*3ff40c12SJohn Marino { 46*3ff40c12SJohn Marino int res; 47*3ff40c12SJohn Marino struct timeval tv; 48*3ff40c12SJohn Marino res = gettimeofday(&tv, NULL); 49*3ff40c12SJohn Marino t->sec = tv.tv_sec; 50*3ff40c12SJohn Marino t->usec = tv.tv_usec; 51*3ff40c12SJohn Marino return res; 52*3ff40c12SJohn Marino } 53*3ff40c12SJohn Marino 54*3ff40c12SJohn Marino 556d49e1aeSJan Lentfer int os_mktime(int year, int month, int day, int hour, int min, int sec, 566d49e1aeSJan Lentfer os_time_t *t) 576d49e1aeSJan Lentfer { 586d49e1aeSJan Lentfer struct tm tm; 596d49e1aeSJan Lentfer 606d49e1aeSJan Lentfer if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 || 616d49e1aeSJan Lentfer hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 || 626d49e1aeSJan Lentfer sec > 60) 636d49e1aeSJan Lentfer return -1; 646d49e1aeSJan Lentfer 656d49e1aeSJan Lentfer os_memset(&tm, 0, sizeof(tm)); 666d49e1aeSJan Lentfer tm.tm_year = year - 1900; 676d49e1aeSJan Lentfer tm.tm_mon = month - 1; 686d49e1aeSJan Lentfer tm.tm_mday = day; 696d49e1aeSJan Lentfer tm.tm_hour = hour; 706d49e1aeSJan Lentfer tm.tm_min = min; 716d49e1aeSJan Lentfer tm.tm_sec = sec; 726d49e1aeSJan Lentfer 736d49e1aeSJan Lentfer *t = (os_time_t) mktime(&tm); 746d49e1aeSJan Lentfer return 0; 756d49e1aeSJan Lentfer } 766d49e1aeSJan Lentfer 776d49e1aeSJan Lentfer 78*3ff40c12SJohn Marino int os_gmtime(os_time_t t, struct os_tm *tm) 79*3ff40c12SJohn Marino { 80*3ff40c12SJohn Marino struct tm *tm2; 81*3ff40c12SJohn Marino time_t t2 = t; 82*3ff40c12SJohn Marino 83*3ff40c12SJohn Marino tm2 = gmtime(&t2); 84*3ff40c12SJohn Marino if (tm2 == NULL) 85*3ff40c12SJohn Marino return -1; 86*3ff40c12SJohn Marino tm->sec = tm2->tm_sec; 87*3ff40c12SJohn Marino tm->min = tm2->tm_min; 88*3ff40c12SJohn Marino tm->hour = tm2->tm_hour; 89*3ff40c12SJohn Marino tm->day = tm2->tm_mday; 90*3ff40c12SJohn Marino tm->month = tm2->tm_mon + 1; 91*3ff40c12SJohn Marino tm->year = tm2->tm_year + 1900; 92*3ff40c12SJohn Marino return 0; 93*3ff40c12SJohn Marino } 94*3ff40c12SJohn Marino 95*3ff40c12SJohn Marino 966d49e1aeSJan Lentfer int os_daemonize(const char *pid_file) 976d49e1aeSJan Lentfer { 986d49e1aeSJan Lentfer if (daemon(0, 0)) { 996d49e1aeSJan Lentfer perror("daemon"); 1006d49e1aeSJan Lentfer return -1; 1016d49e1aeSJan Lentfer } 1026d49e1aeSJan Lentfer 1036d49e1aeSJan Lentfer if (pid_file) { 1046d49e1aeSJan Lentfer FILE *f = fopen(pid_file, "w"); 1056d49e1aeSJan Lentfer if (f) { 1066d49e1aeSJan Lentfer fprintf(f, "%u\n", getpid()); 1076d49e1aeSJan Lentfer fclose(f); 1086d49e1aeSJan Lentfer } 1096d49e1aeSJan Lentfer } 1106d49e1aeSJan Lentfer 1116d49e1aeSJan Lentfer return -0; 1126d49e1aeSJan Lentfer } 1136d49e1aeSJan Lentfer 1146d49e1aeSJan Lentfer 1156d49e1aeSJan Lentfer void os_daemonize_terminate(const char *pid_file) 1166d49e1aeSJan Lentfer { 1176d49e1aeSJan Lentfer if (pid_file) 1186d49e1aeSJan Lentfer unlink(pid_file); 1196d49e1aeSJan Lentfer } 1206d49e1aeSJan Lentfer 1216d49e1aeSJan Lentfer 1226d49e1aeSJan Lentfer int os_get_random(unsigned char *buf, size_t len) 1236d49e1aeSJan Lentfer { 1246d49e1aeSJan Lentfer FILE *f; 1256d49e1aeSJan Lentfer size_t rc; 1266d49e1aeSJan Lentfer 1276d49e1aeSJan Lentfer f = fopen("/dev/urandom", "rb"); 1286d49e1aeSJan Lentfer if (f == NULL) { 1296d49e1aeSJan Lentfer printf("Could not open /dev/urandom.\n"); 1306d49e1aeSJan Lentfer return -1; 1316d49e1aeSJan Lentfer } 1326d49e1aeSJan Lentfer 1336d49e1aeSJan Lentfer rc = fread(buf, 1, len, f); 1346d49e1aeSJan Lentfer fclose(f); 1356d49e1aeSJan Lentfer 1366d49e1aeSJan Lentfer return rc != len ? -1 : 0; 1376d49e1aeSJan Lentfer } 1386d49e1aeSJan Lentfer 1396d49e1aeSJan Lentfer 1406d49e1aeSJan Lentfer unsigned long os_random(void) 1416d49e1aeSJan Lentfer { 1426d49e1aeSJan Lentfer return random(); 1436d49e1aeSJan Lentfer } 1446d49e1aeSJan Lentfer 1456d49e1aeSJan Lentfer 1466d49e1aeSJan Lentfer char * os_rel2abs_path(const char *rel_path) 1476d49e1aeSJan Lentfer { 1486d49e1aeSJan Lentfer char *buf = NULL, *cwd, *ret; 1496d49e1aeSJan Lentfer size_t len = 128, cwd_len, rel_len, ret_len; 1506d49e1aeSJan Lentfer 1516d49e1aeSJan Lentfer if (rel_path[0] == '/') 1526d49e1aeSJan Lentfer return os_strdup(rel_path); 1536d49e1aeSJan Lentfer 1546d49e1aeSJan Lentfer for (;;) { 1556d49e1aeSJan Lentfer buf = os_malloc(len); 1566d49e1aeSJan Lentfer if (buf == NULL) 1576d49e1aeSJan Lentfer return NULL; 1586d49e1aeSJan Lentfer cwd = getcwd(buf, len); 1596d49e1aeSJan Lentfer if (cwd == NULL) { 1606d49e1aeSJan Lentfer os_free(buf); 1616d49e1aeSJan Lentfer if (errno != ERANGE) { 1626d49e1aeSJan Lentfer return NULL; 1636d49e1aeSJan Lentfer } 1646d49e1aeSJan Lentfer len *= 2; 1656d49e1aeSJan Lentfer } else { 1666d49e1aeSJan Lentfer break; 1676d49e1aeSJan Lentfer } 1686d49e1aeSJan Lentfer } 1696d49e1aeSJan Lentfer 1706d49e1aeSJan Lentfer cwd_len = strlen(cwd); 1716d49e1aeSJan Lentfer rel_len = strlen(rel_path); 1726d49e1aeSJan Lentfer ret_len = cwd_len + 1 + rel_len + 1; 1736d49e1aeSJan Lentfer ret = os_malloc(ret_len); 1746d49e1aeSJan Lentfer if (ret) { 1756d49e1aeSJan Lentfer os_memcpy(ret, cwd, cwd_len); 1766d49e1aeSJan Lentfer ret[cwd_len] = '/'; 1776d49e1aeSJan Lentfer os_memcpy(ret + cwd_len + 1, rel_path, rel_len); 1786d49e1aeSJan Lentfer ret[ret_len - 1] = '\0'; 1796d49e1aeSJan Lentfer } 1806d49e1aeSJan Lentfer os_free(buf); 1816d49e1aeSJan Lentfer return ret; 1826d49e1aeSJan Lentfer } 1836d49e1aeSJan Lentfer 1846d49e1aeSJan Lentfer 1856d49e1aeSJan Lentfer int os_program_init(void) 1866d49e1aeSJan Lentfer { 1876d49e1aeSJan Lentfer return 0; 1886d49e1aeSJan Lentfer } 1896d49e1aeSJan Lentfer 1906d49e1aeSJan Lentfer 1916d49e1aeSJan Lentfer void os_program_deinit(void) 1926d49e1aeSJan Lentfer { 1936d49e1aeSJan Lentfer } 1946d49e1aeSJan Lentfer 1956d49e1aeSJan Lentfer 1966d49e1aeSJan Lentfer int os_setenv(const char *name, const char *value, int overwrite) 1976d49e1aeSJan Lentfer { 1986d49e1aeSJan Lentfer return setenv(name, value, overwrite); 1996d49e1aeSJan Lentfer } 2006d49e1aeSJan Lentfer 2016d49e1aeSJan Lentfer 2026d49e1aeSJan Lentfer int os_unsetenv(const char *name) 2036d49e1aeSJan Lentfer { 2046d49e1aeSJan Lentfer #if defined(__FreeBSD__) || defined(__NetBSD__) 2056d49e1aeSJan Lentfer unsetenv(name); 2066d49e1aeSJan Lentfer return 0; 2076d49e1aeSJan Lentfer #else 2086d49e1aeSJan Lentfer return unsetenv(name); 2096d49e1aeSJan Lentfer #endif 2106d49e1aeSJan Lentfer } 2116d49e1aeSJan Lentfer 2126d49e1aeSJan Lentfer 2136d49e1aeSJan Lentfer char * os_readfile(const char *name, size_t *len) 2146d49e1aeSJan Lentfer { 2156d49e1aeSJan Lentfer FILE *f; 2166d49e1aeSJan Lentfer char *buf; 2176d49e1aeSJan Lentfer 2186d49e1aeSJan Lentfer f = fopen(name, "rb"); 2196d49e1aeSJan Lentfer if (f == NULL) 2206d49e1aeSJan Lentfer return NULL; 2216d49e1aeSJan Lentfer 2226d49e1aeSJan Lentfer fseek(f, 0, SEEK_END); 2236d49e1aeSJan Lentfer *len = ftell(f); 2246d49e1aeSJan Lentfer fseek(f, 0, SEEK_SET); 2256d49e1aeSJan Lentfer 2266d49e1aeSJan Lentfer buf = os_malloc(*len); 2276d49e1aeSJan Lentfer if (buf == NULL) { 2286d49e1aeSJan Lentfer fclose(f); 2296d49e1aeSJan Lentfer return NULL; 2306d49e1aeSJan Lentfer } 2316d49e1aeSJan Lentfer 232*3ff40c12SJohn Marino if (fread(buf, 1, *len, f) != *len) { 233*3ff40c12SJohn Marino fclose(f); 234*3ff40c12SJohn Marino os_free(buf); 235*3ff40c12SJohn Marino return NULL; 236*3ff40c12SJohn Marino } 237*3ff40c12SJohn Marino 2386d49e1aeSJan Lentfer fclose(f); 2396d49e1aeSJan Lentfer 2406d49e1aeSJan Lentfer return buf; 2416d49e1aeSJan Lentfer } 2426d49e1aeSJan Lentfer 2436d49e1aeSJan Lentfer 2446d49e1aeSJan Lentfer void * os_zalloc(size_t size) 2456d49e1aeSJan Lentfer { 2466d49e1aeSJan Lentfer void *n = os_malloc(size); 2476d49e1aeSJan Lentfer if (n) 2486d49e1aeSJan Lentfer os_memset(n, 0, size); 2496d49e1aeSJan Lentfer return n; 2506d49e1aeSJan Lentfer } 2516d49e1aeSJan Lentfer 2526d49e1aeSJan Lentfer 2536d49e1aeSJan Lentfer void * os_malloc(size_t size) 2546d49e1aeSJan Lentfer { 2556d49e1aeSJan Lentfer return malloc(size); 2566d49e1aeSJan Lentfer } 2576d49e1aeSJan Lentfer 2586d49e1aeSJan Lentfer 2596d49e1aeSJan Lentfer void * os_realloc(void *ptr, size_t size) 2606d49e1aeSJan Lentfer { 2616d49e1aeSJan Lentfer return realloc(ptr, size); 2626d49e1aeSJan Lentfer } 2636d49e1aeSJan Lentfer 2646d49e1aeSJan Lentfer 2656d49e1aeSJan Lentfer void os_free(void *ptr) 2666d49e1aeSJan Lentfer { 2676d49e1aeSJan Lentfer free(ptr); 2686d49e1aeSJan Lentfer } 2696d49e1aeSJan Lentfer 2706d49e1aeSJan Lentfer 2716d49e1aeSJan Lentfer void * os_memcpy(void *dest, const void *src, size_t n) 2726d49e1aeSJan Lentfer { 2736d49e1aeSJan Lentfer char *d = dest; 2746d49e1aeSJan Lentfer const char *s = src; 2756d49e1aeSJan Lentfer while (n--) 2766d49e1aeSJan Lentfer *d++ = *s++; 2776d49e1aeSJan Lentfer return dest; 2786d49e1aeSJan Lentfer } 2796d49e1aeSJan Lentfer 2806d49e1aeSJan Lentfer 2816d49e1aeSJan Lentfer void * os_memmove(void *dest, const void *src, size_t n) 2826d49e1aeSJan Lentfer { 2836d49e1aeSJan Lentfer if (dest < src) 2846d49e1aeSJan Lentfer os_memcpy(dest, src, n); 2856d49e1aeSJan Lentfer else { 2866d49e1aeSJan Lentfer /* overlapping areas */ 2876d49e1aeSJan Lentfer char *d = (char *) dest + n; 2886d49e1aeSJan Lentfer const char *s = (const char *) src + n; 2896d49e1aeSJan Lentfer while (n--) 2906d49e1aeSJan Lentfer *--d = *--s; 2916d49e1aeSJan Lentfer } 2926d49e1aeSJan Lentfer return dest; 2936d49e1aeSJan Lentfer } 2946d49e1aeSJan Lentfer 2956d49e1aeSJan Lentfer 2966d49e1aeSJan Lentfer void * os_memset(void *s, int c, size_t n) 2976d49e1aeSJan Lentfer { 2986d49e1aeSJan Lentfer char *p = s; 2996d49e1aeSJan Lentfer while (n--) 3006d49e1aeSJan Lentfer *p++ = c; 3016d49e1aeSJan Lentfer return s; 3026d49e1aeSJan Lentfer } 3036d49e1aeSJan Lentfer 3046d49e1aeSJan Lentfer 3056d49e1aeSJan Lentfer int os_memcmp(const void *s1, const void *s2, size_t n) 3066d49e1aeSJan Lentfer { 3076d49e1aeSJan Lentfer const unsigned char *p1 = s1, *p2 = s2; 3086d49e1aeSJan Lentfer 3096d49e1aeSJan Lentfer if (n == 0) 3106d49e1aeSJan Lentfer return 0; 3116d49e1aeSJan Lentfer 3126d49e1aeSJan Lentfer while (*p1 == *p2) { 3136d49e1aeSJan Lentfer p1++; 3146d49e1aeSJan Lentfer p2++; 3156d49e1aeSJan Lentfer n--; 3166d49e1aeSJan Lentfer if (n == 0) 3176d49e1aeSJan Lentfer return 0; 3186d49e1aeSJan Lentfer } 3196d49e1aeSJan Lentfer 3206d49e1aeSJan Lentfer return *p1 - *p2; 3216d49e1aeSJan Lentfer } 3226d49e1aeSJan Lentfer 3236d49e1aeSJan Lentfer 3246d49e1aeSJan Lentfer char * os_strdup(const char *s) 3256d49e1aeSJan Lentfer { 3266d49e1aeSJan Lentfer char *res; 3276d49e1aeSJan Lentfer size_t len; 3286d49e1aeSJan Lentfer if (s == NULL) 3296d49e1aeSJan Lentfer return NULL; 3306d49e1aeSJan Lentfer len = os_strlen(s); 3316d49e1aeSJan Lentfer res = os_malloc(len + 1); 3326d49e1aeSJan Lentfer if (res) 3336d49e1aeSJan Lentfer os_memcpy(res, s, len + 1); 3346d49e1aeSJan Lentfer return res; 3356d49e1aeSJan Lentfer } 3366d49e1aeSJan Lentfer 3376d49e1aeSJan Lentfer 3386d49e1aeSJan Lentfer size_t os_strlen(const char *s) 3396d49e1aeSJan Lentfer { 3406d49e1aeSJan Lentfer const char *p = s; 3416d49e1aeSJan Lentfer while (*p) 3426d49e1aeSJan Lentfer p++; 3436d49e1aeSJan Lentfer return p - s; 3446d49e1aeSJan Lentfer } 3456d49e1aeSJan Lentfer 3466d49e1aeSJan Lentfer 3476d49e1aeSJan Lentfer int os_strcasecmp(const char *s1, const char *s2) 3486d49e1aeSJan Lentfer { 3496d49e1aeSJan Lentfer /* 3506d49e1aeSJan Lentfer * Ignoring case is not required for main functionality, so just use 3516d49e1aeSJan Lentfer * the case sensitive version of the function. 3526d49e1aeSJan Lentfer */ 3536d49e1aeSJan Lentfer return os_strcmp(s1, s2); 3546d49e1aeSJan Lentfer } 3556d49e1aeSJan Lentfer 3566d49e1aeSJan Lentfer 3576d49e1aeSJan Lentfer int os_strncasecmp(const char *s1, const char *s2, size_t n) 3586d49e1aeSJan Lentfer { 3596d49e1aeSJan Lentfer /* 3606d49e1aeSJan Lentfer * Ignoring case is not required for main functionality, so just use 3616d49e1aeSJan Lentfer * the case sensitive version of the function. 3626d49e1aeSJan Lentfer */ 3636d49e1aeSJan Lentfer return os_strncmp(s1, s2, n); 3646d49e1aeSJan Lentfer } 3656d49e1aeSJan Lentfer 3666d49e1aeSJan Lentfer 3676d49e1aeSJan Lentfer char * os_strchr(const char *s, int c) 3686d49e1aeSJan Lentfer { 3696d49e1aeSJan Lentfer while (*s) { 3706d49e1aeSJan Lentfer if (*s == c) 3716d49e1aeSJan Lentfer return (char *) s; 3726d49e1aeSJan Lentfer s++; 3736d49e1aeSJan Lentfer } 3746d49e1aeSJan Lentfer return NULL; 3756d49e1aeSJan Lentfer } 3766d49e1aeSJan Lentfer 3776d49e1aeSJan Lentfer 3786d49e1aeSJan Lentfer char * os_strrchr(const char *s, int c) 3796d49e1aeSJan Lentfer { 3806d49e1aeSJan Lentfer const char *p = s; 3816d49e1aeSJan Lentfer while (*p) 3826d49e1aeSJan Lentfer p++; 3836d49e1aeSJan Lentfer p--; 3846d49e1aeSJan Lentfer while (p >= s) { 3856d49e1aeSJan Lentfer if (*p == c) 3866d49e1aeSJan Lentfer return (char *) p; 3876d49e1aeSJan Lentfer p--; 3886d49e1aeSJan Lentfer } 3896d49e1aeSJan Lentfer return NULL; 3906d49e1aeSJan Lentfer } 3916d49e1aeSJan Lentfer 3926d49e1aeSJan Lentfer 3936d49e1aeSJan Lentfer int os_strcmp(const char *s1, const char *s2) 3946d49e1aeSJan Lentfer { 3956d49e1aeSJan Lentfer while (*s1 == *s2) { 3966d49e1aeSJan Lentfer if (*s1 == '\0') 3976d49e1aeSJan Lentfer break; 3986d49e1aeSJan Lentfer s1++; 3996d49e1aeSJan Lentfer s2++; 4006d49e1aeSJan Lentfer } 4016d49e1aeSJan Lentfer 4026d49e1aeSJan Lentfer return *s1 - *s2; 4036d49e1aeSJan Lentfer } 4046d49e1aeSJan Lentfer 4056d49e1aeSJan Lentfer 4066d49e1aeSJan Lentfer int os_strncmp(const char *s1, const char *s2, size_t n) 4076d49e1aeSJan Lentfer { 4086d49e1aeSJan Lentfer if (n == 0) 4096d49e1aeSJan Lentfer return 0; 4106d49e1aeSJan Lentfer 4116d49e1aeSJan Lentfer while (*s1 == *s2) { 4126d49e1aeSJan Lentfer if (*s1 == '\0') 4136d49e1aeSJan Lentfer break; 4146d49e1aeSJan Lentfer s1++; 4156d49e1aeSJan Lentfer s2++; 4166d49e1aeSJan Lentfer n--; 4176d49e1aeSJan Lentfer if (n == 0) 4186d49e1aeSJan Lentfer return 0; 4196d49e1aeSJan Lentfer } 4206d49e1aeSJan Lentfer 4216d49e1aeSJan Lentfer return *s1 - *s2; 4226d49e1aeSJan Lentfer } 4236d49e1aeSJan Lentfer 4246d49e1aeSJan Lentfer 4256d49e1aeSJan Lentfer char * os_strncpy(char *dest, const char *src, size_t n) 4266d49e1aeSJan Lentfer { 4276d49e1aeSJan Lentfer char *d = dest; 4286d49e1aeSJan Lentfer 4296d49e1aeSJan Lentfer while (n--) { 4306d49e1aeSJan Lentfer *d = *src; 4316d49e1aeSJan Lentfer if (*src == '\0') 4326d49e1aeSJan Lentfer break; 4336d49e1aeSJan Lentfer d++; 4346d49e1aeSJan Lentfer src++; 4356d49e1aeSJan Lentfer } 4366d49e1aeSJan Lentfer 4376d49e1aeSJan Lentfer return dest; 4386d49e1aeSJan Lentfer } 4396d49e1aeSJan Lentfer 4406d49e1aeSJan Lentfer 4416d49e1aeSJan Lentfer size_t os_strlcpy(char *dest, const char *src, size_t siz) 4426d49e1aeSJan Lentfer { 4436d49e1aeSJan Lentfer const char *s = src; 4446d49e1aeSJan Lentfer size_t left = siz; 4456d49e1aeSJan Lentfer 4466d49e1aeSJan Lentfer if (left) { 4476d49e1aeSJan Lentfer /* Copy string up to the maximum size of the dest buffer */ 4486d49e1aeSJan Lentfer while (--left != 0) { 4496d49e1aeSJan Lentfer if ((*dest++ = *s++) == '\0') 4506d49e1aeSJan Lentfer break; 4516d49e1aeSJan Lentfer } 4526d49e1aeSJan Lentfer } 4536d49e1aeSJan Lentfer 4546d49e1aeSJan Lentfer if (left == 0) { 4556d49e1aeSJan Lentfer /* Not enough room for the string; force NUL-termination */ 4566d49e1aeSJan Lentfer if (siz != 0) 4576d49e1aeSJan Lentfer *dest = '\0'; 4586d49e1aeSJan Lentfer while (*s++) 4596d49e1aeSJan Lentfer ; /* determine total src string length */ 4606d49e1aeSJan Lentfer } 4616d49e1aeSJan Lentfer 4626d49e1aeSJan Lentfer return s - src - 1; 4636d49e1aeSJan Lentfer } 4646d49e1aeSJan Lentfer 4656d49e1aeSJan Lentfer 4666d49e1aeSJan Lentfer char * os_strstr(const char *haystack, const char *needle) 4676d49e1aeSJan Lentfer { 4686d49e1aeSJan Lentfer size_t len = os_strlen(needle); 4696d49e1aeSJan Lentfer while (*haystack) { 4706d49e1aeSJan Lentfer if (os_strncmp(haystack, needle, len) == 0) 4716d49e1aeSJan Lentfer return (char *) haystack; 4726d49e1aeSJan Lentfer haystack++; 4736d49e1aeSJan Lentfer } 4746d49e1aeSJan Lentfer 4756d49e1aeSJan Lentfer return NULL; 4766d49e1aeSJan Lentfer } 4776d49e1aeSJan Lentfer 4786d49e1aeSJan Lentfer 4796d49e1aeSJan Lentfer int os_snprintf(char *str, size_t size, const char *format, ...) 4806d49e1aeSJan Lentfer { 4816d49e1aeSJan Lentfer va_list ap; 4826d49e1aeSJan Lentfer int ret; 4836d49e1aeSJan Lentfer 4846d49e1aeSJan Lentfer /* See http://www.ijs.si/software/snprintf/ for portable 4856d49e1aeSJan Lentfer * implementation of snprintf. 4866d49e1aeSJan Lentfer */ 4876d49e1aeSJan Lentfer 4886d49e1aeSJan Lentfer va_start(ap, format); 4896d49e1aeSJan Lentfer ret = vsnprintf(str, size, format, ap); 4906d49e1aeSJan Lentfer va_end(ap); 4916d49e1aeSJan Lentfer if (size > 0) 4926d49e1aeSJan Lentfer str[size - 1] = '\0'; 4936d49e1aeSJan Lentfer return ret; 4946d49e1aeSJan Lentfer } 495