1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/*
2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpa_supplicant/hostapd / OS specific functions for UNIX/POSIX systems
3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *
5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program is free software; you can redistribute it and/or modify
6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * it under the terms of the GNU General Public License version 2 as
7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * published by the Free Software Foundation.
8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *
9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD
10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * license.
11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *
12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * See README and COPYING for more details.
13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */
14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "includes.h"
16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "os.h"
18526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
192c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt#ifdef ANDROID
202c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt#include <linux/capability.h>
212c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt#include <linux/prctl.h>
222c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt#include <private/android_filesystem_config.h>
232c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt#endif
242c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt
25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid os_sleep(os_time_t sec, os_time_t usec)
26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (sec)
28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		sleep(sec);
29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (usec)
30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		usleep(usec);
31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint os_get_time(struct os_time *t)
35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	int res;
37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	struct timeval tv;
38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	res = gettimeofday(&tv, NULL);
39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	t->sec = tv.tv_sec;
40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	t->usec = tv.tv_usec;
41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return res;
42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint os_mktime(int year, int month, int day, int hour, int min, int sec,
46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	      os_time_t *t)
47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	struct tm tm, *tm1;
49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	time_t t_local, t1, t2;
50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	os_time_t tz_offset;
51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ||
53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	    hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 ||
54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	    sec > 60)
55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return -1;
56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	memset(&tm, 0, sizeof(tm));
58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	tm.tm_year = year - 1900;
59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	tm.tm_mon = month - 1;
60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	tm.tm_mday = day;
61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	tm.tm_hour = hour;
62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	tm.tm_min = min;
63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	tm.tm_sec = sec;
64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	t_local = mktime(&tm);
66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* figure out offset to UTC */
68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	tm1 = localtime(&t_local);
69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (tm1) {
70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		t1 = mktime(tm1);
71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		tm1 = gmtime(&t_local);
72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (tm1) {
73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			t2 = mktime(tm1);
74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			tz_offset = t2 - t1;
75526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		} else
76526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			tz_offset = 0;
77526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	} else
78526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		tz_offset = 0;
79526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
80526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	*t = (os_time_t) t_local - tz_offset;
81526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return 0;
82526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
83526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
84526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
85526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef __APPLE__
86526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <fcntl.h>
87526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int os_daemon(int nochdir, int noclose)
88526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
89526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	int devnull;
90526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
91526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (chdir("/") < 0)
92526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return -1;
93526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
94526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	devnull = open("/dev/null", O_RDWR);
95526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (devnull < 0)
96526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return -1;
97526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
98526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (dup2(devnull, STDIN_FILENO) < 0) {
99526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		close(devnull);
100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return -1;
101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (dup2(devnull, STDOUT_FILENO) < 0) {
104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		close(devnull);
105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return -1;
106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (dup2(devnull, STDERR_FILENO) < 0) {
109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		close(devnull);
110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return -1;
111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return 0;
114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else /* __APPLE__ */
116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define os_daemon daemon
117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* __APPLE__ */
118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint os_daemonize(const char *pid_file)
121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef __uClinux__
123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return -1;
124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else /* __uClinux__ */
125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (os_daemon(0, 0)) {
126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		perror("daemon");
127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return -1;
128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (pid_file) {
131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		FILE *f = fopen(pid_file, "w");
132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (f) {
133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			fprintf(f, "%u\n", getpid());
134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			fclose(f);
135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return -0;
139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* __uClinux__ */
140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid os_daemonize_terminate(const char *pid_file)
144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (pid_file)
146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		unlink(pid_file);
147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint os_get_random(unsigned char *buf, size_t len)
151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	FILE *f;
153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t rc;
154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	f = fopen("/dev/urandom", "rb");
156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (f == NULL) {
157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		printf("Could not open /dev/urandom.\n");
158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return -1;
159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	rc = fread(buf, 1, len, f);
162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	fclose(f);
163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return rc != len ? -1 : 0;
165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtunsigned long os_random(void)
169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return random();
171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtchar * os_rel2abs_path(const char *rel_path)
175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	char *buf = NULL, *cwd, *ret;
177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t len = 128, cwd_len, rel_len, ret_len;
178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	int last_errno;
179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (rel_path[0] == '/')
181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return strdup(rel_path);
182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	for (;;) {
184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		buf = malloc(len);
185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (buf == NULL)
186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			return NULL;
187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		cwd = getcwd(buf, len);
188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (cwd == NULL) {
189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			last_errno = errno;
190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			free(buf);
191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			if (last_errno != ERANGE)
192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				return NULL;
193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			len *= 2;
194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			if (len > 2000)
195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				return NULL;
196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		} else {
197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			buf[len - 1] = '\0';
198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			break;
199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	cwd_len = strlen(cwd);
203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	rel_len = strlen(rel_path);
204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	ret_len = cwd_len + 1 + rel_len + 1;
205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	ret = malloc(ret_len);
206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (ret) {
207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		memcpy(ret, cwd, cwd_len);
208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		ret[cwd_len] = '/';
209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		memcpy(ret + cwd_len + 1, rel_path, rel_len);
210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		ret[ret_len - 1] = '\0';
211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	free(buf);
213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return ret;
214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint os_program_init(void)
218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
2192c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt#ifdef ANDROID
2202c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt	/* We ignore errors here since errors are normal if we
2212c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt	 * are already running as non-root.
2222c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt	 */
2232c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt	gid_t groups[] = { AID_INET, AID_WIFI, AID_KEYSTORE };
2242c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt	setgroups(sizeof(groups)/sizeof(groups[0]), groups);
2252c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt
2262c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt	prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
2272c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt
2282c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt	setgid(AID_WIFI);
2292c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt	setuid(AID_WIFI);
2302c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt
2312c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt	struct __user_cap_header_struct header;
2322c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt	struct __user_cap_data_struct cap;
2332c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt	header.version = _LINUX_CAPABILITY_VERSION;
2342c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt	header.pid = 0;
2352c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt	cap.effective = cap.permitted =
2362c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt		(1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
2372c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt	cap.inheritable = 0;
2382c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt	capset(&header, &cap);
2392c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt#endif
2402c23b7348ac966c08728d4908cf89d673d91bb76Dmitry Shmidt
241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return 0;
242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid os_program_deinit(void)
246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint os_setenv(const char *name, const char *value, int overwrite)
251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return setenv(name, value, overwrite);
253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint os_unsetenv(const char *name)
257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
258dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) || \
259dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt    defined(__OpenBSD__)
260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	unsetenv(name);
261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return 0;
262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else
263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return unsetenv(name);
264526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif
265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtchar * os_readfile(const char *name, size_t *len)
269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	FILE *f;
271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	char *buf;
272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	f = fopen(name, "rb");
274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (f == NULL)
275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return NULL;
276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	fseek(f, 0, SEEK_END);
278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	*len = ftell(f);
279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	fseek(f, 0, SEEK_SET);
280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	buf = malloc(*len);
282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (buf == NULL) {
283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		fclose(f);
284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return NULL;
285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (fread(buf, 1, *len, f) != *len) {
288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		fclose(f);
289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		free(buf);
290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return NULL;
291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	fclose(f);
294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return buf;
296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid * os_zalloc(size_t size)
300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return calloc(1, size);
302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtsize_t os_strlcpy(char *dest, const char *src, size_t siz)
306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	const char *s = src;
308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t left = siz;
309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (left) {
311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		/* Copy string up to the maximum size of the dest buffer */
312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		while (--left != 0) {
313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			if ((*dest++ = *s++) == '\0')
314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				break;
315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (left == 0) {
319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		/* Not enough room for the string; force NUL-termination */
320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (siz != 0)
321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			*dest = '\0';
322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		while (*s++)
323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			; /* determine total src string length */
324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return s - src - 1;
327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
328