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: services_ex.c,v 1.1.1.1 2008/10/15 03:28:35 james26_jang Exp $
11 */
12
13#ifdef ASUS_EXT
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17#include <signal.h>
18#include <unistd.h>
19#include <errno.h>
20#include <sys/fcntl.h>
21#include <dirent.h>
22#include <sys/mount.h>
23#include <bcmnvram.h>
24#include <netconf.h>
25#include <shutils.h>
26#include <rc.h>
27#include <syslog.h>
28#include "iboxcom.h"
29#include "lp.h"
30
31#define logs(s) syslog(LOG_NOTICE, s)
32
33#ifdef USB_SUPPORT
34#define WEBCAM_SUPPORT 1
35#define PRINTER_SUPPORT 1
36#define MASSSTORAGE_SUPPORT 1
37#define AUDIO_SUPPORT 1
38
39//#define PARPORT_SUPPORT
40//#define USBCOPY_SUPPORT 1
41
42enum
43{
44	WEB_NONE = 0,
45	WEB_PWCWEB,
46	WEB_OVWEB,
47	WEB_AUDIO
48} WEBTYPE;
49
50char *PWCLIST[] = {"471","69a","46d","55d","41e","4cc","d81", NULL};
51char *OVLIST[] = {"5a9","813","b62", NULL};
52#endif
53
54char buf_g[512];
55
56void diag_PaN(void)
57{
58	FILE *fp;
59	char *token;
60    	char                                mfr[32];
61    	char                                model[64];
62    	int                                 fd;
63        int  i = 0;
64
65    	struct parport_splink_device_info   prn_info;
66
67	/* dump pci device */
68	fp=fopen("/proc/pci", "r");
69	if (fp!=NULL)
70	{
71		while(fgets(buf_g, sizeof(buf_g), fp))
72		{
73			if(strstr(buf_g, "PCI device"))
74				fprintf(stderr, buf_g);
75		}
76		fclose(fp);
77	}
78
79
80#ifdef RT2400_SUPPORT
81	if (nvram_match("nobr", "1"))
82		fprintf(stderr, "dumping 0x4301 for manu.\n");
83#endif
84
85#ifdef USB_SUPPORT
86	if (nvram_match("usb_device", "1"))
87	{
88		fprintf(stderr, "new USB device\r\n");
89	}
90#endif
91
92#ifdef PRINTER_SUPPORT
93#ifdef PARPORT_SUPPORT
94    if( (fd=open("/dev/lp0", O_RDWR)) < 0 ) //Someone is opening the lp0
95    {
96        fp=fopen("/proc/sys/dev/parport/parport0/devices/lp/deviceid","r");
97
98        if( fp != NULL)
99        {
100            while ( fgets(buf_g, sizeof(buf_g), fp) != NULL )
101            {
102                if(buf_g[0] == '\n')
103                {
104                    continue;
105                }
106                if(strncmp(buf_g , "Model: " , strlen("Model: ")) == 0)
107                {
108                    token = buf_g + strlen("Model: ");
109		    sprintf(buf_g, "PARPORT: %s", token);
110		    fprintf(stderr, "%s\r\n", buf_g);
111		    //logmessage("PARPORT", buf_g);
112                }
113	    }
114	    fclose(fp);
115	}
116	//else logmessage("NO", "No printer found");
117    }
118    else
119    {
120        if( ioctl(fd, LPGETID, &prn_info) <0 )
121        {
122	    //logmessage("PaN", "No printer found");
123            //PRINT("ioctl error\n");
124        }
125        else
126        {
127            memccpy(mfr , prn_info.mfr , 1 , 32);
128            memccpy(model , prn_info.model , 1 , 32);
129
130            sprintf(buf_g, "PARPORT: %s", model);
131	    fprintf(stderr, "%s\r\n", buf_g);
132            //logmessage("PARPORT", buf_g);
133        }
134	close(fd);
135   }
136#endif
137#endif
138   fprintf(stderr, "echo for PaN ::: &&&PaN\r\n");
139}
140
141int
142start_dhcpd(void)
143{
144	FILE *fp;
145	char *dhcpd_argv[] = {"udhcpd", "/tmp/udhcpd.conf", NULL, NULL};
146	char *slease = "/tmp/udhcpd-br0.sleases";
147	pid_t pid;
148
149	if (nvram_match("router_disable", "1") || nvram_invmatch("lan_proto", "dhcp"))
150		return 0;
151
152	dprintf("%s %s %s %s\n",
153		nvram_safe_get("lan_ifname"),
154		nvram_safe_get("dhcp_start"),
155		nvram_safe_get("dhcp_end"),
156		nvram_safe_get("lan_lease"));
157
158	if (!(fp = fopen("/tmp/udhcpd-br0.leases", "a"))) {
159		perror("/tmp/udhcpd-br0.leases");
160		return errno;
161	}
162	fclose(fp);
163
164	/* Write configuration file based on current information */
165	if (!(fp = fopen("/tmp/udhcpd.conf", "w"))) {
166		perror("/tmp/udhcpd.conf");
167		return errno;
168	}
169
170	fprintf(fp, "pidfile /var/run/udhcpd-br0.pid\n");
171	fprintf(fp, "start %s\n", nvram_safe_get("dhcp_start"));
172	fprintf(fp, "end %s\n", nvram_safe_get("dhcp_end"));
173	fprintf(fp, "interface %s\n", nvram_safe_get("lan_ifname"));
174	fprintf(fp, "remaining yes\n");
175	fprintf(fp, "lease_file /tmp/udhcpd-br0.leases\n");
176	fprintf(fp, "option subnet %s\n", nvram_safe_get("lan_netmask"));
177
178	if (nvram_invmatch("dhcp_gateway_x",""))
179	    fprintf(fp, "option router %s\n", nvram_safe_get("dhcp_gateway_x"));	else
180	    fprintf(fp, "option router %s\n", nvram_safe_get("lan_ipaddr"));
181
182	if (nvram_invmatch("dhcp_dns1_x",""))
183		fprintf(fp, "option dns %s\n", nvram_safe_get("dhcp_dns1_x"));
184	fprintf(fp, "option dns %s\n", nvram_safe_get("lan_ipaddr"));
185	fprintf(fp, "option lease %s\n", nvram_safe_get("dhcp_lease"));
186
187	if (nvram_invmatch("dhcp_wins_x",""))
188		fprintf(fp, "option wins %s\n", nvram_safe_get("dhcp_wins_x"));
189	if (nvram_invmatch("lan_domain", ""))
190		fprintf(fp, "option domain %s\n", nvram_safe_get("lan_domain"));
191	fclose(fp);
192
193
194	if (nvram_match("dhcp_static_x","1"))
195	{
196		write_static_leases(slease);
197		dhcpd_argv[2] = slease;
198	}
199	else
200	{
201		dhcpd_argv[2] = NULL;
202	}
203
204	_eval(dhcpd_argv, NULL, 0, &pid);
205
206
207	dprintf("done\n");
208	return 0;
209}
210
211int
212stop_dhcpd(void)
213{
214	char sigusr1[] = "-XX";
215	int ret;
216
217/*
218* Process udhcpd handles two signals - SIGTERM and SIGUSR1
219*
220*  - SIGUSR1 saves all leases in /tmp/udhcpd.leases
221*  - SIGTERM causes the process to be killed
222*
223* The SIGUSR1+SIGTERM behavior is what we like so that all current client
224* leases will be honorred when the dhcpd restarts and all clients can extend
225* their leases and continue their current IP addresses. Otherwise clients
226* would get NAK'd when they try to extend/rebind their leases and they
227* would have to release current IP and to request a new one which causes
228* a no-IP gap in between.
229*/
230	ret = eval("killall", "udhcpd");
231
232	dprintf("done\n");
233	return ret;
234}
235
236int
237start_dns(void)
238{
239	FILE *fp;
240	char *dproxy_argv[] = {"dproxy", "-d", "-c", "/tmp/dproxy.conf", NULL};
241	pid_t pid;
242	char word[100], *tmp;
243	int ret, active;
244
245	if (nvram_match("router_disable", "1"))
246		return 0;
247
248
249	/* Create resolv.conf with empty nameserver list */
250	if (!(fp = fopen("/tmp/resolv.conf", "r")))
251	{
252		if (!(fp = fopen("/tmp/resolv.conf", "w")))
253		{
254			perror("/tmp/resolv.conf");
255			return errno;
256		}
257		else fclose(fp);
258	}
259	else fclose(fp);
260
261	if (!(fp = fopen("/tmp/dproxy.conf", "w"))) {
262		perror("/tmp/dproxy.conf");
263		return errno;
264	}
265
266	fprintf(fp, "name_server=140.113.1.1\n");
267	fprintf(fp, "ppp_detect=no\n");
268	fprintf(fp, "purge_time=1200\n");
269	fprintf(fp, "deny_file=/tmp/dproxy.deny\n");
270	fprintf(fp, "cache_file=/tmp/dproxy.cache\n");
271	fprintf(fp, "hosts_file=/tmp/hosts\n");
272	fprintf(fp, "dhcp_lease_file=\n");
273	fprintf(fp, "ppp_dev=/var/run/ppp0.pid\n");
274	fclose(fp);
275
276	// if user want to set dns server by himself
277	if (nvram_invmatch("wan_dnsenable_x", "1"))
278	{
279		/* Write resolv.conf with upstream nameservers */
280		if (!(fp = fopen("/tmp/resolv.conf", "w"))) {
281			perror("/tmp/resolv.conf");
282			return errno;
283		}
284
285		if (nvram_invmatch("wan_dns1_x",""))
286			fprintf(fp, "nameserver %s\n", nvram_safe_get("wan_dns1_x"));
287		if (nvram_invmatch("wan_dns2_x",""))
288			fprintf(fp, "nameserver %s\n", nvram_safe_get("wan_dns2_x"));
289		fclose(fp);
290	}
291
292	active = timecheck_item(nvram_safe_get("url_date_x"),
293				nvram_safe_get("url_time_x"));
294
295	if (nvram_match("url_enable_x", "1") && active)
296	{
297		int i;
298
299		if (!(fp = fopen("/tmp/dproxy.deny", "w"))) {
300			perror("/tmp/dproxy.deny");
301			return errno;
302		}
303
304		for(i=0; i<atoi(nvram_safe_get("url_num_x")); i++) {
305			sprintf(word, "url_keyword_x%d", i);
306			fprintf(fp, "%s\n", nvram_safe_get(word));
307		}
308
309		fclose(fp);
310	}
311	else unlink("/tmp/dproxy.deny");
312
313
314	if (!(fp = fopen("/tmp/hosts", "w"))) {
315		perror("/tmp/hosts");
316		return errno;
317	}
318
319	fprintf(fp, "127.0.0.1 localhost.localdomain localhost\n");
320	fprintf(fp, "%s	my.router\n", nvram_safe_get("lan_ipaddr"));
321	fprintf(fp, "%s	my.%s\n", nvram_safe_get("lan_ipaddr"), nvram_safe_get("productid"));
322
323	if (nvram_invmatch("lan_hostname", ""))
324	{
325		fprintf(fp, "%s %s.%s %s\n", nvram_safe_get("lan_ipaddr"),
326					nvram_safe_get("lan_hostname"),
327					nvram_safe_get("lan_domain"),
328					nvram_safe_get("lan_hostname"));
329	}
330	fclose(fp);
331
332	_eval(dproxy_argv, NULL, 0, &pid);
333
334	dprintf("done\n");
335	return ret;
336}
337
338int
339stop_dns(void)
340{
341	int ret = eval("killall", "dproxy");
342	unlink("/tmp/dproxy.deny");
343	dprintf("done\n");
344	return ret;
345}
346
347int
348ddns_updated_main(int argc, char *argv[])
349{
350	FILE *fp;
351	char buf[64], *ip;
352
353	if (!(fp=fopen("/tmp/ddns.cache", "r"))) return 0;
354
355	fgets(buf, sizeof(buf), fp);
356	fclose(fp);
357
358	if (!(ip=strchr(buf, ','))) return 0;
359
360	nvram_set("ddns_cache", buf);
361	nvram_set("ddns_ipaddr", ip+1);
362	nvram_set("ddns_status", "1");
363	nvram_commit();
364
365	logmessage("ddns", "ddns update ok");
366
367	dprintf("done\n");
368
369	return 0;
370}
371
372
373int
374start_ddns(void)
375{
376	FILE *fp;
377	char buf[64];
378	char *wan_ip, *ddns_cache;
379	char server[32];
380	char user[32];
381	char passwd[32];
382	char host[64];
383	char service[32];
384	char usrstr[64];
385	char wan_ifname[16];
386	int  wild=nvram_match("ddns_wildcard_x", "1");
387
388
389	if (nvram_match("router_disable", "1")) return -1;
390
391	if (nvram_invmatch("ddns_enable_x", "1")) return -1;
392
393	if ((wan_ip = nvram_safe_get("wan_ipaddr_t"))==NULL) return -1;
394
395	if (nvram_match("ddns_ipaddr", wan_ip)) return -1;
396
397	if (inet_addr(wan_ip)==inet_addr(nvram_safe_get("ddns_ipaddr"))) return -1;
398
399	// TODO : Check /tmp/ddns.cache to see current IP in DDNS
400	// update when,
401	// 	1. if ipaddr!= ipaddr in cache
402	//
403        // update
404	// * nvram ddns_cache, the same with /tmp/ddns.cache
405
406
407	if ((fp=fopen("/tmp/ddns.cache", "r"))==NULL &&
408	     (ddns_cache=nvram_get("ddns_cache"))!=NULL)
409	{
410		if ((fp = fopen("/tmp/ddns.cache", "w+"))!=NULL)
411		{
412			fprintf(fp, "%s", ddns_cache);
413			fclose(fp);
414		}
415	}
416
417	strcpy(server, nvram_safe_get("ddns_server_x"));
418	strcpy(user, nvram_safe_get("ddns_username_x"));
419	strcpy(passwd, nvram_safe_get("ddns_passwd_x"));
420	strcpy(host, nvram_safe_get("ddns_hostname_x"));
421	strcpy(service, "");
422
423	if (strcmp(server, "WWW.DYNDNS.ORG")==0)
424		strcpy(service, "dyndns");
425	else if (strcmp(server, "WWW.DYNDNS.ORG(CUSTOM)")==0)
426		strcpy(service, "dyndns");
427	else if (strcmp(server, "WWW.DYNDNS.ORG(STATIC)")==0)
428		strcpy(service, "dyndns");
429	else if (strcmp(server, "WWW.TZO.COM")==0)
430		strcpy(service, "tzo");
431	else if (strcmp(server, "WWW.ZONEEDIT.COM")==0)
432		strcpy(service, "zoneedit");
433	else if (strcmp(server, "WWW.JUSTLINUX.COM")==0)
434		strcpy(service, "justlinux");
435	else if (strcmp(server, "WWW.EASYDNS.COM")==0)
436		strcpy(service, "easydns");
437	else strcpy(service, "dyndns");
438
439	sprintf(usrstr, "%s:%s", user, passwd);
440
441	if (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto", "pptp"))
442	{
443		strcpy(wan_ifname, nvram_safe_get("wan0_pppoe_ifname"));
444	}
445	else
446	{
447		strcpy(wan_ifname, nvram_safe_get("wan0_ifname"));
448	}
449
450	dprintf("wan_ifname: %s\n\n\n\n", wan_ifname);
451
452	if (strlen(service)>0)
453	{
454		char *ddns_argv[] = {"ez-ipupdate",
455		"-S", service,
456	        "-i", wan_ifname,
457 		"-u", usrstr,
458		"-h", host,
459		"-e", "/sbin/ddns_updated",
460		"-b", "/tmp/ddns.cache",
461		wild ? "-w" : NULL,
462		NULL};
463		pid_t pid;
464
465		dprintf("ddns update %s %s\n", server, service);
466		nvram_unset("ddns_cache");
467		nvram_unset("ddns_ipaddr");
468		nvram_unset("ddns_status");
469
470		eval("killall", "ez-ipupdate");
471		_eval(ddns_argv, NULL, 0, &pid);
472	}
473	return 0;
474}
475
476int
477stop_ddns(void)
478{
479	int ret = eval("killall", "ez-ipupdate");
480
481	dprintf("done\n");
482	return ret;
483}
484
485int
486start_logger(void)
487{
488	pid_t pid;
489
490	if (nvram_match("router_disable", "1"))
491		return 0;
492
493	if (nvram_invmatch("log_ipaddr", ""))
494	{
495		char *syslogd_argv[] = {"syslogd", "-m", "0", "-t", nvram_safe_get("time_zone_x"), "-O", "/tmp/syslog.log", "-R", nvram_safe_get("log_ipaddr"), "-L", NULL};
496#ifdef KERNEL_DBG
497		char *klogd_argv[] = {"klogd", "-d", NULL};
498#else
499		char *klogd_argv[] = {"klogd", NULL};
500#endif
501
502		//while(syslogd_argv[i]) printf("log: %s\n", syslogd_argv[i++]);
503
504		_eval(syslogd_argv, NULL, 0, &pid);
505		_eval(klogd_argv, NULL, 0, &pid);
506	}
507	else
508	{
509		char *syslogd_argv[] = {"syslogd", "-m", "0", "-t", nvram_safe_get("time_zone_x"), "-O", "/tmp/syslog.log", NULL};
510
511#ifdef KERNEL_DBG
512		char *klogd_argv[] = {"klogd", "-d", NULL};
513#else
514		char *klogd_argv[] = {"klogd", NULL};
515#endif
516
517		_eval(syslogd_argv, NULL, 0, &pid);
518		_eval(klogd_argv, NULL, 0, &pid);
519	}
520	// remote log not easy to ok
521	sleep(1);
522	return 0;
523}
524
525int
526stop_logger(void)
527{
528	int ret1 = eval("killall", "klogd");
529	int ret2 = eval("killall", "syslogd");
530
531	dprintf("done\n");
532	return (ret1|ret2);
533}
534
535int
536start_misc(void)
537{
538	char *infosvr_argv[] = {"infosvr", "br0", NULL};
539	char *watchdog_argv[] = {"watchdog", NULL};
540	pid_t pid;
541
542	_eval(infosvr_argv, NULL, 0, &pid);
543	_eval(watchdog_argv, NULL, 0, &pid);
544
545	/* adjust some special parameters here */
546	/* tx power */
547#ifdef CHIP5352
548	/* adjust some special parameters here */
549	/* tx power */
550	if (nvram_match("wl_radio_power_x", "0"))
551	{
552		eval("wl", "txpwr1", "-o", "-q", "14");
553	}
554	else if (nvram_match("wl_radio_power_x", "1"))
555        {
556                eval("wl", "txpwr1", "-o", "-q", "15");
557        }
558	else if (nvram_match("wl_radio_power_x", "2"))
559        {
560                eval("wl", "txpwr1", "-o", "-q", "20");
561        }
562	else if (nvram_match("wl_radio_power_x", "3"))
563        {
564                eval("wl", "txpwr1", "-o", "-q", "22");
565        }
566	else if (nvram_match("wl_radio_power_x", "4"))
567        {
568                eval("wl", "txpwr1", "-o", "-q", "23");
569        }
570	else if (nvram_match("wl_radio_power_x", "5"))
571        {
572                eval("wl", "txpwr1", "-o", "-q", "25");
573        }
574	else if (nvram_match("wl_radio_power_x", "6"))
575        {
576                eval("wl", "txpwr1", "-o", "-q", "30");
577        }
578	else if (nvram_match("wl_radio_power_x", "7"))
579        {
580                eval("wl", "txpwr1", "-o", "-q", "35");
581        }
582	else if (nvram_match("wl_radio_power_x", "8"))
583        {
584                eval("wl", "txpwr1", "-o", "-q", "40");
585        }
586	else if (nvram_match("wl_radio_power_x", "9"))
587        {
588                eval("wl", "txpwr1", "-o", "-q", "45");
589        }
590	else if (nvram_match("wl_radio_power_x", "10"))
591        {
592                eval("wl", "txpwr1", "-o", "-q", "50");
593        }
594#else
595	if (nvram_invmatch("wl_radio_power_x", "19"))
596	{
597		eval("wl", "txpwr", nvram_safe_get("wl_radio_power_x"));
598	}
599#endif
600
601
602	// for all product, fix antdiv
603	eval("wl", "antdiv", "0");
604	eval("wl", "txant", "0");
605
606	if (nvram_match("wl_radio_x", "0"))
607		wl_led_ctrl(0);
608
609	return 0;
610}
611
612int
613stop_misc(void)
614{
615	int ret1 = eval("killall", "infosvr");
616	int ret2 = eval("killall", "watchdog");
617	int ret3 = eval("killall", "ntp");
618
619	dprintf("done\n");
620	return(ret1);
621}
622
623#ifndef USB_SUPPORT
624int start_usb(void)
625{
626	return 0;
627}
628
629int stop_usb(void)
630{
631	return 0;
632}
633
634int hotplug_usb(void)
635{
636	return 0;
637}
638#else
639int
640start_usb(void)
641{
642	eval("insmod", "usbcore");
643	eval("insmod", "usb-ohci");
644	eval("insmod", "uhci");
645	eval("insmod", "ehci-hcd");
646
647#ifdef CDMA
648	eval("insmod", "acm.o");
649	eval("insmod", "usbserial.o", "vendor=0x1165", "product=0x0001");
650#endif
651
652#ifdef PRINTER_SUPPORT
653#ifdef PARPORT_SUPPORT
654	symlink("/dev/printers/0", "/dev/lp0");
655	symlink("/dev/lp0", "/tmp/lp0");
656	eval("insmod", "parport.o");
657	eval("insmod", "parport_splink.o");
658	eval("insmod", "lp.o");
659#endif
660	eval("insmod", "printer.o");
661	mkdir("/var/state", 0777);
662	mkdir("/var/state/parport", 0777);
663	mkdir("/var/state/parport/svr_statue", 0777);
664	{
665		char *lpd_argv[]={"lpd", NULL};
666		pid_t pid;
667
668		sleep(1);
669		_eval(lpd_argv, ">/dev/null", 0, &pid);
670	}
671#endif
672#ifdef AUDIO_SUPPORT
673	eval("insmod", "soundcore.o");
674	eval("insmod", "audio.o");
675	start_audio();
676#endif
677#ifdef WEBCAM_SUPPORT
678	if (nvram_invmatch("usb_webenable_x", "0"))
679	{
680		eval("insmod", "videodev.o");
681
682		// link video
683		symlink("/dev/v4l/video0", "/dev/video");
684		start_rcamd();
685	}
686#endif
687#ifdef MASSSTORAGE_SUPPORT
688	if (nvram_invmatch("usb_ftpenable_x", "0"))
689	{
690		eval("insmod", "scsi_mod.o");
691		eval("insmod", "sd_mod.o");
692		eval("insmod", "usb-storage.o");
693		mkdir("/tmp/harddisk", 0444);
694	}
695#endif
696}
697
698int
699stop_usb(void)
700{
701#ifdef MASSSTORAGE_SUPPORT
702	if (nvram_invmatch("usb_ftpenable_x", "0"))
703	{
704		eval("killall", "stupid-fptd");
705		eval("rmmod", "usb-storage");
706		eval("rmmod", "sd_mod");
707		eval("rmmod", "scsi_mod");
708	}
709#endif
710#ifdef WEBCAM_SUPPORT
711	if (nvram_invmatch("usb_webenable_x", "0"))
712	{
713		stop_rcamd();
714		eval("killall", "rcamd");
715		eval("killall", "sendmail");
716		eval("rmmod", "pwc");
717		eval("rmmod", "ov511_decomp");
718		eval("rmmod", "ov518_decomp");
719		eval("rmmod", "ov51x");
720		eval("rmmod", "i2c-core");
721		eval("rmmod", "videodev");
722	}
723#endif
724#ifdef AUDIO_SUPPORT
725	eval("rmmod", "audio");
726	eval("rmmod", "soundcore");
727	stop_audio();
728#endif
729#ifdef PRINTER_SUPPORT
730	eval("killall", "lpd");
731	eval("rmmod", "printer");
732#ifdef PARPORT_SUPPORT
733	eval("rmmod", "lp.o");
734	eval("rmmod", "parport_splink.o");
735	eval("rmmod", "parport.o");
736#endif
737#endif
738	eval("rmmod", "usb-ehci");
739	eval("rmmod", "usb-ohci");
740	eval("rmmod", "usbcore");
741}
742
743void start_script(void)
744{
745	pid_t pid;
746	FILE *fp;
747	char *script;
748	char runbuf[512];
749
750	script = nvram_safe_get("usb_ftpscript_x");
751	if (strlen(script)==0) return;
752	sprintf(runbuf, "/tmp/harddisk/%s", script);
753	fp=fopen(runbuf, "r");
754
755	if (fp)
756	{
757		fclose(fp);
758
759		//char *script_argv[]={"/tmp/harddisk/init.usb", NULL};
760		//_eval(script_argv, NULL, 0, &pid);
761
762		logmessage("USB storage", "start user specified script");
763		eval(runbuf);
764	}
765}
766
767void start_ftpd()
768{
769	FILE *fp;
770	char *ftpd_argv[] = {"stupid-ftpd", NULL};
771	char user[32], user1[32], password[32], path[32];
772	char tmpstr[32];
773	char rright[128], wright[128], maxuser[16];
774	int snum, unum, i, j;
775	pid_t pid;
776
777
778	fp=fopen("/tmp/stupid-ftpd.mtd", "w");
779	if (fp==NULL) return;
780	fprintf(fp, "Welcom to My FTP Site:\n");
781	fclose(fp);
782
783	fp=fopen("/tmp/stupid-ftpd.bye", "w");
784	if (fp==NULL) return;
785	fprintf(fp, "Thanks for your coming. Byte Byte!!\n");
786	fclose(fp);
787
788	fp=fopen("/tmp/stupid-ftpd.conf", "w");
789	if (fp==NULL) return;
790
791	fprintf(fp, "mode=daemon\n");
792	fprintf(fp, "serverroot=/tmp/harddisk\n");
793	fprintf(fp, "changeroottype=real\n");
794
795	fprintf(fp, "motd=/tmp/stupid-ftpd.motd\n");
796	fprintf(fp, "byemsg=/tmp/stupid-ftpd.bye\n");
797	fprintf(fp, "banmsg=You have no permission\n");
798	fprintf(fp, "log=/tmp/stupid-ftpd.log\n");
799	fprintf(fp, "port=%s\n", nvram_safe_get("usb_ftpport_x"));
800	fprintf(fp, "maxusers=%s\n", nvram_safe_get("usb_ftpmax_x"));
801	fprintf(fp, "login-timeout=%s\n", nvram_safe_get("usb_ftptimeout_x"));
802	fprintf(fp, "timeout=%s\n", nvram_safe_get("usb_ftpstaytimeout_x"));
803
804
805	if (nvram_match("usb_ftpanonymous_x", "1"))
806	{
807		fprintf(fp, "user=anonymous * // 0 A\n");
808	}
809	if (nvram_match("usb_ftpsuper_x", "1"))
810	{
811		fprintf(fp, "user=%s %s // 0 A\n", nvram_safe_get("http_username"), nvram_safe_get("http_passwd"));
812	}
813
814	write_ftp_banip(fp);
815	write_ftp_userlist(fp);
816	fclose(fp);
817
818	//_eval(ftpd_argv, NULL, 0, &pid);
819	eval("stupid-ftpd");
820}
821
822int
823hotplug_usb_webcam(char *product, int webflag)
824{
825	char *rcamd_argv[]={"rcamd",
826				"-p", nvram_safe_get("usb_webactivex_x"),
827				"-s", "0",
828				"-z", nvram_safe_get("time_zone_x"),
829				"-a", nvram_safe_get("usb_websecurity_x"),
830				NULL, NULL,	// Model -t
831				NULL, NULL,	// Record Time -r
832				NULL, NULL, 	// Image Size -f
833				NULL, NULL, 	// Sense Vlaue -m
834				NULL, NULL, 	// Sense Limit -c
835				NULL, NULL,
836				NULL};
837	char **arg;
838	pid_t pid;
839
840	if (nvram_match("usb_webenable_x", "0") || strlen(product)==0 || webflag==0) return;
841	for (arg = rcamd_argv; *arg; arg++);
842
843	if (webflag == WEB_PWCWEB)
844	{
845		eval("insmod", "pwc.o", "power_save=0");
846		nvram_set("usb_webdriver_x", "0");
847
848		*arg++ = "-t";
849		*arg++ = "0";
850	}
851	else
852	{
853		eval("insmod", "i2c-core.o");
854		eval("insmod", "ov51x.o");
855		eval("insmod", "ov511_decomp.o");
856		eval("insmod", "ov518_decomp.o");
857		nvram_set("usb_webdriver_x", "1");
858
859		if (strstr(product, "8519"))
860		{
861			*arg++ = "-t";
862			*arg++ = "2";
863		}
864		else
865		{
866			*arg++ = "-t";
867			*arg++ = "1";
868		}
869	}
870
871	// start web cam
872	if (nvram_match("usb_webmode_x", "0")) // ActiveX only
873	{
874		*arg++ = "-r";
875		*arg++ = "60";
876	}
877	else
878	{
879		*arg++ = "-r";
880		*arg++ = "0";
881	}
882
883	// image size
884	if (nvram_match("usb_webimage_x", "0"))
885	{
886		*arg++ = "-f";
887		if (webflag==WEB_PWCWEB) *arg++="320x240";
888		else *arg++="640x480";
889	}
890	else if (nvram_match("usb_webimage_x", "1"))
891	{
892		*arg++ = "-f";
893		*arg++="320x240";
894	}
895	else if (nvram_match("usb_webimage_x", "2"))
896	{
897		*arg++ = "-f";
898		if (webflag==WEB_PWCWEB) *arg++="160x120";
899		else *arg++="176x144";
900	}
901	else
902	{
903		*arg++ = "-f";
904		*arg++ = "80x60";
905	}
906
907
908	if (nvram_match("usb_websense_x", "0"))
909	{
910		*arg++ = "-m";
911		*arg++ = "150";
912		*arg++ = "-c";
913		*arg++ = "100";
914	}
915	else if (nvram_match("usb_websense_x", "1"))
916	{
917		*arg++ = "-m";
918		*arg++ = "100";
919		*arg++ = "-c";
920		*arg++ = "100";
921	}
922	else
923	{
924		*arg++ = "-m";
925		*arg++ = "50";
926		*arg++ = "-c";
927		*arg++ = "100";
928	}
929
930
931	//*arg++="-d";
932	//*arg++="7";
933	mkdir("/tmp/webcam", 0777);
934	chdir("/tmp/webcam");
935
936	symlink("/www/Advanced_ShowTime_Widzard.asp", "/tmp/webcam/index.asp");
937	symlink("/www/Advanced_ShowTime_Widzard.asp", "/tmp/webcam/ShowWebCam.asp");
938	symlink("/www/ShowWebCamPic.asp", "/tmp/webcam/ShowWebCamPic.asp");
939	symlink("/www/graph", "/tmp/webcam/graph");
940	symlink("/www/general.js", "/tmp/webcam/general.js");
941	symlink("/www/overlib.js", "/tmp/webcam/overlib.js");
942	symlink("/www/style.css", "/tmp/webcam/style.css");
943	symlink("/www/netcam_mfc_activeX.cab", "/tmp/webcam/netcam_mfc_activeX.cab");
944	symlink("/var/tmp/display.jpg", "/tmp/webcam/display.jpg");
945
946	//char *httpd_argv[]={"httpd",
947	//			nvram_safe_get("wan0_ifname"),
948	//			nvram_safe_get("usb_webhttpport_x"),
949	//			NULL};
950	//_eval(httpd_argv, NULL, 0, &pid);
951	eval("httpd", nvram_safe_get("wan0_ifname"), nvram_safe_get("usb_webhttpport_x"));
952	chdir("/");
953	_eval(rcamd_argv, ">/dev/null", 0, NULL);
954
955	return 0;
956}
957
958int
959remove_webcam_main(int webflag)
960{
961	if (webflag == WEB_PWCWEB)
962	{
963		eval("rmmod", "pwc");
964	}
965	else
966	{
967		eval("rmmod", "i2c-core");
968		eval("rmmod", "ov511_decomp");
969		eval("rmmod", "ov518_decomp");
970		eval("rmmod", "ov51x");
971	}
972	nvram_set("usb_webdriver_x", "");
973	return 0;
974}
975
976
977int
978remove_usb_webcam(char *product, int webflag)
979{
980	char pidfile[32];
981	sprintf(pidfile, "/var/run/httpd-%s.pid", nvram_safe_get("usb_webhttpport_x"));
982
983	kill_pidfile(pidfile);
984	kill_pidfile("/var/run/rcamd.pid");
985
986	if (webflag == WEB_PWCWEB)
987	{
988		eval("rmmod", "pwc");
989	}
990	else
991	{
992		eval("rmmod", "i2c-core");
993		eval("rmmod", "ov511_decomp");
994		eval("rmmod", "ov518_decomp");
995		eval("rmmod", "ov51x");
996	}
997	nvram_set("usb_webdriver_x", "");
998
999	return 0;
1000}
1001
1002
1003int
1004start_rcamd(void)
1005{
1006	char *rcamd_argv[] = {"rcamdmain", NULL};
1007	pid_t pid;
1008
1009	_eval(rcamd_argv, NULL, 0, &pid);
1010	return 0;
1011}
1012
1013int
1014stop_rcamd(void)
1015{
1016	int ret = eval("killall", "rcamdmain");
1017}
1018
1019
1020/*to unmount all partitions*/
1021int
1022umount_all_part(char *usbdevice)
1023{
1024	int n;
1025	DIR *dir_to_open;
1026	struct dirent *dp;
1027	char umount_dir[32];
1028
1029
1030	if(!(dir_to_open = opendir("/tmp/harddisk")))
1031		perror("***cannot open /tmp/harddisk\n");
1032
1033	while(dir_to_open && (dp=readdir(dir_to_open)))
1034	{
1035		if(strncmp(dp->d_name, "..", NAME_MAX) == 0 ||
1036		strncmp(dp->d_name, ".", NAME_MAX) == 0 ||
1037		strncmp(dp->d_name, "part", 4) != 0)
1038			continue;
1039
1040		sprintf(umount_dir, "/tmp/harddisk/%s", dp->d_name);
1041		if(umount(umount_dir))
1042		{
1043			//perror("umount failed");
1044		}
1045		//eval("umount", umount_dir);
1046	}
1047
1048	if (dir_to_open)
1049		closedir(dir_to_open);
1050
1051	sprintf(umount_dir, "/tmp/harddisk");
1052
1053	//logs(umount_dir);
1054
1055	// retry 3 times
1056	if(umount(umount_dir))
1057	{
1058		//perror("umount failed");
1059	}
1060	//eval("umount", umount_dir);
1061	return 0;
1062}
1063
1064/* remove usb mass storage */
1065int
1066remove_usb_mass(char *product)
1067{
1068#ifdef REMOVE
1069	if (product!=NULL)
1070	   logmessage("USB storage", product);
1071	else
1072    	   logmessage("USB storage", "NULL");
1073#endif
1074
1075	if (product==NULL || nvram_match("usb_ftp_device", product))
1076	{
1077		eval("killall", "stupid-ftpd");
1078		sleep(1);
1079		umount_all_part("usb");
1080		nvram_set("usb_ftp_device", "");
1081		logmessage("USB storage", "removed");
1082	}
1083	return 0;
1084}
1085
1086int mkdir_if_none(char *dir)
1087{
1088	DIR *dp;
1089	if(!(dp=opendir(dir)))
1090		return(mkdir(dir, 0777));
1091	closedir(dp);
1092	return 0;
1093}
1094
1095int
1096remove_storage_main(void)
1097{
1098	remove_usb_mass(NULL);
1099	return 0;
1100}
1101
1102#define MOUNT_VAL_FAIL 	0
1103#define MOUNT_VAL_RONLY	1
1104#define MOUNT_VAL_RW 	2
1105
1106int
1107mount_r(char *usb_part, char *usb_file_part)
1108{
1109	char msg[64];
1110
1111	if(!mount(usb_part, usb_file_part, "ext2", MS_SYNCHRONOUS, NULL))
1112	{
1113		sprintf(msg, "ext2 fs mounted to %s\n", usb_file_part);
1114		logmessage("USB storage", msg);
1115		return MOUNT_VAL_RW;
1116	}
1117#ifdef LANGUAGE_EN
1118	if(!mount(usb_part, usb_file_part, "vfat", MS_SYNCHRONOUS, NULL))
1119	{
1120		sprintf(msg, "vfat fs mounted to %s\n", usb_file_part);
1121		logmessage("USB storage", msg);
1122		return MOUNT_VAL_RW;
1123	}
1124#endif
1125#ifdef LANGUAGE_TW
1126	if(!mount(usb_part, usb_file_part, "vfat", MS_SYNCHRONOUS, "codepage=950,iocharset=cp950"))
1127	{
1128		sprintf(msg, "vfat fs mounted to %s\n", usb_file_part);
1129		logmessage("USB storage", msg);
1130		return MOUNT_VAL_RW;
1131	}
1132#endif
1133#ifdef LANGUAGE_CN
1134	if(!mount(usb_part, usb_file_part, "vfat", MS_SYNCHRONOUS, "codepage=936,iocharset=cp936"))
1135	{
1136		sprintf(msg, "vfat fs mounted to %s\n", usb_file_part);
1137		logmessage("USB storage", msg);
1138		return MOUNT_VAL_RW;
1139	}
1140#endif
1141#ifdef LANGUAGE_KR
1142	if(!mount(usb_part, usb_file_part, "vfat", MS_SYNCHRONOUS, "codepage=949,iocharset=cp949"))
1143	{
1144		sprintf(msg, "vfat fs mounted to %s\n", usb_file_part);
1145		logmessage("USB storage", msg);
1146		return MOUNT_VAL_RW;
1147	}
1148#endif
1149#ifdef LANGUAGE_JP
1150	if(!mount(usb_part, usb_file_part, "vfat", MS_SYNCHRONOUS, "codepage=932,iocharset=cp932"))
1151	{
1152		sprintf(msg, "vfat fs mounted to %s\n", usb_file_part);
1153		logmessage("USB storage", msg);
1154		return MOUNT_VAL_RW;
1155	}
1156#endif
1157
1158	if(!mount(usb_part, usb_file_part, "msdos", MS_SYNCHRONOUS, NULL))
1159	{
1160		sprintf(msg, "msdos fs mounted to %s\n", usb_file_part);
1161		logmessage("USB storage", msg);
1162		return MOUNT_VAL_RW;
1163	}
1164#ifdef LANGUAGE_EN
1165	if(!mount(usb_part, usb_file_part, "ntfs", MS_SYNCHRONOUS, NULL))
1166	{
1167		sprintf(msg, "ntfs(ro) fs mounted to %s\n", usb_file_part);
1168		logmessage("USB storage", msg);
1169		return MOUNT_VAL_RONLY;
1170	}
1171#endif
1172#ifdef LANGUAGE_TW
1173	if(!mount(usb_part, usb_file_part, "ntfs", MS_SYNCHRONOUS, "iocharset=cp932"))
1174	{
1175		sprintf(msg, "ntfs(ro) fs mounted to %s\n", usb_file_part);
1176		logmessage("USB storage", msg);
1177		return MOUNT_VAL_RONLY;
1178	}
1179#endif
1180#ifdef LANGUAGE_CN
1181	if(!mount(usb_part, usb_file_part, "ntfs", MS_SYNCHRONOUS, "iocharset=cp936"))
1182	{
1183		sprintf(msg, "ntfs(ro) fs mounted to %s\n", usb_file_part);
1184		logmessage("USB storage", msg);
1185		return MOUNT_VAL_RONLY;
1186	}
1187#endif
1188#ifdef LANGUAGE_KR
1189	if(!mount(usb_part, usb_file_part, "ntfs", MS_SYNCHRONOUS, "iocharset=cp949"))
1190	{
1191		sprintf(msg, "ntfs(ro) fs mounted to %s\n", usb_file_part);
1192		logmessage("USB storage", msg);
1193		return MOUNT_VAL_RONLY;
1194	}
1195#endif
1196#ifdef LANGUAGE_JP
1197	if(!mount(usb_part, usb_file_part, "ntfs", MS_SYNCHRONOUS, "iocharset=cp950"))
1198	{
1199		sprintf(msg, "ntfs(ro) fs mounted to %s\n", usb_file_part);
1200		logmessage("USB storage", msg);
1201		return MOUNT_VAL_RONLY;
1202	}
1203#endif
1204	return MOUNT_VAL_FAIL;
1205}
1206
1207/* insert usb mass storage */
1208hotplug_usb_mass(char *product)
1209{
1210	DIR *dir_to_open, *dir_of_usb, *usb_dev_disc, *usb_dev_part;
1211	char usb_disc[128], usb_part[128], usb_file_part[128];
1212	int n = 0, m;
1213	struct dirent *dp, *dp_disc, **dpopen;
1214
1215	if (nvram_match("usb_ftpenable_x", "0")) return;
1216
1217	dir_to_open=dir_of_usb=usb_dev_disc=usb_dev_part=NULL;
1218
1219	// Mount USB to system
1220	if((usb_dev_disc = opendir("/dev/discs")))
1221	{
1222		while(usb_dev_disc && (dp=readdir(usb_dev_disc)))
1223		{
1224			if(!strncmp(dp->d_name, "..", NAME_MAX) || !strncmp(dp->d_name, ".", NAME_MAX) /*|| !strncmp(dp->d_name, "disc0", NAME_MAX)*/)
1225				continue;
1226
1227			sprintf(usb_disc, "/dev/discs/%s", dp->d_name);
1228
1229			//logs(usb_disc);
1230
1231			if((usb_dev_part = opendir(usb_disc)))
1232			{
1233				m = 0;
1234
1235				while(usb_dev_part && (dp_disc=readdir(usb_dev_part)))
1236				{
1237					//logs(dp_disc->d_name);
1238
1239					if(!strncmp(dp_disc->d_name, "..", NAME_MAX) || !strncmp(dp_disc->d_name, ".", NAME_MAX) ||
1240!strncmp(dp_disc->d_name, "disc", NAME_MAX))
1241						continue;
1242
1243					sprintf(usb_part, "/dev/discs/%s/%s", dp->d_name, dp_disc->d_name);
1244
1245					if (n==0)
1246						sprintf(usb_file_part, "/tmp/harddisk");
1247					else
1248						sprintf(usb_file_part, "/tmp/harddisk/part%d", n);
1249
1250					mkdir_if_none(usb_file_part);
1251#if MOUNTALL
1252					eval("mount", usb_part, usb_file_part);
1253#else
1254					if (mount_r(usb_part, usb_file_part))
1255					{
1256						n++;
1257						m++;
1258					}
1259#endif
1260				}
1261
1262				if (!m) // There is no other partition
1263				{
1264
1265					sprintf(usb_part, "/dev/discs/%s/disc", dp->d_name);
1266					if (n==0)
1267						sprintf(usb_file_part, "/tmp/harddisk");
1268					else
1269						sprintf(usb_file_part, "/tmp/harddisk/part%d", n++);
1270#ifdef MOUNTALL
1271					eval("mount", usb_part, usb_file_part);
1272#else
1273					if(mount_r(usb_part, usb_file_part))
1274					{
1275						n++;
1276					}
1277#endif
1278				}
1279			}
1280
1281		}
1282	}
1283
1284	if (n)
1285	{
1286		nvram_set("usb_ftp_device", product);
1287		start_ftpd();
1288		//logmessage("USB storage", "attached");
1289		start_script();
1290		//run script if any
1291	}
1292	else
1293	{
1294
1295	}
1296
1297#ifdef USBCOPY_SUPPORT
1298	n = 1;
1299	if((dir_to_open = opendir("/tmp/harddisk")))
1300	{
1301		while(dir_to_open && (dp=readdir(dir_to_open)))
1302		{
1303			if(!strncmp(dp->d_name, "..", NAME_MAX) || !strncmp(dp->d_name, ".", NAME_MAX) || !strncmp(dp->d_name, "part", 4))
1304				continue;
1305			sprintf(usb_part, "/tmp/harddisk/%s", dp->d_name);
1306			if(scandir(usb_part, &dpopen, 0, alphasort) <= 2)
1307				continue;
1308			while(1)
1309			{
1310				sprintf(path_copy_to, "/tmp/harddisk/part1/USBpart%03d", n);
1311				if(!opendir(path_copy_to))
1312				{
1313					if(mkdir(path_copy_to, 0777))
1314					{
1315						perror("error on creating usb directory");
1316					}
1317					eval("echo", path_copy_to);
1318					break;
1319				}
1320				else
1321					n++;
1322			}
1323			if((dir_of_usb = opendir(usb_part)))
1324			{
1325				while(dir_of_usb && (dp_disc=readdir(dir_of_usb)))
1326				{
1327					if(!strncmp(dp_disc->d_name, "..", NAME_MAX) || !strncmp(dp_disc->d_name, ".", NAME_MAX))
1328						continue;
1329					sprintf(path_to_copy, "/tmp/harddisk/%s/%s", dp->d_name, dp_disc->d_name);
1330					eval("cp", "-Rf", path_to_copy, path_copy_to);
1331					sync();
1332				}
1333			}
1334			n++;
1335		}
1336	}
1337#endif
1338	if(usb_dev_disc)
1339		closedir(usb_dev_disc);
1340	if(usb_dev_part)
1341		closedir(usb_dev_part);
1342	if(dir_to_open)
1343		closedir(dir_to_open);
1344
1345	return 0;
1346}
1347
1348/* plugging or removing usb device */
1349/* usbcore, usb-ohci, usb-ehci, printer are always there */
1350/* usb-storage, sd_mod, scsi_mod, videodev are there if functions are enabled */
1351/* pwc, ov511 i2c, depends on current status */
1352
1353int
1354hotplug_usb(void)
1355{
1356	char *action, *interface, *product, *type;
1357	int i;
1358	int isweb;
1359	char flag[6];
1360
1361	if( !(interface = getenv("INTERFACE")) || !(action = getenv("ACTION")))
1362		return EINVAL;
1363
1364	if ((product=getenv("PRODUCT")))
1365	{
1366		nvram_set("cdma_interface", interface);
1367		nvram_set("cdma_product", product);
1368		if (strncmp(interface, "1/1", 3)==0)
1369		{
1370			// if the audio device is the same with web cam,
1371			// just skip it
1372			if (nvram_match("usb_web_device", product))
1373				return 0;
1374			isweb = WEB_AUDIO;
1375			goto usbhandler;
1376		}
1377		else if(strncmp(interface, "1/", 2)==0)
1378			return 0;
1379		i=0;
1380		isweb = WEB_NONE;
1381		while(PWCLIST[i]!=NULL)
1382		{
1383			if (strstr(product, PWCLIST[i]))
1384			{
1385				isweb = WEB_PWCWEB;
1386				goto usbhandler;
1387			}
1388			i++;
1389		}
1390		i=0;
1391		while(OVLIST[i]!=NULL)
1392		{
1393			if (strstr(product, OVLIST[i]))
1394			{
1395				isweb = WEB_OVWEB;
1396				goto usbhandler;
1397			}
1398			i++;
1399		}
1400	}
1401	else return 0;
1402
1403usbhandler:
1404	if (strstr(action, "add"))
1405	{
1406		nvram_set("usb_device", "1");
1407		if (isweb==WEB_NONE)
1408		{
1409			if (nvram_match("usb_ftp_device", "")) // Treat it as USB storage
1410			{
1411				nvram_set("usb_storage_device", product);
1412			}
1413		}
1414		else if (isweb==WEB_AUDIO)
1415		{
1416			if (nvram_match("usb_audio_device", ""))
1417				logmessage("USB audio", "attached");
1418			nvram_set("usb_audio_device", product);
1419			refresh_wave();
1420		}
1421		else
1422		{
1423			if (nvram_match("usb_web_device", ""))
1424				logmessage("USB webcam", "attached");
1425
1426			sprintf(flag, "%d", isweb);
1427			nvram_set("usb_web_device", product);
1428			nvram_set("usb_web_flag", flag);
1429			nvram_set("usb_webdriver_x", "");
1430		}
1431	}
1432	else
1433	{
1434		if (isweb==WEB_NONE) // Treat it as USB Storage
1435		{
1436			remove_usb_mass(product);
1437		}
1438		else if(isweb==WEB_AUDIO)
1439		{
1440			remove_usb_audio(product);
1441			nvram_set("usb_audio_device", "");
1442		}
1443		else
1444		{
1445			if (nvram_invmatch("usb_web_device", ""))
1446			{
1447				logmessage("USB webcam", "removed");
1448				nvram_set("usb_web_device", "");
1449				nvram_set("usb_web_flag", "");
1450			}
1451			remove_usb_webcam(product, isweb);
1452		}
1453	}
1454	return 0;
1455}
1456#endif
1457
1458/* stop necessary services for firmware upgrade */
1459/* stopservice: for firmware upgarde */
1460/* stopservice 1: for button setup   */
1461int
1462stop_service_main(int type)
1463{
1464	if (type==1)
1465	{
1466		//stop_misc();
1467		//stop_logger();
1468		stop_usb();
1469		stop_nas();
1470		stop_upnp();
1471		//stop_dhcpd();
1472		stop_dns();
1473		stop_httpd();
1474		eval("killall", "udhcpc");
1475		//eval("killall", "infosvr");
1476	}
1477	else
1478	{
1479		stop_misc();
1480		stop_logger();
1481		stop_usb();
1482
1483		stop_nas();
1484		stop_upnp();
1485		stop_dhcpd();
1486		stop_dns();
1487	}
1488
1489	dprintf("done\n");
1490	return 0;
1491}
1492
1493int service_handle(void)
1494{
1495	char *service;
1496	char tmp[100], *str;
1497	int unit;
1498	int pid;
1499	char *ping_argv[] = { "ping", "140.113.1.1", NULL};
1500	FILE *fp;
1501
1502	service = nvram_get("rc_service");
1503
1504	if(!service)
1505		kill(1, SIGHUP);
1506
1507	if(strstr(service,"wan_disconnect")!=NULL)
1508	{
1509		cprintf("wan disconnect\n");
1510
1511		logmessage("wan", "disconnected manually");
1512
1513		if (nvram_match("wan0_proto", "dhcp") ||
1514#ifdef CDMA
1515		    nvram_match("wan0_proto", "cdma") ||
1516#endif
1517		    nvram_match("wan0_proto", "bigpond"))
1518		{
1519			snprintf(tmp, sizeof(tmp), "/var/run/udhcpc%d.pid", 0);
1520			if ((str = file2str(tmp))) {
1521				pid = atoi(str);
1522				free(str);
1523				kill(pid, SIGUSR2);
1524			}
1525		}
1526		else
1527		{
1528			stop_wan2();
1529			update_wan_status(0);
1530			sleep(3);
1531		}
1532	}
1533	else if (strstr(service,"wan_connect")!=NULL)
1534	{
1535		cprintf("wan connect\n");
1536		logmessage("wan", "connected manually");
1537		setup_ethernet(nvram_safe_get("wan_ifname"));
1538
1539		if (nvram_match("wan0_proto", "dhcp") ||
1540#ifdef CDMA
1541		    nvram_match("wan0_proto", "cdma") ||
1542#endif
1543		    nvram_match("wan0_proto", "bigpond"))
1544		{
1545			snprintf(tmp, sizeof(tmp), "/var/run/udhcpc%d.pid", 0);
1546			if ((str = file2str(tmp))) {
1547				pid = atoi(str);
1548				free(str);
1549				kill(pid, SIGUSR1);
1550			}
1551		}
1552		else
1553		{
1554#ifndef REMOVE
1555			// pppoe or ppptp, check if /tmp/ppp exist
1556			if (nvram_invmatch("wan0_proto", "static") && (fp=fopen("/tmp/ppp/ip-up", "r"))!=NULL)
1557			{
1558				fclose(fp);
1559				_eval(ping_argv, NULL, 0, &pid);
1560
1561			}
1562			else
1563			{
1564				stop_wan();
1565				sleep(3);
1566				start_wan();
1567				sleep(2);
1568				_eval(ping_argv, NULL, 0, &pid);
1569			}
1570#endif
1571
1572#ifdef REMOVE
1573			stop_wan();
1574			sleep(2);
1575			start_wan();
1576			/* trigger connect */
1577			eval("ntpclient", "-h", "test", "-c", "1");
1578#endif
1579
1580		}
1581	}
1582	nvram_unset("rc_service");
1583	return 0;
1584}
1585
1586#ifdef AUDIO_SUPPORT
1587int hotplug_usb_audio(char *product)
1588{
1589	char *wave_argv[]={"waveserver", NULL};
1590	pid_t pid;
1591
1592	if (strlen(product)==0) return;
1593	_eval(wave_argv, ">/dev/null", 0, NULL);
1594}
1595
1596int remove_usb_audio(char *product)
1597{
1598	eval("killall", "waveserver");
1599}
1600
1601int
1602start_audio(void)
1603{
1604	char *wave_argv[] = {"waveservermain", NULL};
1605	pid_t pid;
1606
1607	_eval(wave_argv, NULL, 0, &pid);
1608	return 0;
1609}
1610
1611int
1612stop_audio(void)
1613{
1614	int ret = eval("killall", "waveserver");
1615}
1616#endif
1617#endif
1618
1619#ifdef GUEST_ACCOUNT
1620int
1621start_dhcpd_guest(void)
1622{
1623	FILE *fp;
1624	char *dhcpd_argv[] = {"udhcpd", "/tmp/udhcpd1.conf", NULL, NULL};
1625	char *slease = "/tmp/udhcpd-br1.sleases";
1626	pid_t pid;
1627
1628	if (nvram_match("router_disable", "1") || nvram_invmatch("wl_guest_enable", "1") || nvram_invmatch("lan1_proto", "dhcp"))
1629		return 0;
1630
1631	dprintf("%s %s %s %s\n",
1632		nvram_safe_get("lan1_ifname"),
1633		nvram_safe_get("dhcp1_start"),
1634		nvram_safe_get("dhcp1_end"),
1635		nvram_safe_get("lan1_lease"));
1636
1637	if (!(fp = fopen("/tmp/udhcpd-br1.leases", "a"))) {
1638		perror("/tmp/udhcpd-br1.leases");
1639		return errno;
1640	}
1641	fclose(fp);
1642
1643	/* Write configuration file based on current information */
1644	if (!(fp = fopen("/tmp/udhcpd1.conf", "w"))) {
1645		perror("/tmp/udhcpd1.conf");
1646		return errno;
1647	}
1648
1649	fprintf(fp, "pidfile /var/run/udhcpd-br1.pid\n");
1650	fprintf(fp, "start %s\n", nvram_safe_get("dhcp1_start"));
1651	fprintf(fp, "end %s\n", nvram_safe_get("dhcp1_end"));
1652	fprintf(fp, "interface %s\n", nvram_safe_get("lan1_ifname"));
1653	fprintf(fp, "remaining yes\n");
1654	fprintf(fp, "lease_file /tmp/udhcpd-br1.leases\n");
1655	fprintf(fp, "option subnet %s\n", nvram_safe_get("lan1_netmask"));
1656	fprintf(fp, "option router %s\n", nvram_safe_get("lan1_ipaddr"));
1657
1658	if (nvram_invmatch("dhcp_dns1_x",""))
1659		fprintf(fp, "option dns %s\n", nvram_safe_get("dhcp_dns1_x"));
1660	fprintf(fp, "option dns %s\n", nvram_safe_get("lan1_ipaddr"));
1661	fprintf(fp, "option lease %s\n", nvram_safe_get("lan1_lease"));
1662
1663	if (nvram_invmatch("dhcp_wins_x",""))
1664		fprintf(fp, "option wins %s\n", nvram_safe_get("dhcp_wins_x"));
1665	if (nvram_invmatch("lan_domain", ""))
1666		fprintf(fp, "option domain %s\n", nvram_safe_get("lan_domain"));
1667	fclose(fp);
1668
1669	dhcpd_argv[2] = NULL;
1670	_eval(dhcpd_argv, NULL, 0, &pid);
1671
1672
1673	dprintf("done\n");
1674	return 0;
1675}
1676
1677int
1678stop_dhcpd_guest(void)
1679{
1680	char sigusr1[] = "-XX";
1681	int ret;
1682
1683/*
1684* Process udhcpd handles two signals - SIGTERM and SIGUSR1
1685*
1686*  - SIGUSR1 saves all leases in /tmp/udhcpd.leases
1687*  - SIGTERM causes the process to be killed
1688*
1689* The SIGUSR1+SIGTERM behavior is what we like so that all current client
1690* leases will be honorred when the dhcpd restarts and all clients can extend
1691* their leases and continue their current IP addresses. Otherwise clients
1692* would get NAK'd when they try to extend/rebind their leases and they
1693* would have to release current IP and to request a new one which causes
1694* a no-IP gap in between.
1695*/
1696	ret = eval("killall", "udhcpd");
1697
1698	dprintf("done\n");
1699	return ret;
1700}
1701#endif
1702