1/*
2 * Copyright 2004, ASUSTek Inc.
3 * All Rights Reserved.
4 *
5 * THIS SOFTWARE IS OFFERED "AS IS", AND ASUS GRANTS NO WARRANTIES OF ANY
6 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
7 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
8 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
9 *
10 * $Id: rc.c,v 1.7 2009/03/11 14:28:15 james26_jang Exp $
11 */
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <limits.h>
16#include <time.h>
17#include <unistd.h>
18#include <errno.h>
19#include <syslog.h>
20#include <signal.h>
21#include <string.h>
22#include <sys/klog.h>
23#include <sys/types.h>
24#include <sys/mount.h>
25#include <sys/reboot.h>
26#include <sys/stat.h>
27#include <sys/sysmacros.h>
28#include <sys/time.h>
29#include <sys/utsname.h>
30#include <sys/wait.h>
31#include <sys/socket.h>
32#include <net/if_arp.h>
33#include <dirent.h>
34
35#include <epivers.h>
36#include <bcmnvram.h>
37#include <mtd.h>
38#include <shutils.h>
39#include <rc.h>
40#include <netconf.h>
41#include <nvparse.h>
42#include <bcmdevs.h>
43#include <wlutils.h>
44#include <bcmparams.h>
45#include <etioctl.h>
46#include <linux/sockios.h>
47//#include <linux/ethtool.h>
48#include "ethtool-util.h"
49
50static void restore_defaults(void);
51static void sysinit(void);
52static void rc_signal(int sig);
53
54extern struct nvram_tuple router_defaults[];
55
56static int restore_defaults_g=0;
57
58static int
59build_ifnames(char *type, char *names, int *size)
60{
61	char name[32], *next;
62	int len = 0;
63	int s;
64
65	/* open a raw scoket for ioctl */
66	if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
67       		return -1;
68
69	/*
70	 * go thru all device names (wl<N> il<N> et<N> vlan<N>) and interfaces to
71	 * build an interface name list in which each i/f name coresponds to a device
72	 * name in device name list. Interface/device name matching rule is device
73	 * type dependant:
74	 *
75	 *	wl:	by unit # provided by the driver, for example, if eth1 is wireless
76	 *		i/f and its unit # is 0, then it will be in the i/f name list if
77	 *		wl0 is in the device name list.
78	 *	il/et:	by mac address, for example, if et0's mac address is identical to
79	 *		that of eth2's, then eth2 will be in the i/f name list if et0 is
80	 *		in the device name list.
81	 *	vlan:	by name, for example, vlan0 will be in the i/f name list if vlan0
82	 *		is in the device name list.
83	 */
84	foreach (name, type, next) {
85		struct ifreq ifr;
86		int i, unit;
87		char var[32], *mac, ea[ETHER_ADDR_LEN];
88
89		//printf("ifname: %s \n", name);
90
91		/* vlan: add it to interface name list */
92		if (!strncmp(name, "vlan", 4)) {
93			/* append interface name to list */
94			len += snprintf(&names[len], *size - len, "%s ", name);
95			continue;
96		}
97
98		/* others: proceed only when rules are met */
99		for (i = 1; i <= DEV_NUMIFS; i ++) {
100			/* ignore i/f that is not ethernet */
101			ifr.ifr_ifindex = i;
102			if (ioctl(s, SIOCGIFNAME, &ifr))
103				continue;
104			if (ioctl(s, SIOCGIFHWADDR, &ifr))
105				continue;
106			if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER)
107				continue;
108			if (!strncmp(ifr.ifr_name, "vlan", 4))
109				continue;
110			/* wl: use unit # to identify wl */
111			if (!strncmp(name, "wl", 2)) {
112				if (wl_probe(ifr.ifr_name) ||
113				    wl_ioctl(ifr.ifr_name, WLC_GET_INSTANCE, &unit, sizeof(unit)) ||
114				    unit != atoi(&name[2]))
115					continue;
116			}
117			/* et/il: use mac addr to identify et/il */
118			else if (!strncmp(name, "et", 2) || !strncmp(name, "il", 2)) {
119				snprintf(var, sizeof(var), "%smacaddr", name);
120				if (!(mac = nvram_get(var)) || !ether_atoe(mac, ea) ||
121				    bcmp(ea, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN))
122					continue;
123
124				// add by Chen-I to filter out wl interface here
125				if (!wl_probe(ifr.ifr_name))
126					continue;
127
128			}
129			/* mac address: compare value */
130			else if (ether_atoe(name, ea) && !bcmp(ea, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN))
131				;
132			/* others: ignore */
133			else
134				continue;
135
136			/* append interface name to list */
137			len += snprintf(&names[len], *size - len, "%s ", ifr.ifr_name);
138		}
139	}
140
141	close(s);
142
143	*size = len;
144	return 0;
145}
146
147#ifdef GUEST_ACCOUNT
148static void
149virtual_radio_restore_defaults(void)
150{
151	char tmp[100], prefix[] = "wlXXXXXXXXXX_mssid_";
152	int i,j;
153
154	nvram_unset("unbridged_ifnames");
155	nvram_unset("ure_disable");
156
157	/* Delete dynamically generated variables */
158	for (i = 0; i < MAX_NVPARSE; i++) {
159		sprintf(prefix, "wl%d_", i);
160		nvram_unset(strcat_r(prefix, "vifs", tmp));
161		nvram_unset(strcat_r(prefix, "ssid", tmp));
162		nvram_unset(strcat_r(prefix, "guest", tmp));
163		nvram_unset(strcat_r(prefix, "ure", tmp));
164		nvram_unset(strcat_r(prefix, "ipconfig_index", tmp));
165		sprintf(prefix, "lan%d_", i);
166		nvram_unset(strcat_r(prefix, "ifname", tmp));
167		nvram_unset(strcat_r(prefix, "ifnames", tmp));
168		nvram_unset(strcat_r(prefix, "gateway", tmp));
169		nvram_unset(strcat_r(prefix, "proto", tmp));
170		nvram_unset(strcat_r(prefix, "ipaddr", tmp));
171		nvram_unset(strcat_r(prefix, "netmask", tmp));
172		nvram_unset(strcat_r(prefix, "lease", tmp));
173		sprintf(prefix, "dhcp%d_", i);
174		nvram_unset(strcat_r(prefix, "start", tmp));
175		nvram_unset(strcat_r(prefix, "end", tmp));
176
177		/* clear virtual versions */
178		for (j=0; j< 16;j++){
179			sprintf(prefix, "wl%d.%d_", i,j);
180			nvram_unset(strcat_r(prefix, "ssid", tmp));
181			nvram_unset(strcat_r(prefix, "ipconfig_index", tmp));
182			nvram_unset(strcat_r(prefix, "guest", tmp));
183			nvram_unset(strcat_r(prefix, "closed", tmp));
184			nvram_unset(strcat_r(prefix, "wpa_psk", tmp));
185			nvram_unset(strcat_r(prefix, "auth", tmp));
186			nvram_unset(strcat_r(prefix, "wep", tmp));
187			nvram_unset(strcat_r(prefix, "auth_mode", tmp));
188			nvram_unset(strcat_r(prefix, "crypto", tmp));
189			nvram_unset(strcat_r(prefix, "akm", tmp));
190		}
191	}
192}
193#endif
194
195static void
196restore_defaults(void)
197{
198	struct nvram_tuple generic[] = {
199		{ "lan_ifname", "br0", 0 },
200		{ "lan_ifnames", "eth0 eth2 eth3 eth4", 0 },
201		{ "wan_ifname", "eth1", 0 },
202		{ "wan_ifnames", "eth1", 0 },
203		{ 0, 0, 0 }
204	};
205	struct nvram_tuple vlan[] = {
206		{ "lan_ifname", "br0", 0 },
207		{ "lan_ifnames", "vlan0 eth1 eth2 eth3", 0 },
208		{ "wan_ifname", "vlan1", 0 },
209		{ "wan_ifnames", "vlan1", 0 },
210		{ 0, 0, 0 }
211	};
212	struct nvram_tuple dyna[] = {
213		{ "lan_ifname", "br0", 0 },
214		{ "lan_ifnames", "", 0 },
215		{ "wan_ifname", "", 0 },
216		{ "wan_ifnames", "", 0 },
217		{ 0, 0, 0 }
218	};
219
220
221#ifdef CONFIG_WL300G
222	struct nvram_tuple wl300g[] = {
223		{ "lan_ifname", "br0", 0 },
224		{ "lan_ifnames", "eth2", 0 },
225		{ "wan_ifname", "eth0", 0 },
226		{ "wan_ifnames", "eth0", 0 },
227		{ "wan_nat_x", "0", 0},
228		{ "wan_route_x", "IP_Bridged", 0},
229		{ 0, 0, 0 }
230	};
231#endif
232
233#ifdef CONFIG_WL300G2
234	struct nvram_tuple wl300g2[] = {
235		{ "lan_ifname", "br0", 0 },
236		{ "lan_ifnames", "eth0 eth2", 0 },
237		{ "wan_ifname", "eth1", 0 },
238		{ "wan_ifnames", "eth1", 0 },
239		{ "wan_nat_x", "1", 0},
240		{ "wan_route_x", "IP_Routed", 0},
241		{ 0, 0, 0 }
242	};
243#endif
244
245#ifdef CONFIG_WL331G
246	struct nvram_tuple wl331g[] = {
247		{ "lan_ifname", "br0", 0 },
248		{ "lan_ifnames", "eth1", 0 },
249		{ "wan_ifname", "eth0", 0 },
250		{ "wan_ifnames", "eth0", 0 },
251		{ "wan_nat_x", "1", 0},
252		{ "wan_route_x", "IP_Routed", 0},
253		{ 0, 0, 0 }
254	};
255#endif
256
257
258#ifdef CONFIG_SENTRY5
259#include "rcs5.h"
260#else
261#define RC1_START()
262#define RC1_STOP()
263#define RC7_START()
264#define RC7_STOP()
265#define LINUX_OVERRIDES()
266#define EXTRA_RESTORE_DEFAULTS()
267#endif
268
269	struct nvram_tuple *linux_overrides;
270	struct nvram_tuple *t, *u;
271	int restore_defaults, i;
272	uint boardflags;
273	char *landevs, *wandevs;
274	char lan_ifnames[128], wan_ifnames[128];
275	char wan_ifname[32], *next;
276	int len;
277	int ap = 0;
278
279	/* Restore defaults if told to or OS has changed */
280	restore_defaults = !nvram_match("restore_defaults", "0") || nvram_invmatch("os_name", "linux");
281
282	if (restore_defaults)
283		cprintf("Restoring defaults...");
284
285	/* Delete dynamically generated variables */
286	if (restore_defaults) {
287		char tmp[100], prefix[] = "wlXXXXXXXXXX_";
288		for (i = 0; i < MAX_NVPARSE; i++) {
289			del_filter_client(i);
290			del_forward_port(i);
291			del_autofw_port(i);
292			snprintf(prefix, sizeof(prefix), "wl%d_", i);
293			for (t = router_defaults; t->name; t ++) {
294				if (!strncmp(t->name, "wl_", 3))
295					nvram_unset(strcat_r(prefix, &t->name[3], tmp));
296			}
297			snprintf(prefix, sizeof(prefix), "wan%d_", i);
298			for (t = router_defaults; t->name; t ++) {
299				if (!strncmp(t->name, "wan_", 4))
300					nvram_unset(strcat_r(prefix, &t->name[4], tmp));
301			}
302		}
303#ifdef GUEST_ACCOUNT
304		virtual_radio_restore_defaults();
305#endif
306	}
307
308	/*
309	 * Build bridged i/f name list and wan i/f name list from lan device name list
310	 * and wan device name list. Both lan device list "landevs" and wan device list
311	 * "wandevs" must exist in order to preceed.
312	 */
313	if ((landevs = nvram_get("landevs")) && (wandevs = nvram_get("wandevs"))) {
314		/* build bridged i/f list based on nvram variable "landevs" */
315		len = sizeof(lan_ifnames);
316		if (!build_ifnames(landevs, lan_ifnames, &len) && len)
317			dyna[1].value = lan_ifnames;
318		else
319			goto canned_config;
320		/* build wan i/f list based on nvram variable "wandevs" */
321		len = sizeof(wan_ifnames);
322		if (!build_ifnames(wandevs, wan_ifnames, &len) && len) {
323			dyna[3].value = wan_ifnames;
324			foreach (wan_ifname, wan_ifnames, next) {
325				dyna[2].value = wan_ifname;
326				break;
327			}
328		}
329		else ap = 1;
330		linux_overrides = dyna;
331	}
332	/* override lan i/f name list and wan i/f name list with default values */
333	else {
334canned_config:
335		boardflags = strtoul(nvram_safe_get("boardflags"), NULL, 0);
336		if (boardflags & BFL_ENETVLAN)
337			linux_overrides = vlan;
338		else
339			linux_overrides = generic;
340
341		/* override the above linux_overrides with a different table */
342		LINUX_OVERRIDES();
343	}
344
345#ifdef CONFIG_WL300G
346	linux_overrides = wl300g;
347#endif
348
349#ifdef CONFIG_WL300G2
350	linux_overrides = wl300g2;
351#endif
352
353#ifdef CONFIG_WL331G
354	linux_overrides = wl331g;
355#endif
356
357#ifdef WL500GX
358	// Thanks for Oleg
359	linux_overrides = vlan;
360
361	if (nvram_match("wan_ifname", "eth0"))
362	{
363		for (u = linux_overrides; u && u->name; u++)
364		{
365			nvram_set(u->name, u->value);
366		}
367	}
368
369	if (!nvram_get("vlan0ports"))
370	{
371		nvram_set("vlan0hwname", "et0");
372		nvram_set("vlan0ports", "1 2 3 4 5*");
373		nvram_set("vlan1hwname", "et0");
374		nvram_set("vlan1ports", "0 5");
375	}
376#endif
377	/* Restore defaults */
378	for (t = router_defaults; t->name; t++) {
379		if (restore_defaults || !nvram_get(t->name)) {
380			for (u = linux_overrides; u && u->name; u++) {
381				if (!strcmp(t->name, u->name)) {
382					nvram_set(u->name, u->value);
383					break;
384				}
385			}
386			if (!u || !u->name)
387				nvram_set(t->name, t->value);
388		}
389	}
390
391#ifdef R100
392	if (restore_defaults)
393		nvram_set("wl_ssid", "R100 Wireless Gateway");
394#endif
395
396#ifdef WIRELESS_WAN //thansk for Oleg
397	if (nvram_invmatch("wl_mode_ex", "ap")) {
398		nvram_set("wan0_ifname", nvram_safe_get("wl0_ifname"));
399		nvram_set("wan0_ifnames", nvram_safe_get("wl0_ifname"));
400	}
401	else {
402		nvram_set("wan0_ifname", nvram_safe_get("wan_ifname"));
403		nvram_set("wan0_ifnames", nvram_safe_get("wan_ifname"));
404	}
405#endif
406
407	/* Force to AP */
408	if (ap)
409		nvram_set("router_disable", "1");
410
411	/* Always set OS defaults */
412	nvram_set("os_name", "linux");
413	nvram_set("os_version", EPI_ROUTER_VERSION_STR);
414	nvram_set("os_date", __DATE__);
415
416	nvram_set("is_modified", "0");
417
418	/* Commit values */
419	if (restore_defaults) {
420		EXTRA_RESTORE_DEFAULTS();
421		/* default value of vlan */
422		nvram_commit();
423		cprintf("done\n");
424	}
425}
426
427static void
428set_wan0_vars(void)
429{
430	int unit;
431	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
432
433	/* check if there are any connections configured */
434	for (unit = 0; unit < MAX_NVPARSE; unit ++) {
435		snprintf(prefix, sizeof(prefix), "wan%d_", unit);
436		if (nvram_get(strcat_r(prefix, "unit", tmp)))
437			break;
438	}
439	/* automatically configure wan0_ if no connections found */
440	if (unit >= MAX_NVPARSE) {
441		struct nvram_tuple *t;
442		char *v;
443
444		/* Write through to wan0_ variable set */
445		snprintf(prefix, sizeof(prefix), "wan%d_", 0);
446		for (t = router_defaults; t->name; t ++) {
447			if (!strncmp(t->name, "wan_", 4)) {
448				if (nvram_get(strcat_r(prefix, &t->name[4], tmp)))
449					continue;
450				v = nvram_get(t->name);
451				nvram_set(tmp, v ? v : t->value);
452			}
453		}
454		nvram_set(strcat_r(prefix, "unit", tmp), "0");
455		nvram_set(strcat_r(prefix, "desc", tmp), "Default Connection");
456		nvram_set(strcat_r(prefix, "primary", tmp), "1");
457	}
458}
459
460static int noconsole = 0;
461
462static void
463sysinit(void)
464{
465	time_t tm = 0;
466
467	/* /proc */
468	mount("proc", "/proc", "proc", MS_MGC_VAL, NULL);
469
470	/* /tmp */
471	mount("ramfs", "/tmp", "ramfs", MS_MGC_VAL, NULL);
472	mkdir("/tmp/rc_notification", 0777);	// 2007.10 James
473	mkdir("/tmp/rc_action_incomplete", 0777);	// 2007.10 James
474
475	/* /var */
476	mkdir("/tmp/var", 0777);
477	mkdir("/var/lock", 0777);
478	mkdir("/var/log", 0777);
479	mkdir("/var/run", 0777);
480	mkdir("/var/tmp", 0777);
481	mkdir("/tmp/samba", 0777);
482	mkdir("/tmp/samba/private", 0777);
483	mkdir("/tmp/samba/var", 0777);
484	mkdir("/tmp/samba/var/locks", 0777);
485	mkdir("/tmp/samba/lib", 0777);
486
487	/* Setup console */
488	if (console_init())
489		noconsole = 1;
490
491	// for debug
492	//nvram_set("console_loglevel", "0");
493
494	klogctl(8, NULL, atoi(nvram_safe_get("console_loglevel")));
495
496	/* Set a sane date */
497	stime(&tm);
498}
499
500static void
501insmod(void)
502{
503	char buf[PATH_MAX];
504	struct utsname name;
505	struct stat tmp_stat;
506
507	/* Modules */
508	uname(&name);
509	snprintf(buf, sizeof(buf), "/lib/modules/%s", name.release);
510	if (stat("/proc/modules", &tmp_stat) == 0 &&
511	    stat(buf, &tmp_stat) == 0) {
512		char module[80], *modules, *next;
513#ifdef WL500GX
514		modules = nvram_get("kernel_mods") ? : "et wl";
515#else
516		modules = nvram_get("kernel_mods") ? : "et wl";
517#endif
518		foreach(module, modules, next)
519			eval("insmod", module);
520	}
521
522#ifdef USB_SUPPORT
523#ifdef LANGUAGE_TW
524	eval("insmod", "nls_cp950.o");
525	eval("insmod", "nls_big5.o");
526	eval("insmod", "nls_cp936.o");
527	eval("insmod", "nls_gb2312.o");
528	eval("insmod", "nls_utf8.o");
529#endif
530#ifdef LANGUAGE_CN
531	eval("insmod", "nls_cp936.o");
532	eval("insmod", "nls_gb2312.o");
533	eval("insmod", "nls_cp950.o");
534	eval("insmod", "nls_big5.o");
535	eval("insmod", "nls_utf8.o");
536#endif
537#ifdef LANGUAGE_KR
538	eval("insmod", "nls_cp949.o");
539	eval("insmod", "nls_euc-kr.o");
540	eval("insmod", "nls_utf8.o");
541#endif
542#ifdef LANGUAGE_JP
543	eval("insmod", "nls_cp932.o");
544	eval("insmod", "nls_euc-jp.o");
545	eval("insmod", "nls_sjis.o");
546	eval("insmod", "nls_utf8.o");
547#endif
548#endif
549	dprintf("done\n");
550}
551
552/* States */
553enum {
554	RESTART,
555	STOP,
556	START,
557	TIMER,
558	IDLE,
559	SERVICE,
560};
561static int state = START;
562static int signalled = -1;
563
564
565/* Signal handling */
566static void
567rc_signal(int sig)
568{
569	if (state == IDLE) {
570		if (sig == SIGHUP) {
571			dprintf("signalling RESTART\n");
572			signalled = RESTART;
573		}
574		else if (sig == SIGUSR2) {
575			dprintf("signalling START\n");
576			signalled = START;
577		}
578		else if (sig == SIGINT) {
579			dprintf("signalling STOP\n");
580			signalled = STOP;
581		}
582		else if (sig == SIGALRM) {
583			dprintf("signalling TIMER\n");
584			signalled = TIMER;
585		}
586		else if (sig == SIGUSR1) {
587			dprintf("signalling USR1\n");
588			signalled = SERVICE;
589		}
590	}
591}
592
593/* Timer procedure */
594int
595do_timer(void)
596{
597	int interval = atoi(nvram_safe_get("timer_interval"));
598	time_t now;
599	struct tm gm, local;
600	struct timezone tz;
601
602	dprintf("%d\n", interval);
603
604#ifdef ASUS_EXT
605	/* Update kernel timezone */
606	setenv("TZ", nvram_safe_get("time_zone_x"), 1);
607	time(&now);
608	gmtime_r(&now, &gm);
609	localtime_r(&now, &local);
610	tz.tz_minuteswest = (mktime(&gm) - mktime(&local)) / 60;
611	settimeofday(NULL, &tz);
612	return 0;
613#endif
614	if (interval == 0)
615		return 0;
616
617	/* Report stats */
618	if (nvram_invmatch("stats_server", "")) {
619		char *stats_argv[] = { "stats", nvram_get("stats_server"), NULL };
620		_eval(stats_argv, NULL, 5, NULL);
621	}
622
623	/* Sync time */
624	start_ntpc();
625
626	/* Update kernel timezone */
627	setenv("TZ", nvram_safe_get("time_zone_x"), 1);
628	time(&now);
629	gmtime_r(&now, &gm);
630	localtime_r(&now, &local);
631	tz.tz_minuteswest = (mktime(&gm) - mktime(&local)) / 60;
632	settimeofday(NULL, &tz);
633	alarm(interval);
634	return 0;
635}
636
637static void
638early_defaults(void)
639{
640	int stbport;
641	char hw_name[32];
642
643	//snprintf(hw_name, 9, "%s", nvram_get("hardware_version"));
644	snprintf(hw_name, 10, "%s", nvram_get("hardware_version"));	// 2008.03 James.
645
646	if(nvram_match("wan_route_x", "IP_Bridged")){
647		if(nvram_match("boardtype", "0x48E") && nvram_match("boardnum", "45")){
648			nvram_set("vlan0ports", "0 1 2 3 4 5*");
649			nvram_set("vlan1ports", "5u");
650		}
651	}
652	else{ /* router mode, use vlans */
653		/* Adjust switch config to bridge STB LAN port with WAN port */
654		stbport = atoi(nvram_safe_get("wan_stb_x"));
655
656		/* Check existing config for validity */
657		if(stbport < 0 || stbport > 5)
658			stbport = 0;
659
660		/* predefined config for WL520gu, WL520gc -- check boardtype for others */
661		/* there is no easy way to do LANx to real port number mapping, so we use array */
662		if(nvram_match("boardtype", "0x48E") && nvram_match("boardnum", "45")){
663			/* use different hardware name */
664			if(!strncmp(hw_name, "WL500GPV2", 9)){
665				static char *vlan0ports[] = {"0 1 2 3 5*",
666																		 "0 1 2 5*",
667																		 "0 1 3 5*",
668																		 "0 2 3 5*",
669																		 "1 2 3 5*",
670																		 "2 3 5*"};
671				static char *vlan1ports[] = {"4 5u",
672																		 "3 4 5u",
673																		 "2 4 5u",
674																		 "1 4 5u",
675																		 "4 0 5u",
676																		 "0 1 4 5u"};
677
678				nvram_set("vlan0ports", vlan0ports[stbport]);
679				nvram_set("vlan1ports", vlan1ports[stbport]);
680			}
681			else{
682				static char *vlan0ports[] = {"1 2 3 4 5*",
683																		 "2 3 4 5*",
684																		 "1 3 4 5*",
685																		 "1 2 4 5*",
686																		 "1 2 3 5*",
687																		 "1 2 5*"};
688				static char *vlan1ports[] = {"0 5u",
689																		 "1 0 5u",
690																		 "2 0 5u",
691																		 "3 0 5u",
692																		 "4 0 5u",
693																		 "3 4 0 5u"};
694
695				nvram_set("vlan0ports", vlan0ports[stbport]);
696				nvram_set("vlan1ports", vlan1ports[stbport]);
697			}
698		}
699	}
700}
701
702// 2007.10 James {
703static void handle_notifications(void){
704	DIR *directory = opendir("/tmp/rc_notification");
705
706	printf("handle_notifications() start\n");
707
708	if(directory == NULL)
709		return;
710
711	while(TRUE){
712		struct dirent *entry;
713		char *full_name;
714		FILE *test_fp;
715
716		entry = readdir(directory);
717		if (entry == NULL)
718			break;
719		if (strcmp(entry->d_name, ".") == 0)
720			continue;
721		if (strcmp(entry->d_name, "..") == 0)
722			continue;
723
724		/* Remove the marker file. */
725		full_name = (char *)(malloc(strlen(entry->d_name) + 100));
726		if (full_name == NULL)
727		{
728			fprintf(stderr,
729					"Error: Failed trying to allocate %lu bytes of memory for "
730					"the full name of an rc notification marker file.\n",
731					(unsigned long)(strlen(entry->d_name) + 100));
732			break;
733		}
734		sprintf(full_name, "/tmp/rc_notification/%s", entry->d_name);
735		remove(full_name);
736
737		//printf("Flag : %s\n", entry->d_name);
738
739		/* Take the appropriate action. */
740		if (strcmp(entry->d_name, "restart_reboot") == 0)
741		{
742			fprintf(stderr, "rc rebooting the system.\n");
743			sleep(1);	// wait httpd sends the page to the browser.
744			eval("reboot");
745			return;
746		}
747		else if (strcmp(entry->d_name, "restart_networking") == 0)
748		{
749			fprintf(stderr, "rc restarting networking.\n");
750
751#ifdef WEB_REDIRECT
752			printf("--- SERVICE: Wait to kill wanduck ---\n");
753			stop_wanduck();
754
755			signalled = RESTART;
756			//eval("reboot");
757#endif
758			return;
759		}
760#ifdef CDMA // HSDPA
761		else if (strcmp(entry->d_name, "restart_hsdpa") == 0)
762		{
763			fprintf(stderr, "rc restarting HSDPA.\n");
764
765			//if(!strcmp(nvram_safe_get("hsdpa_enable"), "1"))
766			if(strcmp(nvram_safe_get("hsdpa_product"), "") != 0)
767				eval("reboot");
768			else
769				printf("--- Needn't reboot! ---\n");
770
771			return;
772		}
773#endif // HSDPA
774#ifdef DLM
775		else if (strcmp(entry->d_name, "restart_cifs") == 0)
776		{
777			fprintf(stderr, "rc restarting CIFS and FTP.\n");
778			nvram_set("usb_storage_busy", "1");	// 2007.12 James.
779			run_ftpsamba();
780			nvram_set("usb_storage_busy", "0");	// 2007.12 James.
781		}
782		/*else if (strcmp(entry->d_name, "restart_ftp") == 0)
783		{
784			fprintf(stderr, "rc restarting FTP.\n");
785			//run_ftp();
786		}*/
787#endif
788		else if (strcmp(entry->d_name, "restart_ddns") == 0)
789		{
790			fprintf(stderr, "rc restarting DDNS.\n");
791			stop_ddns();
792
793			if(nvram_match("ddns_enable_x", "1")){
794				start_ddns();
795
796#ifdef DLM
797				if(nvram_match("ddns_server_x", "WWW.ASUS.COM")
798						&& strstr(nvram_safe_get("ddns_hostname_x"), ".asuscomm.com") != NULL){
799					// because the computer_name is followed by DDNS's hostname.
800					if(nvram_match("samba_running", "1")){
801						stop_samba();
802						run_samba();
803					}
804
805					if(nvram_match("ftp_running", "1")){
806						stop_ftp();
807						run_ftp();
808					}
809
810					if(nvram_match("dms_running", "1")){
811						stop_dms();
812						run_dms();
813					}
814				}
815#endif
816			}
817		}
818		else if (strcmp(entry->d_name, "restart_httpd") == 0)
819		{
820			fprintf(stderr, "rc restarting HTTPD.\n");
821			stop_httpd();
822			nvram_unset("login_ip");
823			nvram_unset("login_timestamp");
824			start_httpd();
825		}
826		else if (strcmp(entry->d_name, "restart_dns") == 0)
827		{
828			fprintf(stderr, "rc restarting DNS.\n");
829			stop_dns();
830			start_dns();
831		}
832		else if (strcmp(entry->d_name, "restart_dhcpd") == 0)
833		{
834			fprintf(stderr, "rc restarting DHCPD.\n");
835			stop_dhcpd();
836			start_dhcpd();
837		}
838		else if (strcmp(entry->d_name, "restart_upnp") == 0)
839		{
840			fprintf(stderr, "rc stoping UPNP.\n");
841			stop_upnp();
842			if(nvram_match("upnp_enable", "1")){
843				fprintf(stderr, "rc restarting UPNP.\n");
844				start_upnp();
845			}
846
847#ifdef DLM
848			fprintf(stderr, "rc stoping Media Server.\n");
849			stop_dms();
850			if(nvram_match("apps_dms", "1")){
851				fprintf(stderr, "rc restarting Media Server.\n");
852				run_dms();
853			}
854#endif
855		}
856#ifdef QOS
857		else if (strcmp(entry->d_name, "restart_qos") == 0)
858		{
859			fprintf(stderr, "rc restarting QOS.\n");
860
861// 2009.03 James. {
862			nvram_set("qos_userspec_app", "0");
863			nvram_set("qos_global_enable", "0");
864			nvram_set("qos_userdef_enable", "0");
865			nvram_set("qos_enable", "0");
866
867			if(nvram_invmatch("qos_rulenum_x", "0"))
868				nvram_set("qos_userspec_app", "1");
869
870			if(nvram_match("qos_tos_prio", "1")
871					|| nvram_match("qos_pshack_prio", "1")
872					|| nvram_match("qos_service_enable", "1")
873					|| nvram_match("qos_shortpkt_prio", "1"))
874				nvram_set("qos_global_enable", "1");
875
876			if(nvram_match("qos_userspec_app", "1")
877					|| nvram_match("qos_dfragment_enable", "1"))
878				nvram_set("qos_userdef_enable", "1");
879
880			if(nvram_match("qos_global_enable", "1") || nvram_match("qos_userdef_enable", "1"))
881				nvram_set("qos_enable", "1");
882			else
883				nvram_set("qos_enable", "0");
884
885			if(nvram_match("qos_enable", "1")){
886			//if(nvram_match("wan_status_t", "Connected")){
887// 2009.03 James. }
888				nvram_set("qos_ubw", "0");
889				nvram_set("qos_ubw_tmp", "0");
890				qos_get_wan_rate();
891				fprintf(stderr, "Get wan rate = %s.\n", nvram_safe_get("qos_ubw"));
892				nvram_set("qos_ubw_tmp", nvram_get("qos_ubw"));
893
894				Speedtest_Init();
895			}
896		}
897#endif
898		else if (strcmp(entry->d_name, "restart_syslog") == 0)
899		{
900			fprintf(stderr, "rc restarting syslogd.\n");
901#ifdef ASUS_EXT
902			stop_logger();
903			start_logger();
904#endif
905		}
906		else if (strcmp(entry->d_name, "restart_firewall") == 0)
907		{
908			char wan_ifname[16];
909			char *wan_proto = nvram_safe_get("wan_proto");
910
911			fprintf(stderr, "rc restarting firewall.\n");
912			/*if(!nvram_match("wan_status_t", "Connected"))
913				continue;//*/
914
915// 2008.08 James. {
916			//wan_ifname = nvram_get("wan0_ifname");
917			memset(wan_ifname, 0, 16);
918			strncpy(wan_ifname, nvram_safe_get("wan_ifname_t"), 16);
919			if(strlen(wan_ifname) == 0){
920				if(!strcmp(wan_proto, "pppoe")
921						|| !strcmp(wan_proto, "pptp")
922						|| !strcmp(wan_proto, "l2tp")
923#ifdef CDMA // HSDPA
924						|| strcmp(nvram_safe_get("hsdpa_product"), "") != 0
925#endif
926						)
927					strcpy(wan_ifname, "ppp0");
928				else
929					strcpy(wan_ifname, "eth0");
930			}
931// 2008.08 James. }
932
933			start_firewall();
934
935#ifdef NOIPTABLES
936			start_firewall2(wan_ifname);
937#else
938			fprintf(stderr, "rc restarting IPTABLES firewall.\n");
939			start_firewall_ex(wan_ifname, nvram_safe_get("wan0_ipaddr"), "br0", nvram_safe_get("lan_ipaddr"));
940#endif
941
942#ifndef ASUS_EXT
943			/* Start connection dependent firewall */
944			start_firewall2(wan_ifname);
945#endif
946		}
947		else if (strcmp(entry->d_name, "restart_ntpc") == 0)
948		{
949			fprintf(stderr, "rc restarting ntpc.\n");
950			stop_ntpc();
951			start_ntpc();
952		}
953		else if (strcmp(entry->d_name, "rebuild_cifs_config_and_password") == 0)
954		{
955			fprintf(stderr, "rc rebuilding CIFS config and password databases.\n");
956//			regen_passwd_files(); /* Must be called before regen_cifs_config_file(). */
957			//regen_cifs_config_file();
958		}
959		else if (strcmp(entry->d_name, "ddns_update") == 0)
960		{
961			fprintf(stderr, "rc updating ez-ipupdate for ddns changes.\n");
962			//update_ddns_changes();
963		}
964// 2008.01 James. {
965		else if(strcmp(entry->d_name, "restart_time") == 0)
966		{
967			fprintf(stderr, "rc restarting time.\n");
968
969			do_timer();
970
971#ifdef ASUS_EXT
972			stop_logger();
973			start_logger();
974#endif
975
976			stop_ntpc();
977			start_ntpc();
978		}
979#ifdef WSC
980		else if(!strcmp(entry->d_name, "restart_wps"))
981		{
982			/*char *wsc_mode = nvram_safe_get("wsc_mode");
983			char *old_wsc_mode = nvram_safe_get("old_wsc_mode");
984
985			if((nvram_match("wsc_config_state", "0") && nvram_match("wsc_proc_status", "0")) || strcmp(wsc_mode, old_wsc_mode) != 0){
986				fprintf(stderr, "rc restarting WPS.\n");
987
988				stop_nas();// Cherry Cho added in 2008/1/24.
989				stop_wsc();
990				start_wsc();
991				start_nas("lan");// Cherry Cho added in 2008/1/24.
992
993				if(strcmp(wsc_mode, old_wsc_mode) != 0){
994					nvram_set("old_wsc_mode", wsc_mode);
995					nvram_commit();
996				}
997			}
998			else
999				fprintf(stderr, "Don't need restarting WPS.\n");*/
1000			;	// do nothing
1001		}
1002#endif
1003#ifdef DLM
1004		// when apps_running isn't set, it means no disk. when apps_running is set 1 or 0, it means there are disks.
1005		else if(!strcmp(entry->d_name, "restart_apps")){
1006			char usb_path1[16], usb_path2[16];
1007
1008			memset(usb_path1, 0, 16);
1009			memset(usb_path2, 0, 16);
1010			strcpy(usb_path1, nvram_safe_get("usb_path1.1"));
1011			strcpy(usb_path2, nvram_safe_get("usb_path1.2"));
1012			if(!strcmp(usb_path1, "storage") || !strcmp(usb_path2, "storage")){
1013				eval("killall", "snarf");
1014				eval("killall", "ctorrent");
1015				eval("killall", "rtorrent");
1016				eval("killall", "giftd");
1017				eval("killall", "dmathined");
1018
1019				nvram_set("apps_running", "0");
1020				nvram_set("apps_installed", "0");
1021				nvram_set("apps_dl_x", "0");
1022				nvram_set("apps_status_checked", "0");
1023				nvram_set("apps_disk_free", "0");
1024
1025				if(!strcmp(nvram_safe_get("apps_dlx"), "1"))
1026					run_apps();
1027				else{
1028					if(!strcmp(nvram_safe_get("swap_on"), "1")){
1029						char *swap_file = nvram_safe_get("swap_file");
1030
1031						if(strcmp(swap_file, "") != 0){
1032							printf("try to swapoff %s.\n", swap_file);
1033							swapoff(swap_file);
1034
1035							sleep(1);
1036
1037							if(swap_check() == 1){
1038								logmessage("USB storage", "swapoff unsuccessfully");
1039								nvram_set("swapoff_failed", "1");
1040							}
1041							else{
1042								logmessage("USB storage", "swapoff successfully");
1043								nvram_set("swap_on", "0");
1044								nvram_set("swap_file", "");	// 2008.06 James.
1045								nvram_set("swapoff_failed", "0");
1046								nvram_set("apps_dms_usb_port_x2", "-1");
1047								unlink(swap_file);
1048							}
1049						}
1050					}
1051				}
1052			}
1053		}
1054#endif
1055// 2008.01 James. }
1056#ifdef NETGEAR_WAY
1057		else if(!strcmp(entry->d_name, "restart_lan")){
1058			int sec;
1059
1060			printf("Restarting LAN...\n");
1061
1062			stop_lan();
1063			for(sec = 0; sec < 3; ++sec){
1064				printf("Sleep %d seconds...\n", sec);
1065				sleep(1);
1066			}
1067			start_lan();
1068		}
1069#endif
1070		else
1071		{
1072			fprintf(stderr,
1073					"WARNING: rc notified of unrecognized event `%s'.\n",
1074					entry->d_name);
1075		}
1076
1077		/*
1078		 * If there hasn't been another request for the same event made since
1079		 * we started, we can safely remove the ``action incomplete'' marker.
1080		 * Otherwise, we leave the marker because we'll go through here again
1081		 * for this even and mark it complete only after we've completed it
1082		 * without getting another request for the same event while handling
1083		 * it.
1084		 */
1085		test_fp = fopen(full_name, "r");
1086		if (test_fp != NULL)
1087		{
1088			fclose(test_fp);
1089		}
1090		else
1091		{
1092			/* Remove the marker file. */
1093			sprintf(full_name, "/tmp/rc_action_incomplete/%s", entry->d_name);
1094			remove(full_name);
1095		}
1096
1097		free(full_name);
1098	}
1099
1100	printf("handle_notifications() end, state : %d\n", state);
1101	closedir(directory);
1102}
1103// 2007.10 James }
1104
1105/* Main loop */
1106static void
1107main_loop(void)
1108{
1109	sigset_t sigset;
1110	pid_t shell_pid = 0;
1111	uint boardflags;
1112
1113	/* Convert vital config before loading modules */
1114	early_defaults();
1115
1116	/* Basic initialization */
1117	sysinit();
1118
1119#ifdef ASUS_EXT
1120	convert_asus_values(0);		// move up by Jiahao for WL500gP
1121#endif
1122
1123#ifndef WL500GX
1124	insmod();
1125#endif
1126
1127	/* Setup signal handlers */
1128	signal_init();
1129	signal(SIGHUP, rc_signal);
1130	signal(SIGUSR1, rc_signal);
1131	signal(SIGUSR2, rc_signal);
1132	signal(SIGINT, rc_signal);
1133	signal(SIGALRM, rc_signal);
1134	sigemptyset(&sigset);
1135
1136	/* Give user a chance to run a shell before bringing up the rest of the system */
1137	if (!noconsole)
1138		run_shell(1, 0);
1139
1140#if defined(WL500GX) && defined(CONFIG_SENTRY5)
1141	if (!nvram_match("restore_defaults", "0"))
1142	{
1143		nvram_set("vlan_enable", "1");
1144		restore_defaults();
1145		set_wan0_vars();
1146		RC1_START();
1147	}
1148#endif
1149
1150#ifdef WL500GX
1151	boardflags = BFL_ENETVLAN;
1152#else
1153	/* Add vlan */
1154	boardflags = strtoul(nvram_safe_get("boardflags"), NULL, 0);
1155#endif
1156
1157	/* Add loopback */
1158	config_loopback();
1159
1160	/* Convert deprecated variables */
1161	convert_deprecated();
1162
1163	/* Restore defaults if necessary */
1164	restore_defaults();
1165#if 0
1166	if((nvram_match("productid", "WL500g.Premium") || nvram_match("productid", "WL500W")) && nvram_invmatch("sdram_init", "0x0009"))
1167	{
1168		nvram_set("sdram_init", "0x0009");
1169		nvram_commit();
1170	}
1171#endif
1172
1173#ifdef ASUS_EXT
1174	convert_asus_values(0);
1175#endif
1176
1177	/* Setup wan0 variables if necessary */
1178	set_wan0_vars();
1179
1180#if !(defined(WL500GX) && defined(CONFIG_SENTRY5))
1181#ifdef WL500GX
1182	insmod();
1183#endif
1184#endif
1185
1186	/* Loop forever */
1187	for (;;) {
1188		switch (state) {
1189		case SERVICE:
1190			dprintf("SERVICE\n");
1191
1192// 2007.10 James {
1193			//service_handle();
1194			if(nvram_get("rc_service") != NULL){	// for original process
1195				printf("\n### start the original process of rc! ###\n");
1196				service_handle();
1197			}
1198			else{	// for new process
1199				printf("\n### start the new process of rc! ###\n");
1200				handle_notifications();
1201			}
1202// 2007.10 James }
1203			state = IDLE;
1204
1205			break;
1206		case RESTART:
1207			dprintf("RESTART\n");
1208			/* Fall through */
1209		case STOP:
1210			dprintf("STOP\n");
1211
1212#ifdef ASUS_EXT
1213			stop_misc();
1214#endif
1215			stop_services();
1216			stop_wan();
1217#ifdef WSC
1218			stop_wsc();/* Cherry Cho added in 2007/4/27. */
1219#endif
1220			stop_lan();
1221
1222#if defined(WL500GX) && defined(CONFIG_SENTRY5)
1223			RC1_STOP();
1224#else
1225			if (boardflags & BFL_ENETVLAN)
1226			{
1227				stop_vlan();
1228			}
1229#endif
1230
1231			if (state == STOP) {
1232				state = IDLE;
1233				break;
1234			}
1235			/* Fall through */
1236		case START:
1237			dprintf("START %d\n", boardflags);
1238
1239#if defined(WL500GX) && defined(CONFIG_SENTRY5)
1240			RC1_START();
1241#else
1242			if (boardflags & BFL_ENETVLAN)
1243			{
1244				start_vlan();
1245			}
1246#endif
1247
1248			start_lan();
1249			//if (restore_defaults_g)
1250			//{
1251			//	goto retry;
1252			//}
1253#ifdef WSC
1254			if(!nvram_match("wsc_down", "1"))
1255				start_wsc();
1256#endif
1257			start_services();
1258			if(nvram_match("wan_proto", "l2tp")
1259					//&& nvram_match("wan_proto", "pptp")
1260					)
1261				sleep(3);	// 2008.11 James.
1262			start_wan();
1263
1264			start_nas("wan");
1265
1266#ifdef ASUS_EXT
1267			if(!nvram_match("misc_down", "1"))
1268				start_misc();
1269// 2007.11 James {
1270			sleep(3);
1271
1272			//sleep(5);
1273// 2007.11 James }
1274
1275			diag_PaN();
1276
1277			//2008.06.30 Yau add to start IP monitor
1278			if(nvram_match("wan_route_x", "IP_Routed")
1279					&& strcmp(nvram_safe_get("networkmap_down"), "1") != 0){
1280				start_networkmap();
1281			}
1282
1283// 2009.09 James. {
1284		char *wsc_argv[] = {"/bin/wsccmd", NULL};
1285		pid_t pid;
1286
1287		nvram_set("system_ready", "1");
1288
1289		if(!strcmp(nvram_safe_get("wan_route_x"), "IP_Bridged")
1290				&& !strcmp(nvram_safe_get("wan_ready"), "1")){
1291csprintf("+++ Restart WSC from rc. +++\n");
1292			eval("killall", "wsccmd");
1293			eval("killall", "nas");
1294			//sleep(1);
1295			eval("ifconfig", "br0", "down");
1296			//sleep(1);
1297			eval("ifconfig", "br0", "up");
1298			//sleep(1);
1299			_eval(wsc_argv, NULL, 0, &pid);
1300		}
1301// 2009.09 James. }
1302#endif
1303			/* Fall through */
1304		case TIMER:
1305			dprintf("TIMER\n");
1306			do_timer();
1307			/* Fall through */
1308		case IDLE:
1309			dprintf("IDLE\n");
1310			state = IDLE;
1311			/* Wait for user input or state change */
1312			while (signalled == -1) {
1313				if (!noconsole && (!shell_pid || kill(shell_pid, 0) != 0))
1314					shell_pid = run_shell(0, 1);
1315				else
1316					sigsuspend(&sigset);
1317			}
1318			state = signalled;
1319			signalled = -1;
1320
1321			break;
1322		default:
1323			dprintf("UNKNOWN\n");
1324			return;
1325		}
1326	}
1327}
1328
1329// 2007.10 James. replace all "strstr" to "!strcmp"
1330int
1331main(int argc, char **argv)
1332{
1333	int result;
1334	char usb_disc[32];
1335	char *base = strrchr(argv[0], '/');
1336
1337	base = base ? base + 1 : argv[0];
1338
1339//	FILE *fp;	// added by Jiahao for WL500gP
1340
1341	/* init */
1342	if (!strcmp(base, "init")) {
1343		main_loop();
1344		return 0;
1345	}
1346
1347	/* Set TZ for all rc programs */
1348	setenv("TZ", nvram_safe_get("time_zone_x"), 1);
1349
1350	/* ppp */
1351	if (!strcmp(base, "ip-up"))
1352		return ipup_main(argc, argv);
1353#ifdef CDMA // HSDPA
1354	else if(!strcmp(base, "write_cdma_conf")){
1355		return write_cdma_conf();
1356	}
1357#endif // CDMA // HSDPA
1358	/* write usb disc status */
1359	else if (!strcmp(base, "write_disc_status"))	// added by Jiahao for WL500gP
1360	{
1361		write_disc_status();
1362		return 0;
1363	}
1364	else if (!strcmp(base, "ip-down"))
1365		return ipdown_main(argc, argv);
1366	/* udhcpc [ deconfig bound renew ] */
1367	else if (!strcmp(base, "udhcpc"))
1368		return udhcpc_main(argc, argv);
1369	/* restore default */
1370	else if (!strcmp(base, "restore"))
1371	{
1372		if (argc==2)
1373		{
1374			int step = atoi(argv[1]);
1375			if (step>=1)
1376			{
1377				nvram_set("vlan_enable", "1");
1378				restore_defaults();
1379			}
1380			/* Setup wan0 variables if necessary */
1381			if (step>=2)
1382				set_wan0_vars();
1383			if (step>=3)
1384				RC1_START();
1385			if (step>=4)
1386				start_lan();
1387		}
1388		return 0;
1389	}
1390	/* stats [ url ] */
1391	else if (!strcmp(base, "stats"))
1392		return http_stats(argv[1] ? : nvram_safe_get("stats_server"));
1393
1394	/* erase [device] */
1395	else if (!strcmp(base, "erase")) {
1396		if (argv[1])
1397			return mtd_erase(argv[1]);
1398		else {
1399			fprintf(stderr, "usage: erase [device]\n");
1400			return EINVAL;
1401		}
1402	}
1403#ifndef FLASH2M
1404	/* write [path] [device] */
1405	else if (!strcmp(base, "write")) {
1406		if (argc >= 3)
1407			return mtd_write(argv[1], argv[2]);
1408		else {
1409			fprintf(stderr, "usage: write [path] [device]\n");
1410			return EINVAL;
1411		}
1412	}
1413#endif
1414	/* hotplug [event] */
1415	else if (!strcmp(base, "hotplug")) {
1416		if (argc >= 2) {
1417			if (!strcmp(argv[1], "net"))
1418				return hotplug_net();
1419#ifdef ASUS_EXT
1420			else if(!strcmp(argv[1], "usb"))
1421			{
1422
1423//				fp = fopen("/tmp/hotplug_usb", "a");	// added by Jiahao for WL500gP
1424//				fprintf(fp, "call hotplug_usb()\n");
1425//				fclose(fp);
1426
1427				return hotplug_usb();
1428			}
1429#endif
1430		} else {
1431			fprintf(stderr, "usage: hotplug [event]\n");
1432			return EINVAL;
1433		}
1434	}
1435
1436#ifdef ASUS_EXT
1437	/* ddns update ok */
1438	else if (!strcmp(base, "stopservice")) {
1439		if (argc >= 2)
1440			return(stop_service_main(atoi(argv[1])));
1441		else return(stop_service_main(0));
1442	}
1443	/* ddns update ok */
1444	else if (!strcmp(base, "ddns_updated"))
1445	{
1446		return ddns_updated_main();
1447	}
1448	/* ddns update ok */
1449	else if (!strcmp(base, "start_ddns"))
1450	{
1451		return start_ddns();
1452	}
1453#ifdef WEBCAM_SUPPORT
1454	/* send alarm */
1455	else if (!strcmp(base, "sendalarm")) {
1456		if (argc >= 1)
1457			return sendalarm_main(argc, argv);
1458		else {
1459			fprintf(stderr, "usage: sendalarm\n");
1460			return EINVAL;
1461		}
1462	}
1463#endif // WEBCAM_SUPPORT
1464	/* invoke watchdog */
1465	else if (!strcmp(base, "watchdog")) {
1466		return(watchdog_main());
1467	}
1468	else if (!strcmp(base, "gpio")) {
1469		return(gpio_main(/*atoi(argv[1])*/));
1470	}
1471	else if (!strcmp(base, "radioctrl")) {
1472		if (argc >= 1)
1473			return(radio_main(atoi(argv[1])));
1474		else return EINVAL;
1475	}
1476#ifdef BTN_SETUP
1477	/* invoke ots(one touch setup) */
1478	else if (!strcmp(base, "ots")) {
1479		return(ots_main());
1480	}
1481#endif
1482#ifdef WEBCAM_SUPPORT
1483	/* remove webcam module */
1484	else if (!strcmp(base, "rmwebcam")) {
1485		if (argc >= 2)
1486			return (remove_webcam_main(atoi(argv[1])));
1487		else return EINVAL;
1488	}
1489#endif // WEBCAM_SUPPORT
1490#ifdef MASSSTORAGE_SUPPORT
1491	/* remove usbstorage module */
1492	else if (!strcmp(base, "rmstorage")) {
1493		return (remove_storage_main());
1494	}
1495#endif // MASSSTORAGE_SUPPORT
1496	/* run ntp client */
1497	else if (!strcmp(base, "ntp")) {
1498		return (ntp_main());
1499	}
1500#ifdef AUDIO_SUPPORT
1501	/* run waveserver */
1502	else if (!strcmp(base, "waveservermain")) {
1503		return (waveserver_main());
1504	}
1505#endif // AUDIO_SUPPORT
1506#ifdef WEBCAM_SUPPORT
1507	/* run rcamd */
1508	else if (!strcmp(base, "rcamdmain")) {
1509		return (rcamd_main());
1510	}
1511#endif // WEBCAM_SUPPORT
1512	/* write srom */
1513	else if (!strcmp(base, "wsrom"))
1514	{
1515		do_timer();
1516		if (argc >= 4)
1517			return wsrom_main(argv[1], atoi(argv[2]), atoi(argv[3]));
1518		else {
1519			fprintf(stderr, "usage: wsrom [dev] [position] [value in 2 bytes]\n");
1520			return EINVAL;
1521		}
1522	}
1523	/* write srom */
1524	else if (!strcmp(base, "rsrom"))
1525	{
1526		if (argc >= 3)
1527		{
1528			rsrom_main(argv[1], atoi(argv[2]), 1);
1529			return 0;
1530		}
1531		else {
1532			fprintf(stderr, "usage: rsrom [dev] [position]\n");
1533			return EINVAL;
1534		}
1535	}
1536	/* write mac */
1537	else if (!strcmp(base, "wmac"))
1538	{
1539		if (argc >= 3)
1540			return write_mac(argv[1], argv[2]);
1541		else {
1542			fprintf(stderr, "usage: wmac [dev] [mac]\n");
1543			return EINVAL;
1544		}
1545	}
1546	/* wlan update */
1547	else if (!strcmp(base, "wlan_update"))
1548	{
1549		wlan_update();
1550		return 0;
1551	}
1552// 2007.10 James {
1553#ifdef QOS
1554	else if(!strcmp(base, "speedtest"))
1555	{
1556		qos_get_wan_rate();
1557		fprintf(stderr, "Get wan rate = %s.\n", nvram_safe_get("qos_ubw"));
1558
1559		return 0;
1560	}
1561	else if(!strcmp(base, "start_qos"))
1562	{
1563		if(argc == 2)
1564			start_qos(argv[1]);
1565		else
1566			fprintf(stderr, "usage: start_qos WAN_IP\n");
1567
1568		return 0;
1569	}
1570#endif
1571	else if(!strcmp(base, "convert_asus_values"))
1572	{
1573		convert_asus_values(1);
1574
1575		return 0;
1576	}
1577#ifdef DLM
1578	else if(!strcmp(base, "run_dms")){
1579		nvram_set("usb_storage_busy", "1");
1580		run_dms();
1581		nvram_set("usb_storage_busy", "0");
1582
1583		return 0;
1584	}
1585	else if(!strcmp(base, "run_samba")){
1586		nvram_set("usb_storage_busy", "1");
1587		run_samba();
1588		nvram_set("usb_storage_busy", "0");
1589
1590		return 0;
1591	}
1592	else if(!strcmp(base, "run_ftp")){
1593		nvram_set("usb_storage_busy", "1");
1594		run_ftp();
1595		nvram_set("usb_storage_busy", "0");
1596
1597		return 0;
1598	}
1599	else if(!strcmp(base, "stop_dms")){
1600		nvram_set("usb_storage_busy", "1");
1601		stop_dms();
1602		nvram_set("usb_storage_busy", "0");
1603
1604		return 0;
1605	}
1606	else if(!strcmp(base, "stop_samba")){
1607		nvram_set("usb_storage_busy", "1");
1608		stop_samba();
1609		nvram_set("usb_storage_busy", "0");
1610
1611		return 0;
1612	}
1613	else if(!strcmp(base, "stop_ftp")){
1614		nvram_set("usb_storage_busy", "1");
1615		stop_ftp();
1616		nvram_set("usb_storage_busy", "0");
1617
1618		return 0;
1619	}
1620	else if(!strcmp(base, "stop_ftpsamba")){
1621		nvram_set("usb_storage_busy", "1");
1622		stop_ftpsamba();
1623		nvram_set("usb_storage_busy", "0");
1624
1625		return 0;
1626	}
1627#ifdef WLEVENT
1628	else if(!strcmp(base, "wlevent")){
1629		return wlevent();
1630	}
1631#endif // WLEVENT
1632#endif // DLM
1633	else if(!strcmp(base, "build_redirect_rules")){
1634		redirect_setting();
1635
1636		return 0;
1637	}
1638// 2007.10 James }
1639#if 0
1640	else if (!strcmp(base, "early_convert"))
1641	{
1642		early_convert_asus_values();
1643		return 0;
1644	}
1645#endif
1646#ifndef FLASH2M
1647	/* udhcpc_ex [ deconfig bound renew ], for lan only */
1648	else if (!strcmp(base, "landhcpc"))
1649		return udhcpc_ex_main(argc, argv);
1650#endif
1651#endif
1652#ifdef BIGPOND
1653	else if (!strcmp(base, "bpa_connect"))
1654		return bpa_connect_main(argc, argv);
1655	else if (!strcmp(base, "bpa_disconnect"))
1656		return bpa_disconnect_main(argc, argv);
1657#endif
1658
1659	/* rc [stop|start|restart ] */
1660	else if (!strcmp(base, "rc")) {
1661		if (argv[1]) {
1662			if (strncmp(argv[1], "start", 5) == 0)
1663				return kill(1, SIGUSR2);
1664			else if (strncmp(argv[1], "stop", 4) == 0)
1665				return kill(1, SIGINT);
1666			else if (strncmp(argv[1], "restart", 7) == 0)
1667				return kill(1, SIGHUP);
1668		} else {
1669			fprintf(stderr, "usage: rc [start|stop|restart]\n");
1670			return EINVAL;
1671		}
1672	}
1673#ifdef DLM
1674	else if (!strcmp(base, "run_apps"))
1675		return run_apps();
1676	else if (!strcmp(base, "run_ftpsamba"))		// added by Jiahao for WL500gP
1677	{
1678		nvram_set("usb_storage_busy", "1");	// 2007.12 James.
1679		run_ftpsamba();
1680		nvram_set("usb_storage_busy", "0");	// 2007.12 James.
1681
1682		return 0;
1683	}
1684#endif
1685#ifdef USB_SUPPORT
1686	else if (!strcmp(base, "hotplug_usb_mass"))	// added by Jiahao for WL500gP
1687	{
1688		return hotplug_usb_mass("");
1689	}
1690	else if (!strcmp(base, "eject_cdrom")){
1691		if(argc != 2){
1692			printf("Usage: eject_cdrom <device_name>\n");
1693
1694			return -1;
1695		}
1696
1697		return eject_cdrom(argv[1]);
1698	}
1699	else if (!strcmp(base, "stop_cdrom")){
1700		if(argc != 2){
1701			printf("Usage: stop_cdrom <device_name>\n");
1702
1703			return -1;
1704		}
1705
1706		return stop_cdrom(argv[1]);
1707	}
1708	else if (!strcmp(base, "eject_scsi")){
1709		if(argc != 2){
1710			printf("Usage: eject_scsi <device_name>\n");
1711
1712			return -1;
1713		}
1714
1715		return eject_scsi(argv[1]);
1716	}
1717	/*else if (!strcmp(base, "stop_cdrom")){
1718		if(argc != 2){
1719			printf("Usage: stop_cdrom <device_name>");
1720
1721			return -1;
1722		}
1723
1724		return stop_cdrom(argv[1]);
1725	}
1726	else if (!strcmp(base, "eject_cdrom")){
1727		if(argc != 2){
1728			printf("Usage: eject_cdrom <device_name>");
1729
1730			return -1;
1731		}
1732
1733		return eject_cdrom(argv[1]);
1734	}//*/
1735	else if (!strcmp(base, "eject_usb1"))		// added by Jiahao for WL500gP
1736	{
1737		memset(usb_disc, 0, 32);
1738		if(!strcmp(nvram_safe_get("usb_disc0_port"), "1")){
1739			strcpy(usb_disc, "usb_disc0_safely_removed");
1740			nvram_set(usb_disc, "1");
1741		}
1742		else if(!strcmp(nvram_safe_get("usb_disc1_port"), "1")){
1743			strcpy(usb_disc, "usb_disc1_safely_removed");
1744			nvram_set(usb_disc, "1");
1745		}
1746		else{
1747			printf("No USB storage device in Port 1.\n");
1748			return 0;
1749		}
1750
1751		result = umount_disc_parts_rc(1);
1752		if(result != 0)
1753			nvram_set(usb_disc, "0");
1754
1755		return 0;
1756	}
1757	else if (!strcmp(base, "eject_usb2"))		// added by Jiahao for WL500gP
1758	{
1759		memset(usb_disc, 0, 32);
1760		if(!strcmp(nvram_safe_get("usb_disc0_port"), "2")){
1761			strcpy(usb_disc, "usb_disc0_safely_removed");
1762			nvram_set(usb_disc, "1");
1763		}
1764		else if(!strcmp(nvram_safe_get("usb_disc1_port"), "2")){
1765			strcpy(usb_disc, "usb_disc1_safely_removed");
1766			nvram_set(usb_disc, "1");
1767		}
1768		else{
1769			printf("No USB storage device in Port 2.\n");
1770			return 0;
1771		}
1772
1773		result = umount_disc_parts_rc(2);
1774		if(result != 0)
1775			nvram_set(usb_disc, "0");
1776
1777		return result;
1778	}
1779#endif // USB_SUPPORT
1780	else if (!strcmp(base, "stop_lan"))
1781	{
1782		stop_lan();
1783	}
1784	else if (!strcmp(base, "start_lan"))
1785	{
1786		start_lan();
1787	}
1788
1789	return EINVAL;
1790}
1791