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 defined(__OpenBSD__) || defined(__DragonFly__) 232 unsetenv(name); 233 return 0; 234 #else 235 return unsetenv(name); 236 #endif 237 } 238 239 240 char * os_readfile(const char *name, size_t *len) 241 { 242 FILE *f; 243 char *buf; 244 245 f = fopen(name, "rb"); 246 if (f == NULL) 247 return NULL; 248 249 fseek(f, 0, SEEK_END); 250 *len = ftell(f); 251 fseek(f, 0, SEEK_SET); 252 253 buf = malloc(*len); 254 if (buf == NULL) { 255 fclose(f); 256 return NULL; 257 } 258 259 if (fread(buf, 1, *len, f) != *len) { 260 fclose(f); 261 free(buf); 262 return NULL; 263 } 264 265 fclose(f); 266 267 return buf; 268 } 269 270 271 void * os_zalloc(size_t size) 272 { 273 return calloc(1, size); 274 } 275 276 277 size_t os_strlcpy(char *dest, const char *src, size_t siz) 278 { 279 const char *s = src; 280 size_t left = siz; 281 282 if (left) { 283 /* Copy string up to the maximum size of the dest buffer */ 284 while (--left != 0) { 285 if ((*dest++ = *s++) == '\0') 286 break; 287 } 288 } 289 290 if (left == 0) { 291 /* Not enough room for the string; force NUL-termination */ 292 if (siz != 0) 293 *dest = '\0'; 294 while (*s++) 295 ; /* determine total src string length */ 296 } 297 298 return s - src - 1; 299 } 300