1#include <fcntl.h>
2#include <signal.h>
3#include <time.h>
4#include <sys/klog.h>
5#include <stdarg.h>
6#include <sys/wait.h>
7#include <dirent.h>
8//#include <wlutils.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <ctype.h>
13#include <errno.h>
14#include <unistd.h>
15#include <limits.h>
16#include <sys/types.h>
17#include <sys/stat.h>
18#include <sys/socket.h>
19#include <netinet/in.h>
20#include <arpa/inet.h>
21#include <httpd.h>
22
23#define nvram_match(name, match) ({ \
24	const char *value = nvram_get(name); \
25	(value && !strcmp(value, match)); \
26})
27
28#define FW_CREATE	0
29#define FW_APPEND	1
30#define FW_NEWLINE	2
31
32#define _dprintf(args...)	do { } while(0)
33
34
35/*
36typedef union {
37	int i;
38	long l;
39	const char *s;
40} nvset_varg_t;
41
42
43typedef struct {
44	const char *name;
45	enum {
46		VT_LENGTH,		// check length of string
47		VT_RANGE,		// expect an integer, check range
48	} vtype;
49	nvset_varg_t va;
50	nvset_varg_t vb;
51} nvset_t;
52
53
54#define V_01				VT_RANGE,	{ .l = 0 },		{ .l = 1 }
55#define V_LENGTH(min, max)	VT_LENGTH,	{ .i = min },	{ .i = max }
56#define V_RANGE(min, max)	VT_RANGE,	{ .l = min },	{ .l = max }
57#define _dprintf(args...)	do { } while(0)
58
59static const nvset_t nvset_list[] = {
60// admin-bwm
61	{ "rstats_enable",		V_01				},
62	{ "rstats_path",		V_LENGTH(0, 48)		},
63	{ "rstats_stime",		V_RANGE(1, 168)		},
64	{ "rstats_offset",		V_RANGE(1, 31)		},
65	{ "rstats_exclude",		V_LENGTH(0, 64)		},
66	{ "rstats_sshut",		V_01				},
67	{ "rstats_bak",			V_01				},
68	{ NULL }
69};
70*/
71
72FILE *connfp;
73
74// for backup =========================================================
75
76int web_eat(int max)
77{
78	char buf[512];
79	int n;
80	while (max > 0) {
81		 if ((n = web_read(buf, (max < sizeof(buf)) ? max : sizeof(buf))) <= 0) return 0;
82		 max -= n;
83	}
84	return 1;
85}
86
87int f_write(const char *path, const void *buffer, int len, unsigned flags, unsigned cmode)
88{
89	static const char nl = '\n';
90	int f;
91	int r = -1;
92	mode_t m;
93
94	m = umask(0);
95	if (cmode == 0) cmode = 0666;
96	if ((f = open(path, (flags & FW_APPEND) ? (O_WRONLY|O_CREAT|O_APPEND) : (O_WRONLY|O_CREAT|O_TRUNC), cmode)) >= 0) {
97		if ((buffer == NULL) || ((r = write(f, buffer, len)) == len)) {
98			if (flags & FW_NEWLINE) {
99				if (write(f, &nl, 1) == 1) ++r;
100			}
101		}
102		close(f);
103	}
104	umask(m);
105	return r;
106}
107
108const char *resmsg_get(void)
109{
110	return get_cgi("resmsg");
111}
112
113void resmsg_set(const char *msg)
114{
115	set_cgi("resmsg", strdup(msg));	// m ok
116}
117
118// for bandwidth =========================================================
119
120int f_exists(const char *path)	// note: anything but a directory
121{
122	struct stat st;
123	return (stat(path, &st) == 0) && (!S_ISDIR(st.st_mode));
124}
125
126static int _f_wait_exists(const char *name, int max, int invert)
127{
128	while (max-- > 0) {
129		if (f_exists(name) ^ invert) return 1;
130		sleep(1);
131	}
132	return 0;
133}
134
135int f_wait_exists(const char *name, int max)
136{
137	return _f_wait_exists(name, max, 0);
138}
139
140int f_read(const char *path, void *buffer, int max)
141{
142	int f;
143	int n;
144
145	if ((f = open(path, O_RDONLY)) < 0) return -1;
146	n = read(f, buffer, max);
147	close(f);
148	return n;
149}
150
151int f_read_string(const char *path, char *buffer, int max)
152{
153	if (max <= 0) return -1;
154	int n = f_read(path, buffer, max - 1);
155	buffer[(n > 0) ? n : 0] = 0;
156	return n;
157}
158
159 size_t strlcpy(char *d, const char *s, size_t bufsize)
160{
161	size_t len = strlen(s);
162	size_t ret = len;
163	if (bufsize <= 0) return 0;
164	if (len >= bufsize) len = bufsize-1;
165	memcpy(d, s, len);
166	d[len] = 0;
167	return ret;
168}
169
170char *psname(int pid, char *buffer, int maxlen)
171{
172	char buf[512];
173	char path[64];
174	char *p;
175
176	if (maxlen <= 0) return NULL;
177	*buffer = 0;
178	sprintf(path, "/proc/%d/stat", pid);
179	if ((f_read_string(path, buf, sizeof(buf)) > 4) && ((p = strrchr(buf, ')')) != NULL)) {
180		*p = 0;
181		if (((p = strchr(buf, '(')) != NULL) && (atoi(buf) == pid)) {
182			strlcpy(buffer, p + 1, maxlen);
183		}
184	}
185	return buffer;
186}
187
188static int _pidof(const char *name, pid_t** pids)
189{
190	const char *p;
191	char *e;
192	DIR *dir;
193	struct dirent *de;
194	pid_t i;
195	int count;
196	char buf[256];
197
198	count = 0;
199	*pids = NULL;
200	if ((p = strchr(name, '/')) != NULL) name = p + 1;
201	if ((dir = opendir("/proc")) != NULL) {
202		while ((de = readdir(dir)) != NULL) {
203			i = strtol(de->d_name, &e, 10);
204			if (*e != 0) continue;
205			if (strcmp(name, psname(i, buf, sizeof(buf))) == 0) {
206				if ((*pids = realloc(*pids, sizeof(pid_t) * (count + 1))) == NULL) {
207					return -1;
208				}
209				(*pids)[count++] = i;
210			}
211		}
212	}
213	closedir(dir);
214	return count;
215}
216
217int killall(const char *name, int sig)
218{
219	pid_t *pids;
220	int i;
221	int r;
222
223	if ((i = _pidof(name, &pids)) > 0) {
224		r = 0;
225		do {
226			r |= kill(pids[--i], sig);
227		} while (i > 0);
228		free(pids);
229		return r;
230	}
231	return -2;
232}
233
234void do_f(char *path, webs_t wp)
235{
236	FILE *f;
237	char buf[1024];
238	int ret;
239
240//printf("do_f: %s\n", path);
241	if ((f = fopen(path, "r")) != NULL) {
242//		while ((nr = fread(buf, 1, sizeof(buf), f)) > 0){
243		while (fgets(buf, sizeof(buf), f) != NULL){
244//printf("%s\n", buf);
245			ret += websWrite(wp, buf);
246		}
247		fclose(f);
248	}
249	return;
250}
251