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