1 /* 2 * wpa_supplicant/hostapd / OS specific functions for UNIX/POSIX systems 3 * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15 #include "includes.h" 16 17 #include "os.h" 18 19 void os_sleep(os_time_t sec, os_time_t usec) 20 { 21 if (sec) 22 sleep(sec); 23 if (usec) 24 usleep(usec); 25 } 26 27 28 int os_get_time(struct os_time *t) 29 { 30 int res; 31 struct timeval tv; 32 res = gettimeofday(&tv, NULL); 33 t->sec = tv.tv_sec; 34 t->usec = tv.tv_usec; 35 return res; 36 } 37 38 39 int os_mktime(int year, int month, int day, int hour, int min, int sec, 40 os_time_t *t) 41 { 42 struct tm tm, *tm1; 43 time_t t_local, t1, t2; 44 os_time_t tz_offset; 45 46 if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 || 47 hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 || 48 sec > 60) 49 return -1; 50 51 memset(&tm, 0, sizeof(tm)); 52 tm.tm_year = year - 1900; 53 tm.tm_mon = month - 1; 54 tm.tm_mday = day; 55 tm.tm_hour = hour; 56 tm.tm_min = min; 57 tm.tm_sec = sec; 58 59 t_local = mktime(&tm); 60 61 /* figure out offset to UTC */ 62 tm1 = localtime(&t_local); 63 if (tm1) { 64 t1 = mktime(tm1); 65 tm1 = gmtime(&t_local); 66 if (tm1) { 67 t2 = mktime(tm1); 68 tz_offset = t2 - t1; 69 } else 70 tz_offset = 0; 71 } else 72 tz_offset = 0; 73 74 *t = (os_time_t) t_local - tz_offset; 75 return 0; 76 } 77 78 79 #ifdef __APPLE__ 80 #include <fcntl.h> 81 static int os_daemon(int nochdir, int noclose) 82 { 83 int devnull; 84 85 if (chdir("/") < 0) 86 return -1; 87 88 devnull = open("/dev/null", O_RDWR); 89 if (devnull < 0) 90 return -1; 91 92 if (dup2(devnull, STDIN_FILENO) < 0) { 93 close(devnull); 94 return -1; 95 } 96 97 if (dup2(devnull, STDOUT_FILENO) < 0) { 98 close(devnull); 99 return -1; 100 } 101 102 if (dup2(devnull, STDERR_FILENO) < 0) { 103 close(devnull); 104 return -1; 105 } 106 107 return 0; 108 } 109 #else /* __APPLE__ */ 110 #define os_daemon daemon 111 #endif /* __APPLE__ */ 112 113 114 int os_daemonize(const char *pid_file) 115 { 116 #ifdef __uClinux__ 117 return -1; 118 #else /* __uClinux__ */ 119 if (os_daemon(0, 0)) { 120 perror("daemon"); 121 return -1; 122 } 123 124 if (pid_file) { 125 FILE *f = fopen(pid_file, "w"); 126 if (f) { 127 fprintf(f, "%u\n", getpid()); 128 fclose(f); 129 } 130 } 131 132 return -0; 133 #endif /* __uClinux__ */ 134 } 135 136 137 void os_daemonize_terminate(const char *pid_file) 138 { 139 if (pid_file) 140 unlink(pid_file); 141 } 142 143 144 int os_get_random(unsigned char *buf, size_t len) 145 { 146 FILE *f; 147 size_t rc; 148 149 f = fopen("/dev/urandom", "rb"); 150 if (f == NULL) { 151 printf("Could not open /dev/urandom.\n"); 152 return -1; 153 } 154 155 rc = fread(buf, 1, len, f); 156 fclose(f); 157 158 return rc != len ? -1 : 0; 159 } 160 161 162 unsigned long os_random(void) 163 { 164 return random(); 165 } 166 167 168 char * os_rel2abs_path(const char *rel_path) 169 { 170 char *buf = NULL, *cwd, *ret; 171 size_t len = 128, cwd_len, rel_len, ret_len; 172 int last_errno; 173 174 if (rel_path[0] == '/') 175 return strdup(rel_path); 176 177 for (;;) { 178 buf = malloc(len); 179 if (buf == NULL) 180 return NULL; 181 cwd = getcwd(buf, len); 182 if (cwd == NULL) { 183 last_errno = errno; 184 free(buf); 185 if (last_errno != ERANGE) 186 return NULL; 187 len *= 2; 188 if (len > 2000) 189 return NULL; 190 } else { 191 buf[len - 1] = '\0'; 192 break; 193 } 194 } 195 196 cwd_len = strlen(cwd); 197 rel_len = strlen(rel_path); 198 ret_len = cwd_len + 1 + rel_len + 1; 199 ret = malloc(ret_len); 200 if (ret) { 201 memcpy(ret, cwd, cwd_len); 202 ret[cwd_len] = '/'; 203 memcpy(ret + cwd_len + 1, rel_path, rel_len); 204 ret[ret_len - 1] = '\0'; 205 } 206 free(buf); 207 return ret; 208 } 209 210 211 int os_program_init(void) 212 { 213 return 0; 214 } 215 216 217 void os_program_deinit(void) 218 { 219 } 220 221 222 int os_setenv(const char *name, const char *value, int overwrite) 223 { 224 return setenv(name, value, overwrite); 225 } 226 227 228 int os_unsetenv(const char *name) 229 { 230 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) 231 unsetenv(name); 232 return 0; 233 #else 234 return unsetenv(name); 235 #endif 236 } 237 238 239 char * os_readfile(const char *name, size_t *len) 240 { 241 FILE *f; 242 char *buf; 243 244 f = fopen(name, "rb"); 245 if (f == NULL) 246 return NULL; 247 248 fseek(f, 0, SEEK_END); 249 *len = ftell(f); 250 fseek(f, 0, SEEK_SET); 251 252 buf = malloc(*len); 253 if (buf == NULL) { 254 fclose(f); 255 return NULL; 256 } 257 258 if (fread(buf, 1, *len, f) != *len) { 259 fclose(f); 260 free(buf); 261 return NULL; 262 } 263 264 fclose(f); 265 266 return buf; 267 } 268 269 270 void * os_zalloc(size_t size) 271 { 272 return calloc(1, size); 273 } 274 275 276 size_t os_strlcpy(char *dest, const char *src, size_t siz) 277 { 278 const char *s = src; 279 size_t left = siz; 280 281 if (left) { 282 /* Copy string up to the maximum size of the dest buffer */ 283 while (--left != 0) { 284 if ((*dest++ = *s++) == '\0') 285 break; 286 } 287 } 288 289 if (left == 0) { 290 /* Not enough room for the string; force NUL-termination */ 291 if (siz != 0) 292 *dest = '\0'; 293 while (*s++) 294 ; /* determine total src string length */ 295 } 296 297 return s - src - 1; 298 } 299