1/*
2 * Miscellaneous services
3 *
4 * Copyright 2004, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
11 *
12 * $Id: services.c,v 1.4 2009/03/03 02:39:54 james26_jang Exp $
13 */
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <signal.h>
19#include <unistd.h>
20#include <errno.h>
21
22#include <bcmnvram.h>
23#include <netconf.h>
24#include <shutils.h>
25#include <rc.h>
26
27#ifndef ASUS_EXT
28int
29start_dhcpd(void)
30{
31	FILE *fp;
32	char name[100];
33
34	if (nvram_match("router_disable", "1") || nvram_invmatch("lan_proto", "dhcp"))
35		return 0;
36
37	dprintf("%s %s %s %s\n",
38		nvram_safe_get("lan_ifname"),
39		nvram_safe_get("dhcp_start"),
40		nvram_safe_get("dhcp_end"),
41		nvram_safe_get("lan_lease"));
42
43	/* Touch leases file */
44	if (!(fp = fopen("/tmp/udhcpd.leases", "a"))) {
45		perror("/tmp/udhcpd.leases");
46		return errno;
47	}
48	fclose(fp);
49
50	/* Write configuration file based on current information */
51	if (!(fp = fopen("/tmp/udhcpd.conf", "w"))) {
52		perror("/tmp/udhcpd.conf");
53		return errno;
54	}
55	fprintf(fp, "pidfile /var/run/udhcpd.pid\n");
56	fprintf(fp, "start %s\n", nvram_safe_get("dhcp_start"));
57	fprintf(fp, "end %s\n", nvram_safe_get("dhcp_end"));
58	fprintf(fp, "interface %s\n", nvram_safe_get("lan_ifname"));
59	fprintf(fp, "remaining yes\n");
60	fprintf(fp, "lease_file /tmp/udhcpd.leases\n");
61	fprintf(fp, "option subnet %s\n", nvram_safe_get("lan_netmask"));
62	fprintf(fp, "option router %s\n", nvram_safe_get("lan_ipaddr"));
63	fprintf(fp, "option dns %s\n", nvram_safe_get("lan_ipaddr"));
64	fprintf(fp, "option lease %s\n", nvram_safe_get("lan_lease"));
65	snprintf(name, sizeof(name), "%s_wins", nvram_safe_get("dhcp_wins"));
66	if (nvram_invmatch(name, ""))
67		fprintf(fp, "option wins %s\n", nvram_get(name));
68	snprintf(name, sizeof(name), "%s_domain", nvram_safe_get("dhcp_domain"));
69	if (nvram_invmatch(name, ""))
70		fprintf(fp, "option domain %s\n", nvram_get(name));
71	fclose(fp);
72
73	eval("udhcpd", "-i", "br0", "/tmp/udhcpd.conf");
74
75	dprintf("done\n");
76	return 0;
77}
78
79int
80stop_dhcpd(void)
81{
82	char sigusr1[] = "-XX";
83	int ret;
84
85/*
86* Process udhcpd handles two signals - SIGTERM and SIGUSR1
87*
88*  - SIGUSR1 saves all leases in /tmp/udhcpd.leases
89*  - SIGTERM causes the process to be killed
90*
91* The SIGUSR1+SIGTERM behavior is what we like so that all current client
92* leases will be honorred when the dhcpd restarts and all clients can extend
93* their leases and continue their current IP addresses. Otherwise clients
94* would get NAK'd when they try to extend/rebind their leases and they
95* would have to release current IP and to request a new one which causes
96* a no-IP gap in between.
97*/
98	sprintf(sigusr1, "-%d", SIGUSR1);
99	eval("killall", sigusr1, "udhcpd");
100	ret = eval("killall", "udhcpd");
101
102	dprintf("done\n");
103	return ret;
104}
105
106int
107start_dns(void)
108{
109	int ret;
110	FILE *fp;
111
112	if (nvram_match("router_disable", "1"))
113		return 0;
114
115	/* Create resolv.conf with empty nameserver list */
116	if (!(fp = fopen("/tmp/resolv.conf", "w"))) {
117		perror("/tmp/resolv.conf");
118		return errno;
119	}
120	fclose(fp);
121
122	/* launch dns relay */
123	ret = eval("dnsmasq", "-h",
124		   "-i", nvram_safe_get("lan_ifname"),
125		   "-r", "/tmp/resolv.conf");
126
127	dprintf("done\n");
128	return ret;
129}
130
131int
132stop_dns(void)
133{
134	int ret = eval("killall", "dnsmasq");
135
136	/* Remove resolv.conf */
137	unlink("/tmp/resolv.conf");
138
139	dprintf("done\n");
140	return ret;
141}
142#endif
143
144int
145start_httpd(void)
146{
147	int ret;
148
149	chdir("/www");
150#ifdef ASUS_EXT
151	if (nvram_invmatch("router_disable", "1"))
152		ret = eval("httpd", nvram_safe_get("wan0_ifname"));
153	else
154#endif
155	ret = eval("httpd");
156
157	chdir("/");
158
159	dprintf("done\n");
160	return ret;
161}
162
163int
164stop_httpd(void)
165{
166	int ret = eval("killall", "httpd");
167
168	dprintf("done\n");
169	return ret;
170}
171
172int
173start_upnp(void)
174{
175	char *wan_ifname;
176	int ret;
177	char var[100], prefix[] = "wanXXXXXXXXXX_";
178
179	if (!nvram_invmatch("upnp_enable", "0") || nvram_match("router_disable", "1"))
180		return 0;
181
182	ret = eval("killall", "-SIGUSR1", "upnp");
183	if (ret != 0) {
184	    snprintf(prefix, sizeof(prefix), "wan%d_", wan_primary_ifunit());
185	    wan_ifname = nvram_match(strcat_r(prefix, "proto", var), "pppoe") ?
186					nvram_safe_get(strcat_r(prefix, "pppoe_ifname", var)) :
187					nvram_safe_get(strcat_r(prefix, "ifname", var));
188	    ret = eval("upnp", "-D",
189		       "-L", nvram_safe_get("lan_ifname"),
190		       "-W", wan_ifname);
191
192	}
193	dprintf("done\n");
194	return ret;
195}
196
197int
198stop_upnp(void)
199{
200	int ret = 0;
201
202	if(nvram_invmatch("upnp_enable", "0"))
203	    ret = eval("killall", "upnp");
204
205	dprintf("done\n");
206	return ret;
207}
208
209int
210start_nas(char *type)
211{
212	char cfgfile[64];
213	char pidfile[64];
214	if (!type || !*type)
215		type = "lan";
216	snprintf(cfgfile, sizeof(cfgfile), "/tmp/nas.%s.conf", type);
217	snprintf(pidfile, sizeof(pidfile), "/tmp/nas.%s.pid", type);
218	{
219		char *argv[] = {"nas", cfgfile, pidfile, type, NULL};
220		pid_t pid;
221
222		_eval(argv, NULL, 0, &pid);
223		dprintf("done\n");
224	}
225	return 0;
226}
227
228int
229stop_nas(void)
230{
231	int ret = eval("killall", "nas");
232
233	dprintf("done\n");
234	return ret;
235}
236
237int
238start_ntpc(void)
239{
240#ifdef ASUS_EXT
241	char *ntp_argv[] = {"ntp", NULL};
242	pid_t pid;
243
244	_eval(ntp_argv, NULL, 0, &pid);
245#else
246	char *servers = nvram_safe_get("ntp_server");
247	char *ntp_argv[] = {"ntpclient", "-h", servers, "-i", "3", "-l", "-s", NULL};
248
249	if (strlen(servers)) {
250		_eval(ntp_argv, NULL, 0, NULL);
251	}
252
253	dprintf("done\n");
254#endif
255	return 0;
256}
257
258int
259stop_ntpc(void)
260{
261#ifdef ASUS_EXT
262	int ret = eval("killall", "ntp");
263#else
264	int ret = eval("killall", "ntpclient");
265#endif
266
267	dprintf("done\n");
268	return ret;
269}
270
271/* +++ Cherry Cho added in 2006/12/14. +++ */
272int start_lltd(void)
273{
274	chdir("/usr/sbin");
275	eval("lld2d", "br0");
276	chdir("/");
277
278	return 0;
279}
280
281int stop_lltd(void)/* Cherry Cho added in 2006/12/14. */
282{
283	int ret;
284
285	ret = eval("killall", "lld2d");
286
287	return ret;
288}
289
290#ifdef WSC
291int
292start_wsc(void)
293{
294
295	/* Set values of WSC variables */
296
297	if(nvram_get("secret_code"))/* Cherry Cho added in 2007/4/13. */
298		nvram_set("wsc_device_pin", nvram_safe_get("secret_code"));
299
300	if((!nvram_match("wsc_cli","1")) && nvram_match("wsc_mode","enabled"))
301	{
302		if (nvram_match("wsc_restart", "no")) {
303			nvram_set("wsc_restart", "normal");
304		}
305		else
306		{
307			char *wsc_argv[] = {"/bin/wsccmd", NULL};
308			pid_t pid;
309
310			dprintf("Starting wsc\n");
311			nvram_set("wsc_restart", "yes");
312			_eval(wsc_argv, NULL, 0, &pid);
313			sleep(5);
314		}
315	}
316	return 0;
317}
318
319int
320stop_wsc(void)
321{
322   	int ret;
323
324	//if((!nvram_match("wsc_cli","1")) && nvram_match("wsc_mode","enabled"))
325	if(!nvram_match("wsc_cli","1"))
326	{
327		if (nvram_match("wsc_restart", "no")) {
328			return 0;
329		}
330		else
331		{
332			nvram_set("wsc_restart", "yes");
333		   	ret = eval("killall","wsccmd");
334		}
335	}
336   	return ret;
337}
338#endif
339/* --- Cherry Cho added in 2006/12/14. --- */
340
341int
342start_services(void)
343{
344	start_httpd();
345	start_dns();
346	start_dhcpd();
347
348#ifdef ASUS_EXT
349	start_logger();
350#endif
351
352	start_upnp();
353
354	start_nas("lan");
355
356#ifdef ASUS_EXT
357	start_usb();
358#endif
359
360#ifdef GUEST_ACCOUNT
361	if (nvram_match("wl_guest_enable", "1"))
362	{
363		sleep(5);
364		start_dhcpd_guest();
365		start_guest_nas();
366	}
367#endif
368
369	start_lltd(); /* Cherry Cho added in 2006/12/14. */
370
371// 2007.11 James {
372#ifdef WEB_REDIRECT
373	if(!nvram_match("wanduck_down", "1")
374			&& nvram_match("wan_nat_x", "1")){
375		printf("--- START: Wait to start wanduck ---\n");
376		redirect_setting();
377		start_wanduck();
378		sleep(1);
379	}
380#endif
381// 2007.11 James }
382#ifdef DLM
383// 2007.10 James {
384	if(!strcmp(nvram_safe_get("restart_usb_apps"), "1")){
385		nvram_unset("restart_usb_apps");
386		start_usb_apps();
387	}
388// 2007.10 James }
389#endif
390	dprintf("done\n");
391
392	return 0;
393}
394
395int
396stop_services(void)
397{
398// 2007.10 James {
399	if(!strcmp(nvram_safe_get("samba_running"), "1") ||
400			!strcmp(nvram_safe_get("ftp_running"), "1") ||
401			!strcmp(nvram_safe_get("apps_running"), "1")
402			){
403printf("\n*** ready to restart_usb_apps ***\n");
404		nvram_set("restart_usb_apps", "1");
405	}
406// 2007.10 James }
407
408#ifdef ASUS_EXT
409	stop_usb();
410#endif
411	stop_nas();
412	stop_upnp();
413#ifdef ASUS_EXT
414	stop_logger();
415#endif
416
417#ifdef GUEST_ACCOUNT
418	stop_dhcpd_guest();
419#endif
420	stop_dhcpd();
421	stop_dns();
422	stop_httpd();
423
424	stop_lltd();/* Cherry Cho added in 2006/12/14. */
425	dprintf("done\n");
426	return 0;
427}
428
429#ifdef GUEST_ACCOUNT
430/* Start NAS for the guest interfaces */
431int
432start_guest_nas(void)
433{
434	char *unbridged_interfaces;
435	char *next;
436	char name[IFNAMSIZ],lan[IFNAMSIZ];
437	int index;
438
439	unbridged_interfaces = nvram_get("unbridged_ifnames");
440
441	if (unbridged_interfaces)
442		foreach(name,unbridged_interfaces,next){
443			index = get_ipconfig_index(name);
444			if (index < 0)
445				continue;
446			snprintf(lan,sizeof(lan),"lan%d",index);
447			start_nas(lan);
448		}
449
450	return 0;
451}
452#endif
453
454// 2007.10 James {
455#ifdef WEB_REDIRECT
456int start_wanduck(void){
457//	kill_pidfile_s("/var/run/wanduckmain.pid", SIGUSR1);
458	char *argv[] = {"/usr/sbin/wanduck", NULL};
459	int ret = 0;
460	pid_t pid;
461	FILE *fp = fopen("/var/run/wanduck.pid", "r");
462	if(fp != NULL){
463		fclose(fp);
464		return 0;
465	}
466
467	ret = _eval(argv, NULL, 0, &pid);
468
469	return ret;
470}
471
472int stop_wanduck(void){
473//	kill_pidfile_s("/var/run/wanduckmain.pid", SIGUSR2);
474	kill_pidfile_s("/var/run/wanduck.pid", SIGTERM);
475
476	return 0;
477}
478#endif
479// 2007.10 James }
480