1/*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License as
4 * published by the Free Software Foundation; either version 2 of
5 * the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
15 * MA 02111-1307 USA
16 */
17/*
18 * ASUS Home Gateway Reference Design
19 * Web Page Configuration Support Routines
20 *
21 * Copyright 2001, ASUSTeK Inc.
22 * All Rights Reserved.
23 *
24 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ASUSTeK Inc.;
25 * the contents of this file may not be disclosed to third parties, copied or
26 * duplicated in any form, in whole or in part, without the prior written
27 * permission of ASUSTeK Inc..
28 *
29 * $Id: web_ex.c,v 1.4 2007/04/09 12:01:50 shinjung Exp $
30 */
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <ctype.h>
35#include <errno.h>
36#include <unistd.h>
37#include <limits.h>
38#include <sys/utsname.h>
39#include <sys/types.h>
40#include <sys/stat.h>
41#include <sys/socket.h>
42#include <netinet/in.h>
43#include <arpa/inet.h>
44#include <httpd.h>
45#include <fcntl.h>
46#include <signal.h>
47#include <time.h>
48#include <sys/klog.h>
49#include <stdarg.h>
50#include <sys/wait.h>
51#include <dirent.h>
52#include <proto/ethernet.h>   //add by Viz 2010.08
53#include <net/route.h>
54#include <sys/ioctl.h>
55#include <math.h>	//for ceil()
56
57#include <typedefs.h>
58#include <bcmutils.h>
59#include <shutils.h>
60#include <bcmnvram.h>
61#include <bcmnvram_f.h>
62#include <common.h>
63#include <shared.h>
64#include <rtstate.h>
65
66#ifdef RTCONFIG_FANCTRL
67#include <wlutils.h>
68#endif
69
70#ifdef RTCONFIG_DSL
71#include <web-dsl.h>
72#include <web-dsl-upg.h>
73#endif
74
75#ifdef RTCONFIG_USB
76#include <usb_info.h>
77#include <disk_io_tools.h>
78#include <disk_initial.h>
79#include <disk_share.h>
80
81#ifdef RTCONFIG_NOTIFICATION_CENTER
82#include <libnt.h>
83#endif
84
85#include <apps.h>
86#else
87typedef unsigned char u8;
88typedef unsigned short u16;
89typedef unsigned int u32;
90typedef unsigned long long u64;
91#endif
92#include "initial_web_hook.h"
93//#endif
94
95//#ifdef RTCONFIG_OPENVPN
96#include "openvpn_options.h"
97//#endif
98
99#include <net/if.h>
100#include <linux/sockios.h>
101#include "../networkmap/networkmap.h"
102//#include <networkmap.h> //2011.03 Yau add for new networkmap
103#include <sys/ipc.h>
104#include <sys/shm.h>
105#include <sys/sysinfo.h>
106
107#ifdef RTCONFIG_QTN
108#include "web-qtn.h"
109#endif
110
111#ifdef RTCONFIG_BWDPI
112#include "bwdpi.h"
113#include "sqlite3.h"
114#include "bwdpi_sqlite.h"
115#endif
116
117#ifdef RTCONFIG_TRAFFIC_LIMITER
118#include "traffic_limiter.h"
119#endif
120
121#include <json.h>
122
123#ifdef RTCONFIG_HTTPS
124extern int do_ssl;
125extern int ssl_stream_fd;
126#endif
127
128extern int ej_wl_sta_list_2g(int eid, webs_t wp, int argc, char_t **argv);
129extern int ej_wl_sta_list_5g(int eid, webs_t wp, int argc, char_t **argv);
130#ifndef RTCONFIG_QTN
131extern int ej_wl_sta_list_5g_2(int eid, webs_t wp, int argc, char_t **argv);
132#endif
133#ifdef RTCONFIG_STAINFO
134extern int ej_wl_stainfo_list_2g(int eid, webs_t wp, int argc, char_t **argv);
135extern int ej_wl_stainfo_list_5g(int eid, webs_t wp, int argc, char_t **argv);
136#ifndef RTCONFIG_QTN
137extern int ej_wl_stainfo_list_5g_2(int eid, webs_t wp, int argc, char_t **argv);
138#endif
139#endif
140extern int ej_wl_auth_list(int eid, webs_t wp, int argc, char_t **argv);
141#ifdef CONFIG_BCMWL5
142extern int ej_wl_control_channel(int eid, webs_t wp, int argc, char_t **argv);
143#endif
144
145#ifdef RTCONFIG_RALINK
146#elif defined(RTCONFIG_QCA)
147#else
148extern int ej_SiteSurvey(int eid, webs_t wp, int argc, char_t **argv);
149#endif
150
151extern int ej_wl_scan_2g(int eid, webs_t wp, int argc, char_t **argv);
152extern int ej_wl_scan_5g(int eid, webs_t wp, int argc, char_t **argv);
153extern int ej_wl_scan_5g_2(int eid, webs_t wp, int argc, char_t **argv);
154extern int ej_wl_channel_list_2g(int eid, webs_t wp, int argc, char_t **argv);
155extern int ej_wl_channel_list_5g(int eid, webs_t wp, int argc, char_t **argv);
156#ifdef RTCONFIG_QTN
157extern int ej_wl_channel_list_5g_20m(int eid, webs_t wp, int argc, char_t **argv);
158extern int ej_wl_channel_list_5g_40m(int eid, webs_t wp, int argc, char_t **argv);
159extern int ej_wl_channel_list_5g_80m(int eid, webs_t wp, int argc, char_t **argv);
160#endif
161extern int ej_wl_channel_list_5g_2(int eid, webs_t wp, int argc, char_t **argv);
162#ifdef CONFIG_BCMWL5
163extern int ej_wl_chanspecs_2g(int eid, webs_t wp, int argc, char_t **argv);
164extern int ej_wl_chanspecs_5g(int eid, webs_t wp, int argc, char_t **argv);
165extern int ej_wl_chanspecs_5g_2(int eid, webs_t wp, int argc, char_t **argv);
166#endif
167#if defined(CONFIG_BCMWL5) || (defined(RTCONFIG_RALINK) && defined(RTCONFIG_WIRELESSREPEATER)) || defined(RTCONFIG_QCA)
168extern int ej_wl_rate_2g(int eid, webs_t wp, int argc, char_t **argv);
169extern int ej_wl_rate_5g(int eid, webs_t wp, int argc, char_t **argv);
170extern int ej_wl_rate_5g_2(int eid, webs_t wp, int argc, char_t **argv);
171#endif
172#ifdef RTCONFIG_PROXYSTA
173int ej_wl_auth_psta(int eid, webs_t wp, int argc, char_t **argv);
174#endif
175
176#ifdef RTCONFIG_IPV6
177extern int ej_lan_ipv6_network(int eid, webs_t wp, int argc, char_t **argv);
178#endif
179
180extern int ej_get_default_reboot_time(int eid, webs_t wp, int argc, char_t **argv);
181
182static int b64_decode( const char* str, unsigned char* space, int size );
183
184extern void send_login_page(int fromapp_flag, int error_status, char* url, int lock_time);
185extern void __send_login_page(int fromapp_flag, int error_status, char* url, int lock_time);
186
187extern char *get_cgi_json(char *name, json_object *root);
188
189extern int ej_generate_region(int eid, webs_t wp, int argc, char_t **argv);
190
191void add_asus_token(char *token);
192
193#define wan_prefix(unit, prefix)	snprintf(prefix, sizeof(prefix), "wan%d_", unit)
194
195#define nvram_default_safe_get(name) (nvram_default_get(name) ? : "")
196
197/*
198#define csprintf(fmt, args...) do{\
199	FILE *cp = fopen("/dev/console", "w");\
200	if (cp) {\
201		fprintf(cp, fmt, ## args);\
202		fclose(cp);\
203	}\
204}while (0)
205*/
206// 2008.08 magic }
207
208#include <sys/mman.h>
209typedef uint32_t __u32; //2008.08 magic
210#ifndef	O_BINARY		/* should be define'd on __WIN32__ */
211#define O_BINARY	0
212#endif
213#ifndef MAP_FAILED
214#define MAP_FAILED (-1)
215#endif
216
217/* #define sys_upgrade(image) eval("mtd-write", "-i", image, "-d", "linux"); */
218#define sys_upload(image) eval("nvram", "restore", image)
219#define sys_download(file) eval("nvram", "save", file)
220#define sys_default() notify_rc("resetdefault"); //   eval("mtd-erase", "-d", "nvram")
221#define sys_reboot() notify_rc("reboot");
222
223#define PROFILE_HEADER 	"HDR1"
224#ifdef RTCONFIG_DSL
225#define PROFILE_HEADER_NEW	"N55U"
226#else
227#if RTCONFIG_QCA
228#define PROFILE_HEADER_NEW	"AC55U"
229#else
230#define PROFILE_HEADER_NEW	"HDR2"
231#endif
232#endif
233#define IH_MAGIC	0x27051956	/* Image Magic Number		*/
234
235int count_sddev_mountpoint();
236
237#define Ralink_WPS	1 //2009.01 magic
238
239char ibuf2[8192];
240
241//static int ezc_error = 0;
242
243#define ACTION_UPGRADE_OK   0
244#define ACTION_UPGRADE_FAIL 1
245
246int action;
247
248char *serviceId;
249#define MAX_GROUP_ITEM 10
250#define MAX_GROUP_COUNT 300
251#define MAX_LINE_SIZE 512
252char *groupItem[MAX_GROUP_ITEM];
253char urlcache[128];
254char *next_host;
255int delMap[MAX_GROUP_COUNT];
256char SystemCmd[128];
257char UserID[32]="";
258char UserPass[32]="";
259char ProductID[32]="";
260extern int redirect;
261extern int change_passwd;	// 2008.08 magic
262extern int reget_passwd;	// 2008.08 magic
263extern int skip_auth;
264extern int lock_flag;
265extern char host_name[64];
266extern char referer_host[64];
267extern unsigned int login_ip_tmp;
268
269extern time_t login_timestamp; // the timestamp of the logined ip
270extern time_t login_timestamp_tmp; // the timestamp of the current session.
271extern time_t last_login_timestamp; // the timestamp of the current session.
272extern unsigned int login_try;
273extern unsigned int MAX_login;
274
275#ifdef RTCONFIG_JFFS2USERICON
276#define JFFS_USERICON		"/jffs/usericon/"
277#endif
278
279static void insert_hook_func(webs_t wp, char *fname, char *param)
280{
281	if (!wp || !fname) {
282		_dprintf("%s: invalid parameter (%p, %p, %p)\n", __func__, wp, fname, param);
283		return;
284	}
285
286	if (!param)
287		param = "";
288
289	websWrite(wp, "<script>\n");
290	websWrite(wp, "%s(%s);\n", fname, param);
291	websWrite(wp, "</script>\n");
292}
293
294char *
295rfctime(const time_t *timep)
296{
297	static char s[201];
298	struct tm tm;
299
300	//it suppose to be convert after applying
301	//time_zone_x_mapping();
302	setenv("TZ", nvram_safe_get_x("", "time_zone_x"), 1);
303	memcpy(&tm, localtime(timep), sizeof(struct tm));
304	strftime(s, 200, "%a, %d %b %Y %H:%M:%S %z", &tm);
305	return s;
306}
307
308void
309reltime(unsigned int seconds, char *cs)
310{
311#ifdef SHOWALL
312	int days=0, hours=0, minutes=0;
313
314	if (seconds > 60*60*24) {
315		days = seconds / (60*60*24);
316		seconds %= 60*60*24;
317	}
318	if (seconds > 60*60) {
319		hours = seconds / (60*60);
320		seconds %= 60*60;
321	}
322	if (seconds > 60) {
323		minutes = seconds / 60;
324		seconds %= 60;
325	}
326	sprintf(cs, "%d days, %d hours, %d minutes, %d seconds", days, hours, minutes, seconds);
327#else
328	sprintf(cs, "%d secs", seconds);
329#endif
330}
331
332/******************************************************************************/
333/*
334 *	Redirect the user to another webs page
335 */
336
337//2008.08 magic{
338void websRedirect(webs_t wp, char_t *url)
339{
340	websWrite(wp, T("<html><head>\r\n"));
341
342	if(strchr(url, '>') || strchr(url, '<'))
343	{
344		websWrite(wp,"<script>parent.location.href='/index.asp';</script>\n");
345	}
346	else
347	{
348#ifdef RTCONFIG_HTTPS
349		if(do_ssl){
350			//websWrite(wp, T("<meta http-equiv=\"refresh\" content=\"0; url=https://%s/%s\">\r\n"), gethost(), url);
351			websWrite(wp,"<script>parent.location.href='/%s';</script>\n",url);
352		}else
353#endif
354		{
355			//websWrite(wp, T("<meta http-equiv=\"refresh\" content=\"0; url=http://%s/%s\">\r\n"), gethost(), url);
356			websWrite(wp,"<script>parent.location.href='/%s';</script>\n",url);
357		}
358	}
359
360	websWrite(wp, T("<meta http-equiv=\"Content-Type\" content=\"text/html\">\r\n"));
361	websWrite(wp, T("</head></html>\r\n"));
362
363	websDone(wp, 200);
364}
365
366void websRedirect_iframe(webs_t wp, char_t *url)
367{
368        websWrite(wp, T("<html><head>\r\n"));
369
370        if(strchr(url, '>') || strchr(url, '<'))
371        {
372                websWrite(wp,"<script>parent.location.href='/index.asp';</script>\n");
373        }
374        else
375        {
376#ifdef RTCONFIG_HTTPS
377                if(do_ssl){
378                        websWrite(wp, T("<meta http-equiv=\"refresh\" content=\"0; url=https://%s/%s\">\r\n"), gethost(), url);
379                }else
380#endif
381                {
382			websWrite(wp, T("<meta http-equiv=\"refresh\" content=\"0; url=http://%s/%s\">\r\n"), gethost(), url);
383                }
384        }
385
386        websWrite(wp, T("<meta http-equiv=\"Content-Type\" content=\"text/html\">\r\n"));
387        websWrite(wp, T("</head></html>\r\n"));
388
389        websDone(wp, 200);
390}
391//2008.08 magic}
392
393void sys_script(char *name)
394{
395
396     char scmd[64];
397
398     sprintf(scmd, "/tmp/%s", name);
399     //printf("run %s %d %s\n", name, strlen(name), scmd);	// tmp test
400
401     //handle special scirpt first
402     if (strcmp(name,"syscmd.sh")==0)
403     {
404	   if (strcmp(SystemCmd, "")!=0)
405	   {
406		snprintf(SystemCmd, sizeof(SystemCmd), "%s > /tmp/syscmd.log 2>&1 && echo 'XU6J03M6' >> /tmp/syscmd.log &\n", SystemCmd);
407		system(SystemCmd);
408		strcpy(SystemCmd, ""); // decrease loading time.
409	   }
410	   else
411	   {
412	   	f_write_string("/tmp/syscmd.log", "", 0, 0);
413	   }
414     }
415//#ifdef U2EC
416     else if (strcmp(name,"eject-usb.sh")==0)
417     {
418		eval("rmstorage");
419     }
420#ifdef ASUS_DDNS //2007.03.22 Yau add
421     else if (strcmp(name,"ddnsclient")==0)
422     {
423		notify_rc("restart_ddns");
424     }
425     else if (strstr(name,"asusddns_register") != NULL)
426     {
427		notify_rc("asusddns_reg_domain");
428     }
429#endif
430     else if (strcmp(name, "leases.sh")==0 || strcmp(name, "dleases.sh")==0)
431     {
432		// do nothing
433     }
434     else if (strstr(scmd, " ") == 0) // no parameter, run script with eval
435     {
436		eval(scmd);
437     }
438     else system(scmd);
439}
440
441void websScan(char_t *str)
442{
443	unsigned int i, flag;
444	char_t *v1, *v2, *v3, *sp;
445	char_t groupid[64];
446	char_t value[MAX_LINE_SIZE];
447	char_t name[MAX_LINE_SIZE];
448
449	v1 = strchr(str, '?');
450
451	i = 0;
452	flag = 0;
453
454	while (v1!=NULL)
455	{
456	    v2 = strchr(v1+1, '=');
457	    v3 = strchr(v1+1, '&');
458
459// 2008.08 magic {
460		if (v2 == NULL)
461			break;
462// 2008.08 magic }
463
464	    if (v3!=NULL)
465	    {
466	       strncpy(value, v2+1, v3-v2-1);
467	       value[v3-v2-1] = 0;
468	    }
469	    else
470	    {
471	       strcpy(value, v2+1);
472	    }
473
474	    strncpy(name, v1+1, v2-v1-1);
475	    name[v2-v1-1] = 0;
476	    /*printf("Value: %s %s\n", name, value);*/
477
478	    if (v2 != NULL && ((sp = strchr(v1+1, ' ')) == NULL || (sp > v2)))
479	    {
480	       if (flag && strncmp(v1+1, groupid, strlen(groupid))==0)
481	       {
482		   delMap[i] = atoi(value);
483		   /*printf("Del Scan : %x\n", delMap[i]);*/
484		   if (delMap[i]==-1)  break;
485		   i++;
486	       }
487	       else if (strncmp(v1+1,"group_id", 8)==0)
488	       {
489		   sprintf(groupid, "%s_s", value);
490		   flag = 1;
491	       }
492	    }
493	    v1 = strchr(v1+1, '&');
494	}
495	delMap[i] = -1;
496	return;
497}
498
499
500void websApply(webs_t wp, char_t *url)
501{
502#ifdef TRANSLATE_ON_FLY
503	do_ej (url, wp);
504	websDone (wp, 200);
505#else   // define TRANSLATE_ON_FLY
506
507     FILE *fp;
508     char buf[MAX_LINE_SIZE];
509
510     fp = fopen(url, "r");
511
512     if (fp==NULL) return;
513
514     while (fgets(buf, sizeof(buf), fp))
515     {
516	websWrite(wp, buf);
517     }
518
519     websDone(wp, 200);
520     fclose(fp);
521#endif
522}
523
524
525/*
526 * Example:
527 * lan_ipaddr=192.168.1.1
528 * <% nvram_get("lan_ipaddr"); %> produces "192.168.1.1"
529 * <% nvram_get("undefined"); %> produces ""
530 */
531static int
532ej_nvram_get(int eid, webs_t wp, int argc, char_t **argv)
533{
534	char *name, *c;
535	int ret = 0;
536//	char sid_dummy = "",
537	int from_app = 0;
538
539	from_app = check_user_agent(user_agent);
540
541	if (ejArgs(argc, argv, "%s", &name) < 1) {
542		websError(wp, 400, "Insufficient args\n");
543		return -1;
544	}
545
546	if (strcmp(name, "modem_spn") == 0 && !nvram_invmatch(name, ""))
547		name = "modem_isp";
548
549	for (c = nvram_safe_get(name); *c; c++) {
550		if (isprint(*c) &&
551		    *c != '"' && *c != '&' && *c != '<' && *c != '>' && *c != '\\')
552			ret += websWrite(wp, "%c", *c);
553		else if(*c == '\\'){
554			if(from_app != 0)
555				ret += websWrite(wp, "\\\\");
556			else
557				ret += websWrite(wp, "%c", *c);
558		}
559		else
560			ret += websWrite(wp, "&#%d", *c);
561	}
562
563	return ret;
564}
565
566
567/* This will return properly encoded HTML entities - required
568   for retrieving stored certs/keys.
569*/
570
571static int
572ej_nvram_clean_get(int eid, webs_t wp, int argc, char_t **argv)
573{
574	char *name, *c;
575	int ret = 0;
576
577	if (ejArgs(argc, argv, "%s", &name) < 1) {
578		websError(wp, 400, "Insufficient args\n");
579		return -1;
580	}
581
582	for (c = nvram_safe_get(name); *c; c++) {
583		if (isprint(*c) &&
584			*c != '"' && *c != '&' && *c != '<' && *c != '>')
585				ret += websWrite(wp, "%c", *c);
586		else
587			ret += websWrite(wp, "&#%d;", *c);
588	}
589
590	return ret;
591}
592
593
594static int
595ej_nvram_default_get(int eid, webs_t wp, int argc, char_t **argv)
596{
597	char *name, *c;
598	int ret = 0;
599//	char sid_dummy = "",
600
601	if (ejArgs(argc, argv, "%s", &name) < 1) {
602		websError(wp, 400, "Insufficient args\n");
603		return -1;
604	}
605
606	for (c = nvram_default_safe_get(name); *c; c++) {
607		if (isprint(*c) &&
608		    *c != '"' && *c != '&' && *c != '<' && *c != '>')
609			ret += websWrite(wp, "%c", *c);
610		else
611			ret += websWrite(wp, "&#%d", *c);
612	}
613
614	return ret;
615}
616
617/*
618 * Example:
619 * lan_ipaddr=192.168.1.1
620 * <% nvram_get_x("lan_ipaddr"); %> produces "192.168.1.1"
621 * <% nvram_get_x("undefined"); %> produces ""
622 */
623static int
624ej_nvram_get_x(int eid, webs_t wp, int argc, char_t **argv)
625{
626	char *sid, *name, *c;
627	int ret = 0;
628
629	if (ejArgs(argc, argv, "%s %s", &sid, &name) < 2) {
630		websError(wp, 400, "Insufficient args\n");
631		return -1;
632	}
633
634	for (c = nvram_safe_get_x(sid, name); *c; c++) {
635		if (isprint(*c) &&
636		    *c != '"' && *c != '&' && *c != '<' && *c != '>')
637			ret += websWrite(wp, "%c", *c);
638		else
639			ret += websWrite(wp, "&#%d", *c);
640	}
641
642	return ret;
643}
644
645#ifdef ASUS_DDNS
646
647static int
648ej_nvram_get_ddns(int eid, webs_t wp, int argc, char_t **argv)
649{
650	char *sid, *name, *c;
651	int ret = 0;
652
653	if (ejArgs(argc, argv, "%s %s", &sid, &name) < 2) {
654		websError(wp, 400, "Insufficient args\n");
655		return -1;
656	}
657
658	for (c = nvram_safe_get_x(sid, name); *c; c++) {
659		if (isprint(*c) &&
660		    *c != '"' && *c != '&' && *c != '<' && *c != '>')
661			ret += websWrite(wp, "%c", *c);
662		else
663			ret += websWrite(wp, "&#%d", *c);
664	}
665	if (strcmp(name,"ddns_return_code")==0) {
666		if(!nvram_match("ddns_return_code", "ddns_query")) {
667			nvram_set("ddns_return_code","");
668		}
669	}
670
671	return ret;
672}
673#endif
674/*
675 * Example:
676 * lan_ipaddr=192.168.1.1
677 * <% nvram_get_x("lan_ipaddr"); %> produces "192.168.1.1"
678 * <% nvram_get_x("undefined"); %> produces ""
679 */
680static int
681ej_nvram_get_f(int eid, webs_t wp, int argc, char_t **argv)
682{
683	char *file, *field, *c, buf[64];
684	int ret = 0;
685
686	if (ejArgs(argc, argv, "%s %s", &file, &field) < 2) {
687		websError(wp, 400, "Insufficient args\n");
688		return -1;
689	}
690
691	strcpy(buf, nvram_safe_get_f(file, field));
692	for (c = buf; *c; c++) {
693		if (isprint(*c) &&
694		    *c != '"' && *c != '&' && *c != '<' && *c != '>')
695			ret += websWrite(wp, "%c", *c);
696		else
697			ret += websWrite(wp, "&#%d", *c);
698	}
699
700	return ret;
701}
702
703static int
704ej_nvram_show_chinese_char(int eid, webs_t wp, int argc, char_t **argv)
705{
706	char *name, *c;
707	int ret = 0;
708
709	if (ejArgs(argc, argv, "%s", &name) < 1) {
710		websError(wp, 400, "Insufficient args\n");
711		return -1;
712	}
713
714	for (c = nvram_safe_get(name); *c; c++) {
715		ret += websWrite(wp, "%c", *c);
716	}
717
718	return ret;
719}
720
721/*
722 * Example:
723 * wan_proto=dhcp
724 * <% nvram_match("wan_proto", "dhcp", "selected"); %> produces "selected"
725 * <% nvram_match("wan_proto", "static", "selected"); %> does not produce
726 */
727static int
728ej_nvram_match(int eid, webs_t wp, int argc, char_t **argv)
729{
730	char *name, *match, *output;
731
732	if (ejArgs(argc, argv, "%s %s %s", &name, &match, &output) < 3) {
733		websError(wp, 400, "Insufficient args\n");
734		return -1;
735	}
736
737	if (nvram_match(name, match))
738	{
739		return websWrite(wp, output);
740	}
741
742	return 0;
743}
744
745/*
746 * Example:
747 * wan_proto=dhcp
748 * <% nvram_match("wan_proto", "dhcp", "selected"); %> produces "selected"
749 * <% nvram_match("wan_proto", "static", "selected"); %> does not produce
750 */
751static int
752ej_nvram_match_x(int eid, webs_t wp, int argc, char_t **argv)
753{
754	char *sid, *name, *match, *output;
755
756	if (ejArgs(argc, argv, "%s %s %s %s", &sid, &name, &match, &output) < 4) {
757		websError(wp, 400, "Insufficient args\n");
758		return -1;
759	}
760
761	if (nvram_match_x(sid, name, match))
762	{
763		return websWrite(wp, output);
764	}
765
766	return 0;
767}
768
769static int
770ej_nvram_double_match(int eid, webs_t wp, int argc, char_t **argv)
771{
772	char *name, *match, *output;
773	char *name2, *match2;
774
775	if (ejArgs(argc, argv, "%s %s %s %s %s", &name, &match, &name2, &match2, &output) < 5) {
776		websError(wp, 400, "Insufficient args\n");
777		return -1;
778	}
779
780	if (nvram_match(name, match) && nvram_match(name2, match2))
781	{
782		return websWrite(wp, output);
783	}
784
785	return 0;
786}
787
788static int
789ej_nvram_double_match_x(int eid, webs_t wp, int argc, char_t **argv)
790{
791	char *sid, *name, *match, *output;
792	char *sid2, *name2, *match2;
793
794	if (ejArgs(argc, argv, "%s %s %s %s %s %s %s", &sid, &name, &match, &sid2, &name2, &match2, &output) < 7) {
795		websError(wp, 400, "Insufficient args\n");
796		return -1;
797	}
798
799	if (nvram_match_x(sid, name, match) && nvram_match_x(sid2, name2, match2))
800	{
801		return websWrite(wp, output);
802	}
803
804	return 0;
805}
806
807/*
808 * Example:
809 * wan_proto=dhcp
810 * <% nvram_match("wan_proto", "dhcp", "selected"); %> produces "selected"
811 * <% nvram_match("wan_proto", "static", "selected"); %> does not produce
812 */
813static int
814ej_nvram_match_both_x(int eid, webs_t wp, int argc, char_t **argv)
815{
816	char *sid, *name, *match, *output, *output_not;
817
818	if (ejArgs(argc, argv, "%s %s %s %s %s", &sid, &name, &match, &output, &output_not) < 5)
819	{
820		websError(wp, 400, "Insufficient args\n");
821		return -1;
822	}
823
824	if (nvram_match_x(sid, name, match))
825	{
826		return websWrite(wp, output);
827	}
828	else
829	{
830		return websWrite(wp, output_not);
831	}
832}
833
834/*
835 * Example:
836 * lan_ipaddr=192.168.1.1 192.168.39.248
837 * <% nvram_get_list("lan_ipaddr", 0); %> produces "192.168.1.1"
838 * <% nvram_get_list("lan_ipaddr", 1); %> produces "192.168.39.248"
839 */
840static int
841ej_nvram_get_list_x(int eid, webs_t wp, int argc, char_t **argv)
842{
843	char *sid, *name;
844	int which;
845	int ret = 0;
846
847	if (ejArgs(argc, argv, "%s %s %d", &sid, &name, &which) < 3) {
848		websError(wp, 400, "Insufficient args\n");
849		return -1;
850	}
851
852	ret += websWrite(wp, nvram_get_list_x(sid, name, which));
853	return ret;
854}
855
856/*
857 * Example:
858 * lan_ipaddr=192.168.1.1 192.168.39.248
859 * <% nvram_get_list("lan_ipaddr", 0); %> produces "192.168.1.1"
860 * <% nvram_get_list("lan_ipaddr", 1); %> produces "192.168.39.248"
861 */
862static int
863ej_nvram_get_buf_x(int eid, webs_t wp, int argc, char_t **argv)
864{
865	char *sid, *name;
866	int which;
867
868	if (ejArgs(argc, argv, "%s %s %d", &sid, &name, &which) < 3) {
869		websError(wp, 400, "Insufficient args\n");
870		return -1;
871	}
872
873	return 0;
874}
875
876
877/*
878 * Example:
879 * wan_proto=dhcp;dns
880 * <% nvram_match_list("wan_proto", "dhcp", "selected", 0); %> produces "selected"
881 * <% nvram_match_list("wan_proto", "static", "selected", 1); %> does not produce
882 */
883static int
884ej_nvram_match_list_x(int eid, webs_t wp, int argc, char_t **argv)
885{
886	char *sid, *name, *match, *output;
887	int which;
888
889	if (ejArgs(argc, argv, "%s %s %s %s %d", &sid, &name, &match, &output, &which) < 5) {
890		websError(wp, 400, "Insufficient args\n");
891		return -1;
892	}
893
894	if (nvram_match_list_x(sid, name, match, which))
895		return websWrite(wp, output);
896	else
897		return 0;
898}
899
900static int
901ej_select_channel(int eid, webs_t wp, int argc, char_t **argv)
902{
903	char *sid, chstr[32];
904	int ret = 0;
905	int idx = 0, channel;
906	char *value = nvram_safe_get("wl0_country_code");
907	char *channel_s = nvram_safe_get("wl_channel");
908
909	if (ejArgs(argc, argv, "%s", &sid) < 1) {
910		websError(wp, 400, "Insufficient args\n");
911		return -1;
912	}
913
914	channel = (channel_s == NULL)? 0 : atoi(channel_s);
915
916	for (idx = 0; idx < 12; idx++)
917	{
918		if (idx == 0)
919			strcpy(chstr, "Auto");
920		else
921			sprintf(chstr, "%d", idx);
922		ret += websWrite(wp, "<option value=\"%d\" %s>%s</option>", idx, (idx == channel)? "selected" : "", chstr);
923	}
924
925	if (    strcasecmp(value, "CA") && strcasecmp(value, "CO") && strcasecmp(value, "DO") &&
926		strcasecmp(value, "GT") && strcasecmp(value, "MX") && strcasecmp(value, "NO") &&
927		strcasecmp(value, "PA") && strcasecmp(value, "PR") && strcasecmp(value, "TW") &&
928		strcasecmp(value, "US") && strcasecmp(value, "UZ") )
929	{
930		for (idx = 12; idx < 14; idx++)
931		{
932			sprintf(chstr, "%d", idx);
933			ret += websWrite(wp, "<option value=\"%d\" %s>%s</option>", idx, (idx == channel)? "selected" : "", chstr);
934		}
935	}
936
937	if ((strcmp(value, "") == 0) || (strcasecmp(value, "DB") == 0)/* || (strcasecmp(value, "JP") == 0)*/)
938		ret += websWrite(wp, "<option value=\"14\" %s>14</option>", (14 == channel)? "selected" : "");
939
940	return ret;
941}
942
943static int
944ej_nvram_char_to_ascii(int eid, webs_t wp, int argc, char_t **argv)
945{
946	char *sid, *name;
947	char tmp[MAX_LINE_SIZE];
948	char *buf = tmp, *str;
949	int ret;
950
951	if (ejArgs(argc, argv, "%s %s", &sid, &name) < 2) {
952		websError(wp, 400, "Insufficient args\n");
953		return -1;
954	}
955
956	str = nvram_safe_get_x(sid, name);
957
958	/* each char expands to %XX at max */
959	ret = strlen(str) * sizeof(char)*3 + sizeof(char);
960	if (ret > sizeof(tmp)) {
961		buf = (char *)malloc(ret);
962		if (buf == NULL) {
963			csprintf("No memory.\n");
964			return 0;
965		}
966	}
967
968	char_to_ascii_safe(buf, str, ret);
969	ret = websWrite(wp, "%s", buf);
970
971	if (buf != tmp)
972		free(buf);
973
974	return ret;
975}
976
977static int
978ej_load_clientlist_char_to_ascii(int eid, webs_t wp, int argc, char_t **argv)
979{
980
981	FILE *fp;
982	char tmp[MAX_LINE_SIZE];
983	char *buf = tmp, *str;
984	int ret;
985	int size_ncl;
986
987
988	/* Read networkmap client list file */
989	if (!(fp = fopen(NMP_CLIENT_LIST_FILENAME, "r"))) {
990		return 0;
991	}
992
993	fseek(fp, 0L, SEEK_END);
994	size_ncl = ftell(fp);
995	fseek(fp, 0L, SEEK_SET);
996	if (size_ncl && size_ncl <= NCL_LIMIT) {
997		str = (char *)malloc(sizeof(char)*size_ncl+1);
998		if (fread(str, 1, size_ncl, fp) != size_ncl) {
999			csprintf("Read nmp_client_list FILE ERR\n");
1000			return 0;
1001		}
1002	}
1003	else
1004		return 0;
1005        fclose(fp);
1006	str[size_ncl] = '\0';
1007
1008	/* each char expands to %XX at max */
1009	ret = strlen(str) * sizeof(char)*3 + sizeof(char);
1010	if (ret > sizeof(tmp)) {
1011		buf = (char *)malloc(ret);
1012		if (buf == NULL) {
1013			csprintf("No memory.\n");
1014			return 0;
1015		}
1016	}
1017	char_to_ascii_safe(buf, str, ret);
1018	ret = websWrite(wp, "%s", buf);
1019
1020	if (buf != tmp)
1021		free(buf);
1022
1023	return ret;
1024}
1025
1026/* Report sys up time */
1027static int
1028ej_uptime(int eid, webs_t wp, int argc, char_t **argv)
1029{
1030
1031//	FILE *fp;
1032	char buf[MAX_LINE_SIZE];
1033//	unsigned long uptime;
1034	int ret;
1035	char *str = file2str("/proc/uptime");
1036	time_t tm;
1037
1038	time(&tm);
1039	sprintf(buf, rfctime(&tm));
1040
1041	if (str) {
1042		unsigned int up = atoi(str);
1043		free(str);
1044		char lease_buf[128];
1045		memset(lease_buf, 0, sizeof(lease_buf));
1046		reltime(up, lease_buf);
1047		sprintf(buf, "%s(%s since boot)", buf, lease_buf);
1048	}
1049
1050	ret = websWrite(wp, buf);
1051	return ret;
1052}
1053
1054static int
1055ej_sysuptime(int eid, webs_t wp, int argc, char_t **argv)
1056{
1057	int ret=0;
1058	char *str = file2str("/proc/uptime");
1059
1060	if (str) {
1061		unsigned int up = atoi(str);
1062		free(str);
1063
1064		char lease_buf[128];
1065		memset(lease_buf, 0, sizeof(lease_buf));
1066		reltime(up, lease_buf);
1067		ret = websWrite(wp, "%s since boot", lease_buf);
1068	}
1069
1070	return ret;
1071}
1072
1073struct lease_t {
1074	unsigned char chaddr[16];
1075	u_int32_t yiaddr;
1076	u_int32_t expires;
1077	char hostname[64];
1078};
1079
1080
1081static int
1082ej_ddnsinfo(int eid, webs_t wp, int argc, char_t **argv)
1083{
1084	int ret;
1085
1086	ret = websWrite(wp, "[\"%s\", \"%s\", \"%s\", \"%s\"]",
1087		nvram_safe_get("ddns_enable_x"),
1088		nvram_safe_get("ddns_server_x"),
1089		nvram_safe_get("ddns_hostname_x"),
1090		nvram_safe_get("ddns_return_code")
1091		);
1092
1093	return ret;
1094}
1095
1096int
1097websWriteCh(webs_t wp, char *ch, int count)
1098{
1099   int i, ret;
1100
1101   ret = 0;
1102   for (i=0; i<count; i++)
1103      ret+=websWrite(wp, "%s", ch);
1104   return (ret);
1105}
1106
1107static int dump_file(webs_t wp, char *filename)
1108{
1109	FILE *fp;
1110	char buf[MAX_LINE_SIZE];
1111	int ret=0;
1112
1113	fp = fopen(filename, "r");
1114
1115	if (fp==NULL)
1116	{
1117		ret+=websWrite(wp, "%s", "");
1118		return (ret);
1119	}
1120
1121	ret = 0;
1122
1123	while (fgets(buf, MAX_LINE_SIZE, fp)!=NULL)
1124	{
1125	    int len;
1126	    len = strlen(buf); // fgets() would fill the '\0' at the last character in buffer.
1127	    ret += websWriteData(wp, buf, len);
1128	}
1129
1130	fclose(fp);
1131
1132	return (ret);
1133}
1134
1135extern int wl_wps_info(int eid, webs_t wp, int argc, char_t **argv, int unit);
1136
1137static int
1138ej_dump(int eid, webs_t wp, int argc, char_t **argv)
1139{
1140//	FILE *fp;
1141//	char buf[MAX_LINE_SIZE];
1142	char filename[PATH_MAX], path[PATH_MAX];
1143	char *file,*script;
1144	int ret;
1145
1146	if (ejArgs(argc, argv, "%s %s", &file, &script) < 2) {
1147		websError(wp, 400, "Insufficient args\n");
1148		return -1;
1149	}
1150
1151	//csprintf("Script : %s, File: %s\n", script, file);
1152
1153	// run scrip first to update some status
1154	if (strcmp(script,"")!=0) sys_script(script);
1155
1156	if (strcmp(file, "wlan11b.log")==0)
1157		return (ej_wl_status(eid, wp, 0, NULL, 0));	/* FIXME */
1158	else if (strcmp(file, "wlan11b_2g.log")==0)
1159		return (ej_wl_status_2g(eid, wp, 0, NULL));
1160	else if (strcmp(file, "leases.log")==0)
1161		return (ej_lan_leases(eid, wp, 0, NULL));
1162#ifdef RTCONFIG_IPV6
1163	else if (strcmp(file, "ipv6_network.log")==0)
1164		return (ej_lan_ipv6_network(eid, wp, 0, NULL));
1165#endif
1166	else if (strcmp(file, "iptable.log")==0)
1167		return (get_nat_vserver_table(eid, wp, 0, NULL));
1168	else if (strcmp(file, "route.log")==0)
1169		return (ej_route_table(eid, wp, 0, NULL));
1170	else if (strcmp(file, "wps_info.log")==0)
1171	{
1172#ifndef RTAC3200
1173		if (nvram_match("wps_band", "0"))
1174			return (ej_wps_info_2g(eid, wp, 0, NULL));
1175		else
1176			return (ej_wps_info(eid, wp, 0, NULL));
1177#else
1178		return wl_wps_info(eid, wp, argc, argv, nvram_get_int("wps_band"));
1179#endif
1180	}
1181#if 0
1182	else if (strcmp(file, "apselect.log")==0)
1183		return (ej_getSiteSurvey(eid, wp, 0, NULL));
1184	else if (strcmp(file, "apscan")==0)
1185		return (ej_SiteSurvey(eid, wp, 0, NULL));
1186	else if (strcmp(file, "urelease")==0)
1187		return (ej_urelease(eid, wp, 0, NULL));
1188#endif
1189
1190	ret = 0;
1191
1192	strcpy(path, get_logfile_path());
1193	if (strcmp(file, "syslog.log")==0)
1194	{
1195		sprintf(filename, "%s/%s-1", path, file);
1196		ret += dump_file(wp, filename);
1197		sprintf(filename, "%s/%s", path, file);
1198		ret += dump_file(wp, filename);
1199	}
1200//#ifdef RTCONFIG_CLOUDSYNC
1201	else if(!strcmp(file, "cloudsync.log")){
1202		sprintf(filename, "/tmp/smartsync/.logs/system.log");
1203		ret += dump_file(wp, filename);
1204		sprintf(filename, "/tmp/%s", file);
1205		ret += dump_file(wp, filename);
1206	}
1207	else if(!strcmp(file, "clouddisk.log")){
1208		sprintf(filename, "/tmp/lighttpd/syslog.log");
1209		ret += dump_file(wp, filename);
1210		sprintf(filename, "/tmp/%s", file);
1211		ret += dump_file(wp, filename);
1212	}
1213//#endif
1214#ifdef RTCONFIG_OPENVPN
1215	else if(!strcmp(file, "openvpn_connected")){
1216		int unit = nvram_get_int("vpn_server_unit");
1217		parse_openvpn_status(unit);
1218		sprintf(filename, "/etc/openvpn/server%d/client_status", unit);
1219		ret += dump_file(wp, filename);
1220	}
1221#endif
1222#ifdef RTCONFIG_PUSH_EMAIL
1223#ifdef RTCONFIG_DSL
1224	else if(!strcmp(file, "fb_fail_content")){
1225		sprintf(filename, "/tmp/xdslissuestracking");
1226		if(check_if_file_exist(filename)) {
1227			eval("sed", "-i", "/PIN Code:/d", filename);
1228			eval("sed", "-i", "/MAC Address:/d", filename);
1229			eval("sed", "-i", "/E-mail:/d", filename);
1230			eval("sed", "-i", "/Download Master:/d", filename);
1231			eval("sed", "-i", "/Cloud Disk:/d", filename);
1232			eval("sed", "-i", "/Smart Access:/d", filename);
1233			eval("sed", "-i", "/Smart Sync:/d", filename);
1234			eval("sed", "-i", "/Guest Network 1\\/2\\/3 \\(.*\\):/d", filename);
1235			eval("sed", "-i", "/Current connected Clients:/d", filename);
1236			eval("sed", "-i", "/CC\\(.*\\)\\/CC\\(.*\\)\\/TC:/d", filename);
1237			eval("sed", "-i", "/regrev\\(.*\\)\\/regrev\\(.*\\):/d", filename);
1238			ret += dump_file(wp, filename);
1239			unlink(filename);
1240		}
1241		else {
1242			char buf[4096] = {0};
1243			snprintf(buf, 4095,
1244				"Your ISP / Internet Service Provider: %s\n"
1245				"Name of the Subscribed Plan/Service/Package:  %s\n"
1246				"DSL service performance option: %s\n"
1247				"Firmware version: %s.%s_%s\n"
1248				"DSL Firmware version: %s\n"
1249				"&nbsp;\n"
1250				"Comments / Suggestions:\n"
1251				"%s\n"
1252				, nvram_safe_get("fb_ISP")
1253				, nvram_safe_get("fb_Subscribed_Info")
1254				, nvram_safe_get("fb_availability")
1255				, nvram_safe_get("firmver"), nvram_safe_get("buildno"), nvram_safe_get("extendno")
1256				, nvram_safe_get("dsllog_fwver")
1257				, nvram_safe_get("fb_comment")
1258				);
1259			ret += websWrite(wp, buf);
1260		}
1261	}
1262#else /* RTCONFIG_DSL */
1263	else if(!strcmp(file, "fb_fail_content")){
1264		sprintf(filename, "/tmp/xdslissuestracking");
1265		if(check_if_file_exist(filename)) {
1266			eval("sed", "-i", "/PIN Code:/d", filename);
1267			eval("sed", "-i", "/MAC Address:/d", filename);
1268			eval("sed", "-i", "/E-mail:/d", filename);
1269			eval("sed", "-i", "/Download Master:/d", filename);
1270			eval("sed", "-i", "/Cloud Disk:/d", filename);
1271			eval("sed", "-i", "/Smart Access:/d", filename);
1272			eval("sed", "-i", "/Smart Sync:/d", filename);
1273			eval("sed", "-i", "/Guest Network 1\\/2\\/3 \\(.*\\):/d", filename);
1274			eval("sed", "-i", "/Current connected Clients:/d", filename);
1275			eval("sed", "-i", "/CC\\(.*\\)\\/CC\\(.*\\)\\/TC:/d", filename);
1276			eval("sed", "-i", "/regrev\\(.*\\)\\/regrev\\(.*\\):/d", filename);
1277			ret += dump_file(wp, filename);
1278			unlink(filename);
1279		}
1280		else {
1281			char buf[4096] = {0};
1282			snprintf(buf, 4095,
1283				"Feedback problem type: %s\n"
1284				"Feedback problem description:  %s\n"
1285				"Firmware version: %s.%s_%s\n"
1286				"&nbsp;\n"
1287				"Comments / Suggestions:\n"
1288				"%s\n"
1289				, nvram_safe_get("fb_ptype")
1290				, nvram_safe_get("fb_pdesc")
1291				, nvram_safe_get("firmver"), nvram_safe_get("buildno"), nvram_safe_get("extendno")
1292				, nvram_safe_get("fb_comment")
1293				);
1294			ret += websWrite(wp, buf);
1295		}
1296	}
1297#endif /* RTCONFIG_DSL */
1298#endif /* RTCONFIG_PUSH_EMAIL */
1299	else {
1300		sprintf(filename, "/tmp/%s", file);
1301		ret += dump_file(wp, filename);
1302	}
1303
1304	return ret;
1305}
1306
1307static int
1308ej_load(int eid, webs_t wp, int argc, char_t **argv)
1309{
1310	char *script;
1311
1312	if (ejArgs(argc, argv, "%s", &script) < 1) {
1313		websError(wp, 400, "Insufficient args\n");
1314		return -1;
1315	}
1316
1317	sys_script(script);
1318	return (websWrite(wp,"%s",""));
1319}
1320
1321/*
1322 * retreive and convert wl values for specified wl_unit
1323 * Example:
1324 * <% wl_get_parameter(); %> for coping wl[n]_ to wl_
1325 */
1326
1327static int
1328ej_wl_get_parameter(int eid, webs_t wp, int argc, char_t **argv)
1329{
1330	int unit, subunit;
1331
1332	unit = nvram_get_int("wl_unit");
1333	subunit = nvram_get_int("wl_subunit");
1334
1335	// handle generate cases first
1336	(void)copy_index_to_unindex("wl_", unit, subunit);
1337
1338	return (websWrite(wp,"%s",""));
1339}
1340
1341int webWriteNvram(webs_t wp, char *name)
1342{
1343	char *c;
1344	int ret = 0;
1345
1346	for (c = nvram_safe_get(name); *c; c++) {
1347		if (isprint(*c) &&
1348		    *c != '"' && *c != '&' && *c != '<' && *c != '>' && *c != '\\' && *c != '%')
1349			ret += websWrite(wp, "%c", *c);
1350		else
1351			ret += websWrite(wp, "%%%02X", *c);
1352	}
1353
1354	return ret;
1355}
1356
1357int webWriteNvram2(webs_t wp, char *name)
1358{
1359	char *c;
1360	int ret = 0;
1361
1362	for (c = nvram_safe_get(name); *c; c++) {
1363		if (isprint(*c) &&
1364		    *c != '"' && *c != '&' && *c != '<' && *c != '>' && *c != '\\' && *c != '%')
1365			ret += websWrite(wp, "%c", *c);
1366		else
1367			ret += websWrite(wp, "&#%d", *c);
1368	}
1369
1370	return ret;
1371}
1372
1373/*
1374 * retreive guest network releated wl values
1375 */
1376
1377static int
1378ej_wl_get_guestnetwork(int eid, webs_t wp, int argc, char_t **argv)
1379{
1380	char word2[128], tmp[128], *next2;
1381	char *unitname;
1382	char prefix[32];
1383	int  unit, subunit;
1384	int ret = 0;
1385
1386	if (ejArgs(argc, argv, "%s", &unitname) < 1) {
1387		websError(wp, 400, "Insufficient args\n");
1388		return -1;
1389	}
1390
1391	unit = atoi(unitname);
1392	snprintf(prefix, sizeof(prefix), "wl%d_", unit);
1393	ret += websWrite(wp, "[");
1394
1395	subunit = 0;
1396	foreach(word2, nvram_safe_get(strcat_r(prefix, "vifnames", tmp)), next2) {
1397		if(subunit>0) websWrite(wp, ", ");
1398
1399		subunit++;
1400
1401		ret += websWrite(wp, "[\"");
1402		ret += webWriteNvram(wp, strcat_r(word2, "_bss_enabled", tmp));
1403		ret += websWrite(wp, "\", \"");
1404		ret += webWriteNvram(wp, strcat_r(word2, "_ssid", tmp));
1405		ret += websWrite(wp, "\", \"");
1406		ret += webWriteNvram(wp, strcat_r(word2, "_auth_mode_x", tmp));
1407		ret += websWrite(wp, "\", \"");
1408		ret += webWriteNvram(wp, strcat_r(word2, "_crypto", tmp));
1409		ret += websWrite(wp, "\", \"");
1410		ret += webWriteNvram(wp, strcat_r(word2, "_wpa_psk", tmp));
1411		ret += websWrite(wp, "\", \"");
1412		ret += webWriteNvram(wp, strcat_r(word2, "_wep_x", tmp));
1413		ret += websWrite(wp, "\", \"");
1414		ret += webWriteNvram(wp, strcat_r(word2, "_key", tmp));
1415		ret += websWrite(wp, "\", \"");
1416		ret += webWriteNvram(wp, strcat_r(word2, "_key1", tmp));
1417		ret += websWrite(wp, "\", \"");
1418		ret += webWriteNvram(wp, strcat_r(word2, "_key2", tmp));
1419		ret += websWrite(wp, "\", \"");
1420		ret += webWriteNvram(wp, strcat_r(word2, "_key3", tmp));
1421		ret += websWrite(wp, "\", \"");
1422		ret += webWriteNvram(wp, strcat_r(word2, "_key4", tmp));
1423		ret += websWrite(wp, "\", \"");
1424		ret += webWriteNvram(wp, strcat_r(word2, "_expire", tmp));
1425		ret += websWrite(wp, "\", \"");
1426		ret += webWriteNvram(wp, strcat_r(word2, "_lanaccess", tmp));
1427		ret += websWrite(wp, "\", \"");
1428		ret += webWriteNvram(wp, strcat_r(word2, "_expire_tmp", tmp));
1429		ret += websWrite(wp, "\", \"");
1430		ret += webWriteNvram(wp, strcat_r(word2, "_macmode", tmp));	// gn_array[][14]
1431		ret += websWrite(wp, "\", \"");
1432		ret += webWriteNvram(wp, strcat_r(word2, "_mbss", tmp));	// gn_array[][15]
1433		ret += websWrite(wp, "\", \"");
1434		ret += webWriteNvram2(wp, strcat_r(word2, "_maclist_x", tmp));	// gn_array[][16]
1435		ret += websWrite(wp, "\", \"");
1436		ret += webWriteNvram2(wp, strcat_r(word2, "_phrase_x", tmp));	// gn_array[][17]
1437		ret += websWrite(wp, "\"]");
1438	}
1439	ret += websWrite(wp, "]");
1440	return ret;
1441}
1442
1443
1444/*
1445 * retreive and convert wan values for specified wan_unit
1446 * Example:
1447 * <% wan_get_parameter(); %> for coping wan[n]_ to wan_
1448 */
1449
1450static int
1451ej_wan_get_parameter(int eid, webs_t wp, int argc, char_t **argv)
1452{
1453	int unit;
1454
1455	unit = nvram_get_int("wan_unit");
1456
1457	// handle generate cases first
1458	(void)copy_index_to_unindex("wan_", unit, -1);
1459
1460	return (websWrite(wp,"%s",""));
1461}
1462
1463
1464/*
1465
1466 * retreive and convert lan values for specified lan_unit
1467 * Example:
1468 * <% lan_get_parameter(); %> for coping lan[n]_ to lan_
1469 */
1470
1471static int
1472ej_lan_get_parameter(int eid, webs_t wp, int argc, char_t **argv)
1473{
1474	int unit;
1475
1476	unit = nvram_get_int("lan_unit");
1477
1478	// handle generate cases first
1479	(void)copy_index_to_unindex("lan_", unit, -1);
1480
1481	return (websWrite(wp,"%s",""));
1482}
1483
1484#ifdef RTCONFIG_OPENVPN
1485static int
1486ej_vpn_server_get_parameter(int eid, webs_t wp, int argc, char_t **argv)
1487{
1488	int unit;
1489
1490	unit = nvram_get_int("vpn_server_unit");
1491	// handle generate cases first
1492	(void)copy_index_to_unindex("vpn_server_", unit, -1);
1493
1494	return (websWrite(wp,"%s",""));
1495}
1496
1497static int
1498ej_vpn_client_get_parameter(int eid, webs_t wp, int argc, char_t **argv)
1499{
1500	int unit;
1501
1502	unit = nvram_get_int("vpn_client_unit");
1503	// handle generate cases first
1504	(void)copy_index_to_unindex("vpn_client_", unit, -1);
1505
1506	return (websWrite(wp,"%s",""));
1507}
1508static int
1509ej_vpn_crt_server(int eid, webs_t wp, int argc, char **argv) {
1510	char buf[4000];
1511	char file_name[32];
1512	int idx = 0;
1513
1514	for (idx = 1; idx < 2; idx++) {
1515		char *c;
1516
1517		//vpn_crt_server_ca
1518		memset(buf, 0, sizeof(buf));
1519		memset(file_name, 0, sizeof(file_name));
1520		sprintf(file_name, "vpn_crt_server%d_ca", idx);
1521		get_parsed_crt(file_name, buf, sizeof(buf));
1522		websWrite(wp, "%s=['", file_name);
1523
1524		for (c = buf; *c; c++) {
1525			if (isprint(*c) &&
1526				*c != '"' && *c != '&' && *c != '<' && *c != '>')
1527					websWrite(wp, "%c", *c);
1528			else
1529				websWrite(wp, "&#%d", *c);
1530		}
1531		websWrite(wp, "'];\n");
1532
1533		//vpn_crt_server_crt
1534		memset(buf, 0, sizeof(buf));
1535		memset(file_name, 0, sizeof(file_name));
1536		sprintf(file_name, "vpn_crt_server%d_crt", idx);
1537		get_parsed_crt(file_name, buf, sizeof(buf));
1538		websWrite(wp, "%s=['", file_name);
1539		for (c = buf; *c; c++) {
1540			if (isprint(*c) &&
1541				*c != '"' && *c != '&' && *c != '<' && *c != '>')
1542					websWrite(wp, "%c", *c);
1543			else
1544				websWrite(wp, "&#%d", *c);
1545		}
1546		websWrite(wp, "'];\n");
1547
1548		//vpn_crt_server_key
1549		memset(buf, 0, sizeof(buf));
1550		memset(file_name, 0, sizeof(file_name));
1551		sprintf(file_name, "vpn_crt_server%d_key", idx);
1552		get_parsed_crt(file_name, buf, sizeof(buf));
1553		websWrite(wp, "%s=['", file_name);
1554		for (c = buf; *c; c++) {
1555			if (isprint(*c) &&
1556				*c != '"' && *c != '&' && *c != '<' && *c != '>')
1557					websWrite(wp, "%c", *c);
1558			else
1559				websWrite(wp, "&#%d", *c);
1560		}
1561		websWrite(wp, "'];\n");
1562
1563		//vpn_crt_server_dh
1564		memset(buf, 0, sizeof(buf));
1565		memset(file_name, 0, sizeof(file_name));
1566		sprintf(file_name, "vpn_crt_server%d_dh", idx);
1567		get_parsed_crt(file_name, buf, sizeof(buf));
1568		websWrite(wp, "%s=['", file_name);
1569		for (c = buf; *c; c++) {
1570			if (isprint(*c) &&
1571				*c != '"' && *c != '&' && *c != '<' && *c != '>')
1572					websWrite(wp, "%c", *c);
1573			else
1574				websWrite(wp, "&#%d", *c);
1575		}
1576		websWrite(wp, "'];\n");
1577
1578		//vpn_crt_server_crl
1579		memset(buf, 0, sizeof(buf));
1580		memset(file_name, 0, sizeof(file_name));
1581		sprintf(file_name, "vpn_crt_server%d_crl", idx);
1582		get_parsed_crt(file_name, buf, sizeof(buf));
1583		websWrite(wp, "%s=['", file_name);
1584		for (c = buf; *c; c++) {
1585			if (isprint(*c) &&
1586				*c != '"' && *c != '&' && *c != '<' && *c != '>')
1587					websWrite(wp, "%c", *c);
1588			else
1589				websWrite(wp, "&#%d", *c);
1590		}
1591		websWrite(wp, "'];\n");
1592
1593		//vpn_crt_server_static
1594		memset(buf, 0, sizeof(buf));
1595		memset(file_name, 0, sizeof(file_name));
1596		sprintf(file_name, "vpn_crt_server%d_static", idx);
1597		get_parsed_crt(file_name, buf, sizeof(buf));
1598		websWrite(wp, "%s=['", file_name);
1599		for (c = buf; *c; c++) {
1600			if (isprint(*c) &&
1601				*c != '"' && *c != '&' && *c != '<' && *c != '>')
1602					websWrite(wp, "%c", *c);
1603			else
1604				websWrite(wp, "&#%d", *c);
1605		}
1606		websWrite(wp, "'];\n");
1607
1608		websWrite(wp, "\n");
1609	}
1610	return 0;
1611}
1612static int
1613ej_vpn_crt_client(int eid, webs_t wp, int argc, char **argv) {
1614	char buf[4000];
1615	char file_name[32];
1616	int idx = 0;
1617
1618	for (idx = 1; idx < 6; idx++) {
1619		char *c;
1620
1621		//vpn_crt_client_ca
1622		memset(buf, 0, sizeof(buf));
1623		memset(file_name, 0, sizeof(file_name));
1624		sprintf(file_name, "vpn_crt_client%d_ca", idx);
1625		get_parsed_crt(file_name, buf, sizeof(buf));
1626		websWrite(wp, "%s=['", file_name);
1627
1628		for (c = buf; *c; c++) {
1629			if (isprint(*c) &&
1630				*c != '"' && *c != '&' && *c != '<' && *c != '>')
1631					websWrite(wp, "%c", *c);
1632			else
1633				websWrite(wp, "&#%d", *c);
1634		}
1635		websWrite(wp, "'];\n");
1636
1637		//vpn_crt_client_crt
1638		memset(buf, 0, sizeof(buf));
1639		memset(file_name, 0, sizeof(file_name));
1640		sprintf(file_name, "vpn_crt_client%d_crt", idx);
1641		get_parsed_crt(file_name, buf, sizeof(buf));
1642		websWrite(wp, "%s=['", file_name);
1643		for (c = buf; *c; c++) {
1644			if (isprint(*c) &&
1645				*c != '"' && *c != '&' && *c != '<' && *c != '>')
1646					websWrite(wp, "%c", *c);
1647			else
1648				websWrite(wp, "&#%d", *c);
1649		}
1650		websWrite(wp, "'];\n");
1651
1652		//vpn_crt_client_key
1653		memset(buf, 0, sizeof(buf));
1654		memset(file_name, 0, sizeof(file_name));
1655		sprintf(file_name, "vpn_crt_client%d_key", idx);
1656		get_parsed_crt(file_name, buf, sizeof(buf));
1657		websWrite(wp, "%s=['", file_name);
1658		for (c = buf; *c; c++) {
1659			if (isprint(*c) &&
1660				*c != '"' && *c != '&' && *c != '<' && *c != '>')
1661					websWrite(wp, "%c", *c);
1662			else
1663				websWrite(wp, "&#%d", *c);
1664		}
1665		websWrite(wp, "'];\n");
1666
1667		//vpn_crt_client_static
1668		memset(buf, 0, sizeof(buf));
1669		memset(file_name, 0, sizeof(file_name));
1670		sprintf(file_name, "vpn_crt_client%d_static", idx);
1671		get_parsed_crt(file_name, buf, sizeof(buf));
1672		websWrite(wp, "%s=['", file_name);
1673		for (c = buf; *c; c++) {
1674			if (isprint(*c) &&
1675				*c != '"' && *c != '&' && *c != '<' && *c != '>')
1676					websWrite(wp, "%c", *c);
1677			else
1678				websWrite(wp, "&#%d", *c);
1679		}
1680		websWrite(wp, "'];\n");
1681
1682		//vpn_crt_client_crl
1683		memset(buf, 0, sizeof(buf));
1684		memset(file_name, 0, sizeof(file_name));
1685		sprintf(file_name, "vpn_crt_client%d_crl", idx);
1686		get_parsed_crt(file_name, buf, sizeof(buf));
1687		websWrite(wp, "%s=['", file_name);
1688		for (c = buf; *c; c++) {
1689			if (isprint(*c) &&
1690				*c != '"' && *c != '&' && *c != '<' && *c != '>')
1691					websWrite(wp, "%c", *c);
1692			else
1693				websWrite(wp, "&#%d", *c);
1694		}
1695		websWrite(wp, "'];\n");
1696
1697		websWrite(wp, "\n");
1698	}
1699	return 0;
1700}
1701#endif
1702
1703//2008.08 magic {
1704// Largest POST will be the OpenVPN key page:
1705// 2*5 fields + 2*4 fields = 18 fields total
1706// Each field can have up to 3500 characters, for a potential
1707// total of 63KB.  Going for 64KB to account for additional POST/GET data.
1708
1709static char post_buf[65535] = { 0 };
1710static char post_buf_backup[65535] = { 0 };
1711static char post_json_buf[65535] = { 0 };
1712
1713static void do_html_post_and_get(char *url, FILE *stream, int len, char *boundary){
1714	char *query = NULL;
1715
1716	init_cgi(NULL);
1717
1718	memset(post_buf, 0, sizeof(post_buf));
1719	memset(post_buf_backup, 0, sizeof(post_buf));
1720	memset(post_json_buf, 0, sizeof(post_json_buf));
1721
1722	if (fgets(post_buf, MIN(len+1, sizeof(post_buf)), stream)){
1723		len -= strlen(post_buf);
1724
1725		while (len--)
1726			(void)fgetc(stream);
1727	}
1728	sprintf(post_json_buf, "%s", post_buf);
1729	query = url;
1730	strsep(&query, "?");
1731
1732	if (query && strlen(query) > 0){
1733		if (strlen(post_buf) > 0)
1734			sprintf(post_buf_backup, "?%s&%s", post_buf, query);
1735		else
1736			sprintf(post_buf_backup, "?%s", query);
1737		sprintf(post_buf, "%s", post_buf_backup+1);
1738	}
1739	else if (strlen(post_buf) > 0)
1740		sprintf(post_buf_backup, "?%s", post_buf);
1741	//websScan(post_buf_backup);
1742	init_cgi(post_buf);
1743}
1744
1745extern struct nvram_tuple router_defaults[];
1746extern struct nvram_tuple router_state_defaults[];
1747
1748// used for handling multiple instance
1749// copy nvram from, ex wl0_ to wl_
1750// prefix is wl_, wan_, or other function with multiple instance
1751// [prefix]_unit and [prefix]_subunit must exist
1752void copy_index_to_unindex(char *prefix, int unit, int subunit)
1753{
1754	struct nvram_tuple *t;
1755	char *value;
1756	char name[64], unitname[64], unitptr[32];
1757	char tmp[64], unitprefix[32];
1758
1759	// check if unit exist
1760	if(unit == -1) return;
1761	snprintf(unitptr, sizeof(unitptr), "%sunit", prefix);
1762	if((value=nvram_get(unitptr))==NULL) return;
1763
1764	strncpy(tmp, prefix, sizeof(tmp));
1765	tmp[strlen(prefix)-1]=0;
1766	if(subunit==-1||subunit==0)
1767		snprintf(unitprefix, sizeof(unitprefix), "%s%d_", tmp, unit);
1768	else snprintf(unitprefix, sizeof(unitprefix), "%s%d.%d_", tmp, unit, subunit);
1769
1770	/* go through each nvram value */
1771	for (t = router_defaults; t->name; t++)
1772	{
1773		memset(name, 0, 64);
1774		sprintf(name, "%s", t->name);
1775
1776		// exception here
1777		if(strcmp(name, unitptr)==0) continue;
1778		if(!strcmp(name, "wan_primary")) continue;
1779
1780		if(!strncmp(name, prefix, strlen(prefix)))
1781		{
1782			(void)strcat_r(unitprefix, &name[strlen(prefix)], unitname);
1783
1784			if((value=nvram_get(unitname))!=NULL)
1785			{
1786				nvram_set(name, value);
1787			}
1788		}
1789	}
1790}
1791
1792#ifdef RTCONFIG_DUALWAN
1793void save_index_to_interface(){//Cherry Cho added for exchanging settings of dualwan in 2014/10/20.
1794	int i;
1795	char word[80], *next;
1796	char tmp[64], prefix[32], unitprefix[32], name[64], unitname[64];
1797	char *wans_dualwan = nvram_get("wans_dualwan");
1798	char *wan_prefix = "wan_";
1799	struct nvram_tuple *t;
1800	char *value;
1801
1802	i = 0;
1803	foreach(word, wans_dualwan, next) {
1804		memset(prefix, 0, sizeof(prefix));
1805		memset(unitprefix, 0, sizeof(unitprefix));
1806		snprintf(prefix, sizeof(prefix), "%s_", word);
1807		snprintf(unitprefix, sizeof(unitprefix), "wan%d_", i);
1808
1809		/* go through each nvram value */
1810		for (t = router_defaults; t->name; t++)
1811		{
1812			memset(name, 0, 64);
1813			sprintf(name, "%s", t->name);
1814
1815			if(!strcmp(name, "wan_unit")) continue;
1816			if(!strcmp(name, "wan_primary")) continue;
1817
1818			if(!strncmp(name, wan_prefix, strlen(wan_prefix))){
1819				memset(tmp, 0, sizeof(tmp));
1820				memset(unitname, 0, sizeof(unitname));
1821				(void)strcat_r(prefix, name, tmp);
1822				(void)strcat_r(unitprefix, &name[strlen(wan_prefix)], unitname);
1823				if((value = nvram_get(unitname)) != NULL){
1824					nvram_set(tmp, value);
1825				}
1826			}
1827		}
1828		i++;
1829	}
1830}
1831
1832
1833void save_interface_to_index(char *wans_dualwan){
1834	int i;
1835	char word[80], *next;
1836	char tmp[64], prefix[32], unitprefix[32], name[64], unitname[64];
1837	char *wan_prefix = "wan_";
1838	struct nvram_tuple *t;
1839	char *value;
1840
1841	i = 0;
1842	foreach(word, wans_dualwan, next) {
1843		memset(prefix, 0, sizeof(prefix));
1844		memset(unitprefix, 0, sizeof(unitprefix));
1845		snprintf(prefix, sizeof(prefix), "%s_", word);
1846		snprintf(unitprefix, sizeof(unitprefix), "wan%d_", i);
1847
1848		/* go through each nvram value */
1849		for (t = router_defaults; t->name; t++)
1850		{
1851			memset(name, 0, 64);
1852			sprintf(name, "%s", t->name);
1853
1854			if(!strcmp(name, "wan_unit")) continue;
1855			if(!strcmp(name, "wan_primary")) continue;
1856
1857			if(!strncmp(name, wan_prefix, strlen(wan_prefix))){
1858				memset(tmp, 0, sizeof(tmp));
1859				memset(unitname, 0, sizeof(unitname));
1860				(void)strcat_r(prefix, name, tmp);
1861				(void)strcat_r(unitprefix, &name[strlen(wan_prefix)], unitname);
1862				if((value = nvram_get(tmp)) != NULL){
1863					nvram_set(unitname, value);
1864				}
1865			}
1866		}
1867		i++;
1868	}
1869}
1870#endif
1871
1872#ifdef RTCONFIG_JFFS2USERICON
1873void handle_upload_icon(char *value) {
1874	char *mac, *uploadicon;
1875	char filename[32];
1876	memset(filename, 0, 32);
1877
1878	//Check folder exist or not
1879	if(!check_if_dir_exist(JFFS_USERICON))
1880		mkdir(JFFS_USERICON, 0755);
1881
1882	if((vstrsep(value, ">", &mac, &uploadicon) == 2)) {
1883		sprintf(filename, "/jffs/usericon/%s.log", mac);
1884
1885		//Delete exist file
1886		if(check_if_file_exist(filename)) {
1887			unlink(filename);
1888		}
1889		//If upload icon string is not noupload, then write to file.
1890		if(strcmp(uploadicon, "noupload")) {
1891			FILE *fp;
1892			if((fp = fopen(filename, "w")) != NULL) {
1893				fprintf(fp, "%s", uploadicon);
1894				fclose(fp);
1895			}
1896		}
1897	}
1898}
1899void del_upload_icon(char *value) {
1900	char *buf, *g, *p;
1901	char filename[32];
1902	memset(filename, 0, 32);
1903
1904	g = buf = strdup(value);
1905	while (buf) {
1906		if ((p = strsep(&g, ">")) == NULL) break;
1907
1908		if(strcmp(p, "")) {
1909			sprintf(filename, "/jffs/usericon/%s.log", p);
1910			//Delete exist file
1911			if(check_if_file_exist(filename)) {
1912				unlink(filename);
1913			}
1914		}
1915	}
1916	free(buf);
1917}
1918#endif
1919
1920#define NVRAM_MODIFIED_BIT		1
1921#define NVRAM_MODIFIED_WL_BIT		2
1922#ifdef RTCONFIG_QTN
1923#define NVRAM_MODIFIED_WL_QTN_BIT	4
1924#endif
1925#define NVRAM_MODIFIED_DUALWAN_ADDUSB		8          /* ex: {wan, none}  =>  {wan, usb} */
1926#define NVRAM_MODIFIED_DUALWAN_EXCHANGE		16	       /* ex: {wan, usb}   =>  {usb, wan}   {wan, lan} => {lan, wan}*/
1927#define NVRAM_MODIFIED_DUALWAN_REBOOT		32		   /* Other cases */
1928
1929int validate_instance(webs_t wp, char *name, json_object *root)
1930{
1931	char prefix[32], word[100], tmp[100], *next, *value;
1932	char prefix1[32], word1[100], *next1;
1933	int i=0; /*, j=0;*/
1934	int found = 0;
1935
1936	// handle instance for wlx, wanx, lanx
1937	if(strncmp(name, "wl", 2)==0) {
1938		foreach(word, nvram_safe_get("wl_ifnames"), next) {
1939			sprintf(prefix, "wl%d_", i++);
1940			value = get_cgi_json(strcat_r(prefix, name+3, tmp),root);
1941			if(!value) {
1942				// find variable with subunit
1943				foreach(word1, nvram_safe_get(strcat_r(prefix, "vifnames", tmp)), next1) {
1944					sprintf(prefix1, "%s_", word1);
1945					value = get_cgi_json(strcat_r(prefix1, name+3, tmp),root);
1946					//printf("find %s\n", tmp);
1947
1948					if(value) break;
1949				}
1950			}
1951
1952			if(value && strcmp(nvram_safe_get(tmp), value)) {
1953				//printf("instance value %s=%s\n", tmp, value);
1954				dbG("nvram set %s = %s\n", tmp, value);
1955				nvram_set(tmp, value);
1956				found = NVRAM_MODIFIED_BIT|NVRAM_MODIFIED_WL_BIT;
1957#ifdef RTCONFIG_QTN
1958				if (!strncmp(tmp, "wl1", 3))
1959				{
1960					if (rpc_qtn_ready())
1961					{
1962						rpc_parse_nvram(tmp, value);
1963						found |= NVRAM_MODIFIED_WL_QTN_BIT;
1964					}
1965				}
1966#endif
1967			}
1968		}
1969	}
1970	else if(strncmp(name, "wan", 3)==0) {
1971		foreach(word, nvram_safe_get("wan_ifnames"), next) {
1972			sprintf(prefix, "wan%d_", i++);
1973			value = get_cgi_json(strcat_r(prefix, name+4, tmp),root);
1974			if(value && strcmp(nvram_safe_get(tmp), value)) {
1975				dbG("nvram set %s = %s\n", tmp, value);
1976				nvram_set(tmp, value);
1977				found = NVRAM_MODIFIED_BIT;
1978			}
1979		}
1980#ifdef RTCONFIG_MULTICAST_IPTV
1981        if(nvram_match("switch_wantag", "movistar")){
1982                sprintf(prefix, "wan10_");//IPTV
1983                value = get_cgi_json(strcat_r(prefix, name+4, tmp), root);
1984                if(value && strcmp(nvram_safe_get(tmp), value)) {
1985                    //dbG("nvram set %s = %s\n", tmp, value);
1986                    nvram_set(tmp, value);
1987                    found = NVRAM_MODIFIED_BIT;
1988                }
1989                sprintf(prefix, "wan11_");//VoIP
1990                value = get_cgi_json(strcat_r(prefix, name+4, tmp), root);
1991                if(value && strcmp(nvram_safe_get(tmp), value)) {
1992                    //dbG("nvram set %s = %s\n", tmp, value);
1993                    nvram_set(tmp, value);
1994                    found = NVRAM_MODIFIED_BIT;
1995                }
1996        }
1997#endif
1998	}
1999#ifdef RTCONFIG_DSL
2000	else if(strncmp(name, "dsl", 3)==0) {
2001		for(i=0;i<8;i++) {
2002			sprintf(prefix, "dsl%d_", i++);
2003			value = get_cgi_json(strcat_r(prefix, name+4, tmp),root);
2004			if(value && strcmp(nvram_safe_get(tmp), value)) {
2005				dbG("nvram set %s = %s\n", tmp, value);
2006				nvram_set(tmp, value);
2007				found = NVRAM_MODIFIED_BIT;
2008			}
2009		}
2010#ifdef RTCONFIG_VDSL
2011		for(i=0;i<8;i++) {
2012			if(i)
2013				snprintf(prefix, sizeof(prefix), "dsl8.%d_", i);
2014			else
2015				snprintf(prefix, sizeof(prefix), "dsl8_");
2016			value = get_cgi_json(strcat_r(prefix, name+4, tmp),root);
2017			if(value && strcmp(nvram_safe_get(tmp), value)) {
2018				dbG("nvram set %s = %s\n", tmp, value);
2019				nvram_set(tmp, value);
2020				found = NVRAM_MODIFIED_BIT;
2021			}
2022		}
2023#endif
2024	}
2025#endif
2026	else if(strncmp(name, "lan", 3)==0) {
2027	}
2028// This seems to create default values for each unit.
2029// Is it really necessary?  lan_ does not seem to use it.
2030#ifdef RTCONFIG_OPENVPN
2031	else if(strncmp(name, "vpn_server_", 11)==0) {
2032		for(i=1;i<3;i++) {
2033			sprintf(prefix, "vpn_server%d_", i);
2034			value = get_cgi_json(strcat_r(prefix, name+11, tmp),root);
2035			if(value && strcmp(nvram_safe_get(tmp), value)) {
2036				dbG("nvram set %s = %s\n", tmp, value);
2037				nvram_set(tmp, value);
2038				found = NVRAM_MODIFIED_BIT;
2039			}
2040		}
2041	}
2042	else if(strncmp(name, "vpn_client_", 11)==0) {
2043		for(i=1;i<3;i++) {
2044			sprintf(prefix, "vpn_client%d_", i);
2045			value = get_cgi_json(strcat_r(prefix, name+11, tmp),root);
2046			if(value && strcmp(nvram_safe_get(tmp), value)) {
2047				dbG("nvram set %s = %s\n", tmp, value);
2048				nvram_set(tmp, value);
2049				found = NVRAM_MODIFIED_BIT;
2050			}
2051		}
2052	}
2053#endif
2054	return found;
2055}
2056
2057static int validate_apply(webs_t wp, json_object *root) {
2058	struct nvram_tuple *t;
2059	char *value;
2060	char name[64];
2061	char tmp[3500], prefix[32];
2062	int unit=-1, subunit=-1;
2063	int nvram_modified = 0;
2064	int nvram_modified_wl = 0;
2065	int acc_modified = 0;
2066	int ret;
2067#ifdef RTCONFIG_DUALWAN
2068	int wans_dualwan_usb = 0;
2069#endif
2070#ifdef RTCONFIG_USB
2071#if defined(RTCONFIG_USB_MODEM) && (defined(RTCONFIG_JFFS2) || defined(RTCONFIG_BRCM_NAND_JFFS2) || defined(RTCONFIG_UBIFS))
2072	int got_modem_data = 0;
2073#endif
2074	char orig_acc[128], modified_acc[128], modified_pass[128];
2075
2076	memset(orig_acc, 0, 128);
2077	memset(modified_acc, 0, 128);
2078	memset(modified_pass, 0, 128);
2079#endif
2080
2081	/* go through each nvram value */
2082	for (t = router_defaults; t->name; t++)
2083	{
2084		snprintf(name, sizeof(name), t->name);
2085
2086		value = get_cgi_json(name, root);
2087
2088		if(!value || (!strncmp(name, "wan", 3) && nvram_match("switch_wantag", "movistar"))) {
2089			if((ret=validate_instance(wp, name,root))) {
2090				if(ret&NVRAM_MODIFIED_BIT) nvram_modified = 1;
2091				if(ret&NVRAM_MODIFIED_WL_BIT) nvram_modified_wl = 1;
2092			}
2093		}
2094		else {
2095#ifdef RTCONFIG_JFFS2USERICON
2096			if(strcmp(name, "custom_usericon"))
2097#endif
2098			_dprintf("value %s=%s\n", name, value);
2099
2100			// unit nvram should be in fron of each apply,
2101			// seems not a good design
2102
2103			if(!strcmp(name, "wl_unit")
2104					|| !strcmp(name, "wan_unit")
2105					|| !strcmp(name, "lan_unit")
2106#ifdef RTCONFIG_DSL
2107					|| !strcmp(name, "dsl_unit")
2108#endif
2109#ifdef RTCONFIG_OPENVPN
2110					|| !strcmp(name, "vpn_server_unit")
2111					|| !strcmp(name, "vpn_client_unit")
2112#endif
2113					) {
2114				unit = atoi(value);
2115				if(unit != nvram_get_int(name)) {
2116					nvram_set_int(name, unit);
2117					nvram_modified=1;
2118				}
2119			}
2120			else if(!strcmp(name, "wl_subunit")) {
2121				subunit = atoi(value);
2122				if(subunit!=nvram_get_int(name)) {
2123					nvram_set_int(name, subunit);
2124					nvram_modified=1;
2125				}
2126			}
2127			else if(!strncmp(name, "wl_", 3) && unit != -1) {
2128				// convert wl_ to wl[unit], only when wl_unit is parsed
2129				if(subunit==-1||subunit==0)
2130					snprintf(prefix, sizeof(prefix), "wl%d_", unit);
2131				else snprintf(prefix, sizeof(prefix), "wl%d.%d_", unit, subunit);
2132				(void)strcat_r(prefix, name+3, tmp);
2133				if(strcmp(nvram_safe_get(tmp), value))
2134				{
2135					nvram_set(tmp, value);
2136					nvram_modified = 1;
2137					nvram_modified_wl = 1;
2138					_dprintf("set %s=%s\n", tmp, value);
2139
2140#ifdef RTCONFIG_QTN
2141					if (unit == 1)
2142					{
2143						if (rpc_qtn_ready())
2144						{
2145							rpc_parse_nvram(tmp, value);
2146						}
2147					}
2148#endif
2149				}
2150			}
2151			else if(!strncmp(name, "wan_", 4) && unit != -1) {
2152				snprintf(prefix, sizeof(prefix), "wan%d_", unit);
2153				(void)strcat_r(prefix, name+4, tmp);
2154
2155				if(strcmp(nvram_safe_get(tmp), value)) {
2156					nvram_set(tmp, value);
2157					nvram_modified = 1;
2158					_dprintf("set %s=%s\n", tmp, value);
2159				}
2160			}
2161			else if(!strncmp(name, "lan_", 4) && unit != -1) {
2162				snprintf(prefix, sizeof(prefix), "lan%d_", unit);
2163				(void)strcat_r(prefix, name+4, tmp);
2164
2165				if(strcmp(nvram_safe_get(tmp), value)) {
2166					nvram_set(tmp, value);
2167					nvram_modified = 1;
2168					_dprintf("set %s=%s\n", tmp, value);
2169				}
2170			}
2171#ifdef RTCONFIG_DSL
2172			else if(!strcmp(name, "dsl_subunit")) {
2173				subunit = atoi(value);
2174				if(subunit!=nvram_get_int(name)) {
2175					nvram_set_int(name, subunit);
2176					nvram_modified=1;
2177				}
2178			}
2179			else if(!strncmp(name, "dsl_", 4) && unit != -1) {
2180				if(subunit==-1||subunit==0)
2181					snprintf(prefix, sizeof(prefix), "dsl%d_", unit);
2182				else
2183					snprintf(prefix, sizeof(prefix), "dsl%d.%d_", unit, subunit);
2184				(void)strcat_r(prefix, name+4, tmp);
2185
2186				if(strcmp(nvram_safe_get(tmp), value)) {
2187					nvram_set(tmp, value);
2188					nvram_modified = 1;
2189					_dprintf("set %s=%s\n", tmp, value);
2190				}
2191			}
2192#endif
2193#ifdef RTCONFIG_OPENVPN
2194			else if(!strncmp(name, "vpn_server_", 11) && unit!=-1) {
2195				snprintf(prefix, sizeof(prefix), "vpn_server%d_", unit);
2196				(void)strcat_r(prefix, name+11, tmp);
2197
2198				if(strcmp(nvram_safe_get(tmp), value)) {
2199					nvram_set(tmp, value);
2200					nvram_modified = 1;
2201					_dprintf("set %s=%s\n", tmp, value);
2202				}
2203			}
2204			else if(!strncmp(name, "vpn_client_", 11) && unit!=-1) {
2205				snprintf(prefix, sizeof(prefix), "vpn_client%d_", unit);
2206				(void)strcat_r(prefix, name+11, tmp);
2207
2208				if(strcmp(nvram_safe_get(tmp), value)) {
2209					nvram_set(tmp, value);
2210					nvram_modified = 1;
2211					_dprintf("set %s=%s\n", tmp, value);
2212				}
2213			}
2214#endif
2215#ifdef RTCONFIG_DISK_MONITOR
2216			else if(!strncmp(name, "diskmon_", 8)) {
2217				snprintf(prefix, sizeof(prefix), "usb_path%s_diskmon_", nvram_safe_get("diskmon_usbport"));
2218				(void)strcat_r(prefix, name+8, tmp);
2219
2220				if(strcmp(nvram_safe_get(tmp), value)) {
2221					nvram_set(tmp, value);
2222					nvram_modified = 1;
2223					_dprintf("set %s=%s\n", tmp, value);
2224				}
2225			}
2226#endif
2227#ifdef RTCONFIG_JFFS2USERICON
2228			else if(!strcmp(name, "custom_usericon")) {
2229				(void)handle_upload_icon(value);
2230				nvram_set(name, "");
2231				nvram_modified = 1;
2232			}
2233			else if(!strcmp(name, "custom_usericon_del")) {
2234				(void)del_upload_icon(value);
2235				nvram_set(name, "");
2236				nvram_modified = 1;
2237			}
2238#endif
2239			// TODO: add other multiple instance handle here
2240			else if(strcmp(nvram_safe_get(name), value)) {
2241
2242				// the flag is set only when username or password is changed
2243				if(!strcmp(t->name, "http_username")
2244						|| !strcmp(t->name, "http_passwd")){
2245#ifdef RTCONFIG_USB
2246					if(!strcmp(t->name, "http_username")){
2247						strncpy(orig_acc, nvram_safe_get(name), 128);
2248						strncpy(modified_acc, value, 128);
2249					}
2250					else if(!strcmp(t->name, "http_passwd"))
2251						strncpy(modified_pass, value, 128);
2252
2253#endif
2254
2255					acc_modified = 1;
2256					change_passwd = 1;
2257				}
2258
2259#ifdef RTCONFIG_HTTPS
2260				if(!strcmp(name, "PM_SMTP_AUTH_PASS")){
2261					_dprintf("PM_SMTP_AUTH_PASS match\n");
2262					char pw_tmp[256];
2263					memset(pw_tmp, 0, 256);
2264					strncpy(pw_tmp, value,256);
2265					strncpy(value, (char *) pwenc(pw_tmp),256);
2266				}
2267#endif
2268
2269#ifdef RTCONFIG_DUALWAN//Cherry Cho added for exchanging settings of dualwan in 2014/10/20.
2270				if(!strcmp(name, "wans_dualwan")){
2271					char *orig_wans_dualwan, *wans_dualwan;
2272					char *orig_primary, *orig_second, *new_primary, *new_second;
2273					char *orig, *new, *tmp, *tmp2;
2274
2275					save_index_to_interface();
2276					save_interface_to_index(value);
2277
2278					orig_wans_dualwan = nvram_safe_get("wans_dualwan");
2279					tmp = orig = strdup(orig_wans_dualwan);
2280					vstrsep(orig, " ", &orig_primary, &orig_second);
2281
2282					wans_dualwan = value;
2283					tmp2 = new = strdup(value);
2284					vstrsep(new, " ", &new_primary, &new_second);
2285					//_dprintf("validate_apply: orig_primary = %s orig_second = %s new_primary = %s new_second = %s\n", orig_primary, orig_second, new_primary, new_second);
2286
2287					if( strstr(orig_wans_dualwan, "none") && (strstr(orig_wans_dualwan, "usb") == NULL) &&
2288					    strstr(wans_dualwan, "usb") && (strstr(wans_dualwan, "none") == NULL) &&
2289					   (strstr(wans_dualwan, orig_primary) || strstr(wans_dualwan, orig_second)) ){ //Add USB
2290						//_dprintf("validate_apply: NVRAM_MODIFIED_DUALWAN_ADDUSB\n");
2291						wans_dualwan_usb = NVRAM_MODIFIED_DUALWAN_ADDUSB;
2292					}
2293					else if( strstr(orig_wans_dualwan, "usb") && (strstr(orig_wans_dualwan, "none") == NULL) &&
2294					    strstr(wans_dualwan, "none") && (strstr(wans_dualwan, "usb") == NULL) &&
2295					   (strstr(wans_dualwan, orig_primary) || strstr(wans_dualwan, orig_second)) ){ //Remove USB
2296						//_dprintf("validate_apply: NVRAM_MODIFIED_DUALWAN_ADDUSB Remove\n");
2297						wans_dualwan_usb = NVRAM_MODIFIED_DUALWAN_ADDUSB;
2298					}
2299					else if(!strcmp(orig_primary, new_second) && !strcmp(orig_second, new_primary)){ // Exchange Value
2300						//_dprintf("validate_apply: NVRAM_MODIFIED_DUALWAN_EXCHANGE\n");
2301						wans_dualwan_usb = NVRAM_MODIFIED_DUALWAN_EXCHANGE;
2302					}
2303					else{
2304						//_dprintf("validate_apply: NVRAM_MODIFIED_DUALWAN_REBOOT\n");
2305						wans_dualwan_usb = NVRAM_MODIFIED_DUALWAN_REBOOT;
2306					}
2307					free(tmp);
2308					free(tmp2);
2309				}
2310#endif
2311
2312#if defined(RTCONFIG_JFFS2) || defined(RTCONFIG_BRCM_NAND_JFFS2) || defined(RTCONFIG_UBIFS)
2313				if(!strcmp(name, "modem_bytes_data_cycle") || !strcmp(name, "modem_bytes_data_limit") || !strcmp(name, "modem_bytes_data_warning")){
2314					notify_rc("restart_set_dataset");
2315				}
2316#endif
2317				if(!strcmp(name, "wps_enable")) {
2318					nvram_set("wps_enable_old", value);
2319					_dprintf("set wps_enable_old=%s\n", value);
2320				}
2321
2322				nvram_set(name, value);
2323				if(strcmp(name, "wans_dualwan")) //not wans_dualwan
2324					nvram_modified = 1;
2325				_dprintf("set %s=%s\n", name, value);
2326
2327#if defined(RTCONFIG_USB_MODEM) && (defined(RTCONFIG_JFFS2) || defined(RTCONFIG_BRCM_NAND_JFFS2) || defined(RTCONFIG_UBIFS))
2328				if(!strncmp(name, "modem_bytes_data", 16)){
2329					got_modem_data = 1;
2330				}
2331#endif
2332			}
2333		}
2334	}
2335
2336	if(acc_modified){
2337		// ugly solution?
2338		notify_rc("chpass");
2339
2340#ifdef RTCONFIG_USB
2341		if(strlen(orig_acc) <= 0)
2342			strncpy(orig_acc, nvram_safe_get("http_username"), 128);
2343		if(strlen(modified_pass) <= 0)
2344			strncpy(modified_pass, nvram_safe_get("http_passwd"), 128);
2345
2346		if(strlen(modified_acc) <= 0)
2347			mod_account(orig_acc, NULL, modified_pass);
2348		else
2349			mod_account(orig_acc, modified_acc, modified_pass);
2350
2351		notify_rc_and_wait("restart_ftpsamba");
2352#endif
2353	}
2354
2355#if defined(RTCONFIG_USB_MODEM) && (defined(RTCONFIG_JFFS2) || defined(RTCONFIG_BRCM_NAND_JFFS2) || defined(RTCONFIG_UBIFS))
2356	if(got_modem_data){
2357		eval("modem_status.sh", "set_dataset");
2358	}
2359#endif
2360
2361	/* go through each temp nvram value */
2362	/* but not support instance now */
2363	for (t = router_state_defaults; t->name; t++)
2364	{
2365		// skip some unhandled variables
2366		if(strcmp(t->name, "rc_service")==0)
2367			continue;
2368
2369		memset(name, 0, 64);
2370		sprintf(name, "%s", t->name);
2371
2372		value = websGetVar(wp, name, NULL);
2373
2374		if(value) {
2375			if(strcmp(nvram_safe_get(name), value)) {
2376				nvram_set(name, value);
2377			}
2378		}
2379	}
2380
2381#ifdef RTCONFIG_DSL
2382	if(nvram_match("dsltmp_qis_dsl_pvc_set", "1")) {
2383		update_dsl_iptv_variables();
2384		nvram_modified = 1;
2385	}
2386#endif
2387
2388#ifdef RTCONFIG_DUALWAN
2389	nvram_modified |= wans_dualwan_usb;
2390	//_dprintf("validate_apply: nvram_modified = %X\n", nvram_modified);
2391#endif
2392
2393	if(nvram_modified)
2394	{
2395#ifdef RTCONFIG_TR069
2396		if(pids("tr069")) {
2397			_dprintf("value change from web!\n");
2398			eval("sendtocli", "http://127.0.0.1:1234/web/value/change", "\"name=change\"");
2399		}
2400#endif
2401		// TODO: is it necessary to separate the different?
2402		if(nvram_match("x_Setting", "0")){
2403
2404			int fromapp_flag = 0;
2405			char *current_page;
2406
2407			fromapp_flag = check_user_agent(user_agent);
2408
2409			current_page = websGetVar(wp, "current_page", NULL);
2410			if(current_page != NULL){
2411				if(!strstr(current_page, "QIS_"))
2412					nvram_set("x_Setting", "1");
2413
2414				if(nvram_match("productid", "4G-AC55U") && nvram_match("wans_mode", "lb")){//Cherry Cho added in 2014/10/03.
2415					if(!strstr(current_page, "QIS_"))
2416						nvram_set("wans_mode", "fo");
2417				}
2418			}else if(fromapp_flag != 0)
2419				nvram_set("x_Setting", "1");
2420		}
2421
2422		if (nvram_modified_wl)
2423			nvram_set("w_Setting", "1");
2424		nvram_commit();
2425	}
2426
2427	return nvram_modified;
2428}
2429
2430bool isIP(char *ipAddress)
2431{
2432    struct sockaddr_in sa;
2433    int result = inet_pton(AF_INET, ipAddress, &(sa.sin_addr));
2434    return result != 0;
2435}
2436
2437bool isMAC(const char* mac) {
2438    int i = 0;
2439    int s = 0;
2440
2441    while (*mac) {
2442       if (isxdigit(*mac)) {
2443          i++;
2444       }
2445       else if (*mac == ':') {
2446          if (i == 0 || i / 2 - 1 != s)
2447            break;
2448          ++s;
2449       }
2450       else {
2451           s = -1;
2452       }
2453       ++mac;
2454    }
2455    return (i == 12 && s == 5);
2456}
2457
2458bool isNumber(const char*s) {
2459   char* e = NULL;
2460   (void) strtol(s, &e, 0);
2461   return e != NULL && *e == (char)0;
2462}
2463
2464#ifdef RTCONFIG_ROG
2465#define ApiMaxNumRegister 32
2466#define ApiMaxNumPortforward 32
2467#define ApiMaxNumQos 32
2468static int ej_set_variables(int eid, webs_t wp, int argc, char_t **argv) {
2469	char *apiName;
2470	char *apiAction;
2471	char *webVar_1;
2472	char *webVar_2;
2473	char *webVar_3;
2474	char *webVar_4;
2475	char *webVar_5;
2476	char *webVar_6;
2477	int retStatus = 0;
2478	char retList[65536]={0};
2479	char *buf, *g, *p;
2480	char nvramTmp[4096]={0}, strTmp[4096]={0};
2481	int iCurrentListNum = 0;
2482
2483	apiName = websGetVar(wp, "apiname", "");
2484	apiAction = websGetVar(wp, "action", "");
2485	_dprintf("[httpd] api.asp: apiname->%s, apiAction->%s\n", apiName, apiAction);
2486
2487	if(!strcmp(apiName, "register")){
2488		char *name, *mac, *group, *type, *callback, *keeparp;
2489
2490		if(!strcmp(apiAction, "add")){
2491			webVar_1 = websGetVar(wp, "name", "");
2492			webVar_2 = websGetVar(wp, "mac", "");
2493			webVar_3 = websGetVar(wp, "group", "");
2494			webVar_4 = websGetVar(wp, "type", "");
2495			webVar_5 = websGetVar(wp, "callback", "");
2496			webVar_6 = websGetVar(wp, "keeparp", "");
2497
2498			if(!strcmp(webVar_1, "") || !strcmp(webVar_2, "") ||
2499			   !strcmp(webVar_3, "") || !strcmp(webVar_4, "") ){
2500				retStatus = 3;
2501			}
2502			else if(strlen(webVar_1) > 32){
2503				retStatus = 3;
2504			}
2505			else if(!isMAC(webVar_2)){
2506				retStatus = 3;
2507			}
2508			else if(!isNumber(webVar_3)){
2509				retStatus = 3;
2510			}
2511			else if(!isNumber(webVar_4)){
2512				retStatus = 3;
2513			}
2514                        else if(!isNumber(webVar_5)){
2515                                retStatus = 3;
2516                        }
2517                        else if(!isNumber(webVar_6)){
2518                                retStatus = 3;
2519                        }
2520			else{
2521				g = buf = strdup(nvram_safe_get("custom_clientlist"));
2522				while (buf) {
2523					if ((p = strsep(&g, "<")) == NULL) break;
2524
2525					iCurrentListNum++;
2526
2527					if((vstrsep(p, ">", &name, &mac, &group, &type, &callback, &keeparp)) != 6) continue;
2528
2529					if(!strcmp(webVar_2, mac)){
2530						retStatus = 1;
2531						break;
2532					}
2533				}
2534				free(buf);
2535
2536				// if this current list already is the maximum, can't be added.
2537				if((iCurrentListNum-1) == ApiMaxNumRegister)
2538					retStatus = 4;
2539
2540				if(retStatus == 0){
2541					strcat(nvramTmp, "<");
2542					strcat(nvramTmp, webVar_1);
2543					strcat(nvramTmp, ">");
2544					strcat(nvramTmp, webVar_2);
2545					strcat(nvramTmp, ">");
2546					strcat(nvramTmp, webVar_3);
2547					strcat(nvramTmp, ">");
2548					strcat(nvramTmp, webVar_4);
2549					strcat(nvramTmp, ">");
2550					strcat(nvramTmp, webVar_5);
2551					strcat(nvramTmp, ">");
2552					strcat(nvramTmp, webVar_6);
2553					strcat(nvramTmp, nvram_safe_get("custom_clientlist"));
2554
2555					nvram_set("custom_clientlist", nvramTmp);
2556					nvram_commit();
2557				}
2558			}
2559		}
2560		else if(!strcmp(apiAction, "del")){
2561			webVar_1 = websGetVar(wp, "mac", "");
2562
2563			if(!strcmp(webVar_1, "")){
2564				retStatus = 3;
2565			}
2566			else{
2567				retStatus = 2;
2568				g = buf = strdup(nvram_safe_get("custom_clientlist"));
2569				while (buf) {
2570					if ((p = strsep(&g, "<")) == NULL) break;
2571					if((vstrsep(p, ">", &name, &mac, &group, &type, &callback, &keeparp)) != 6) continue;
2572
2573					if(!strcmp(webVar_1, mac)){
2574						retStatus = 0;
2575						continue;
2576					}
2577					else{
2578						strcat(nvramTmp, "<");
2579						strcat(nvramTmp, name);
2580						strcat(nvramTmp, ">");
2581						strcat(nvramTmp, mac);
2582						strcat(nvramTmp, ">");
2583						strcat(nvramTmp, group);
2584						strcat(nvramTmp, ">");
2585						strcat(nvramTmp, type);
2586						strcat(nvramTmp, ">");
2587						strcat(nvramTmp, callback);
2588						strcat(nvramTmp, ">");
2589						strcat(nvramTmp, keeparp);
2590					}
2591				}
2592				free(buf);
2593
2594				if(retStatus == 0){
2595					nvram_set("custom_clientlist", nvramTmp);
2596					nvram_commit();
2597				}
2598			}
2599		}
2600		else if(!strcmp(apiAction, "list")){
2601			g = buf = strdup(nvram_safe_get("custom_clientlist"));
2602			strcat(retList, "<list>\n");
2603			while (buf) {
2604				if ((p = strsep(&g, "<")) == NULL) break;
2605				if((vstrsep(p, ">", &name, &mac, &group, &type, &callback, &keeparp)) != 6) continue;
2606
2607				strcat(retList, "<device>\n");
2608				sprintf(strTmp, "<name>%s</name>\n", name);
2609				strcat(retList, strTmp);
2610				sprintf(strTmp, "<mac>%s</mac>\n", mac);
2611				strcat(retList, strTmp);
2612				sprintf(strTmp, "<group>%s</group>\n", group);
2613				strcat(retList, strTmp);
2614				sprintf(strTmp, "<type>%s</type>\n", type);
2615				strcat(retList, strTmp);
2616				sprintf(strTmp, "<callback>%s</callback>\n", callback);
2617				strcat(retList, strTmp);
2618				sprintf(strTmp, "<keeparp>%s</keeparp>\n", keeparp);
2619				strcat(retList, strTmp);
2620				strcat(retList, "</device>\n");
2621			}
2622			free(buf);
2623			strcat(retList, "</list>\n");
2624		}
2625		else{
2626			retStatus = 3;
2627		}
2628	}
2629	else if(!strcmp(apiName, "portforward")){
2630		char *name, *rport, *lip, *lport, *proto;
2631
2632		if(!strcmp(apiAction, "enable")){
2633			if(nvram_match("vts_enable_x", "0")){
2634				nvram_set("vts_enable_x", "1");
2635				nvram_commit();
2636				notify_rc("restart_firewall");
2637			}
2638		}
2639		else if(!strcmp(apiAction, "disable")){
2640			if(nvram_match("vts_enable_x", "1")){
2641				nvram_set("vts_enable_x", "0");
2642				nvram_commit();
2643				notify_rc("restart_firewall");
2644			}
2645		}
2646		else if(!strcmp(apiAction, "add")){
2647			webVar_1 = websGetVar(wp, "name", "");
2648			webVar_2 = websGetVar(wp, "rport", "");
2649			webVar_3 = websGetVar(wp, "lip", "");
2650			webVar_4 = websGetVar(wp, "lport", "");
2651			webVar_5 = websGetVar(wp, "proto", "");
2652
2653			if(!strcmp(webVar_1, "") || !strcmp(webVar_2, "") || !strcmp(webVar_3, "") ||
2654			   !strcmp(webVar_4, "") || !strcmp(webVar_5, "")){
2655				retStatus = 3;
2656			}
2657			else if(strlen(webVar_1) > 32){
2658				retStatus = 3;
2659			}
2660			else if(!isNumber(webVar_2)){
2661				retStatus = 3;
2662			}
2663			else if(!isIP(webVar_3)){
2664				retStatus = 3;
2665			}
2666			else if(!isNumber(webVar_4)){
2667				retStatus = 3;
2668			}
2669			else if(strcmp(webVar_5, "TCP") && strcmp(webVar_5, "UDP") &&
2670					strcmp(webVar_5, "BOTH") && strcmp(webVar_5, "OTHER")){
2671				retStatus = 3;
2672			}
2673			else{
2674				g = buf = strdup(nvram_safe_get("vts_rulelist"));
2675				while (buf) {
2676					if ((p = strsep(&g, "<")) == NULL) break;
2677
2678					iCurrentListNum++;
2679
2680					if((vstrsep(p, ">", &name, &rport, &lip, &lport, &proto)) != 5) continue;
2681
2682					if(!strcmp(webVar_1, name) && !strcmp(webVar_2, rport) &&
2683					   !strcmp(webVar_3, lip) && !strcmp(webVar_4, lport) &&
2684					   !strcmp(webVar_5, proto)
2685					){
2686						retStatus = 1;
2687						break;
2688					}
2689				}
2690				free(buf);
2691
2692				// if this current list already is the maximum, can't be added.
2693				if((iCurrentListNum-1) == ApiMaxNumPortforward)
2694					retStatus = 4;
2695
2696				if(retStatus == 0){
2697					strcat(nvramTmp, "<");
2698					strcat(nvramTmp, webVar_1);
2699					strcat(nvramTmp, ">");
2700					strcat(nvramTmp, webVar_2);
2701					strcat(nvramTmp, ">");
2702					strcat(nvramTmp, webVar_3);
2703					strcat(nvramTmp, ">");
2704					strcat(nvramTmp, webVar_4);
2705					strcat(nvramTmp, ">");
2706					strcat(nvramTmp, webVar_5);
2707					strcat(nvramTmp, nvram_safe_get("vts_rulelist"));
2708
2709					nvram_set("vts_rulelist", nvramTmp);
2710					nvram_commit();
2711					notify_rc("restart_firewall"); // need to reboot if ctf is enabled.
2712				}
2713			}
2714		}
2715		else if(!strcmp(apiAction, "del")){
2716			webVar_1 = websGetVar(wp, "name", "");
2717			webVar_2 = websGetVar(wp, "rport", "");
2718			webVar_3 = websGetVar(wp, "lip", "");
2719			webVar_4 = websGetVar(wp, "lport", "");
2720			webVar_5 = websGetVar(wp, "proto", "");
2721
2722			if(!strcmp(webVar_1, "") && !strcmp(webVar_2, "") && !strcmp(webVar_3, "") &&
2723			   !strcmp(webVar_4, "") && !strcmp(webVar_5, "")){
2724				retStatus = 3;
2725			}
2726			else{
2727				retStatus = 2;
2728				g = buf = strdup(nvram_safe_get("vts_rulelist"));
2729				while (buf) {
2730					if ((p = strsep(&g, "<")) == NULL) break;
2731					if((vstrsep(p, ">", &name, &rport, &lip, &lport, &proto)) != 5) continue;
2732
2733					if(!strcmp(webVar_1, name) && !strcmp(webVar_2, rport) &&
2734					   !strcmp(webVar_3, lip) && !strcmp(webVar_4, lport) &&
2735					   !strcmp(webVar_5, proto)
2736					){
2737						retStatus = 0;
2738						continue;
2739					}
2740					else{
2741						strcat(nvramTmp, "<");
2742						strcat(nvramTmp, name);
2743						strcat(nvramTmp, ">");
2744						strcat(nvramTmp, rport);
2745						strcat(nvramTmp, ">");
2746						strcat(nvramTmp, lip);
2747						strcat(nvramTmp, ">");
2748						strcat(nvramTmp, lport);
2749						strcat(nvramTmp, ">");
2750						strcat(nvramTmp, proto);
2751					}
2752				}
2753				free(buf);
2754
2755				if(retStatus == 0){
2756					nvram_set("vts_rulelist", nvramTmp);
2757					nvram_commit();
2758					notify_rc("restart_firewall");
2759				}
2760			}
2761		}
2762		else if(!strcmp(apiAction, "list")){
2763			g = buf = strdup(nvram_safe_get("vts_rulelist"));
2764			strcat(retList, "<list>\n");
2765			while (buf) {
2766				if ((p = strsep(&g, "<")) == NULL) break;
2767				if((vstrsep(p, ">", &name, &rport, &lip, &lport, &proto)) != 5) continue;
2768
2769				strcat(retList, "<item>\n");
2770				sprintf(strTmp, "<name>%s</name>\n", name);
2771				strcat(retList, strTmp);
2772				sprintf(strTmp, "<rport>%s</rport>\n", rport);
2773				strcat(retList, strTmp);
2774				sprintf(strTmp, "<lip>%s</lip>\n", lip);
2775				strcat(retList, strTmp);
2776				sprintf(strTmp, "<lport>%s</lport>\n", lport);
2777				strcat(retList, strTmp);
2778				sprintf(strTmp, "<proto>%s</proto>\n", proto);
2779				strcat(retList, strTmp);
2780				strcat(retList, "</item>\n");
2781			}
2782			free(buf);
2783
2784			strcat(retList, "</list>\n");
2785		}
2786		else{
2787			retStatus = 3;
2788		}
2789	}
2790	else if(!strcmp(apiName, "qos")){
2791		char *desc, *addr, *port, *prio, *transferred, *proto;
2792
2793		if(!strcmp(apiAction, "enable")){
2794			webVar_1 = websGetVar(wp, "upbw", "");
2795			webVar_2 = websGetVar(wp, "downbw", "");
2796
2797			if(!strcmp(webVar_1, "") || !isNumber(webVar_1)){
2798				retStatus = 3;
2799			}
2800			else if(!strcmp(webVar_2, "") || !isNumber(webVar_2)){
2801				retStatus = 3;
2802			}
2803			else{
2804				nvram_set("qos_obw", webVar_1);
2805				nvram_set("qos_ibw", webVar_2);
2806				if(nvram_match("qos_enable", "1")){
2807					nvram_commit();
2808					notify_rc("restart_qos");
2809				}
2810				else{
2811					nvram_set("qos_enable", "1");
2812					nvram_commit();
2813					sys_reboot();
2814				}
2815			}
2816		}
2817		else if(!strcmp(apiAction, "disable")){
2818			if(nvram_match("qos_enable", "1")){
2819				nvram_set("qos_enable", "0");
2820				nvram_commit();
2821				sys_reboot();
2822			}
2823		}
2824		else if(!strcmp(apiAction, "add")){
2825			webVar_1 = websGetVar(wp, "name", "");
2826			webVar_2 = websGetVar(wp, "src", "");
2827			webVar_3 = websGetVar(wp, "dstport", "");
2828			webVar_4 = websGetVar(wp, "proto", "");
2829			webVar_5 = websGetVar(wp, "transferred", "");
2830			webVar_6 = websGetVar(wp, "prio", "");
2831
2832			if(!strcmp(webVar_1, "") || !strcmp(webVar_6, "")){
2833				retStatus = 3;
2834			}
2835			else if(!strcmp(webVar_2, "") && !strcmp(webVar_3, "") &&
2836					!strcmp(webVar_4, "") && !strcmp(webVar_5, "")){
2837				retStatus = 3;
2838			}
2839			else if(strlen(webVar_1) > 32){
2840				retStatus = 3;
2841			}
2842			else if(strcmp(webVar_2, "") && (!isMAC(webVar_2) && !isIP(webVar_2))){
2843				retStatus = 3;
2844			}
2845			else if(strcmp(webVar_4, "") &&
2846					(strcmp(webVar_4, "tcp") && strcmp(webVar_4, "udp") &&
2847					 strcmp(webVar_4, "tcp/udp") && strcmp(webVar_4, "any"))) {
2848				retStatus = 3;
2849			}
2850			else if(strcmp(webVar_6, "0") && strcmp(webVar_6, "1") &&
2851					strcmp(webVar_6, "2") && strcmp(webVar_6, "3") && strcmp(webVar_6, "4")){
2852				retStatus = 3;
2853			}
2854			else{
2855				g = buf = strdup(nvram_safe_get("qos_rulelist"));
2856				while (buf) {
2857					if ((p = strsep(&g, "<")) == NULL) break;
2858
2859					iCurrentListNum++;
2860
2861					if((vstrsep(p, ">", &desc, &addr, &port, &proto, &transferred, &prio)) != 6) continue;
2862
2863					if(!strcmp(webVar_1, desc) && !strcmp(webVar_2, addr) &&
2864					   !strcmp(webVar_3, port) && !strcmp(webVar_4, proto) &&
2865					   !strcmp(webVar_5, transferred) && !strcmp(webVar_6, prio)
2866					){
2867						retStatus = 1;
2868						break;
2869					}
2870				}
2871				free(buf);
2872
2873				// if this current list already is the maximum, can't be added.
2874				if((iCurrentListNum-1) == ApiMaxNumQos)
2875					retStatus = 4;
2876
2877				if(retStatus == 0){
2878					strcat(nvramTmp, "<");
2879					strcat(nvramTmp, webVar_1);
2880					strcat(nvramTmp, ">");
2881					strcat(nvramTmp, webVar_2);
2882					strcat(nvramTmp, ">");
2883					strcat(nvramTmp, webVar_3);
2884					strcat(nvramTmp, ">");
2885					strcat(nvramTmp, webVar_4);
2886					strcat(nvramTmp, ">");
2887					strcat(nvramTmp, webVar_5);
2888					strcat(nvramTmp, ">");
2889					strcat(nvramTmp, webVar_6);
2890					strcat(nvramTmp, nvram_safe_get("qos_rulelist"));
2891
2892					nvram_set("qos_rulelist", nvramTmp);
2893					nvram_commit();
2894					notify_rc("restart_qos"); // need to reboot if ctf is enabled.
2895				}
2896			}
2897		}
2898		else if(!strcmp(apiAction, "del")){
2899			webVar_1 = websGetVar(wp, "name", "");
2900			webVar_2 = websGetVar(wp, "src", "");
2901			webVar_3 = websGetVar(wp, "dstport", "");
2902			webVar_4 = websGetVar(wp, "proto", "");
2903			webVar_5 = websGetVar(wp, "transferred", "");
2904			webVar_6 = websGetVar(wp, "prio", "");
2905
2906			if(!strcmp(webVar_1, "") && !strcmp(webVar_2, "") && !strcmp(webVar_3, "") &&
2907			   !strcmp(webVar_4, "") && !strcmp(webVar_5, "") && !strcmp(webVar_6, "")){
2908				retStatus = 3;
2909			}
2910			else{
2911				retStatus = 2;
2912				g = buf = strdup(nvram_safe_get("qos_rulelist"));
2913				while (buf) {
2914					if ((p = strsep(&g, "<")) == NULL) break;
2915					if((vstrsep(p, ">", &desc, &addr, &port, &proto, &transferred, &prio)) != 6) continue;
2916
2917					if(!strcmp(webVar_1, desc) && !strcmp(webVar_2, addr) &&
2918					   !strcmp(webVar_3, port) && !strcmp(webVar_4, proto) &&
2919					   !strcmp(webVar_5, transferred) && !strcmp(webVar_6, prio)
2920					){
2921						retStatus = 0;
2922						continue;
2923					}
2924					else{
2925						strcat(nvramTmp, "<");
2926						strcat(nvramTmp, desc);
2927						strcat(nvramTmp, ">");
2928						strcat(nvramTmp, addr);
2929						strcat(nvramTmp, ">");
2930						strcat(nvramTmp, port);
2931						strcat(nvramTmp, ">");
2932						strcat(nvramTmp, proto);
2933						strcat(nvramTmp, ">");
2934						strcat(nvramTmp, transferred);
2935						strcat(nvramTmp, ">");
2936						strcat(nvramTmp, prio);
2937					}
2938				}
2939				free(buf);
2940
2941				if(retStatus == 0){
2942					nvram_set("qos_rulelist", nvramTmp);
2943					nvram_commit();
2944					notify_rc("restart_qos"); // need to reboot if ctf is enabled.
2945				}
2946			}
2947		}
2948		else if(!strcmp(apiAction, "list")){
2949			g = buf = strdup(nvram_safe_get("qos_rulelist"));
2950			strcat(retList, "<list>\n");
2951
2952			sprintf(strTmp, "<enable>%s</enable>\n", nvram_get("qos_enable"));
2953			strcat(retList, strTmp);
2954			sprintf(strTmp, "<upbw>%s</upbw>\n", nvram_get("qos_obw"));
2955			strcat(retList, strTmp);
2956			sprintf(strTmp, "<downbw>%s</downbw>\n", nvram_get("qos_ibw"));
2957			strcat(retList, strTmp);
2958
2959			while (buf) {
2960				if ((p = strsep(&g, "<")) == NULL) break;
2961				if((vstrsep(p, ">", &desc, &addr, &port, &proto, &transferred, &prio)) != 6) continue;
2962
2963				strcat(retList, "<item>\n");
2964				sprintf(strTmp, "<name>%s</name>\n", desc);
2965				strcat(retList, strTmp);
2966				sprintf(strTmp, "<src>%s</src>\n", addr);
2967				strcat(retList, strTmp);
2968				sprintf(strTmp, "<dstport>%s</dstport>\n", port);
2969				strcat(retList, strTmp);
2970				sprintf(strTmp, "<proto>%s</proto>\n", proto);
2971				strcat(retList, strTmp);
2972				sprintf(strTmp, "<transferred>%s</transferred>\n", transferred);
2973				strcat(retList, strTmp);
2974				sprintf(strTmp, "<prio>%s</prio>\n", prio);
2975				strcat(retList, strTmp);
2976				strcat(retList, "</item>\n");
2977			}
2978			free(buf);
2979
2980			strcat(retList, "</list>\n");
2981		}
2982		else{
2983				retStatus = 3;
2984		}
2985	}
2986	else{
2987		retStatus = 3;
2988	}
2989
2990	websWrite(wp, "<status>%d</status>\n", retStatus);
2991	if(!strcmp(apiAction, "list"))
2992		websWrite(wp, "%s", retList);
2993	return 0;
2994}
2995#endif
2996
2997static int ej_update_variables(int eid, webs_t wp, int argc, char_t **argv) {
2998	char *action_mode;
2999	char *action_script;
3000	char *action_wait;
3001	char *wan_unit = websGetVar(wp, "wan_unit", "0");
3002	char notify_cmd[128];
3003	int do_apply;
3004#ifdef RTCONFIG_DUALWAN
3005	char new_action_script[128], new_action_wait[16];
3006#endif
3007
3008	// assign control variables
3009	action_mode = websGetVar(wp, "action_mode", "");
3010	action_script = websGetVar(wp, "action_script", "restart_net");
3011	action_wait = websGetVar(wp, "action_wait", "5");
3012
3013	_dprintf("update_variables: [%s] [%s] [%s]\n", action_mode, action_script, action_wait);
3014
3015	if ((do_apply = !strcmp(action_mode, "apply")) ||
3016	    !strcmp(action_mode, "apply_new"))
3017	{
3018		int has_modify;
3019		if (!(has_modify = validate_apply(wp, NULL))) {
3020			websWrite(wp, "<script>no_changes_and_no_committing();</script>\n");
3021		}
3022		else {
3023			websWrite(wp, "<script>done_committing();</script>\n");
3024		}
3025		if(do_apply || has_modify) {
3026
3027#ifdef RTCONFIG_QTN
3028			/* early stop wps for QTN */
3029			if (strcmp(action_script, "restart_wireless") == 0
3030			  ||strcmp(action_script, "restart_net") == 0)
3031			{
3032#if 0
3033				if (rpc_qtn_ready())
3034				{
3035					rpc_qcsapi_wifi_disable_wps(WIFINAME, 1);
3036
3037					if (nvram_get_int("wps_enable")){
3038						rpc_qcsapi_wifi_disable_wps(WIFINAME, !nvram_get_int("wps_enable"));
3039						qcsapi_wps_set_ap_pin(WIFINAME, nvram_safe_get("wps_device_pin"));
3040					}
3041
3042				}
3043#endif
3044			}
3045#endif
3046
3047#ifdef RTCONFIG_DUALWAN
3048			memset(new_action_script, 0, sizeof(new_action_script));
3049			memset(new_action_wait, 0, sizeof(new_action_wait));
3050			//_dprintf("has_modify = 0X%X\n\n", has_modify);
3051			if( (has_modify & 1) == 0){
3052				if( ((has_modify & NVRAM_MODIFIED_DUALWAN_ADDUSB) == NVRAM_MODIFIED_DUALWAN_ADDUSB) ||
3053					((has_modify & NVRAM_MODIFIED_DUALWAN_EXCHANGE) == NVRAM_MODIFIED_DUALWAN_EXCHANGE)){
3054					//_dprintf("ej_update_variables: start_multipath\n");
3055					strcpy(new_action_script, "start_multipath");
3056					action_script = (char *)new_action_script;
3057					strcpy(new_action_wait, "10");
3058					action_wait = (char *)new_action_wait;
3059				}
3060				else if( (has_modify & NVRAM_MODIFIED_DUALWAN_REBOOT) == NVRAM_MODIFIED_DUALWAN_REBOOT){
3061					strcpy(new_action_script, "reboot");
3062					action_script = (char *)new_action_script;
3063					strcpy(new_action_wait, nvram_safe_get("reboot_time"));
3064					action_wait = (char *)new_action_wait;
3065				}
3066			}
3067#endif
3068
3069			if (strlen(action_script) > 0) {
3070				char *p1, *p2;
3071
3072				memset(notify_cmd, 0, sizeof(notify_cmd));
3073				if((p1 = strstr(action_script, "_wan_if")))
3074				{
3075					p1 += 7;
3076					strncpy(notify_cmd, action_script, p1 - action_script);
3077					p2 = notify_cmd + strlen(notify_cmd);
3078					sprintf(p2, " %s%s", wan_unit, p1);
3079				}
3080				else
3081					strncpy(notify_cmd, action_script, 128);
3082
3083				if(strcmp(action_script, "saveNvram"))
3084				{
3085					if(!strcmp(action_script, "QisFinish")){
3086						skip_auth = 0;
3087					}else{
3088						nvram_set("freeze_duck", "15");
3089						notify_rc(notify_cmd);
3090					}
3091				}
3092			}
3093#if defined(RTCONFIG_RALINK) ||  defined(RTCONFIG_QCA)
3094			if (!strcmp(action_script, "restart_wireless") || !strcmp(action_script, "restart_net")) {
3095				char *rc_support = nvram_safe_get("rc_support");
3096				if (find_word(rc_support, "2.4G") && find_word(rc_support, "5G"))
3097					websWrite(wp, "<script>restart_needed_time(%d);</script>\n", atoi(action_wait) + 20);
3098				else
3099					websWrite(wp, "<script>restart_needed_time(%d);</script>\n", atoi(action_wait) + 5);
3100			}
3101			else
3102#endif
3103#if defined(RTCONFIG_RALINK)
3104			if (!strcmp(action_script, "restart_net_and_phy")) {
3105				char *rc_support = nvram_safe_get("rc_support");
3106				if (find_word(rc_support, "2.4G") && find_word(rc_support, "5G"))
3107					websWrite(wp, "<script>restart_needed_time(%d);</script>\n", atoi(action_wait) + 10);
3108				else
3109					websWrite(wp, "<script>restart_needed_time(%d);</script>\n", atoi(action_wait) + 5);
3110			}
3111			else
3112#endif
3113			websWrite(wp, "<script>restart_needed_time(%d);</script>\n", atoi(action_wait));
3114		}
3115	}
3116	return 0;
3117}
3118
3119static int convert_asus_variables(int eid, webs_t wp, int argc, char_t **argv) {
3120	return 0;
3121}
3122
3123static int asus_nvram_commit(int eid, webs_t wp, int argc, char_t **argv) {
3124	return 0;
3125}
3126
3127static int ej_notify_services(int eid, webs_t wp, int argc, char_t **argv) {
3128	return 0;
3129}
3130
3131char *Ch_conv(char *proto_name, int idx)
3132{
3133	char *proto;
3134	char qos_name_x[32];
3135	sprintf(qos_name_x, "%s%d", proto_name, idx);
3136	if (nvram_match(qos_name_x,""))
3137	{
3138		return NULL;
3139	}
3140	else
3141	{
3142		proto=nvram_get(qos_name_x);
3143		return proto;
3144	}
3145}
3146
3147static int enable_hwnat()
3148{
3149	int qos_userspec_app_en = 0;
3150	int rulenum = nvram_get_int("qos_rulenum_x"), idx_class = 0;
3151	int ret = 0;
3152	int unit;
3153	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
3154	char wan_proto[16];
3155
3156#if defined (W7_LOGO) || defined (WIFI_LOGO)
3157		return 0;
3158#endif
3159
3160	if(nvram_invmatch("sw_mode_ex", "1"))
3161		return 0;
3162
3163	unit = 0;
3164	wan_prefix(unit, prefix);
3165	memset(wan_proto, 0, 16);
3166	strcpy(wan_proto, nvram_safe_get(strcat_r(prefix, "proto", tmp)));
3167
3168	if(!strcmp(wan_proto, "pptp") || !strcmp(wan_proto, "l2tp"))
3169		return 0;
3170
3171	/* Add class for User specify, 10:20(high), 10:40(middle), 10:60(low)*/
3172	if (rulenum) {
3173		for (idx_class=0; idx_class < rulenum; idx_class++)
3174		{
3175			if (atoi(Ch_conv("qos_prio_x", idx_class)) == 1)
3176			{
3177				qos_userspec_app_en = 1;
3178				break;
3179			}
3180			else if (atoi(Ch_conv("qos_prio_x", idx_class)) == 6)
3181			{
3182				qos_userspec_app_en = 1;
3183				break;
3184			}
3185		}
3186	}
3187/*
3188	if (nvram_match("mr_enable_x", "1"))
3189		ret += 1;
3190
3191	if (	nvram_match("qos_tos_prio", "1") ||
3192		nvram_match("qos_pshack_prio", "1") ||
3193		nvram_match("qos_service_enable", "1") ||
3194		nvram_match("qos_shortpkt_prio", "1")	)
3195		ret += 2;
3196*/
3197
3198	if (	(nvram_invmatch("qos_manual_ubw","0") && nvram_invmatch("qos_manual_ubw","")) ||
3199		(rulenum && qos_userspec_app_en)	)
3200		ret = 1;
3201
3202	return ret;
3203}
3204
3205static int check_hwnat(int eid, webs_t wp, int argc, char_t **argv){
3206	if(!enable_hwnat())
3207		websWrite(wp, "0");
3208	else
3209		websWrite(wp, "1");
3210
3211	return 0;
3212}
3213
3214static int wanstate_hook(int eid, webs_t wp, int argc, char_t **argv){
3215	int unit;
3216	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
3217	int wan_state = -1, wan_sbstate = -1, wan_auxstate = -1;
3218
3219	/* current unit */
3220#ifdef RTCONFIG_DUALWAN
3221	if(nvram_match("wans_mode", "lb"))
3222		unit = WAN_UNIT_FIRST;
3223	else
3224#endif
3225		unit = wan_primary_ifunit();
3226	wan_prefix(unit, prefix);
3227
3228	wan_state = nvram_get_int(strcat_r(prefix, "state_t", tmp));
3229	wan_sbstate = nvram_get_int(strcat_r(prefix, "sbstate_t", tmp));
3230	wan_auxstate = nvram_get_int(strcat_r(prefix, "auxstate_t", tmp));
3231
3232	websWrite(wp, "wanstate = %d;\n", wan_state);
3233	websWrite(wp, "wansbstate = %d;\n", wan_sbstate);
3234	websWrite(wp, "wanauxstate = %d;\n", wan_auxstate);
3235
3236	return 0;
3237}
3238
3239static int dual_wanstate_hook(int eid, webs_t wp, int argc, char_t **argv){
3240#ifdef RTCONFIG_DUALWAN
3241	int unit;
3242	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
3243	int wan_state = -1, wan_sbstate = -1, wan_auxstate = -1;
3244
3245	unit = WAN_UNIT_FIRST;
3246	wan_prefix(unit, prefix);
3247
3248	wan_state = nvram_get_int(strcat_r(prefix, "state_t", tmp));
3249	wan_sbstate = nvram_get_int(strcat_r(prefix, "sbstate_t", tmp));
3250	wan_auxstate = nvram_get_int(strcat_r(prefix, "auxstate_t", tmp));
3251
3252	websWrite(wp, "first_wanstate = %d;\n", wan_state);
3253	websWrite(wp, "first_wansbstate = %d;\n", wan_sbstate);
3254	websWrite(wp, "first_wanauxstate = %d;\n", wan_auxstate);
3255
3256	memset(prefix, 0, sizeof(prefix));
3257	unit = WAN_UNIT_SECOND;
3258	wan_prefix(unit, prefix);
3259
3260	memset(tmp, 0, 100);
3261	wan_state = nvram_get_int(strcat_r(prefix, "state_t", tmp));
3262	wan_sbstate = nvram_get_int(strcat_r(prefix, "sbstate_t", tmp));
3263	wan_auxstate = nvram_get_int(strcat_r(prefix, "auxstate_t", tmp));
3264
3265	websWrite(wp, "second_wanstate = %d;\n", wan_state);
3266	websWrite(wp, "second_wansbstate = %d;\n", wan_sbstate);
3267	websWrite(wp, "second_wanauxstate = %d;\n", wan_auxstate);
3268#else
3269	websWrite(wp, "first_wanstate = -1;\n");
3270	websWrite(wp, "first_wansbstate = -1;\n");
3271	websWrite(wp, "first_wanauxstate = -1;\n");
3272	websWrite(wp, "second_wanstate = -1;\n");
3273	websWrite(wp, "second_wansbstate = -1;\n");
3274	websWrite(wp, "second_wanauxstate = -1;\n");
3275#endif
3276
3277	return 0;
3278}
3279
3280static int ajax_dualwanstate_hook(int eid, webs_t wp, int argc, char_t **argv){
3281#ifdef RTCONFIG_DUALWAN
3282	int unit;
3283	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
3284	int wan_state = -1, wan_sbstate = -1, wan_auxstate = -1;
3285
3286	unit = WAN_UNIT_FIRST;
3287	wan_prefix(unit, prefix);
3288
3289	wan_state = nvram_get_int(strcat_r(prefix, "state_t", tmp));
3290	wan_sbstate = nvram_get_int(strcat_r(prefix, "sbstate_t", tmp));
3291	wan_auxstate = nvram_get_int(strcat_r(prefix, "auxstate_t", tmp));
3292
3293	websWrite(wp, "<first_wan>%d</first_wan>\n", wan_state);
3294	websWrite(wp, "<first_wan>%d</first_wan>\n", wan_sbstate);
3295	websWrite(wp, "<first_wan>%d</first_wan>\n", wan_auxstate);
3296
3297	memset(prefix, 0, sizeof(prefix));
3298	unit = WAN_UNIT_SECOND;
3299	wan_prefix(unit, prefix);
3300
3301	memset(tmp, 0, 100);
3302	wan_state = nvram_get_int(strcat_r(prefix, "state_t", tmp));
3303	wan_sbstate = nvram_get_int(strcat_r(prefix, "sbstate_t", tmp));
3304	wan_auxstate = nvram_get_int(strcat_r(prefix, "auxstate_t", tmp));
3305
3306	websWrite(wp, "<second_wan>%d</second_wan>\n", wan_state);
3307	websWrite(wp, "<second_wan>%d</second_wan>\n", wan_sbstate);
3308	websWrite(wp, "<second_wan>%d</second_wan>\n", wan_auxstate);
3309#else
3310	websWrite(wp, "<first_wan>-1</first_wan>\n");
3311	websWrite(wp, "<first_wan>-1</first_wan>\n");
3312	websWrite(wp, "<first_wan>-1</first_wan>\n");
3313	websWrite(wp, "<second_wan>-1</second_wan>\n");
3314	websWrite(wp, "<second_wan>-1</second_wan>\n");
3315	websWrite(wp, "<second_wan>-1</second_wan>\n");
3316#endif
3317
3318	return 0;
3319}
3320
3321
3322static int ajax_wanstate_hook(int eid, webs_t wp, int argc, char_t **argv){
3323	int unit;
3324	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
3325	int wan_state = -1, wan_sbstate = -1, wan_auxstate = -1;
3326
3327	/* current unit */
3328#ifdef RTCONFIG_DUALWAN
3329	if(nvram_match("wans_mode", "lb"))
3330		unit = WAN_UNIT_FIRST;
3331	else
3332#endif
3333		unit = wan_primary_ifunit();
3334	wan_prefix(unit, prefix);
3335
3336	wan_state = nvram_get_int(strcat_r(prefix, "state_t", tmp));
3337	wan_sbstate = nvram_get_int(strcat_r(prefix, "sbstate_t", tmp));
3338	wan_auxstate = nvram_get_int(strcat_r(prefix, "auxstate_t", tmp));
3339
3340	websWrite(wp, "<wan>%d</wan>\n", wan_state);
3341	websWrite(wp, "<wan>%d</wan>\n", wan_sbstate);
3342	websWrite(wp, "<wan>%d</wan>\n", wan_auxstate);
3343
3344	return 0;
3345}
3346
3347static int secondary_ajax_wanstate_hook(int eid, webs_t wp, int argc, char_t **argv){
3348#ifdef RTCONFIG_DUALWAN
3349	int unit;
3350	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
3351	int wan_state = -1, wan_sbstate = -1, wan_auxstate = -1;
3352
3353	/* current unit */
3354	unit = WAN_UNIT_SECOND;
3355	wan_prefix(unit, prefix);
3356
3357	wan_state = nvram_get_int(strcat_r(prefix, "state_t", tmp));
3358	wan_sbstate = nvram_get_int(strcat_r(prefix, "sbstate_t", tmp));
3359	wan_auxstate = nvram_get_int(strcat_r(prefix, "auxstate_t", tmp));
3360
3361	websWrite(wp, "<secondary_wan>%d</secondary_wan>\n", wan_state);
3362	websWrite(wp, "<secondary_wan>%d</secondary_wan>\n", wan_sbstate);
3363	websWrite(wp, "<secondary_wan>%d</secondary_wan>\n", wan_auxstate);
3364#else
3365	websWrite(wp, "<secondary_wan>-1</secondary_wan>\n");
3366	websWrite(wp, "<secondary_wan>-1</secondary_wan>\n");
3367	websWrite(wp, "<secondary_wan>-1</secondary_wan>\n");
3368#endif
3369
3370	return 0;
3371}
3372
3373static int wanlink_hook(int eid, webs_t wp, int argc, char_t **argv){
3374	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
3375	int wan_state = -1, wan_sbstate = -1, wan_auxstate = -1;
3376	int unit, status = 0;
3377	char *statusstr[2] = { "Disconnected", "Connected" };
3378	char *wan_proto, *type;
3379	char *ip = "0.0.0.0";
3380	char *netmask = "0.0.0.0";
3381	char *gateway = "0.0.0.0";
3382	unsigned int lease = 0, expires = 0;
3383	char *xtype = "";
3384	char *xip = "0.0.0.0";
3385	char *xnetmask = "0.0.0.0";
3386	char *xgateway = "0.0.0.0";
3387	unsigned int xlease = 0, xexpires = 0;
3388	char *name = NULL;
3389
3390	if (ejArgs(argc, argv, "%s", &name) < 1) {
3391		//_dprintf("name = NULL\n");
3392	}
3393
3394	/* current unit */
3395#ifdef RTCONFIG_DUALWAN
3396	if(nvram_match("wans_mode", "lb"))
3397		unit = WAN_UNIT_FIRST;
3398	else
3399#endif
3400	unit = wan_primary_ifunit(); //Paul add 2013/7/24, get current working wan unit
3401
3402	wan_prefix(unit, prefix);
3403
3404	wan_state = nvram_get_int(strcat_r(prefix, "state_t", tmp));
3405	wan_sbstate = nvram_get_int(strcat_r(prefix, "sbstate_t", tmp));
3406	wan_auxstate = nvram_get_int(strcat_r(prefix, "auxstate_t", tmp));
3407
3408	wan_proto = nvram_safe_get(strcat_r(prefix, "proto", tmp));
3409
3410	if (dualwan_unit__usbif(unit)) {
3411		if(wan_state == WAN_STATE_CONNECTED){
3412			status = 1;
3413		}
3414		else{
3415			status = 0;
3416		}
3417	}
3418	else if(wan_state == WAN_STATE_DISABLED){
3419		status = 0;
3420	}
3421// DSLTODO, need a better integration
3422#ifdef RTCONFIG_DSL
3423	// if dualwan & enable lan port as wan
3424	// it always report disconnected
3425	//Some AUXSTATE is displayed for reference only
3426	else if(wan_auxstate == WAN_AUXSTATE_NOPHY && (nvram_get_int("web_redirect")&WEBREDIRECT_FLAG_NOLINK)) {
3427		status = 0;
3428	}
3429#else
3430	//Some AUXSTATE is displayed for reference only
3431	else if(wan_auxstate == WAN_AUXSTATE_NOPHY && (nvram_get_int("web_redirect")&WEBREDIRECT_FLAG_NOLINK)) {
3432		status = 0;
3433	}
3434#endif
3435	else if(wan_auxstate == WAN_AUXSTATE_NO_INTERNET_ACTIVITY&&(nvram_get_int("web_redirect")&WEBREDIRECT_FLAG_NOINTERNET)) {
3436		status = 0;
3437	}
3438	else if(!strcmp(wan_proto, "pppoe")
3439			|| !strcmp(wan_proto, "pptp")
3440			|| !strcmp(wan_proto, "l2tp")
3441			)
3442	{
3443		if(wan_state == WAN_STATE_INITIALIZING){
3444			status = 0;
3445		}
3446		else if(wan_state == WAN_STATE_CONNECTING){
3447			status = 0;
3448		}
3449		else if(wan_state == WAN_STATE_DISCONNECTED){
3450			status = 0;
3451		}
3452		else if(wan_state == WAN_STATE_STOPPED && wan_sbstate != WAN_STOPPED_REASON_PPP_LACK_ACTIVITY){
3453			status = 0;
3454		}
3455		else{
3456			status = 1;
3457		}
3458	}
3459	else{
3460		//if(wan_state == WAN_STATE_STOPPED && wan_sbstate == WAN_STOPPED_REASON_INVALID_IPADDR){
3461		if(wan_state == WAN_STATE_STOPPED){
3462			status = 0;
3463		}
3464		else if(wan_state == WAN_STATE_INITIALIZING){
3465			status = 0;
3466		}
3467		else if(wan_state == WAN_STATE_CONNECTING){
3468			status = 0;
3469		}
3470		else if(wan_state == WAN_STATE_DISCONNECTED){
3471			status = 0;
3472		}
3473		else {
3474			// treat short lease time as disconnected
3475			if(!strcmp(wan_proto, "dhcp") &&
3476			  nvram_get_int(strcat_r(prefix, "lease", tmp)) <= 60 &&
3477			  is_private_subnet(nvram_safe_get(strcat_r(prefix, "ipaddr", tmp)))
3478			) {
3479				status = 0;
3480			}
3481			else {
3482				status = 1;
3483			}
3484		}
3485	}
3486
3487#ifdef RTCONFIG_USB
3488	if (dualwan_unit__usbif(unit))
3489		type = "USB Modem";
3490	else
3491#endif
3492		type = wan_proto;
3493
3494	if(status != 0){
3495		ip = nvram_safe_get(strcat_r(prefix, "ipaddr", tmp));
3496		netmask = nvram_safe_get(strcat_r(prefix, "netmask", tmp));
3497		gateway = nvram_safe_get(strcat_r(prefix, "gateway", tmp));
3498		lease = nvram_get_int(strcat_r(prefix, "lease", tmp));
3499		if (lease > 0)
3500			expires = nvram_get_int(strcat_r(prefix, "expires", tmp)) - uptime();
3501	}
3502
3503	if(name == NULL){
3504		websWrite(wp, "function wanlink_status() { return %d;}\n", status);
3505		websWrite(wp, "function wanlink_statusstr() { return '%s';}\n", statusstr[status]);
3506		websWrite(wp, "function wanlink_type() { return '%s';}\n", type);
3507		websWrite(wp, "function wanlink_ipaddr() { return '%s';}\n", ip);
3508		websWrite(wp, "function wanlink_netmask() { return '%s';}\n", netmask);
3509		websWrite(wp, "function wanlink_gateway() { return '%s';}\n", gateway);
3510		websWrite(wp, "function wanlink_dns() { return '%s';}\n", nvram_safe_get(strcat_r(prefix, "dns", tmp)));
3511		websWrite(wp, "function wanlink_lease() { return %d;}\n", lease);
3512		websWrite(wp, "function wanlink_expires() { return %d;}\n", expires);
3513		websWrite(wp, "function is_private_subnet() { return '%d';}\n", is_private_subnet(nvram_safe_get(strcat_r(prefix, "ipaddr", tmp))));
3514	}else if(!strcmp(name,"status"))
3515		websWrite(wp, "\"%d\"", status);
3516	else if(!strcmp(name,"statusstr"))
3517		websWrite(wp, "\"%s\"", statusstr[status]);
3518	else if(!strcmp(name,"type"))
3519		websWrite(wp, "\"%s\"", type);
3520	else if(!strcmp(name,"ipaddr"))
3521		websWrite(wp, "\"%s\"", ip);
3522	else if(!strcmp(name,"netmask"))
3523		websWrite(wp, "\"%s\"", netmask);
3524	else if(!strcmp(name,"gateway"))
3525		websWrite(wp, "\"%s\"", gateway);
3526	else if(!strcmp(name,"dns"))
3527		websWrite(wp, "\"%s\"", nvram_safe_get(strcat_r(prefix, "dns", tmp)));
3528	else if(!strcmp(name,"lease"))
3529		websWrite(wp, "\"%d\"", lease);
3530	else if(!strcmp(name,"expires"))
3531		websWrite(wp, "\"%d\"", expires);
3532	else if(!strcmp(name,"private_subnet"))
3533		websWrite(wp, "\"%d\"", is_private_subnet(nvram_safe_get(strcat_r(prefix, "ipaddr", tmp))));
3534
3535	if (strcmp(wan_proto, "pppoe") == 0 ||
3536	    strcmp(wan_proto, "pptp") == 0 ||
3537	    strcmp(wan_proto, "l2tp") == 0) {
3538		int dhcpenable = nvram_get_int(strcat_r(prefix, "dhcpenable_x", tmp));
3539		xtype = (dhcpenable == 0) ? "static" :
3540			(strcmp(wan_proto, "pppoe") == 0 && nvram_match(strcat_r(prefix, "vpndhcp", tmp), "0")) ? "" : /* zeroconf */
3541			"dhcp";
3542		xip = nvram_safe_get(strcat_r(prefix, "xipaddr", tmp));
3543		xnetmask = nvram_safe_get(strcat_r(prefix, "xnetmask", tmp));
3544		xgateway = nvram_safe_get(strcat_r(prefix, "xgateway", tmp));
3545		xlease = nvram_get_int(strcat_r(prefix, "xlease", tmp));
3546		if (xlease > 0)
3547			xexpires = nvram_get_int(strcat_r(prefix, "xexpires", tmp)) - uptime();
3548	}
3549
3550	if(name == NULL){
3551		websWrite(wp, "function wanlink_xtype() { return '%s';}\n", xtype);
3552		websWrite(wp, "function wanlink_xipaddr() { return '%s';}\n", xip);
3553		websWrite(wp, "function wanlink_xnetmask() { return '%s';}\n", xnetmask);
3554		websWrite(wp, "function wanlink_xgateway() { return '%s';}\n", xgateway);
3555		websWrite(wp, "function wanlink_xdns() { return '%s';}\n", nvram_safe_get(strcat_r(prefix, "xdns", tmp)));
3556		websWrite(wp, "function wanlink_xlease() { return %d;}\n", xlease);
3557		websWrite(wp, "function wanlink_xexpires() { return %d;}\n", xexpires);
3558	}else if(!strcmp(name,"xtype"))
3559		websWrite(wp, "\"%s\"", xtype);
3560	else if(!strcmp(name,"xipaddr"))
3561		websWrite(wp, "\"%s\"", xip);
3562	else if(!strcmp(name,"xnetmask"))
3563		websWrite(wp, "\"%s\"", xnetmask);
3564	else if(!strcmp(name,"xgateway"))
3565		websWrite(wp, "\"%s\"", xgateway);
3566	else if(!strcmp(name,"xdns"))
3567		websWrite(wp, "\"%s\"", nvram_safe_get(strcat_r(prefix, "xdns", tmp)));
3568	else if(!strcmp(name,"xlease"))
3569		websWrite(wp, "\"%d\"", xlease);
3570	else if(!strcmp(name,"xexpires"))
3571		websWrite(wp, "\"%d\"", xexpires);
3572
3573	return 0;
3574}
3575
3576static int first_wanlink_hook(int eid, webs_t wp, int argc, char_t **argv){
3577	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
3578	int wan_state = -1, wan_sbstate = -1, wan_auxstate = -1;
3579	int unit, status = 0;
3580	char *statusstr[2] = { "Disconnected", "Connected" };
3581	char *wan_proto, *type;
3582	char *ip = "0.0.0.0";
3583	char *netmask = "0.0.0.0";
3584	char *gateway = "0.0.0.0";
3585	unsigned int lease = 0, expires = 0;
3586	char *xtype = "";
3587	char *xip = "0.0.0.0";
3588	char *xnetmask = "0.0.0.0";
3589	char *xgateway = "0.0.0.0";
3590	unsigned int xlease = 0, xexpires = 0;
3591
3592	unit = WAN_UNIT_FIRST;
3593	wan_prefix(unit, prefix);
3594
3595	wan_state = nvram_get_int(strcat_r(prefix, "state_t", tmp));
3596	wan_sbstate = nvram_get_int(strcat_r(prefix, "sbstate_t", tmp));
3597	wan_auxstate = nvram_get_int(strcat_r(prefix, "auxstate_t", tmp));
3598
3599	wan_proto = nvram_safe_get(strcat_r(prefix, "proto", tmp));
3600
3601	if (dualwan_unit__usbif(unit)) {
3602		if(wan_state == WAN_STATE_CONNECTED){
3603			status = 1;
3604		}
3605		else{
3606			status = 0;
3607		}
3608	}
3609	else if(wan_state == WAN_STATE_DISABLED){
3610		status = 0;
3611	}
3612// DSLTODO, need a better integration
3613#ifdef RTCONFIG_DSL
3614	// if dualwan & enable lan port as wan
3615	// it always report disconnected
3616	//Some AUXSTATE is displayed for reference only
3617	else if(wan_auxstate == WAN_AUXSTATE_NOPHY && (nvram_get_int("web_redirect")&WEBREDIRECT_FLAG_NOLINK)) {
3618		status = 0;
3619	}
3620#else
3621	//Some AUXSTATE is displayed for reference only
3622	else if(wan_auxstate == WAN_AUXSTATE_NOPHY && (nvram_get_int("web_redirect")&WEBREDIRECT_FLAG_NOLINK)) {
3623		status = 0;
3624	}
3625#endif
3626	else if(wan_auxstate == WAN_AUXSTATE_NO_INTERNET_ACTIVITY&&(nvram_get_int("web_redirect")&WEBREDIRECT_FLAG_NOINTERNET)) {
3627		status = 0;
3628	}
3629	else if(!strcmp(wan_proto, "pppoe")
3630			|| !strcmp(wan_proto, "pptp")
3631			|| !strcmp(wan_proto, "l2tp")
3632			)
3633	{
3634		if(wan_state == WAN_STATE_INITIALIZING){
3635			status = 0;
3636		}
3637		else if(wan_state == WAN_STATE_CONNECTING){
3638			status = 0;
3639		}
3640		else if(wan_state == WAN_STATE_DISCONNECTED){
3641			status = 0;
3642		}
3643		else if(wan_state == WAN_STATE_STOPPED && wan_sbstate != WAN_STOPPED_REASON_PPP_LACK_ACTIVITY){
3644			status = 0;
3645		}
3646		else{
3647			status = 1;
3648		}
3649	}
3650	else{
3651		//if(wan_state == WAN_STATE_STOPPED && wan_sbstate == WAN_STOPPED_REASON_INVALID_IPADDR){
3652		if(wan_state == WAN_STATE_STOPPED){
3653			status = 0;
3654		}
3655		else if(wan_state == WAN_STATE_INITIALIZING){
3656			status = 0;
3657		}
3658		else if(wan_state == WAN_STATE_CONNECTING){
3659			status = 0;
3660		}
3661		else if(wan_state == WAN_STATE_DISCONNECTED){
3662			status = 0;
3663		}
3664		else {
3665			// treat short lease time as disconnected
3666			if(!strcmp(wan_proto, "dhcp") &&
3667			  nvram_get_int(strcat_r(prefix, "lease", tmp)) <= 60 &&
3668			  is_private_subnet(nvram_safe_get(strcat_r(prefix, "ipaddr", tmp)))
3669			) {
3670				status = 0;
3671			}
3672			else {
3673				status = 1;
3674			}
3675		}
3676	}
3677
3678#ifdef RTCONFIG_USB
3679	if (dualwan_unit__usbif(unit))
3680		type = "USB Modem";
3681	else
3682#endif
3683		type = wan_proto;
3684
3685	if(status != 0){
3686		ip = nvram_safe_get(strcat_r(prefix, "ipaddr", tmp));
3687		netmask = nvram_safe_get(strcat_r(prefix, "netmask", tmp));
3688		gateway = nvram_safe_get(strcat_r(prefix, "gateway", tmp));
3689		lease = nvram_get_int(strcat_r(prefix, "lease", tmp));
3690		if (lease > 0)
3691			expires = nvram_get_int(strcat_r(prefix, "expires", tmp)) - uptime();
3692	}
3693
3694	websWrite(wp, "function first_wanlink_status() { return %d;}\n", status);
3695	websWrite(wp, "function first_wanlink_statusstr() { return '%s';}\n", statusstr[status]);
3696	websWrite(wp, "function first_wanlink_type() { return '%s';}\n", type);
3697	websWrite(wp, "function first_wanlink_ipaddr() { return '%s';}\n", ip);
3698	websWrite(wp, "function first_wanlink_netmask() { return '%s';}\n", netmask);
3699	websWrite(wp, "function first_wanlink_gateway() { return '%s';}\n", gateway);
3700	websWrite(wp, "function first_wanlink_dns() { return '%s';}\n", nvram_safe_get(strcat_r(prefix, "dns", tmp)));
3701	websWrite(wp, "function first_wanlink_lease() { return %d;}\n", lease);
3702	websWrite(wp, "function first_wanlink_expires() { return %d;}\n", expires);
3703
3704	if (strcmp(wan_proto, "pppoe") == 0 ||
3705	    strcmp(wan_proto, "pptp") == 0 ||
3706	    strcmp(wan_proto, "l2tp") == 0) {
3707		int dhcpenable = nvram_get_int(strcat_r(prefix, "dhcpenable_x", tmp));
3708		xtype = (dhcpenable == 0) ? "static" :
3709			(strcmp(wan_proto, "pppoe") == 0 && nvram_match(strcat_r(prefix, "vpndhcp", tmp), "0")) ? "" : /* zeroconf */
3710			"dhcp";
3711		xip = nvram_safe_get(strcat_r(prefix, "xipaddr", tmp));
3712		xnetmask = nvram_safe_get(strcat_r(prefix, "xnetmask", tmp));
3713		xgateway = nvram_safe_get(strcat_r(prefix, "xgateway", tmp));
3714		xlease = nvram_get_int(strcat_r(prefix, "xlease", tmp));
3715		if (xlease > 0)
3716			xexpires = nvram_get_int(strcat_r(prefix, "xexpires", tmp)) - uptime();
3717	}
3718
3719	websWrite(wp, "function first_wanlink_xtype() { return '%s';}\n", xtype);
3720	websWrite(wp, "function first_wanlink_xipaddr() { return '%s';}\n", xip);
3721	websWrite(wp, "function first_wanlink_xnetmask() { return '%s';}\n", xnetmask);
3722	websWrite(wp, "function first_wanlink_xgateway() { return '%s';}\n", xgateway);
3723	websWrite(wp, "function first_wanlink_xdns() { return '%s';}\n", nvram_safe_get(strcat_r(prefix, "xdns", tmp)));
3724	websWrite(wp, "function first_wanlink_xlease() { return %d;}\n", xlease);
3725	websWrite(wp, "function first_wanlink_xexpires() { return %d;}\n", xexpires);
3726
3727	return 0;
3728}
3729
3730static int secondary_wanlink_hook(int eid, webs_t wp, int argc, char_t **argv){
3731#ifdef RTCONFIG_DUALWAN
3732	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
3733	int wan_state = -1, wan_sbstate = -1, wan_auxstate = -1;
3734	int unit, status = 0;
3735	char *statusstr[2] = { "Disconnected", "Connected" };
3736	char *wan_proto, *type;
3737	char *ip = "0.0.0.0";
3738	char *netmask = "0.0.0.0";
3739	char *gateway = "0.0.0.0";
3740	unsigned int lease = 0, expires = 0;
3741	char *xtype = "";
3742	char *xip = "0.0.0.0";
3743	char *xnetmask = "0.0.0.0";
3744	char *xgateway = "0.0.0.0";
3745	unsigned int xlease = 0, xexpires = 0;
3746
3747	/* current unit */
3748	unit = WAN_UNIT_SECOND;
3749	wan_prefix(unit, prefix);
3750
3751	wan_state = nvram_get_int(strcat_r(prefix, "state_t", tmp));
3752	wan_sbstate = nvram_get_int(strcat_r(prefix, "sbstate_t", tmp));
3753	wan_auxstate = nvram_get_int(strcat_r(prefix, "auxstate_t", tmp));
3754
3755	wan_proto = nvram_safe_get(strcat_r(prefix, "proto", tmp));
3756	if (dualwan_unit__usbif(unit)) {
3757		if(wan_state == WAN_STATE_CONNECTED){
3758			status = 1;
3759		}
3760		else{
3761			status = 0;
3762		}
3763	}
3764	else if(wan_state == WAN_STATE_DISABLED){
3765		status = 0;
3766	}
3767// DSLTODO, need a better integration
3768#ifdef RTCONFIG_DSL
3769	// if dualwan & enable lan port as wan
3770	// it always report disconnected
3771	//Some AUXSTATE is displayed for reference only
3772	else if(wan_auxstate == WAN_AUXSTATE_NOPHY && (nvram_get_int("web_redirect")&WEBREDIRECT_FLAG_NOLINK)) {
3773		status = 0;
3774	}
3775#else
3776	//Some AUXSTATE is displayed for reference only
3777	else if(wan_auxstate == WAN_AUXSTATE_NOPHY && (nvram_get_int("web_redirect")&WEBREDIRECT_FLAG_NOLINK)) {
3778		status = 0;
3779	}
3780#endif
3781	else if(wan_auxstate == WAN_AUXSTATE_NO_INTERNET_ACTIVITY&&(nvram_get_int("web_redirect")&WEBREDIRECT_FLAG_NOINTERNET)) {
3782		status = 0;
3783	}
3784	else if(!strcmp(wan_proto, "pppoe")
3785			|| !strcmp(wan_proto, "pptp")
3786			|| !strcmp(wan_proto, "l2tp")
3787			)
3788	{
3789		if(wan_state == WAN_STATE_INITIALIZING){
3790			status = 0;
3791		}
3792		else if(wan_state == WAN_STATE_CONNECTING){
3793			status = 0;
3794		}
3795		else if(wan_state == WAN_STATE_DISCONNECTED){
3796			status = 0;
3797		}
3798		else if(wan_state == WAN_STATE_STOPPED && wan_sbstate != WAN_STOPPED_REASON_PPP_LACK_ACTIVITY){
3799			status = 0;
3800		}
3801		else{
3802			status = 1;
3803		}
3804	}
3805	else{
3806		if(wan_state == WAN_STATE_STOPPED){
3807			status = 0;
3808		}
3809		else if(wan_state == WAN_STATE_INITIALIZING){
3810			status = 0;
3811		}
3812		else if(wan_state == WAN_STATE_CONNECTING){
3813			status = 0;
3814		}
3815		else if(wan_state == WAN_STATE_DISCONNECTED){
3816			status = 0;
3817		}
3818		else {
3819			// treat short lease time as disconnected
3820			if(!strcmp(wan_proto, "dhcp") &&
3821			  nvram_get_int(strcat_r(prefix, "lease", tmp)) <= 60 &&
3822			  is_private_subnet(nvram_safe_get(strcat_r(prefix, "ipaddr", tmp)))
3823			) {
3824				status = 0;
3825			}
3826			else {
3827				status = 1;
3828			}
3829		}
3830	}
3831
3832	if (dualwan_unit__usbif(unit))
3833		type = "USB Modem";
3834	else
3835		type = wan_proto;
3836
3837	if(status != 0){
3838		ip = nvram_safe_get(strcat_r(prefix, "ipaddr", tmp));
3839		netmask = nvram_safe_get(strcat_r(prefix, "netmask", tmp));
3840		gateway = nvram_safe_get(strcat_r(prefix, "gateway", tmp));
3841		lease = nvram_get_int(strcat_r(prefix, "lease", tmp));
3842		if (lease > 0)
3843			expires = nvram_get_int(strcat_r(prefix, "expires", tmp)) - uptime();
3844	}
3845
3846	websWrite(wp, "function secondary_wanlink_status() { return %d;}\n", status);
3847	websWrite(wp, "function secondary_wanlink_statusstr() { return '%s';}\n", statusstr[status]);
3848	websWrite(wp, "function secondary_wanlink_type() { return '%s';}\n", type);
3849	websWrite(wp, "function secondary_wanlink_ipaddr() { return '%s';}\n", ip);
3850	websWrite(wp, "function secondary_wanlink_netmask() { return '%s';}\n", netmask);
3851	websWrite(wp, "function secondary_wanlink_gateway() { return '%s';}\n", gateway);
3852	websWrite(wp, "function secondary_wanlink_dns() { return '%s';}\n", nvram_safe_get(strcat_r(prefix, "dns", tmp)));
3853	websWrite(wp, "function secondary_wanlink_lease() { return %d;}\n", lease);
3854	websWrite(wp, "function secondary_wanlink_expires() { return %d;}\n", expires);
3855
3856	if (strcmp(wan_proto, "pppoe") == 0 ||
3857	    strcmp(wan_proto, "pptp") == 0 ||
3858	    strcmp(wan_proto, "l2tp") == 0) {
3859		int dhcpenable = nvram_get_int(strcat_r(prefix, "dhcpenable_x", tmp));
3860		xtype = (dhcpenable == 0) ? "static" :
3861			(strcmp(wan_proto, "pppoe") == 0 && nvram_match(strcat_r(prefix, "vpndhcp", tmp), "0")) ? "" : /* zeroconf */
3862			"dhcp";
3863		xip = nvram_safe_get(strcat_r(prefix, "xipaddr", tmp));
3864		xnetmask = nvram_safe_get(strcat_r(prefix, "xnetmask", tmp));
3865		xgateway = nvram_safe_get(strcat_r(prefix, "xgateway", tmp));
3866		xlease = nvram_get_int(strcat_r(prefix, "xlease", tmp));
3867		if (xlease > 0)
3868			xexpires = nvram_get_int(strcat_r(prefix, "xexpires", tmp)) - uptime();
3869	}
3870
3871	websWrite(wp, "function secondary_wanlink_xtype() { return '%s';}\n", xtype);
3872	websWrite(wp, "function secondary_wanlink_xipaddr() { return '%s';}\n", xip);
3873	websWrite(wp, "function secondary_wanlink_xnetmask() { return '%s';}\n", xnetmask);
3874	websWrite(wp, "function secondary_wanlink_xgateway() { return '%s';}\n", xgateway);
3875	websWrite(wp, "function secondary_wanlink_xdns() { return '%s';}\n", nvram_safe_get(strcat_r(prefix, "xdns", tmp)));
3876	websWrite(wp, "function secondary_wanlink_xlease() { return %d;}\n", xlease);
3877	websWrite(wp, "function secondary_wanlink_xexpires() { return %d;}\n", xexpires);
3878#else
3879	websWrite(wp, "function secondary_wanlink_status() { return -1;}\n");
3880	websWrite(wp, "function secondary_wanlink_statusstr() { return -1;}\n");
3881	websWrite(wp, "function secondary_wanlink_type() { return -1;}\n");
3882	websWrite(wp, "function secondary_wanlink_ipaddr() { return -1;}\n");
3883	websWrite(wp, "function secondary_wanlink_netmask() { return -1;}\n");
3884	websWrite(wp, "function secondary_wanlink_gateway() { return -1;}\n");
3885	websWrite(wp, "function secondary_wanlink_dns() { return -1;}\n");
3886	websWrite(wp, "function secondary_wanlink_lease() { return -1;}\n");
3887	websWrite(wp, "function secondary_wanlink_expires() { return -1;}\n");
3888
3889	websWrite(wp, "function secondary_wanlink_xtype() { return -1;}\n");
3890	websWrite(wp, "function secondary_wanlink_xipaddr() { return -1;}\n");
3891	websWrite(wp, "function secondary_wanlink_xnetmask() { return -1;}\n");
3892	websWrite(wp, "function secondary_wanlink_xgateway() { return -1;}\n");
3893	websWrite(wp, "function secondary_wanlink_xdns() { return -1;}\n");
3894	websWrite(wp, "function secondary_wanlink_xlease() { return -1;}\n");
3895	websWrite(wp, "function secondary_wanlink_xexpires() { return -1;}\n");
3896#endif
3897	return 0;
3898}
3899
3900static int wan_action_hook(int eid, webs_t wp, int argc, char_t **argv){
3901	char *action;
3902	int needed_seconds = 0;
3903	int unit;
3904	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
3905	char wan_enable[16];
3906
3907	unit = wan_primary_ifunit();
3908	wan_prefix(unit, prefix);
3909	memset(wan_enable, 0, 16);
3910	strcpy(wan_enable, strcat_r(prefix, "enable", tmp));
3911
3912	// assign control variables
3913	action = websGetVar(wp, "wanaction", "");
3914	if (strlen(action) <= 0){
3915		fprintf(stderr, "No connect action in wan_action_hook!\n");
3916		return -1;
3917	}
3918
3919	fprintf(stderr, "wan action: %s\n", action);
3920
3921	// TODO: multiple interface
3922	if(!strcmp(action, "Connect")){
3923		nvram_set_int(wan_enable, 0);
3924		nvram_set("freeze_duck", "15");
3925		notify_rc("start_wan");
3926	}
3927	else if (!strcmp(action, "Disconnect")){
3928		nvram_set_int(wan_enable, 1);
3929		nvram_set("freeze_duck", "10");
3930		notify_rc("stop_wan");
3931	}
3932
3933	websWrite(wp, "<script>restart_needed_time(%d);</script>\n", needed_seconds);
3934
3935	return 0;
3936}
3937
3938static int get_wan_unit_hook(int eid, webs_t wp, int argc, char_t **argv){
3939	int unit;
3940
3941	unit = wan_primary_ifunit();
3942
3943	websWrite(wp, "%d", unit);
3944
3945	return 0;
3946}
3947
3948static int wanlink_state_hook(int eid, webs_t wp, int argc, char_t **argv){
3949
3950	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
3951	int wan_state = -1, wan_sbstate = -1, wan_auxstate = -1;
3952	int unit, status = 0;
3953	char *statusstr[2] = { "Disconnected", "Connected" };
3954	char *wan_proto, *type;
3955	char *ip = "0.0.0.0";
3956	char *netmask = "0.0.0.0";
3957	char *gateway = "0.0.0.0";
3958	unsigned int lease = 0, expires = 0;
3959	char *xtype = "";
3960	char *xip = "0.0.0.0";
3961	char *xnetmask = "0.0.0.0";
3962	char *xgateway = "0.0.0.0";
3963	unsigned int xlease = 0, xexpires = 0;
3964	char *name = NULL;
3965
3966	if (ejArgs(argc, argv, "%s", &name) < 1) {
3967		//_dprintf("name = NULL\n");
3968	}
3969
3970	/* current unit */
3971#ifdef RTCONFIG_DUALWAN
3972	if(nvram_match("wans_mode", "lb"))
3973		unit = WAN_UNIT_FIRST;
3974	else
3975#endif
3976		unit = wan_primary_ifunit();
3977	wan_prefix(unit, prefix);
3978
3979	wan_state = nvram_get_int(strcat_r(prefix, "state_t", tmp));
3980	wan_sbstate = nvram_get_int(strcat_r(prefix, "sbstate_t", tmp));
3981	wan_auxstate = nvram_get_int(strcat_r(prefix, "auxstate_t", tmp));
3982
3983	websWrite(wp, "\"wanstate\":\"%d\",\n", wan_state);
3984	websWrite(wp, "\"wansbstate\":\"%d\",\n", wan_sbstate);
3985	websWrite(wp, "\"wanauxstate\":\"%d\",\n", wan_auxstate);
3986	websWrite(wp, "\"autodet_state\":\"%d\",\n", nvram_get_int("autodet_state"));
3987	websWrite(wp, "\"autodet_auxstate\":\"%d\",\n", nvram_get_int("autodet_auxstate"));
3988
3989	wan_proto = nvram_safe_get(strcat_r(prefix, "proto", tmp));
3990
3991	if (dualwan_unit__usbif(unit)) {
3992		if(wan_state == WAN_STATE_CONNECTED){
3993			status = 1;
3994		}
3995		else{
3996			status = 0;
3997		}
3998	}
3999	else if(wan_state == WAN_STATE_DISABLED){
4000		status = 0;
4001	}
4002// DSLTODO, need a better integration
4003#ifdef RTCONFIG_DSL
4004	// if dualwan & enable lan port as wan
4005	// it always report disconnected
4006	//Some AUXSTATE is displayed for reference only
4007	else if(wan_auxstate == WAN_AUXSTATE_NOPHY && (nvram_get_int("web_redirect")&WEBREDIRECT_FLAG_NOLINK)) {
4008		status = 0;
4009	}
4010#else
4011	//Some AUXSTATE is displayed for reference only
4012	else if(wan_auxstate == WAN_AUXSTATE_NOPHY && (nvram_get_int("web_redirect")&WEBREDIRECT_FLAG_NOLINK)) {
4013		status = 0;
4014	}
4015#endif
4016	else if(wan_auxstate == WAN_AUXSTATE_NO_INTERNET_ACTIVITY&&(nvram_get_int("web_redirect")&WEBREDIRECT_FLAG_NOINTERNET)) {
4017		status = 0;
4018	}
4019	else if(!strcmp(wan_proto, "pppoe")
4020			|| !strcmp(wan_proto, "pptp")
4021			|| !strcmp(wan_proto, "l2tp")
4022			)
4023	{
4024		if(wan_state == WAN_STATE_INITIALIZING){
4025			status = 0;
4026		}
4027		else if(wan_state == WAN_STATE_CONNECTING){
4028			status = 0;
4029		}
4030		else if(wan_state == WAN_STATE_DISCONNECTED){
4031			status = 0;
4032		}
4033		else if(wan_state == WAN_STATE_STOPPED && wan_sbstate != WAN_STOPPED_REASON_PPP_LACK_ACTIVITY){
4034			status = 0;
4035		}
4036		else{
4037			status = 1;
4038		}
4039	}
4040	else{
4041		//if(wan_state == WAN_STATE_STOPPED && wan_sbstate == WAN_STOPPED_REASON_INVALID_IPADDR){
4042		if(wan_state == WAN_STATE_STOPPED){
4043			status = 0;
4044		}
4045		else if(wan_state == WAN_STATE_INITIALIZING){
4046			status = 0;
4047		}
4048		else if(wan_state == WAN_STATE_CONNECTING){
4049			status = 0;
4050		}
4051		else if(wan_state == WAN_STATE_DISCONNECTED){
4052			status = 0;
4053		}
4054		else {
4055			// treat short lease time as disconnected
4056			if(!strcmp(wan_proto, "dhcp") &&
4057			  nvram_get_int(strcat_r(prefix, "lease", tmp)) <= 60 &&
4058			  is_private_subnet(nvram_safe_get(strcat_r(prefix, "ipaddr", tmp)))
4059			) {
4060				status = 0;
4061			}
4062			else {
4063				status = 1;
4064			}
4065		}
4066	}
4067
4068#ifdef RTCONFIG_USB
4069	if (dualwan_unit__usbif(unit))
4070		type = "USB Modem";
4071	else
4072#endif
4073		type = wan_proto;
4074
4075	if(status != 0){
4076		ip = nvram_safe_get(strcat_r(prefix, "ipaddr", tmp));
4077		netmask = nvram_safe_get(strcat_r(prefix, "netmask", tmp));
4078		gateway = nvram_safe_get(strcat_r(prefix, "gateway", tmp));
4079		lease = nvram_get_int(strcat_r(prefix, "lease", tmp));
4080		if (lease > 0)
4081			expires = nvram_get_int(strcat_r(prefix, "expires", tmp)) - uptime();
4082	}
4083
4084	if(!strcmp(name,"appobj")){
4085		websWrite(wp, "\"wanlink_status\":\"%d\",\n", status);
4086		websWrite(wp, "\"wanlink_statusstr\":\"%s\",\n", statusstr[status]);
4087		websWrite(wp, "\"wanlink_type\":\"%s\",\n", type);
4088		websWrite(wp, "\"wanlink_ipaddr\":\"%s\",\n", ip);
4089		websWrite(wp, "\"wanlink_netmask\":\"%s\",\n", netmask);
4090		websWrite(wp, "\"wanlink_gateway\":\"%s\",\n", gateway);
4091		websWrite(wp, "\"wanlink_dns\":\"%s\",\n", nvram_safe_get(strcat_r(prefix, "dns", tmp)));
4092		websWrite(wp, "\"wanlink_lease\":\"%d\",\n", lease);
4093		websWrite(wp, "\"wanlink_expires\":\"%d\",\n", expires);
4094		websWrite(wp, "\"is_private_subnet\":\"%d\",\n", is_private_subnet(nvram_safe_get(strcat_r(prefix, "ipaddr", tmp))));
4095	}else if(!strcmp(name,"status"))
4096		websWrite(wp, "%d", status);
4097	else if(!strcmp(name,"statusstr"))
4098		websWrite(wp, "%s", statusstr[status]);
4099	else if(!strcmp(name,"type"))
4100		websWrite(wp, "%s", type);
4101	else if(!strcmp(name,"ipaddr"))
4102		websWrite(wp, "%s", ip);
4103	else if(!strcmp(name,"netmask"))
4104		websWrite(wp, "%s", netmask);
4105	else if(!strcmp(name,"gateway"))
4106		websWrite(wp, "%s", gateway);
4107	else if(!strcmp(name,"dns"))
4108		websWrite(wp, "%s", nvram_safe_get(strcat_r(prefix, "dns", tmp)));
4109	else if(!strcmp(name,"lease"))
4110		websWrite(wp, "%d", lease);
4111	else if(!strcmp(name,"expires"))
4112		websWrite(wp, "%d", expires);
4113	else if(!strcmp(name,"private_subnet"))
4114		websWrite(wp, "%d", is_private_subnet(nvram_safe_get(strcat_r(prefix, "ipaddr", tmp))));
4115
4116	if (strcmp(wan_proto, "pppoe") == 0 ||
4117	    strcmp(wan_proto, "pptp") == 0 ||
4118	    strcmp(wan_proto, "l2tp") == 0) {
4119		int dhcpenable = nvram_get_int(strcat_r(prefix, "dhcpenable_x", tmp));
4120		xtype = (dhcpenable == 0) ? "static" :
4121			(strcmp(wan_proto, "pppoe") == 0 && nvram_match(strcat_r(prefix, "vpndhcp", tmp), "0")) ? "" : /* zeroconf */
4122			"dhcp";
4123		xip = nvram_safe_get(strcat_r(prefix, "xipaddr", tmp));
4124		xnetmask = nvram_safe_get(strcat_r(prefix, "xnetmask", tmp));
4125		xgateway = nvram_safe_get(strcat_r(prefix, "xgateway", tmp));
4126		xlease = nvram_get_int(strcat_r(prefix, "xlease", tmp));
4127		if (xlease > 0)
4128			xexpires = nvram_get_int(strcat_r(prefix, "xexpires", tmp)) - uptime();
4129	}
4130
4131	if(!strcmp(name,"appobj")){
4132		websWrite(wp, "\"wanlink_xtype\":\"%s\",\n", xtype);
4133		websWrite(wp, "\"wanlink_xipaddr\":\"%s\",\n", xip);
4134		websWrite(wp, "\"wanlink_xnetmask\":\"%s\",\n", xnetmask);
4135		websWrite(wp, "\"wanlink_xgateway\":\"%s\",\n", xgateway);
4136		websWrite(wp, "\"wanlink_xdns\":\"%s\",\n", nvram_safe_get(strcat_r(prefix, "xdns", tmp)));
4137		websWrite(wp, "\"wanlink_xlease\":\"%d\",\n", xlease);
4138		websWrite(wp, "\"wanlink_xexpires\":\"%d\"\n", xexpires);
4139	}else if(!strcmp(name,"xtype"))
4140		websWrite(wp, "%s", xtype);
4141	else if(!strcmp(name,"xipaddr"))
4142		websWrite(wp, "%s", xip);
4143	else if(!strcmp(name,"xnetmask"))
4144		websWrite(wp, "%s", xnetmask);
4145	else if(!strcmp(name,"xgateway"))
4146		websWrite(wp, "%s", xgateway);
4147	else if(!strcmp(name,"xdns"))
4148		websWrite(wp, "%s", nvram_safe_get(strcat_r(prefix, "xdns", tmp)));
4149	else if(!strcmp(name,"xlease"))
4150		websWrite(wp, "%d", xlease);
4151	else if(!strcmp(name,"xexpires"))
4152		websWrite(wp, "%d", xexpires);
4153
4154	return 0;
4155}
4156
4157static int ej_get_ascii_parameter(int eid, webs_t wp, int argc, char_t **argv){
4158	char tmp[MAX_LINE_SIZE];
4159	char *buf = tmp, *str;
4160	int ret = 0;
4161
4162	if (argc < 1){
4163		websError(wp, 400,
4164			"get_parameter() used with no arguments, but at least one "
4165			"argument is required to specify the parameter name\n");
4166		return -1;
4167	}
4168
4169	str = websGetVar(wp, argv[0], "");
4170
4171	/* each char expands to %XX at max */
4172	ret = strlen(str) * sizeof(char)*3 + sizeof(char);
4173	if (ret > sizeof(tmp)) {
4174		buf = (char *)malloc(ret);
4175		if (buf == NULL) {
4176			csprintf("No memory.\n");
4177			return 0;
4178		}
4179	}
4180
4181	char_to_ascii_safe(buf, str, ret);
4182	ret = websWrite(wp, "%s", buf);
4183
4184	if (buf != tmp)
4185		free(buf);
4186
4187	return ret;
4188}
4189
4190static int ej_get_parameter(int eid, webs_t wp, int argc, char_t **argv){
4191	char *c;
4192	bool last_was_escaped;
4193	int ret = 0;
4194
4195	if (argc < 1){
4196		websError(wp, 400,
4197				"get_parameter() used with no arguments, but at least one "
4198				"argument is required to specify the parameter name\n");
4199		return -1;
4200	}
4201
4202	last_was_escaped = FALSE;
4203
4204	char *value = websGetVar(wp, argv[0], "");
4205	if(value != NULL){
4206		if(strstr(value, "javascript")){
4207			return ret;
4208		}
4209	}
4210	//websWrite(wp, "%s", value);
4211	for (c = websGetVar(wp, argv[0], ""); *c; c++){
4212		if (isalnum(*c) != 0 || *c == '-' || *c == '_' || *c == '.' || *c == '/' || *c == ':')
4213		{
4214			ret += websWrite(wp, "%c", *c);
4215			last_was_escaped = FALSE;
4216		}
4217		else
4218		{
4219			ret += websWrite(wp, " ");
4220			//ret += websWrite(wp, "&#%d", *c);
4221			//last_was_escaped = TRUE;
4222		}
4223	}
4224
4225	return ret;
4226}
4227
4228unsigned int getpeerip(webs_t wp){
4229	int fd, ret;
4230	struct sockaddr peer;
4231	socklen_t peerlen = sizeof(struct sockaddr);
4232	struct sockaddr_in *sa;
4233
4234	fd = fileno((FILE *)wp);
4235	ret = getpeername(fd, (struct sockaddr *)&peer, &peerlen);
4236	sa = (struct sockaddr_in *)&peer;
4237
4238	if (!ret){
4239//		csprintf("peer: %x\n", sa->sin_addr.s_addr);
4240		return (unsigned int)sa->sin_addr.s_addr;
4241	}
4242	else{
4243		csprintf("error: %d %d \n", ret, errno);
4244		return 0;
4245	}
4246}
4247
4248extern long uptime(void);
4249
4250static int login_state_hook(int eid, webs_t wp, int argc, char_t **argv){
4251	unsigned int ip, login_ip, login_port;
4252	char ip_str[16], login_ip_str[16];
4253	time_t login_timestamp_t;
4254	struct in_addr now_ip_addr, login_ip_addr;
4255	time_t now;
4256	const int MAX = 80;
4257	const int VALUELEN = 18;
4258	char buffer[MAX], values[6][VALUELEN];
4259
4260	ip = getpeerip(wp);
4261	//csprintf("ip = %u\n",ip);
4262
4263	now_ip_addr.s_addr = ip;
4264	memset(ip_str, 0, 16);
4265	strcpy(ip_str, inet_ntoa(now_ip_addr));
4266//	time(&now);
4267	now = uptime();
4268
4269	login_ip = (unsigned int)atoll(nvram_safe_get("login_ip"));
4270	login_ip_addr.s_addr = login_ip;
4271	memset(login_ip_str, 0, 16);
4272	strcpy(login_ip_str, inet_ntoa(login_ip_addr));
4273//	login_timestamp = (unsigned long)atol(nvram_safe_get("login_timestamp"));
4274	login_timestamp_t = strtoul(nvram_safe_get("login_timestamp"), NULL, 10);
4275	login_port = (unsigned int)atol(nvram_safe_get("login_port"));
4276
4277	FILE *fp = fopen("/proc/net/arp", "r");
4278	if (fp){
4279		memset(buffer, 0, MAX);
4280		memset(values, 0, 6*VALUELEN);
4281
4282		while (fgets(buffer, MAX, fp)){
4283			if (strstr(buffer, "br0") && !strstr(buffer, "00:00:00:00:00:00")){
4284				if (sscanf(buffer, "%s%s%s%s%s%s", values[0], values[1], values[2], values[3], values[4], values[5]) == 6){
4285					if (!strcmp(values[0], ip_str)){
4286						break;
4287					}
4288				}
4289
4290				memset(values, 0, 6*VALUELEN);
4291			}
4292
4293			memset(buffer, 0, MAX);
4294		}
4295
4296		fclose(fp);
4297	}
4298
4299	if (ip != 0 && login_ip == ip && login_port != 0 && login_port == http_port) {
4300		websWrite(wp, "function is_logined() { return 1; }\n");
4301		websWrite(wp, "function login_ip_dec() { return '%u'; }\n", login_ip);
4302		websWrite(wp, "function login_ip_str() { return '%s'; }\n", login_ip_str);
4303		websWrite(wp, "function login_ip_str_now() { return '%s'; }\n", ip_str);
4304
4305		if (values[3] != NULL)
4306			websWrite(wp, "function login_mac_str() { return '%s'; }\n", values[3]);
4307		else
4308			websWrite(wp, "function login_mac_str() { return ''; }\n");
4309//		time(&login_timestamp);
4310		login_timestamp_t = uptime();
4311	}
4312	else{
4313		websWrite(wp, "function is_logined() { return 0; }\n");
4314		websWrite(wp, "function login_ip_dec() { return '%u'; }\n", login_ip);
4315
4316		if ((unsigned long)(now-login_timestamp_t) > 60)	//one minitues
4317			websWrite(wp, "function login_ip_str() { return '0.0.0.0'; }\n");
4318		else
4319			websWrite(wp, "function login_ip_str() { return '%s'; }\n", login_ip_str);
4320
4321		websWrite(wp, "function login_ip_str_now() { return '%s'; }\n", ip_str);
4322
4323		if (values[3] != NULL)
4324			websWrite(wp, "function login_mac_str() { return '%s'; }\n", values[3]);
4325		else
4326			websWrite(wp, "function login_mac_str() { return ''; }\n");
4327	}
4328
4329	return 0;
4330}
4331#ifdef RTCONFIG_FANCTRL
4332static int get_fanctrl_info(int eid, webs_t wp, int argc, char_t **argv)
4333{
4334	int ret = 0;
4335	unsigned int *temp_24 = NULL;
4336	unsigned int *temp_50 = NULL;
4337	char buf[WLC_IOCTL_SMLEN];
4338	char buf2[WLC_IOCTL_SMLEN];
4339
4340	strcpy(buf, "phy_tempsense");
4341	strcpy(buf2, "phy_tempsense");
4342
4343	if ((ret = wl_ioctl("eth1", WLC_GET_VAR, buf, sizeof(buf))))
4344		return ret;
4345
4346	if ((ret = wl_ioctl("eth2", WLC_GET_VAR, buf2, sizeof(buf2))))
4347		return ret;
4348
4349	temp_24 = (unsigned int *)buf;
4350	temp_50 = (unsigned int *)buf2;
4351//	dbG("phy_tempsense 2.4G: %d, 5G: %d\n", *temp_24, *temp_50);
4352
4353	ret += websWrite(wp, "[\"%d\", \"%d\", \"%d\", \"%s\"]", button_pressed(BTN_FAN), *temp_24, *temp_50, nvram_safe_get("fanctrl_dutycycle_ex"));
4354
4355	return ret;
4356}
4357#endif
4358
4359#ifdef RTCONFIG_BCMARM
4360static int get_cpu_temperature(int eid, webs_t wp, int argc, char_t **argv)
4361{
4362	FILE *fp;
4363	int temperature = -1;
4364
4365	if ((fp = fopen("/proc/dmu/temperature", "r")) != NULL) {
4366		if (fscanf(fp, "%*s %*s %*s %d", &temperature) != 1);
4367			temperature = -1;
4368		fclose(fp);
4369	}
4370
4371	return websWrite(wp, "%d", temperature);
4372}
4373#endif
4374
4375static int get_machine_name(int eid, webs_t wp, int argc, char_t **argv)
4376{
4377	int ret = 0;
4378	struct utsname utsn;
4379
4380	uname(&utsn);
4381
4382	ret += websWrite(wp, "%s", utsn.machine);
4383
4384	return ret;
4385}
4386
4387int ej_dhcp_leases(int eid, webs_t wp, int argc, char_t **argv)
4388{
4389	return 0;
4390}
4391
4392int
4393ej_dhcpLeaseInfo(int eid, webs_t wp, int argc, char_t **argv)
4394{
4395	FILE *fp;
4396	struct in_addr addr4;
4397	struct in6_addr addr6;
4398	char line[256];
4399	char *hwaddr, *ipaddr, *name, *next;
4400	unsigned int expires;
4401	int ret = 0;
4402
4403	if (!nvram_get_int("dhcp_enable_x") || !nvram_match("sw_mode", "1"))
4404		return ret;
4405
4406	/* Read leases file */
4407	if (!(fp = fopen("/var/lib/misc/dnsmasq.leases", "r")))
4408		return ret;
4409
4410	while ((next = fgets(line, sizeof(line), fp)) != NULL) {
4411		/* line should start from numeric value */
4412		if (sscanf(next, "%u ", &expires) != 1)
4413			continue;
4414
4415		strsep(&next, " ");
4416		hwaddr = strsep(&next, " ") ? : "";
4417		ipaddr = strsep(&next, " ") ? : "";
4418		name = strsep(&next, " ") ? : "";
4419
4420		if (inet_pton(AF_INET6, ipaddr, &addr6) != 0) {
4421			/* skip ipv6 leases, thay have no hwaddr, but client id */
4422			// hwaddr = next ? : "";
4423			continue;
4424		} else if (inet_pton(AF_INET, ipaddr, &addr4) == 0)
4425			continue;
4426
4427		ret += websWrite(wp,
4428			"<client>\n"
4429			    "<mac>value=%s</mac>\n"
4430			    "<hostname>value=%s</hostname>\n"
4431			"</client>\n", hwaddr, name);
4432	}
4433	fclose(fp);
4434
4435	return ret;
4436}
4437
4438int
4439ej_dhcpLeaseMacList(int eid, webs_t wp, int argc, char_t **argv)
4440{
4441	FILE *fp;
4442	struct in_addr addr4;
4443	struct in6_addr addr6;
4444	char line[256];
4445	char *hwaddr, *ipaddr, *name, *next;
4446	unsigned int expires;
4447	int ret = 0;
4448	int name_len;
4449	char tmp[MAX_LINE_SIZE];
4450	char *buf = tmp;
4451
4452	if (!nvram_get_int("dhcp_enable_x") || !nvram_match("sw_mode", "1")){
4453		ret += websWrite(wp, "[[\"\", \"\"]]");
4454		return ret;
4455	}
4456
4457	/* Read leases file */
4458	if (!(fp = fopen("/var/lib/misc/dnsmasq.leases", "r"))){
4459		ret += websWrite(wp, "[[\"\", \"\"]]");
4460		return ret;
4461	}
4462
4463	ret += websWrite(wp, "[");
4464	while ((next = fgets(line, sizeof(line), fp)) != NULL) {
4465		/* line should start from numeric value */
4466		if (sscanf(next, "%u ", &expires) != 1)
4467			continue;
4468
4469		strsep(&next, " ");
4470		hwaddr = strsep(&next, " ") ? : "";
4471		ipaddr = strsep(&next, " ") ? : "";
4472		name = strsep(&next, " ") ? : "";
4473
4474		if (inet_pton(AF_INET6, ipaddr, &addr6) != 0) {
4475			/* skip ipv6 leases, thay have no hwaddr, but client id */
4476			// hwaddr = next ? : "";
4477			continue;
4478		} else if (inet_pton(AF_INET, ipaddr, &addr4) == 0)
4479			continue;
4480
4481		/* each char expands to %XX at max */
4482		name_len = strlen(name) * sizeof(char)*3 + sizeof(char);
4483
4484		if (name_len > sizeof(tmp)) {
4485			buf = (char *)malloc(name_len);
4486			if (buf == NULL) {
4487				csprintf("No memory.\n");
4488				return 0;
4489			}
4490		}
4491
4492		char_to_ascii_safe(buf, name, name_len);
4493
4494		ret += websWrite(wp,"[\"%s\", \"%s\"],", hwaddr, buf);
4495	}
4496	ret += websWrite(wp, "[\"\",\"\"]]");
4497	fclose(fp);
4498
4499	return ret;
4500}
4501
4502int
4503ej_lan_leases(int eid, webs_t wp, int argc, char_t **argv)
4504{
4505	FILE *fp;
4506	struct in_addr addr4;
4507	struct in6_addr addr6;
4508	char line[256], timestr[sizeof("999:59:59")];
4509	char *hwaddr, *ipaddr, *name, *next;
4510	unsigned int expires;
4511	int ret = 0;
4512
4513	ret += websWrite(wp, "%-32s %-15s %-17s %-9s\n",
4514		"Hostname", "IP Address", "MAC Address", "Expires");
4515
4516	if (!nvram_get_int("dhcp_enable_x"))
4517		return ret;
4518
4519	/* Refresh lease file to get actual expire time */
4520/*	nvram_set("flush_dhcp_lease", "1"); */
4521	killall("dnsmasq", SIGUSR2);
4522	sleep (1);
4523/*	while(nvram_match("flush_dhcp_lease", "1"))
4524		sleep(1); */
4525
4526	/* Read leases file */
4527	if (!(fp = fopen("/var/lib/misc/dnsmasq.leases", "r")))
4528		return ret;
4529
4530	while ((next = fgets(line, sizeof(line), fp)) != NULL) {
4531		/* line should start from numeric value */
4532		if (sscanf(next, "%u ", &expires) != 1)
4533			continue;
4534
4535		strsep(&next, " ");
4536		hwaddr = strsep(&next, " ") ? : "";
4537		ipaddr = strsep(&next, " ") ? : "";
4538		name = strsep(&next, " ") ? : "";
4539
4540		if (strlen(name) > 32)
4541		{
4542			strcpy(name + 29, "...");
4543			name[32] = '\0';
4544		}
4545
4546		if (inet_pton(AF_INET6, ipaddr, &addr6) != 0) {
4547			/* skip ipv6 leases, thay have no hwaddr, but client id */
4548			// hwaddr = next ? : "";
4549			continue;
4550		} else if (inet_pton(AF_INET, ipaddr, &addr4) == 0)
4551			continue;
4552
4553		if (expires) {
4554			snprintf(timestr, sizeof(timestr), "%u:%02u:%02u",
4555			    expires / 3600,
4556			    expires % 3600 / 60,
4557			    expires % 60);
4558		}
4559
4560		ret += websWrite(wp, "%-32s %-15s %-17s %-9s\n",
4561			name, ipaddr, hwaddr,
4562			expires ? timestr : "Static");
4563	}
4564	fclose(fp);
4565
4566	return ret;
4567}
4568
4569int
4570ej_IP_dhcpLeaseInfo(int eid, webs_t wp, int argc, char_t **argv)
4571{
4572	FILE *fp;
4573	struct in_addr addr4;
4574	struct in6_addr addr6;
4575	char line[256];
4576	char *hwaddr, *ipaddr, *name, *next;
4577	unsigned int expires;
4578	int ret = 0;
4579
4580	if (!nvram_get_int("dhcp_enable_x") || !nvram_match("sw_mode", "1"))
4581		return (ret + websWrite(wp, "[]"));
4582
4583	/* Read leases file */
4584	if (!(fp = fopen("/var/lib/misc/dnsmasq.leases", "r")))
4585		return (ret + websWrite(wp, "[]"));
4586
4587	ret += websWrite(wp, "[");
4588	while ((next = fgets(line, sizeof(line), fp)) != NULL) {
4589		/* line should start from numeric value */
4590		if (sscanf(next, "%u ", &expires) != 1)
4591			continue;
4592
4593		strsep(&next, " ");
4594		hwaddr = strsep(&next, " ") ? : "";
4595		ipaddr = strsep(&next, " ") ? : "";
4596		name = strsep(&next, " ") ? : "";
4597
4598		if (inet_pton(AF_INET6, ipaddr, &addr6) != 0) {
4599			/* skip ipv6 leases, thay have no hwaddr, but client id */
4600			// hwaddr = next ? : "";
4601			continue;
4602		} else if (inet_pton(AF_INET, ipaddr, &addr4) == 0)
4603			continue;
4604
4605		ret += websWrite(wp,"['%s', '%s'],", ipaddr, name);
4606	}
4607	ret += websWrite(wp, "['', '']];");
4608	fclose(fp);
4609
4610	return ret;
4611}
4612
4613#ifdef RTCONFIG_IPV6
4614#define DHCP_LEASE_FILE		"/var/lib/misc/dnsmasq.leases"
4615#define IPV6_CLIENT_NEIGH	"/tmp/ipv6_neigh"
4616#define IPV6_CLIENT_INFO	"/tmp/ipv6_client_info"
4617#define	IPV6_CLIENT_LIST	"/tmp/ipv6_client_list"
4618#define	MAC			1
4619#define	HOSTNAME		2
4620#define	IPV6_ADDRESS		3
4621#define BUFSIZE			8192
4622
4623static int compare_back(FILE *fp, int current_line, char *buffer);
4624static int check_mac_previous(char *mac);
4625static char *value(FILE *fp, int line, int token);
4626static void find_hostname_by_mac(char *mac, char *hostname);
4627static void get_ipv6_client_info();
4628static int total_lines = 0;
4629
4630/* Init File and clear the content */
4631void init_file(char *file)
4632{
4633	FILE *fp;
4634
4635	if ((fp = fopen(file ,"w")) == NULL) {
4636		_dprintf("can't open %s: %s", file,
4637			strerror(errno));
4638	}
4639
4640	fclose(fp);
4641}
4642
4643void save_file(const char *file, const char *fmt, ...)
4644{
4645	char buf[BUFSIZE];
4646	va_list args;
4647	FILE *fp;
4648
4649	if ((fp = fopen(file ,"a")) == NULL) {
4650		_dprintf("can't open %s: %s", file,
4651			strerror(errno));
4652	}
4653
4654	va_start(args, fmt);
4655	vsnprintf(buf, sizeof(buf), fmt, args);
4656	va_end(args);
4657	va_start(args, fmt);
4658	fprintf(fp, "%s", buf);
4659	va_end(args);
4660
4661	fclose(fp);
4662}
4663
4664static char *get_stok(char *str, char *dest, char delimiter)
4665{
4666	char *p;
4667
4668	p = strchr(str, delimiter);
4669	if (p) {
4670		if (p == str)
4671			*dest = '\0';
4672		else
4673			strncpy(dest, str, p-str);
4674
4675		p++;
4676	} else
4677		strcpy(dest, str);
4678
4679	return p;
4680}
4681
4682static char *value(FILE *fp, int line, int token)
4683{
4684	int i;
4685	static char temp[BUFSIZE], buffer[BUFSIZE];
4686	char *ptr;
4687	int temp_len;
4688
4689	fseek(fp, 0, SEEK_SET);
4690	for(i = 0; i < line; i++) {
4691		memset(temp, 0, sizeof(temp));
4692		fgets(temp, sizeof(temp), fp);
4693		temp_len = strlen(temp);
4694		if (temp_len && temp[temp_len-1] == '\n')
4695			temp[temp_len-1] = '\0';
4696	}
4697	memset(buffer, 0, sizeof(buffer));
4698	switch (token) {
4699		case MAC:
4700			get_stok(temp, buffer, ' ');
4701			break;
4702		case HOSTNAME:
4703			ptr = get_stok(temp, buffer, ' ');
4704			if (ptr)
4705				get_stok(ptr, buffer, ' ');
4706			break;
4707		case IPV6_ADDRESS:
4708			ptr = get_stok(temp, buffer, ' ');
4709			if (ptr) {
4710				ptr = get_stok(ptr, buffer, ' ');
4711				if (ptr)
4712					ptr = get_stok(ptr, buffer, ' ');
4713			}
4714			break;
4715		default:
4716			_dprintf("error option\n");
4717			strcpy(buffer, "ERROR");
4718			break;
4719	}
4720
4721	return buffer;
4722}
4723
4724static int check_mac_previous(char *mac)
4725{
4726	FILE *fp;
4727	char temp[BUFSIZE];
4728	memset(temp, 0, sizeof(temp));
4729
4730	if ((fp = fopen(IPV6_CLIENT_LIST, "r")) == NULL)
4731	{
4732		_dprintf("can't open %s: %s", IPV6_CLIENT_LIST,
4733			strerror(errno));
4734
4735		return 0;
4736	}
4737
4738	while (fgets(temp, BUFSIZE, fp)) {
4739		if (strstr(temp, mac)) {
4740			fclose(fp);
4741			return 1;
4742		}
4743	}
4744	fclose(fp);
4745
4746	return 0;
4747}
4748
4749static int compare_back(FILE *fp, int current_line, char *buffer)
4750{
4751	int i = 0;
4752	char mac[32], compare_mac[32];
4753
4754	buffer[strlen(buffer) -1] = '\0';
4755	strcpy(mac, value(fp, current_line, MAC));
4756
4757	if (check_mac_previous(mac))
4758		return 0;
4759
4760	for(i = 0; i<(total_lines - current_line); i++) {
4761		strcpy(compare_mac, value(fp, current_line + 1 + i, MAC));
4762		if (strcmp(mac, compare_mac) == 0) {
4763			strcat(buffer, ",");
4764			strcat(buffer, value(fp, current_line + 1 + i, IPV6_ADDRESS));
4765		}
4766	}
4767	save_file(IPV6_CLIENT_LIST, "%s\n", buffer);
4768
4769	return 0;
4770}
4771
4772static void find_hostname_by_mac(char *mac, char *hostname)
4773{
4774	FILE *fp;
4775	unsigned int expires;
4776	char *macaddr, *ipaddr, *host_name, *next;
4777	char line[256];
4778
4779	if ((fp = fopen(DHCP_LEASE_FILE, "r")) == NULL)
4780	{
4781		_dprintf("can't open %s: %s", DHCP_LEASE_FILE,
4782			strerror(errno));
4783
4784		goto END;
4785	}
4786
4787	while ((next = fgets(line, sizeof(line), fp)) != NULL)
4788	{
4789		if (sscanf(next, "%u ", &expires) != 1)
4790			continue;
4791
4792		strsep(&next, " ");
4793		macaddr = strsep(&next, " ") ? : "";
4794		ipaddr = strsep(&next, " ") ? : "";
4795		host_name = strsep(&next, " ") ? : "";
4796
4797		if (strncasecmp(macaddr, mac, 17) == 0) {
4798			fclose(fp);
4799			strcpy(hostname, host_name);
4800			return;
4801		}
4802
4803		memset(macaddr, 0, sizeof(macaddr));
4804		memset(ipaddr, 0, sizeof(ipaddr));
4805		memset(host_name, 0, sizeof(host_name));
4806	}
4807	fclose(fp);
4808END:
4809	strcpy(hostname, "");
4810}
4811
4812static void get_ipv6_client_info()
4813{
4814	FILE *fp;
4815	char buffer[128], ipv6_addr[128], mac[32];
4816	char *ptr_end, hostname[64];
4817	doSystem("ip -f inet6 neigh show dev %s > %s", nvram_safe_get("lan_ifname"), IPV6_CLIENT_NEIGH);
4818	usleep(1000);
4819
4820	if ((fp = fopen(IPV6_CLIENT_NEIGH, "r")) == NULL)
4821	{
4822		_dprintf("can't open %s: %s", IPV6_CLIENT_NEIGH,
4823			strerror(errno));
4824
4825		return;
4826	}
4827
4828	init_file(IPV6_CLIENT_INFO);
4829	while (fgets(buffer, 128, fp)) {
4830		int temp_len = strlen(buffer);
4831		if (temp_len && buffer[temp_len-1] == '\n')
4832			buffer[temp_len-1] = '\0';
4833		if ((ptr_end = strstr(buffer, "lladdr")))
4834		{
4835			ptr_end = ptr_end - 1;
4836			memset(ipv6_addr, 0, sizeof(ipv6_addr));
4837			strncpy(ipv6_addr, buffer, ptr_end - buffer);
4838			ptr_end = ptr_end + 8;
4839			memset(mac, 0, sizeof(mac));
4840			strncpy(mac, ptr_end, 17);
4841			find_hostname_by_mac(mac, hostname);
4842			if ( (ipv6_addr[0] == '2' || ipv6_addr[0] == '3')
4843				&& ipv6_addr[0] != ':' && ipv6_addr[1] != ':'
4844				&& ipv6_addr[2] != ':' && ipv6_addr[3] != ':')
4845				save_file(IPV6_CLIENT_INFO, "%s %s %s\n", hostname, mac, ipv6_addr);
4846		}
4847
4848		memset(buffer, 0, sizeof(buffer));
4849	}
4850	fclose(fp);
4851}
4852
4853static void get_ipv6_client_list(void)
4854{
4855	FILE *fp;
4856	int line_index = 1;
4857	char temp[BUFSIZE];
4858	memset(temp, 0, sizeof(temp));
4859	init_file(IPV6_CLIENT_LIST);
4860
4861	if ((fp = fopen(IPV6_CLIENT_INFO, "r")) == NULL)
4862	{
4863		_dprintf("can't open %s: %s", IPV6_CLIENT_INFO,
4864			strerror(errno));
4865
4866		return;
4867	}
4868
4869	total_lines = 0;
4870	while (fgets(temp, BUFSIZE, fp))
4871		total_lines++;
4872	fseek(fp, 0, SEEK_SET);
4873	memset(temp, 0, sizeof(temp));
4874
4875	while (fgets(temp, BUFSIZE, fp)) {
4876		compare_back(fp, line_index, temp);
4877		value(fp, line_index, MAC);
4878		line_index++;
4879	}
4880	fclose(fp);
4881
4882	line_index = 1;
4883}
4884#if 0
4885static int ipv6_client_numbers(void)
4886{
4887	FILE *fp;
4888	int numbers = 0;
4889	char temp[BUFSIZE];
4890
4891	if ((fp = fopen(IPV6_CLIENT_LIST, "r")) == NULL)
4892	{
4893		_dprintf("can't open %s: %s", IPV6_CLIENT_LIST,
4894			strerror(errno));
4895
4896		return 0;
4897	}
4898
4899	while (fgets(temp, BUFSIZE, fp))
4900		numbers++;
4901	fclose(fp);
4902
4903	return numbers;
4904}
4905#endif
4906
4907int
4908ej_lan_ipv6_network(int eid, webs_t wp, int argc, char_t **argv)
4909{
4910	FILE *fp;
4911	char buf[64+32+8192+1];
4912	char *hostname, *macaddr, ipaddrs[8192+1];
4913	char ipv6_dns_str[1024];
4914	char *wan_type, *wan_dns, *p;
4915	int service, i, ret = 0;
4916
4917	if (!(ipv6_enabled() && is_routing_enabled())) {
4918		ret += websWrite(wp, "IPv6 disabled\n");
4919		return ret;
4920	}
4921
4922	service = get_ipv6_service();
4923	switch (service) {
4924	case IPV6_NATIVE_DHCP:
4925		wan_type = "Native with DHCP-PD"; break;
4926#ifdef RTCONFIG_6RELAYD
4927	case IPV6_PASSTHROUGH:
4928		wan_type = "IPv6 Passthrough"; break;
4929#endif
4930	case IPV6_6TO4:
4931		wan_type = "Tunnel 6to4"; break;
4932	case IPV6_6IN4:
4933		wan_type = "Tunnel 6in4"; break;
4934	case IPV6_6RD:
4935		wan_type = "Tunnel 6rd"; break;
4936	case IPV6_MANUAL:
4937		wan_type = "Static"; break;
4938	default:
4939		wan_type = "Disabled"; break;
4940	}
4941
4942	ret += websWrite(wp, "%30s: %s\n", "IPv6 Connection Type", wan_type);
4943	ret += websWrite(wp, "%30s: %s\n", "WAN IPv6 Address",
4944			 getifaddr(get_wan6face(), AF_INET6, GIF_PREFIXLEN) ? : nvram_safe_get(ipv6_nvname("ipv6_ipaddr")));
4945	ret += websWrite(wp, "%30s: %s\n", "WAN IPv6 Gateway",
4946			 ipv6_gateway_address() ? : "");
4947#ifdef RTCONFIG_6RELAYD
4948	if (service == IPV6_PASSTHROUGH)
4949	ret += websWrite(wp, "%30s: %s\n", "LAN IPv6 Address",
4950			 getifaddr(nvram_safe_get("lan_ifname"), AF_INET6, GIF_PREFIXLEN) ? : "");
4951	else
4952#endif
4953	ret += websWrite(wp, "%30s: %s/%d\n", "LAN IPv6 Address",
4954			 nvram_safe_get(ipv6_nvname("ipv6_rtr_addr")), nvram_get_int(ipv6_nvname("ipv6_prefix_length")));
4955	ret += websWrite(wp, "%30s: %s\n", "LAN IPv6 Link-Local Address",
4956			 getifaddr(nvram_safe_get("lan_ifname"), AF_INET6, GIF_LINKLOCAL | GIF_PREFIXLEN) ? : "");
4957	if (service == IPV6_NATIVE_DHCP) {
4958		ret += websWrite(wp, "%30s: %s\n", "DHCP-PD",
4959				 nvram_get_int(ipv6_nvname("ipv6_dhcp_pd")) ? "Enabled" : "Disabled");
4960	}
4961#ifdef RTCONFIG_6RELAYD
4962	if (service == IPV6_PASSTHROUGH)
4963	ret += websWrite(wp, "%30s: %s\n", "LAN IPv6 Prefix",
4964			 getifaddr(nvram_safe_get("lan_ifname"), AF_INET6, GIF_PREFIX | GIF_PREFIXLEN) ? : "");
4965	else
4966#endif
4967	ret += websWrite(wp, "%30s: %s/%d\n", "LAN IPv6 Prefix",
4968			 nvram_safe_get(ipv6_nvname("ipv6_prefix")), nvram_get_int(ipv6_nvname("ipv6_prefix_length")));
4969
4970	if (service == IPV6_NATIVE_DHCP &&
4971	    nvram_get_int(ipv6_nvname("ipv6_dnsenable"))) {
4972		wan_dns = nvram_safe_get(ipv6_nvname("ipv6_get_dns"));
4973#ifdef RTCONFIG_6RELAYD
4974	} else if (service == IPV6_PASSTHROUGH) {
4975		wan_dns = nvram_safe_get(ipv6_nvname("ipv6_get_dns"));
4976#endif
4977	} else {
4978		char nvname[sizeof("ipv6_dnsXXX")];
4979		char *next = ipv6_dns_str;
4980
4981		ipv6_dns_str[0] = '\0';
4982		for (i = 1; i <= 3; i++) {
4983			snprintf(nvname, sizeof(nvname), "ipv6_dns%d", i);
4984			wan_dns = nvram_safe_get(nvname);
4985			if (*wan_dns)
4986				next += sprintf(next, *ipv6_dns_str ? " %s" : "%s", wan_dns);
4987		}
4988		wan_dns = ipv6_dns_str;
4989	}
4990	ret += websWrite(wp, "%30s: %s\n", "DNS Address", wan_dns);
4991
4992	ret += websWrite(wp, "\n\nIPv6 LAN Devices List\n");
4993	ret += websWrite(wp, "-------------------------------------------------------------------\n");
4994	ret += websWrite(wp, "%-32s %-17s %-39s\n",
4995			 "Hostname", "MAC Address", "IPv6 Address");
4996
4997	/* Refresh lease file to get actual expire time */
4998	killall("dnsmasq", SIGUSR2);
4999	usleep(100 * 1000);
5000
5001	get_ipv6_client_info();
5002	get_ipv6_client_list();
5003
5004	if ((fp = fopen(IPV6_CLIENT_LIST, "r")) == NULL) {
5005		_dprintf("can't open %s: %s", IPV6_CLIENT_LIST, strerror(errno));
5006		return ret;
5007	}
5008
5009	while (fgets(buf, sizeof(buf), fp) != NULL) {
5010		char *ptr = buf;
5011
5012		ptr = strsep(&ptr, "\n");
5013		hostname = strsep(&ptr, " ");
5014		macaddr = strsep(&ptr, " ");
5015		if (!macaddr || *macaddr == '\0' ||
5016		    !ptr || *ptr == '\0')
5017			continue;
5018
5019		if (strlen(hostname) > 32)
5020			sprintf(hostname + 29, "...");
5021
5022		ipaddrs[0] = '\0';
5023		p = ipaddrs;
5024		while (ptr && *ptr) {
5025			char *next = strsep(&ptr, ",\n");
5026			if (next && *next)
5027				p += snprintf(p, sizeof(ipaddrs) + ipaddrs - p, "%s%s", *ipaddrs ? ", " : "", next);
5028		}
5029
5030		ret += websWrite(wp, "%-32s %-17s %-39s\n",
5031				 hostname, macaddr, ipaddrs);
5032	}
5033	fclose(fp);
5034
5035	return ret;
5036}
5037#endif
5038
5039#ifndef RTF_PREFIX_RT
5040#define RTF_PREFIX_RT	0x00080000
5041#endif
5042#ifndef RTF_EXPIRES
5043#define RTF_EXPIRES	0x00400000
5044#endif
5045#ifndef RTF_ROUTEINFO
5046#define RTF_ROUTEINFO	0x00800000
5047#endif
5048
5049const static struct {
5050	unsigned int flag;
5051	char name;
5052} route_flags[] = {
5053	{ RTF_REJECT,    '!' },		/* be first */
5054	{ RTF_UP,        'U' },
5055	{ RTF_GATEWAY,   'G' },
5056	{ RTF_HOST,      'H' },
5057	{ RTF_REINSTATE, 'R' },		/* ipv4 only */
5058	{ RTF_DYNAMIC,   'D' },		/* ipv4 only */
5059	{ RTF_MODIFIED,  'M' },		/* ipv4 only */
5060#ifdef RTCONFIG_IPV6
5061	{ RTF_DEFAULT,   'D' },		/* ipv6 only */
5062	{ RTF_ADDRCONF,  'A' },		/* ipv6 only */
5063	{ RTF_PREFIX_RT, 'P' },		/* ipv6 only */
5064	{ RTF_NONEXTHOP, 'n' },		/* ipv6 only */
5065	{ RTF_EXPIRES,   'E' },		/* ipv6 only */
5066	{ RTF_ROUTEINFO, 'R' },		/* ipv6 only */
5067//	{ RTF_CACHE,     'C' },		/* ipv6 only */
5068#endif
5069};
5070
5071#ifdef RTCONFIG_IPV6
5072static int inet_raddr6_pton(const char *src, void *dst, void *buf)
5073{
5074	char *sptr = (char *) src;
5075	char *dptr = buf;
5076	int i;
5077
5078	for (i = 0; *sptr && i < 32; i++) {
5079		if (i && (i % 4) == 0)
5080			*dptr++ = ':';
5081		*dptr++ = *sptr++;
5082	} *dptr = '\0';
5083
5084	return inet_pton(AF_INET6, buf, dst);
5085}
5086
5087static int ipv6_route_table(webs_t wp)
5088{
5089	FILE *fp;
5090	char buf[256], *str, *dev, *sflags, *route, fmt[sizeof("%999s")];
5091	char sdest[INET6_ADDRSTRLEN], snexthop[INET6_ADDRSTRLEN], ifname[16];
5092	struct in6_addr dest, nexthop;
5093	int flags, ref, use, metric, prefix;
5094	int i, pass, maxlen, routing, ret = 0;
5095
5096	fp = fopen("/proc/net/ipv6_route", "r");
5097	if (fp == NULL)
5098		return 0;
5099
5100	pass = maxlen = 0;
5101	routing = is_routing_enabled();
5102again:
5103	if (pass) {
5104		ret += websWrite(wp, fmt, "Destination & Next Hop");
5105		ret += websWrite(wp, "%-9s%s\n",
5106				 "Flags", "Metric Ref    Use Type Iface");
5107	}
5108	while ((str = fgets(buf, sizeof(buf), fp)) != NULL) {
5109		if (sscanf(str, "%32s%x%*s%*x%32s%x%x%x%x%15s",
5110			   sdest, &prefix, snexthop,
5111			   &metric, &ref, &use, &flags, ifname) != 8)
5112			continue;
5113
5114		/* Skip down and cache routes */
5115		if ((flags & (RTF_UP | RTF_CACHE)) != RTF_UP)
5116			continue;
5117		/* Skip interfaces here */
5118		if (strcmp(ifname, "lo") == 0)
5119			continue;
5120
5121		/* Parse dst, reuse buf */
5122		if (inet_raddr6_pton(sdest, &dest, str) < 1)
5123			break;
5124		if (prefix || !IN6_IS_ADDR_UNSPECIFIED(&dest)) {
5125			inet_ntop(AF_INET6, &dest, sdest, sizeof(sdest));
5126			if (prefix != 128) {
5127				i = strlen(sdest);
5128				snprintf(sdest + i, sizeof(sdest) - i, "/%d", prefix);
5129			}
5130		} else
5131			snprintf(sdest, sizeof(sdest), "default");
5132
5133		/* Parse nexthop, reuse buf */
5134		if (inet_raddr6_pton(snexthop, &nexthop, str) < 1)
5135			break;
5136		inet_ntop(AF_INET6, &nexthop, snexthop, sizeof(snexthop));
5137
5138		/* Format addresses, reuse buf */
5139		route = str;
5140		i = snprintf(str, buf + sizeof(buf) - str, ((flags & RTF_NONEXTHOP) ||
5141			     IN6_IS_ADDR_UNSPECIFIED(&nexthop)) ? "%s" : "%s via %s",
5142			     sdest, snexthop);
5143		if (pass == 0) {
5144			if (maxlen < i)
5145				maxlen = i;
5146			continue;
5147		} else
5148			str += i + 1;
5149
5150		/* Parse flags, reuse buf */
5151		sflags = str;
5152		for (i = 0; i < ARRAY_SIZE(route_flags); i++) {
5153			if (flags & route_flags[i].flag)
5154				*str++ = route_flags[i].name;
5155		}
5156		*str++ = '\0';
5157
5158		/* Replace known interfaces with LAN/WAN/MAN */
5159		dev = NULL;
5160		if (nvram_match("lan_ifname", ifname)) /* br0, wl0, etc */
5161			dev = "LAN";
5162		else if (routing && strcmp(get_wan6face(), ifname) == 0)
5163			dev = "WAN";
5164
5165		ret = websWrite(wp, fmt, route);
5166		ret += websWrite(wp, "%-9s%-6d %-3d%7d %-4s %s\n",
5167				 sflags, metric, ref, use, dev ? : "", ifname);
5168	}
5169	if (pass++ == 0) {
5170		/* NB: 48 is to fit IPv4 routing table header */
5171		snprintf(fmt, sizeof(fmt), "%%-%ds", max(maxlen + 1, 48));
5172		if (maxlen > 0)
5173			rewind(fp);
5174		goto again;
5175	}
5176	fclose(fp);
5177
5178	return ret;
5179}
5180#endif
5181
5182static int ipv4_route_table(webs_t wp)
5183{
5184	FILE *fp;
5185	char tmp[100], prefix[sizeof("wanXXXXXXXXXX_")];
5186	char buf[256], *str, *dev, *sflags, *ifname;
5187	struct in_addr dest, gateway, mask;
5188	int flags, ref, use, metric;
5189	int i, unit, routing, ret = 0;
5190
5191	fp = fopen("/proc/net/route", "r");
5192	if (fp == NULL)
5193		return 0;
5194
5195	routing = is_routing_enabled();
5196
5197	ret += websWrite(wp, "%-16s%-16s%-16s%-9s%s\n",
5198			 "Destination", "Gateway", "Genmask",
5199			 "Flags", "Metric Ref    Use Type Iface");
5200
5201	while ((str = fgets(buf, sizeof(buf), fp)) != NULL) {
5202		ifname = strsep(&str, " \t");
5203		if (!str || ifname == str)
5204			continue;
5205		if (sscanf(str, "%x%x%x%d%u%d%x", &dest.s_addr, &gateway.s_addr,
5206			   &flags, &ref, &use, &metric, &mask.s_addr) != 7)
5207			continue;
5208
5209		/* Skip interfaces here */
5210		if (strcmp(ifname, "lo") == 0)
5211			continue;
5212
5213		/* Parse flags, reuse buf */
5214		sflags = str;
5215		for (i = 0; i < ARRAY_SIZE(route_flags); i++) {
5216			if (flags & route_flags[i].flag)
5217				*str++ = route_flags[i].name;
5218		}
5219		*str++ = '\0';
5220
5221		/* Replace known interfaces with LAN/WAN/MAN */
5222		dev = NULL;
5223		if (nvram_match("lan_ifname", ifname)) /* br0, wl0, etc */
5224			dev = "LAN";
5225		else if (routing) {
5226			/* Tricky, it's better to move wan_ifunit/wanx_ifunit to shared instead */
5227			for (unit = WAN_UNIT_FIRST; unit < WAN_UNIT_MAX; unit++) {
5228				wan_prefix(unit, prefix);
5229				if (nvram_match(strcat_r(prefix, "pppoe_ifname", tmp), ifname)) {
5230					dev = "WAN";
5231					break;
5232				}
5233				if (nvram_match(strcat_r(prefix, "ifname", tmp), ifname)) {
5234					char *wan_proto = nvram_safe_get(strcat_r(prefix, "proto", tmp));
5235					dev = (strcmp(wan_proto, "dhcp") == 0 ||
5236					       strcmp(wan_proto, "static") == 0 ) ? "WAN" : "MAN";
5237					break;
5238				}
5239			}
5240#ifdef RTCONFIG_DUALWAN
5241			if (dev) {
5242				snprintf(str, sizeof(buf) - (str - buf), "%s%d", dev, unit);
5243				dev = str;
5244			}
5245#endif
5246		}
5247
5248		ret += websWrite(wp, "%-16s", dest.s_addr == INADDR_ANY ? "default" : inet_ntoa(dest));
5249		ret += websWrite(wp, "%-16s", gateway.s_addr == INADDR_ANY ? "*" : inet_ntoa(gateway));
5250		ret += websWrite(wp, "%-16s%-9s%-6d %-3d%7d %-4s %s\n",
5251				 inet_ntoa(mask), sflags, metric, ref, use, dev ? : "", ifname);
5252	}
5253	fclose(fp);
5254
5255	return ret;
5256}
5257
5258int
5259ej_route_table(int eid, webs_t wp, int argc, char_t **argv)
5260{
5261	int ret;
5262
5263	ret = ipv4_route_table(wp);
5264
5265#ifdef RTCONFIG_IPV6
5266	if (get_ipv6_service() != IPV6_DISABLED) {
5267		ret += websWrite(wp, "\n"
5268				     "IPv6 routing table\n");
5269		ret += ipv6_route_table(wp);
5270	}
5271#endif
5272
5273	return ret;
5274}
5275
5276static int ej_get_arp_table(int eid, webs_t wp, int argc, char_t **argv){
5277	const int MAX = 80;
5278	const int FIELD_NUM = 6;
5279	const int VALUELEN = 18;
5280	char buffer[MAX], values[FIELD_NUM][VALUELEN];
5281	int num, firstRow;
5282
5283	FILE *fp = fopen("/proc/net/arp", "r");
5284	if (fp){
5285		memset(buffer, 0, MAX);
5286		memset(values, 0, FIELD_NUM*VALUELEN);
5287
5288		firstRow = 1;
5289		while (fgets(buffer, MAX, fp)){
5290			if (strstr(buffer, "br0") && !strstr(buffer, "00:00:00:00:00:00")){
5291				if (firstRow == 1)
5292					firstRow = 0;
5293				else
5294					websWrite(wp, ", ");
5295
5296				if ((num = sscanf(buffer, "%s%s%s%s%s%s", values[0], values[1], values[2], values[3], values[4], values[5])) == FIELD_NUM){
5297					websWrite(wp, "[\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\"]", values[0], values[1], values[2], values[3], values[4], values[5]);
5298				}
5299
5300				memset(values, 0, FIELD_NUM*VALUELEN);
5301			}
5302
5303			memset(buffer, 0, MAX);
5304		}
5305
5306		fclose(fp);
5307	}
5308
5309	return 0;
5310}
5311
5312#if defined(CONFIG_BCMWL5) || (defined(RTCONFIG_RALINK) && defined(RTCONFIG_WIRELESSREPEATER)) || defined(RTCONFIG_QCA)
5313static int ej_get_ap_info(int eid, webs_t wp, int argc, char_t **argv)
5314{
5315	FILE *fp;
5316	char buf[MAX_LINE_SIZE];
5317	int ret_l = 0;
5318	unsigned int i_l, len_l;
5319	int i;
5320	int lock;
5321
5322	// get info from file generated by wlc_scan
5323	if(nvram_get_int("wlc_scan_state")!=WLCSCAN_STATE_FINISHED){
5324		ret_l += websWrite(wp, "[]");
5325		return ret_l;
5326	}
5327	lock = file_lock("sitesurvey");
5328	fp = fopen("/tmp/apscan_info.txt", "r");
5329	if( fp == NULL ){
5330		csprintf("[httpd] open apscan_info.txt error\n");
5331		ret_l += websWrite(wp, "[]");
5332		return ret_l;
5333	}else{
5334		//ret_l += websWrite(wp, "[");
5335		i = 0;
5336		while (fgets(buf, MAX_LINE_SIZE, fp)){
5337			if(i>0) ret_l += websWrite(wp, ",");
5338			len_l = strlen(buf);
5339			i_l = 0;
5340			while (i_l < len_l + 1){
5341				if(buf[i_l] == '\n') buf[i_l] = '\0';
5342				i_l++;
5343			}
5344			ret_l += websWrite(wp, "[");
5345			ret_l += websWrite(wp, "%s", buf);
5346			ret_l += websWrite(wp, "]");
5347			memset(buf, 0, MAX_LINE_SIZE);
5348			i++;
5349		}
5350		//ret_l += websWrite(wp, "];");	/* insert empty for last record */
5351	}
5352	fclose(fp);
5353	file_unlock(lock);
5354	return ret_l;
5355
5356}
5357#endif
5358
5359//2011.03 Yau add for new networkmap
5360static int ej_get_client_detail_info(int eid, webs_t wp, int argc, char_t **argv){
5361	int i, shm_client_info_id;
5362	void *shared_client_info=(void *) 0;
5363	char output_buf[128], dev_name[32];
5364	P_CLIENT_DETAIL_INFO_TABLE p_client_info_tab;
5365	int lock;
5366	char devname[LINE_SIZE], character;
5367	int j, len;
5368
5369	lock = file_lock("networkmap");
5370	shm_client_info_id = shmget((key_t)1001, sizeof(CLIENT_DETAIL_INFO_TABLE), 0666|IPC_CREAT);
5371	if (shm_client_info_id == -1){
5372	    fprintf(stderr,"shmget failed\n");
5373	    file_unlock(lock);
5374	    return 0;
5375	}
5376
5377	shared_client_info = shmat(shm_client_info_id,(void *) 0,0);
5378	if (shared_client_info == (void *)-1){
5379		fprintf(stderr,"shmat failed\n");
5380		file_unlock(lock);
5381		return 0;
5382	}
5383
5384	p_client_info_tab = (P_CLIENT_DETAIL_INFO_TABLE)shared_client_info;
5385	for(i=0; i<p_client_info_tab->ip_mac_num; i++) {
5386		if(strcmp((const char *)p_client_info_tab->user_define[i], ""))
5387			strlcpy(dev_name, (const char *)p_client_info_tab->user_define[i], sizeof(dev_name));
5388		else
5389			strlcpy(dev_name, (const char *)p_client_info_tab->device_name[i], sizeof(dev_name));
5390
5391		memset(output_buf, 0, 128);
5392		memset(devname, 0, LINE_SIZE);
5393
5394	    if(p_client_info_tab->exist[i]==1) {
5395		len = strlen(dev_name);
5396		for (j=0; (j < len) && (j < LINE_SIZE-1); j++) {
5397			character = dev_name[j];
5398			if ((isalnum(character)) || (character == ' ') || (character == '-') || (character == '_'))
5399				devname[j] = character;
5400			else
5401				devname[j] = ' ';
5402		}
5403
5404		sprintf(output_buf, "<%d>%s>%d.%d.%d.%d>%02X:%02X:%02X:%02X:%02X:%02X>%d>%d>%d>%s",
5405		p_client_info_tab->type[i],
5406		devname,
5407		p_client_info_tab->ip_addr[i][0],p_client_info_tab->ip_addr[i][1],
5408		p_client_info_tab->ip_addr[i][2],p_client_info_tab->ip_addr[i][3],
5409		p_client_info_tab->mac_addr[i][0],p_client_info_tab->mac_addr[i][1],
5410		p_client_info_tab->mac_addr[i][2],p_client_info_tab->mac_addr[i][3],
5411		p_client_info_tab->mac_addr[i][4],p_client_info_tab->mac_addr[i][5],
5412		p_client_info_tab->http[i],
5413		p_client_info_tab->printer[i],
5414		p_client_info_tab->itune[i],
5415                p_client_info_tab->apple_model[i]
5416		);
5417		websWrite(wp, output_buf);
5418	    }
5419	}
5420	shmdt(shared_client_info);
5421	file_unlock(lock);
5422
5423	return 0;
5424}
5425
5426
5427// for detect static IP's client.
5428static int ej_get_static_client(int eid, webs_t wp, int argc, char_t **argv){
5429	FILE *fp = fopen("/tmp/static_ip.inf", "r");
5430	char buf[1024], *head, *tail, field[1024];
5431	int len, i, first_client, first_field;
5432
5433	if (fp == NULL){
5434		csprintf("Don't detect static clients!\n");
5435		return 0;
5436	}
5437
5438	memset(buf, 0, 1024);
5439
5440	first_client = 1;
5441	while (fgets(buf, 1024, fp)){
5442		if (first_client == 1)
5443			first_client = 0;
5444		else
5445			websWrite(wp, ", ");
5446
5447		len = strlen(buf);
5448		buf[len-1] = ',';
5449		head = buf;
5450		first_field = 1;
5451		for (i = 0; i < 7; ++i){
5452			tail = strchr(head, ',');
5453			if (tail != NULL){
5454				memset(field, 0, 1024);
5455				strncpy(field, head, (tail-head));
5456			}
5457
5458			if (first_field == 1){
5459				first_field = 0;
5460				websWrite(wp, "[");
5461			}
5462			else
5463				websWrite(wp, ", ");
5464
5465			if (strlen(field) > 0)
5466				websWrite(wp, "\"%s\"", field);
5467			else
5468				websWrite(wp, "null");
5469
5470			//if (tail+1 != NULL)
5471				head = tail+1;
5472
5473			if (i == 6)
5474				websWrite(wp, "]");
5475		}
5476
5477		memset(buf, 0, 1024);
5478	}
5479
5480	fclose(fp);
5481	return 0;
5482}
5483
5484static int yadns_servers_hook(int eid, webs_t wp, int argc, char_t **argv)
5485{
5486#ifdef RTCONFIG_YANDEXDNS
5487	int yadns_mode = nvram_get_int("yadns_enable_x") ? nvram_get_int("yadns_mode") : YADNS_DISABLED;
5488	char *server[2];
5489	int i, count;
5490
5491	if (yadns_mode != YADNS_DISABLED) {
5492		count = get_yandex_dns(AF_INET, yadns_mode, server, sizeof(server)/sizeof(server[0]));
5493		for (i = 0; i < count; i++)
5494			websWrite(wp, i ? ",\"%s\"" : "\"%s\"", server[i]);
5495	}
5496#endif
5497	return 0;
5498}
5499
5500static int yadns_clients_hook(int eid, webs_t wp, int argc, char_t **argv)
5501{
5502#ifdef RTCONFIG_YANDEXDNS
5503	char *name, *mac, *mode, *enable;
5504	char *nv, *nvp, *b;
5505	int i, dnsmode, clients[YADNS_COUNT];
5506
5507	memset(&clients, 0, sizeof(clients));
5508
5509	if (nvram_get_int("yadns_enable_x")) {
5510		nv = nvp = strdup(nvram_safe_get("yadns_rulelist"));
5511		while (nv && (b = strsep(&nvp, "<")) != NULL) {
5512			if (vstrsep(b, ">", &name, &mac, &mode, &enable) < 3)
5513				continue;
5514			if (enable && atoi(enable) == 0)
5515				continue;
5516			if (!*mac || !*mode)
5517				continue;
5518			dnsmode = atoi(mode);
5519			/* Skip incorrect levels */
5520			if (dnsmode < YADNS_FIRST || dnsmode >= YADNS_COUNT)
5521				continue;
5522			clients[dnsmode]++;
5523		}
5524		free(nv);
5525	}
5526
5527	for (i = YADNS_FIRST; i < YADNS_COUNT; i++)
5528		websWrite(wp, (i == YADNS_FIRST) ? "%d" : ",%d", clients[i]);
5529#endif
5530	return 0;
5531}
5532
5533static int ej_get_changed_status(int eid, webs_t wp, int argc, char_t **argv){
5534	char *arp_info = read_whole_file("/proc/net/arp");
5535#ifdef RTCONFIG_USB
5536	char *disk_info = read_whole_file(PARTITION_FILE);
5537	char *mount_info = read_whole_file(MOUNT_FILE);
5538#endif
5539	u32 arp_info_len, disk_info_len, mount_info_len;
5540//	u32 arp_change, disk_change;
5541
5542	//printf("get changed status\n");	// tmp test
5543
5544	if (arp_info != NULL){
5545		arp_info_len = strlen(arp_info);
5546		free(arp_info);
5547	}
5548	else
5549		arp_info_len = 0;
5550
5551#ifdef RTCONFIG_USB
5552	if (disk_info != NULL){
5553		disk_info_len = strlen(disk_info);
5554		free(disk_info);
5555	}
5556	else
5557		disk_info_len = 0;
5558
5559	if (mount_info != NULL){
5560		mount_info_len = strlen(mount_info);
5561		free(mount_info);
5562	}
5563	else
5564		mount_info_len = 0;
5565#endif
5566
5567	websWrite(wp, "function get_client_status_changed(){\n");
5568	websWrite(wp, "    return %u;\n", arp_info_len);
5569	websWrite(wp, "}\n\n");
5570
5571#ifdef RTCONFIG_USB
5572	websWrite(wp, "function get_disk_status_changed(){\n");
5573	websWrite(wp, "    return %u;\n", disk_info_len);
5574	websWrite(wp, "}\n\n");
5575
5576	websWrite(wp, "function get_mount_status_changed(){\n");
5577	websWrite(wp, "    return %u;\n", mount_info_len);
5578	websWrite(wp, "}\n\n");
5579#endif
5580	return 0;
5581}
5582
5583#ifdef RTCONFIG_USB
5584static int ej_show_usb_path(int eid, webs_t wp, int argc, char_t **argv){
5585	DIR *bus_usb;
5586	struct dirent *interface;
5587	char usb_port[8], port_path[8], *ptr;
5588	int port_num, port_order, hub_order;
5589	char all_usb_path[MAX_USB_PORT][MAX_USB_HUB_PORT][3][16]; // MAX USB hub port number is 6.
5590	char prefix[] = "usb_pathXXXXXXXXXXXXXXXXX_", tmp[100];
5591	int port_set, got_port, got_hub;
5592
5593	if((bus_usb = opendir(USB_DEVICE_PATH)) == NULL)
5594		return -1;
5595
5596	memset(all_usb_path, 0, MAX_USB_PORT*MAX_USB_HUB_PORT*3*16);
5597
5598	while((interface = readdir(bus_usb)) != NULL){
5599		if(interface->d_name[0] == '.')
5600			continue;
5601
5602		if(!isdigit(interface->d_name[0]))
5603			continue;
5604
5605		if(strchr(interface->d_name, ':'))
5606			continue;
5607
5608		if(get_usb_port_by_string(interface->d_name, usb_port, 8) == NULL)
5609			continue;
5610
5611		port_num = get_usb_port_number(usb_port);
5612		port_order = port_num-1;
5613		if((ptr = strchr(interface->d_name+strlen(usb_port), '.')) != NULL)
5614			hub_order = atoi(ptr+1);
5615		else
5616			hub_order = 0;
5617
5618		if(get_path_by_node(interface->d_name, port_path, 8) == NULL)
5619			continue;
5620
5621		strncpy(all_usb_path[port_order][hub_order][0], port_path, 16);
5622		snprintf(prefix, sizeof(prefix), "usb_path%s", port_path);
5623		strncpy(all_usb_path[port_order][hub_order][1], nvram_safe_get(prefix), 16);
5624		strncpy(all_usb_path[port_order][hub_order][2], nvram_safe_get(strcat_r(prefix, "_speed", tmp)), 16);
5625	}
5626	closedir(bus_usb);
5627
5628	port_set = got_port = got_hub = 0;
5629
5630	websWrite(wp, "[");
5631	for(port_order = 0; port_order < MAX_USB_PORT; ++port_order){
5632		got_hub = 0;
5633		for(hub_order = 0; hub_order < MAX_USB_HUB_PORT; ++hub_order){
5634			if(strlen(all_usb_path[port_order][hub_order][1]) > 0){
5635				if(!port_set){ // port range.
5636					port_set = 1;
5637
5638					if(!got_port)
5639						got_port = 1;
5640					else
5641						websWrite(wp, ", ");
5642
5643					websWrite(wp, "[");
5644				}
5645
5646				if(!got_hub)
5647					got_hub = 1;
5648				else
5649					websWrite(wp, ", ");
5650
5651				websWrite(wp, "[\"%s\", \"%s\", \"%s\"]", all_usb_path[port_order][hub_order][0], all_usb_path[port_order][hub_order][1], all_usb_path[port_order][hub_order][2]);
5652			}
5653		}
5654
5655		if(port_set){ // port range.
5656			port_set = 0;
5657			websWrite(wp, "]");
5658		}
5659	}
5660	websWrite(wp, "]");
5661
5662	return 0;
5663}
5664
5665static int ej_disk_pool_mapping_info(int eid, webs_t wp, int argc, char_t **argv){
5666	disk_info_t *disks_info, *follow_disk;
5667	partition_info_t *follow_partition;
5668	int first;
5669	char *Ptr;
5670
5671	disks_info = read_disk_data();
5672	if (disks_info == NULL){
5673		websWrite(wp, "%s", initial_disk_pool_mapping_info());
5674		return -1;
5675	}
5676
5677	websWrite(wp, "function total_disk_sizes(){\n");
5678	websWrite(wp, "    return [");
5679	first = 1;
5680	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next){
5681		if (first == 1)
5682			first = 0;
5683		else
5684			websWrite(wp, ", ");
5685
5686		websWrite(wp, "\"%llu\"", follow_disk->size_in_kilobytes);
5687	}
5688	websWrite(wp, "];\n");
5689	websWrite(wp, "}\n\n");
5690
5691	websWrite(wp, "function disk_interface_names(){\n");
5692	websWrite(wp, "    return [");
5693	first = 1;
5694	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next){
5695		if (first == 1)
5696			first = 0;
5697		else
5698			websWrite(wp, ", ");
5699
5700		websWrite(wp, "\"usb\"");
5701	}
5702	websWrite(wp, "];\n");
5703	websWrite(wp, "}\n\n");
5704
5705	websWrite(wp, "function pool_names(){\n");
5706	websWrite(wp, "    return [");
5707
5708	first = 1;
5709	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next)
5710		for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next){
5711			if (first == 1)
5712				first = 0;
5713			else
5714				websWrite(wp, ", ");
5715
5716			if (follow_partition->mount_point == NULL){
5717				websWrite(wp, "\"%s\"", follow_partition->device);
5718				continue;
5719			}
5720
5721			Ptr = rindex(follow_partition->mount_point, '/');
5722			if (Ptr == NULL){
5723				websWrite(wp, "\"unknown\"");
5724				continue;
5725			}
5726
5727			++Ptr;
5728			websWrite(wp, "\"%s\"", Ptr);
5729		}
5730	websWrite(wp, "];\n");
5731	websWrite(wp, "}\n\n");
5732
5733	websWrite(wp, "function pool_devices(){\n");
5734	websWrite(wp, "    return [");
5735
5736	first = 1;
5737	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next)
5738		for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next){
5739			if (first == 1)
5740				first = 0;
5741			else
5742				websWrite(wp, ", ");
5743
5744			websWrite(wp, "\"%s\"", follow_partition->device);
5745		}
5746	websWrite(wp, "];\n");
5747	websWrite(wp, "}\n\n");
5748
5749	websWrite(wp, "function pool_types(){\n");
5750	websWrite(wp, "    return [");
5751	first = 1;
5752	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next)
5753		for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next){
5754			if (first == 1)
5755				first = 0;
5756			else
5757				websWrite(wp, ", ");
5758
5759			if (follow_partition->mount_point == NULL){
5760				websWrite(wp, "\"unknown\"");
5761				continue;
5762			}
5763
5764			websWrite(wp, "\"%s\"", follow_partition->file_system);
5765		}
5766	websWrite(wp, "];\n");
5767	websWrite(wp, "}\n\n");
5768
5769	websWrite(wp, "function pool_mirror_counts(){\n");
5770	websWrite(wp, "    return [");
5771	first = 1;
5772	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next)
5773		for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next){
5774			if (first == 1)
5775				first = 0;
5776			else
5777				websWrite(wp, ", ");
5778
5779			websWrite(wp, "0");
5780		}
5781	websWrite(wp, "];\n");
5782	websWrite(wp, "}\n\n");
5783
5784	websWrite(wp, "function pool_status(){\n");
5785	websWrite(wp, "    return [");
5786	first = 1;
5787	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next)
5788		for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next){
5789			if (first == 1)
5790				first = 0;
5791			else
5792				websWrite(wp, ", ");
5793
5794			if (follow_partition->mount_point == NULL){
5795				websWrite(wp, "\"unmounted\"");
5796				continue;
5797			}
5798
5799			//if (strcmp(follow_partition->file_system, "ntfs") == 0)
5800			//	websWrite(wp, "\"ro\"");
5801			//else
5802			websWrite(wp, "\"rw\"");
5803		}
5804	websWrite(wp, "];\n");
5805	websWrite(wp, "}\n\n");
5806
5807	websWrite(wp, "function pool_kilobytes(){\n");
5808	websWrite(wp, "    return [");
5809	first = 1;
5810	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next)
5811		for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next){
5812			if (first == 1)
5813				first = 0;
5814			else
5815				websWrite(wp, ", ");
5816
5817			websWrite(wp, "%llu", follow_partition->size_in_kilobytes);
5818		}
5819	websWrite(wp, "];\n");
5820	websWrite(wp, "}\n\n");
5821
5822	websWrite(wp, "function pool_encryption_password_is_missing(){\n");
5823	websWrite(wp, "    return [");
5824	first = 1;
5825	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next)
5826		for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next){
5827			if (first == 1)
5828				first = 0;
5829			else
5830				websWrite(wp, ", ");
5831
5832			websWrite(wp, "\"no\"");
5833		}
5834	websWrite(wp, "];\n");
5835	websWrite(wp, "}\n\n");
5836
5837	websWrite(wp, "function pool_kilobytes_in_use(){\n");
5838	websWrite(wp, "    return [");
5839	first = 1;
5840	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next)
5841		for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next){
5842			if (first == 1)
5843				first = 0;
5844			else
5845				websWrite(wp, ", ");
5846
5847			websWrite(wp, "%llu", follow_partition->used_kilobytes);
5848		}
5849
5850	websWrite(wp, "];\n");
5851	websWrite(wp, "}\n\n");
5852
5853	u64 disk_used_kilobytes;
5854
5855	websWrite(wp, "function disk_usage(){\n");
5856	websWrite(wp, "    return [");
5857	first = 1;
5858	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next){
5859		if (first == 1)
5860			first = 0;
5861		else
5862			websWrite(wp, ", ");
5863
5864		disk_used_kilobytes = 0;
5865		for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next)
5866			disk_used_kilobytes += follow_partition->size_in_kilobytes;
5867
5868		websWrite(wp, "%llu", disk_used_kilobytes);
5869	}
5870	websWrite(wp, "];\n");
5871	websWrite(wp, "}\n\n");
5872
5873	disk_info_t *follow_disk2;
5874	u32 disk_num, pool_num;
5875	websWrite(wp, "function per_pane_pool_usage_kilobytes(pool_num, disk_num){\n");
5876	for (follow_disk = disks_info, pool_num = 0; follow_disk != NULL; follow_disk = follow_disk->next){
5877		for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next, ++pool_num){
5878			websWrite(wp, "    if (pool_num == %d){\n", pool_num);
5879			for (follow_disk2 = disks_info, disk_num = 0; follow_disk2 != NULL; follow_disk2 = follow_disk2->next, ++disk_num){
5880				websWrite(wp, "	if (disk_num == %d) {\n", disk_num);
5881
5882				//if (strcmp(follow_disk2->tag, follow_disk->tag) == 0)
5883				if (follow_disk2->major == follow_disk->major && follow_disk2->minor == follow_disk->minor)
5884					websWrite(wp, "	    return [%llu];\n", follow_partition->size_in_kilobytes);
5885				else
5886					websWrite(wp, "	    return [0];\n");
5887
5888				websWrite(wp, "	}\n");
5889			}
5890			websWrite(wp, "    }\n");
5891		}
5892	}
5893	websWrite(wp, "}\n\n");
5894	free_disk_data(&disks_info);
5895
5896	return 0;
5897}
5898
5899static int ej_available_disk_names_and_sizes(int eid, webs_t wp, int argc, char_t **argv){
5900	disk_info_t *disks_info, *follow_disk;
5901	int first;
5902	char ascii_tag[PATH_MAX], ascii_vendor[PATH_MAX], ascii_model[PATH_MAX];
5903
5904	websWrite(wp, "function available_disks(){ return [];}\n\n");
5905	websWrite(wp, "function available_disk_sizes(){ return [];}\n\n");
5906	websWrite(wp, "function claimed_disks(){ return [];}\n\n");
5907	websWrite(wp, "function claimed_disk_interface_names(){ return [];}\n\n");
5908	websWrite(wp, "function claimed_disk_model_info(){ return [];}\n\n");
5909	websWrite(wp, "function claimed_disk_total_size(){ return [];}\n\n");
5910	websWrite(wp, "function claimed_disk_total_mounted_number(){ return [];}\n\n");
5911	websWrite(wp, "function blank_disks(){ return [];}\n\n");
5912	websWrite(wp, "function blank_disk_interface_names(){ return [];}\n\n");
5913	websWrite(wp, "function blank_disk_model_info(){ return [];}\n\n");
5914	websWrite(wp, "function blank_disk_total_size(){ return [];}\n\n");
5915	websWrite(wp, "function blank_disk_total_mounted_number(){ return [];}\n\n");
5916
5917	disks_info = read_disk_data();
5918	if (disks_info == NULL){
5919		websWrite(wp, "%s", initial_available_disk_names_and_sizes());
5920		return -1;
5921	}
5922
5923	/* show name of the foreign disks */
5924	websWrite(wp, "function foreign_disks(){\n");
5925	websWrite(wp, "    return [");
5926	first = 1;
5927	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next){
5928		if (first == 1)
5929			first = 0;
5930		else
5931			websWrite(wp, ", ");
5932
5933		memset(ascii_tag, 0, PATH_MAX);
5934		char_to_ascii_safe(ascii_tag, follow_disk->tag, PATH_MAX);
5935		websWrite(wp, "\"%s\"", ascii_tag);
5936	}
5937	websWrite(wp, "];\n");
5938	websWrite(wp, "}\n\n");
5939
5940	/* show interface of the foreign disks */
5941	websWrite(wp, "function foreign_disk_interface_names(){\n");
5942	websWrite(wp, "    return [");
5943	first = 1;
5944	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next){
5945		if (first == 1)
5946			first = 0;
5947		else
5948			websWrite(wp, ", ");
5949
5950//		websWrite(wp, "\"USB\"");
5951		websWrite(wp, "\"%s\"", follow_disk->port);
5952	}
5953	websWrite(wp, "];\n");
5954	websWrite(wp, "}\n\n");
5955
5956	/* show model info of the foreign disks */
5957	websWrite(wp, "function foreign_disk_model_info(){\n");
5958	websWrite(wp, "    return [");
5959	first = 1;
5960	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next){
5961		if (first == 1)
5962			first = 0;
5963		else
5964			websWrite(wp, ", ");
5965
5966		websWrite(wp, "\"");
5967
5968		if (follow_disk->vendor != NULL){
5969			memset(ascii_vendor, 0, PATH_MAX);
5970			char_to_ascii_safe(ascii_vendor, follow_disk->vendor, PATH_MAX);
5971			websWrite(wp, "%s", ascii_vendor);
5972		}
5973		if (follow_disk->model != NULL){
5974			if (follow_disk->vendor != NULL)
5975				websWrite(wp, " ");
5976
5977			memset(ascii_model, 0, PATH_MAX);
5978			char_to_ascii_safe(ascii_model, follow_disk->model, PATH_MAX);
5979			websWrite(wp, "%s", ascii_model);
5980		}
5981		websWrite(wp, "\"");
5982	}
5983	websWrite(wp, "];\n");
5984	websWrite(wp, "}\n\n");
5985
5986	/* show total_size of the foreign disks */
5987	websWrite(wp, "function foreign_disk_total_size(){\n");
5988	websWrite(wp, "    return [");
5989	first = 1;
5990	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next){
5991		if (first == 1)
5992			first = 0;
5993		else
5994			websWrite(wp, ", ");
5995
5996		websWrite(wp, "\"%llu\"", follow_disk->size_in_kilobytes);
5997	}
5998	websWrite(wp, "];\n");
5999	websWrite(wp, "}\n\n");
6000
6001	/* show total number of the partitions in this foreign disk */
6002	websWrite(wp, "function foreign_disk_pool_number(){\n");
6003	websWrite(wp, "    return [");
6004	first = 1;
6005	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next){
6006		if (first == 1)
6007			first = 0;
6008		else
6009			websWrite(wp, ", ");
6010
6011		websWrite(wp, "\"%u\"", follow_disk->partition_number);
6012	}
6013	websWrite(wp, "];\n");
6014	websWrite(wp, "}\n\n");
6015
6016	/* show total number of the mounted partitions in this foreign disk */
6017	websWrite(wp, "function foreign_disk_total_mounted_number(){\n");
6018	websWrite(wp, "    return [");
6019	first = 1;
6020	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next){
6021		if (first == 1)
6022			first = 0;
6023		else
6024			websWrite(wp, ", ");
6025
6026		websWrite(wp, "\"%u\"", follow_disk->mounted_number);
6027	}
6028	websWrite(wp, "];\n");
6029	websWrite(wp, "}\n\n");
6030
6031	free_disk_data(&disks_info);
6032
6033	return 0;
6034}
6035
6036static int ej_get_printer_info(int eid, webs_t wp, int argc, char_t **argv){
6037	int printer_num, got_printer;
6038	char prefix[] = "usb_pathXXXXXXXXXXXXXXXXX_", tmp[100];
6039	char printer_array[MAX_USB_PRINTER_NUM][4][64];
6040	char usb_node[32];
6041	char port_path[8];
6042
6043	memset(printer_array, 0, MAX_USB_PRINTER_NUM*4*64);
6044
6045	for(printer_num = 0, got_printer = 0; printer_num < MAX_USB_PRINTER_NUM; ++printer_num){
6046		snprintf(prefix, sizeof(prefix), "usb_path_lp%d", printer_num);
6047		memset(usb_node, 0, 32);
6048		strncpy(usb_node, nvram_safe_get(prefix), 32);
6049
6050		if(strlen(usb_node) > 0){
6051			if(get_path_by_node(usb_node, port_path, 8) != NULL){
6052				snprintf(prefix, sizeof(prefix), "usb_path%s", port_path);
6053
6054				strncpy(printer_array[got_printer][0], nvram_safe_get(strcat_r(prefix, "_manufacturer", tmp)), 64);
6055				strncpy(printer_array[got_printer][1], nvram_safe_get(strcat_r(prefix, "_product", tmp)), 64);
6056				strncpy(printer_array[got_printer][2], nvram_safe_get(strcat_r(prefix, "_serial", tmp)), 64);
6057				strncpy(printer_array[got_printer][3], port_path, 64);
6058
6059				++got_printer;
6060			}
6061		}
6062	}
6063
6064	websWrite(wp, "function printer_manufacturers(){\n");
6065	websWrite(wp, "    return [");
6066
6067	for(printer_num = 0; printer_num < got_printer; ++printer_num){
6068		if(printer_num != 0)
6069			websWrite(wp, ", ");
6070
6071		if(strlen(printer_array[printer_num][0]) > 0)
6072			websWrite(wp, "\"%s\"", printer_array[printer_num][0]);
6073		else
6074			websWrite(wp, "\"\"");
6075	}
6076
6077	websWrite(wp, "];\n");
6078	websWrite(wp, "}\n\n");
6079
6080	websWrite(wp, "function printer_models(){\n");
6081	websWrite(wp, "    return [");
6082
6083	for(printer_num = 0; printer_num < got_printer; ++printer_num){
6084		if(printer_num != 0)
6085			websWrite(wp, ", ");
6086
6087		if(strlen(printer_array[printer_num][1]) > 0)
6088			websWrite(wp, "\"%s\"", printer_array[printer_num][1]);
6089		else
6090			websWrite(wp, "\"\"");
6091	}
6092
6093	websWrite(wp, "];\n");
6094	websWrite(wp, "}\n\n");
6095
6096	websWrite(wp, "function printer_serialn(){\n");
6097	websWrite(wp, "    return [");
6098
6099	for(printer_num = 0; printer_num < got_printer; ++printer_num){
6100		if(printer_num != 0)
6101			websWrite(wp, ", ");
6102
6103		if(strlen(printer_array[printer_num][2]) > 0)
6104			websWrite(wp, "\"%s\"", printer_array[printer_num][2]);
6105		else
6106			websWrite(wp, "\"\"");
6107	}
6108
6109	websWrite(wp, "];\n");
6110	websWrite(wp, "}\n\n");
6111
6112	websWrite(wp, "function printer_pool(){\n");
6113	websWrite(wp, "    return [");
6114
6115	for(printer_num = 0; printer_num < got_printer; ++printer_num){
6116		if(printer_num != 0)
6117			websWrite(wp, ", ");
6118
6119		if(strlen(printer_array[printer_num][3]) > 0)
6120			websWrite(wp, "\"%s\"", printer_array[printer_num][3]);
6121		else
6122			websWrite(wp, "\"\"");
6123	}
6124
6125	websWrite(wp, "];\n");
6126	websWrite(wp, "}\n\n");
6127
6128	return 0;
6129}
6130
6131static long old_uptime = 0;
6132
6133static int ej_get_modem_info(int eid, webs_t wp, int argc, char_t **argv){
6134	int i, j, got_modem;
6135	char prefix[] = "usb_pathXXXXXXXXXXXXXXXXX_", tmp[100];
6136#ifdef RTCONFIG_INTERNAL_GOBI
6137	char modem_array[MAX_USB_PORT*MAX_USB_HUB_PORT][6][64];
6138#else
6139	char modem_array[MAX_USB_PORT*MAX_USB_HUB_PORT][4][64];
6140#endif
6141	char port_path[8];
6142	char act_node[32], act_port_path[8];
6143	long now;
6144#ifdef RTCONFIG_INTERNAL_GOBI
6145	char *cmd_sig[] = {"/usr/sbin/modem_status.sh", "signal", NULL};
6146	char *cmd_op[] = {"/usr/sbin/modem_status.sh", "operation", NULL};
6147	int pid;
6148#endif
6149
6150	snprintf(act_node, 32, "%s", nvram_safe_get("usb_modem_act_path"));
6151	if(strlen(act_node) <= 0 || get_path_by_node(act_node, act_port_path, 8) == NULL){
6152		memset(act_port_path, 0, 8);
6153		old_uptime = 0;
6154	}
6155	else{
6156		now = uptime();
6157		if(!old_uptime || now-old_uptime >= 60){
6158#ifdef RTCONFIG_INTERNAL_GOBI
6159_dprintf("httpd: run modem_status.sh.\n");
6160#if 0
6161			_eval(cmd_sig, NULL, 0, &pid);
6162			_eval(cmd_op, NULL, 0, &pid);
6163#else
6164			eval("/usr/sbin/modem_status.sh", "signal");
6165			eval("/usr/sbin/modem_status.sh", "operation");
6166#endif
6167#endif
6168			old_uptime = now;
6169		}
6170	}
6171
6172#ifdef RTCONFIG_INTERNAL_GOBI
6173	memset(modem_array, 0, MAX_USB_PORT*MAX_USB_HUB_PORT*6*64);
6174#else
6175	memset(modem_array, 0, MAX_USB_PORT*MAX_USB_HUB_PORT*4*64);
6176#endif
6177
6178	got_modem = 0;
6179	for(i = 1; i <= MAX_USB_PORT; ++i){
6180		snprintf(prefix, sizeof(prefix), "usb_path%d", i);
6181		if(!strcmp(nvram_safe_get(prefix), "modem")){
6182			snprintf(port_path, 8, "%d", i);
6183
6184			strncpy(modem_array[got_modem][0], nvram_safe_get(strcat_r(prefix, "_manufacturer", tmp)), 64);
6185			strncpy(modem_array[got_modem][1], nvram_safe_get(strcat_r(prefix, "_product", tmp)), 64);
6186			strncpy(modem_array[got_modem][2], nvram_safe_get(strcat_r(prefix, "_serial", tmp)), 64);
6187			strncpy(modem_array[got_modem][3], port_path, 64);
6188#ifdef RTCONFIG_INTERNAL_GOBI
6189			if(!strcmp(port_path, act_port_path)){
6190				strncpy(modem_array[got_modem][4], nvram_safe_get("usb_modem_act_signal"), 64);
6191				strncpy(modem_array[got_modem][5], nvram_safe_get("usb_modem_act_operation"), 64);
6192			}
6193#endif
6194
6195			++got_modem;
6196		}
6197		else{
6198			for(j = 1; j <= MAX_USB_HUB_PORT; ++j){
6199				snprintf(prefix, sizeof(prefix), "usb_path%d.%d", i, j);
6200
6201				if(!strcmp(nvram_safe_get(prefix), "modem")){
6202					snprintf(port_path, 8, "%d.%d", i, j);
6203
6204					strncpy(modem_array[got_modem][0], nvram_safe_get(strcat_r(prefix, "_manufacturer", tmp)), 64);
6205					strncpy(modem_array[got_modem][1], nvram_safe_get(strcat_r(prefix, "_product", tmp)), 64);
6206					strncpy(modem_array[got_modem][2], nvram_safe_get(strcat_r(prefix, "_serial", tmp)), 64);
6207					strncpy(modem_array[got_modem][3], port_path, 64);
6208#ifdef RTCONFIG_INTERNAL_GOBI
6209					if(!strcmp(port_path, act_port_path)){
6210						strncpy(modem_array[got_modem][4], nvram_safe_get("usb_modem_act_signal"), 64);
6211						strncpy(modem_array[got_modem][5], nvram_safe_get("usb_modem_act_operation"), 64);
6212					}
6213#endif
6214
6215					++got_modem;
6216				}
6217			}
6218		}
6219	}
6220
6221	websWrite(wp, "function modem_manufacturers(){\n");
6222	websWrite(wp, "    return [");
6223
6224	for(i = 0; i < got_modem; ++i){
6225		if(i != 0)
6226			websWrite(wp, ", ");
6227
6228		if(strlen(modem_array[i][0]) > 0)
6229			websWrite(wp, "\"%s\"", modem_array[i][0]);
6230		else
6231			websWrite(wp, "\"\"");
6232	}
6233
6234	websWrite(wp, "];\n");
6235	websWrite(wp, "}\n\n");
6236
6237	websWrite(wp, "function modem_models(){\n");
6238	websWrite(wp, "    return [");
6239
6240	for(i = 0; i < got_modem; ++i){
6241		if(i != 0)
6242			websWrite(wp, ", ");
6243
6244		if(strlen(modem_array[i][1]) > 0)
6245			websWrite(wp, "\"%s\"", modem_array[i][1]);
6246		else
6247			websWrite(wp, "\"\"");
6248	}
6249
6250	websWrite(wp, "];\n");
6251	websWrite(wp, "}\n\n");
6252
6253	websWrite(wp, "function modem_serialn(){\n");
6254	websWrite(wp, "    return [");
6255
6256	for(i = 0; i < got_modem; ++i){
6257		if(i != 0)
6258			websWrite(wp, ", ");
6259
6260		if(strlen(modem_array[i][2]) > 0)
6261			websWrite(wp, "\"%s\"", modem_array[i][2]);
6262		else
6263			websWrite(wp, "\"\"");
6264	}
6265
6266	websWrite(wp, "];\n");
6267	websWrite(wp, "}\n\n");
6268
6269	websWrite(wp, "function modem_pool(){\n");
6270	websWrite(wp, "    return [");
6271
6272	for(i = 0; i < got_modem; ++i){
6273		if(i != 0)
6274			websWrite(wp, ", ");
6275
6276		if(strlen(modem_array[i][3]) > 0)
6277			websWrite(wp, "\"%s\"", modem_array[i][3]);
6278		else
6279			websWrite(wp, "\"\"");
6280	}
6281
6282	websWrite(wp, "];\n");
6283	websWrite(wp, "}\n\n");
6284
6285#ifdef RTCONFIG_INTERNAL_GOBI
6286	websWrite(wp, "function modem_signal(){\n");
6287	websWrite(wp, "    return [");
6288
6289	for(i = 0; i < got_modem; ++i){
6290		if(i != 0)
6291			websWrite(wp, ", ");
6292
6293		if(strlen(modem_array[i][4]) > 0)
6294			websWrite(wp, "\"%s\"", modem_array[i][4]);
6295		else
6296			websWrite(wp, "\"\"");
6297	}
6298
6299	websWrite(wp, "];\n");
6300	websWrite(wp, "}\n\n");
6301
6302	websWrite(wp, "function modem_operation(){\n");
6303	websWrite(wp, "    return [");
6304
6305	for(i = 0; i < got_modem; ++i){
6306		if(i != 0)
6307			websWrite(wp, ", ");
6308
6309		if(strlen(modem_array[i][5]) > 0)
6310			websWrite(wp, "\"%s\"", modem_array[i][5]);
6311		else
6312			websWrite(wp, "\"\"");
6313	}
6314
6315	websWrite(wp, "];\n");
6316	websWrite(wp, "}\n\n");
6317#endif
6318
6319	return 0;
6320}
6321#if 0
6322static int modem_simstatus_hook(int eid, webs_t wp, int argc, char_t **argv){//Cherry Cho added in 2014/9/4.
6323#ifdef RTCONFIG_INTERNAL_GOBI
6324	char act_node[32], act_port_path[8];
6325	char *cmd_simsignal[] = {"modem_status.sh", "signal", NULL};
6326	char *cmd_simop[] = {"modem_status.sh", "operation", NULL};
6327	char *cmd_simbytes[] = {"modem_status.sh", "bytes", NULL};
6328	float rx_Gbytes, tx_Gbytes;
6329	int pid2, pid3, pid4;
6330
6331	snprintf(act_node, 32, "%s", nvram_safe_get("usb_modem_act_path"));
6332	if(strlen(act_node) <= 0 || get_path_by_node(act_node, act_port_path, 8) == NULL){
6333		return 0;
6334	}
6335
6336	_eval(cmd_simsignal, NULL, 0, &pid2);
6337	_eval(cmd_simop, NULL, 0, &pid3);
6338	_eval(cmd_simbytes, NULL, 0, &pid4);
6339#endif
6340	return 0;
6341}
6342
6343static int ej_check_modem_sim(int eid, webs_t wp, int argc, char_t **argv){
6344	char act_node[32], act_port_path[8];
6345	int status;
6346
6347	snprintf(act_node, 32, "%s", nvram_safe_get("usb_modem_act_path"));
6348	if(strlen(act_node) <= 0 || get_path_by_node(act_node, act_port_path, 8) == NULL){
6349		return 0;
6350	}
6351
6352	status = nvram_get_int("usb_modem_act_sim");
6353	websWrite(wp, "%d", status);
6354
6355	return 0;
6356}
6357#endif
6358static int ej_get_isp_scan_results(int eid, webs_t wp, int argc, char_t **argv){
6359#ifdef RTCONFIG_INTERNAL_GOBI
6360	char file_name[MAX_LINE_SIZE];
6361	int ret = 0;
6362
6363	memset(file_name, 0, MAX_LINE_SIZE);
6364	sprintf(file_name, "%s", nvram_safe_get("modem_roaming_scanlist"));
6365	if(strlen(file_name) >= 0)
6366		ret = dump_file(wp, file_name);
6367
6368	return ret;
6369#endif
6370	return 0;
6371}
6372
6373static int ej_get_simact_result(int eid, webs_t wp, int argc, char_t **argv){
6374#ifdef RTCONFIG_INTERNAL_GOBI
6375	char act_node[32], act_port_path[8];
6376	FILE *fp;
6377	char buf[256];
6378	int len = 0;
6379
6380	snprintf(act_node, 32, "%s", nvram_safe_get("usb_modem_act_path"));
6381	if(strlen(act_node) <= 0 || get_path_by_node(act_node, act_port_path, 8) == NULL){
6382		return 0;
6383	}
6384
6385	if ((fp = fopen("/tmp/modem_action.ret", "r")) != NULL) {
6386		while(fgets(buf, sizeof(buf), fp) != NULL){
6387			len = strlen(buf) - 1;
6388			if(len > 0){
6389				if(buf[len] == '\n' || buf[len] == '\r')
6390					buf[len] = '\0';
6391				websWrite(wp, buf);
6392				break;
6393			}
6394		}
6395		fclose(fp);
6396	}
6397#endif
6398	return 0;
6399}
6400
6401static int ej_modemuptime(int eid, webs_t wp, int argc, char_t **argv){
6402	int ret = 0;
6403	unsigned int now, start = atoi(nvram_safe_get("usb_modem_act_startsec"));
6404	char *str;
6405
6406	if(start <= 0){
6407		ret = websWrite(wp, "0");
6408		return ret;
6409	}
6410
6411	str = file2str("/proc/uptime");
6412	if(!str){
6413		ret = websWrite(wp, "0");
6414		return ret;
6415	}
6416
6417	now = atoi(str);
6418	free(str);
6419
6420	ret = websWrite(wp, "%u", (now-start));
6421
6422	return ret;
6423}
6424
6425#else
6426static int ej_show_usb_path(int eid, webs_t wp, int argc, char_t **argv){
6427	websWrite(wp, "[]");
6428	return 0;
6429}
6430
6431int ej_apps_fsck_ret(int eid, webs_t wp, int argc, char **argv){
6432	websWrite(wp, "[]");
6433	return 0;
6434}
6435#endif
6436
6437int ej_shown_language_css(int eid, webs_t wp, int argc, char **argv){
6438	struct language_table *pLang = NULL;
6439	char lang[4];
6440	int len;
6441#ifdef RTCONFIG_AUTODICT
6442	unsigned char header[3] = { 0xef, 0xbb, 0xbf };
6443	FILE *fp = fopen("Lang_Hdr.txt", "r");
6444#else
6445	FILE *fp = fopen("Lang_Hdr", "r");
6446#endif
6447	char buffer[1024], key[30], target[30];
6448	char *follow_info, *follow_info_end;
6449	int offset = 0;
6450
6451	if (fp == NULL){
6452		fprintf(stderr, "No English dictionary!\n");
6453		return 0;
6454	}
6455
6456	memset(lang, 0, 4);
6457	strcpy(lang, nvram_safe_get("preferred_lang"));
6458	if(!strncmp(nvram_safe_get("territory_code"), "JP", 2) && strcmp(nvram_safe_get("ATEMODE"), "1")){
6459		websWrite(wp, "<li style=\"visibility:hidden;\"><dl><a href=\"#\"><dt id=\"selected_lang\"></dt></a>\\n");
6460	}
6461	else{
6462		websWrite(wp, "<li><dl><a href=\"#\"><dt id=\"selected_lang\"></dt></a>\\n");
6463		while (1) {
6464			memset(buffer, 0, sizeof(buffer));
6465			if ((follow_info = fgets(buffer, sizeof(buffer), fp)) != NULL){
6466	#ifdef RTCONFIG_AUTODICT
6467				if (memcmp(buffer, header, 3) == 0) offset = 3;
6468	#endif
6469				if (strncmp(follow_info+offset, "LANG_", 5))    // 5 = strlen("LANG_")
6470					continue;
6471
6472				follow_info += 5;
6473				follow_info_end = strstr(follow_info, "=");
6474				len = follow_info_end-follow_info;
6475				memset(key, 0, sizeof(key));
6476				strncpy(key, follow_info, len);
6477
6478				for (pLang = language_tables; pLang->Lang != NULL; ++pLang){
6479					if (strcmp(key, pLang->Target_Lang))
6480						continue;
6481					follow_info = follow_info_end+1;
6482					follow_info_end = strstr(follow_info, "\n");
6483					len = follow_info_end-follow_info;
6484					memset(target, 0, sizeof(target));
6485					strncpy(target, follow_info, len);
6486					if (check_lang_support(key) && strcmp(key,lang))
6487						websWrite(wp, "<dd><a onclick=\"submit_language(this)\" id=\"%s\">%s</a></dd>\\n", key, target);
6488					break;
6489				}
6490			}
6491			else
6492				break;
6493
6494		}
6495	}
6496
6497	websWrite(wp, "</dl></li>\\n");
6498	fclose(fp);
6499
6500	return 0;
6501}
6502
6503//andi
6504char*
6505send_action(char *ftp_url,int port)
6506{
6507        char str[1024]={0};
6508        char buf[1024]={0};
6509	int my_fd;
6510	if ((my_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
6511            perror("socket");
6512            return NULL;
6513        }
6514
6515        struct sockaddr_in their_addr; /* connector's address information */
6516        bzero(&(their_addr), sizeof(their_addr)); /* zero the rest of the struct */
6517        their_addr.sin_family = AF_INET; /* host byte order */
6518        their_addr.sin_port = htons(port); /* short, network byte order */
6519        their_addr.sin_addr.s_addr = INADDR_ANY;
6520        //their_addr.sin_addr.s_addr = ((struct in_addr *)(he->h_addr))->s_addr;
6521        bzero(&(their_addr.sin_zero), sizeof(their_addr.sin_zero)); /* zero the rest of the struct */
6522
6523        if (connect(my_fd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == -1) {
6524            perror("connect");
6525	    close(my_fd);
6526            return NULL;
6527        }
6528        sprintf(str,"refresh@%s",ftp_url);
6529	_dprintf("socket:%s\n",str);
6530        if (send(my_fd, str, strlen(str), 0) == -1) {
6531            perror("send");
6532	    close(my_fd);
6533            return NULL;
6534        }
6535
6536	int len;
6537	while ((len = recv(my_fd, buf, 1024, 0))) {
6538        	//_dprintf("BUF:%s\n",buf);
6539		close(my_fd);
6540		return strdup(buf);
6541    	}
6542
6543        close(my_fd);
6544	return NULL;
6545}
6546
6547//andi
6548static int
6549ftpServerTree_cgi(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
6550		char_t *url, char_t *path, char_t *query)
6551{
6552        char *ftp_url;
6553        ftp_url = websGetVar(wp, "path","");
6554    	_dprintf("URL:%s\n",ftp_url);
6555
6556        char *buf = send_action(ftp_url,3568);
6557	_dprintf("BUF:%s\n",buf);
6558	if(buf == NULL)
6559	{
6560		websWrite(wp,"NULL");
6561		return 0;
6562	}
6563	else
6564		websWrite(wp,buf);
6565
6566        return 0;
6567}
6568
6569#ifdef  __CONFIG_NORTON__
6570/* Trigger an NGA LiveUpdate (linux/netbsd - no support for ECOS) */
6571static int
6572nga_update(void)
6573{
6574	char *str = NULL;
6575	int pid;
6576
6577	if ((str = file2str("/var/run/bootstrap.pid"))) {
6578		pid = atoi(str);
6579		free(str);
6580		return kill(pid, SIGHUP);
6581	}
6582
6583	return -1;
6584}
6585#endif /* __CONFIG_NORTON__ */
6586
6587void
6588json_unescape(char *s)
6589{
6590	unsigned int c;
6591
6592	while ((s = strpbrk(s, "%+"))) {
6593		/* Parse %xx */
6594		if (*s == '%') {
6595			sscanf(s + 1, "%02x", &c);
6596			*s++ = (char) c;
6597			strncpy(s, s + 2, strlen(s) + 1);
6598		}
6599		/* Space is special */
6600		else if (*s == '+')
6601			*s++ = ' ';
6602	}
6603}
6604
6605void
6606decode_json_buffer(char *query)
6607{
6608	int len;
6609	char *q, *name, *value;
6610
6611	/* Clear variables */
6612	if (!query) {
6613		//hdestroy_r(&htab);
6614		return;
6615	}
6616
6617	/* Parse into individual assignments */
6618	q = query;
6619	len = strlen(query);
6620
6621	for (q = query; q < (query + len);) {
6622		/* Unescape each assignment */
6623		json_unescape(name = value = q);
6624
6625		/* Skip to next assignment */
6626		for (q += strlen(q); q < (query + len) && !*q; q++);
6627	}
6628}
6629
6630static int
6631apply_cgi(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
6632		char_t *url, char_t *path, char_t *query)
6633{
6634	char *action_mode;
6635	char *action_para;
6636	char *current_url;
6637	char command[32];
6638	int i=0, j=0, len=0;
6639
6640	struct json_object *root=NULL;
6641
6642	if(!strcmp(url, "applyapp.cgi")){
6643		decode_json_buffer(post_json_buf);
6644		root = json_tokener_parse(post_json_buf);
6645		if (!root) {
6646			//return 0; /* Aicloud app can not use JSON format */
6647		}
6648	}
6649
6650	action_mode = get_cgi_json("action_mode", root);
6651	current_url = get_cgi_json("current_page", root);
6652	_dprintf("apply: %s %s\n", action_mode, current_url);
6653
6654	if(!action_mode){
6655		_dprintf("action_mode get null\n");
6656		return 1;
6657	}
6658
6659	if (!strcmp(action_mode, "apply")) {
6660		if (!validate_apply(wp,root)) {
6661			websWrite(wp, "NOT MODIFIED\n");
6662		}
6663		else {
6664			websWrite(wp, "MODIFIED\n");
6665		}
6666
6667		action_para = get_cgi_json("rc_service",root);
6668
6669		if(action_para && strlen(action_para) > 0) {
6670			notify_rc(action_para);
6671		}
6672		websWrite(wp, "RUN SERVICE\n");
6673	}
6674	else if (!strcmp(action_mode," Refresh "))
6675	{
6676		char *system_cmd;
6677		system_cmd = get_cgi_json("SystemCmd",root);
6678		len = strlen(system_cmd);
6679
6680		for(i=0;i<len;i++){
6681			if (isalnum(system_cmd[i]) != 0 || system_cmd[i] == ':' || system_cmd[i] == '-' || system_cmd[i] == '_' || system_cmd[i] == '.' || isspace(system_cmd[i]) != 0)
6682				j++;
6683			else{
6684				_dprintf("[httpd] Invalid SystemCmd!\n");
6685				strcpy(SystemCmd, "");
6686
6687				json_object_put(root);
6688				websRedirect_iframe(wp, current_url);
6689
6690				return 0;
6691			}
6692		}
6693		if(!strcmp(current_url, "Main_Netstat_Content.asp") && (
6694			strncasecmp(system_cmd, "netstat", 7) == 0
6695		)){
6696			strncpy(SystemCmd, system_cmd, sizeof(SystemCmd));
6697		}
6698		else if(!strcmp(current_url, "Main_Analysis_Content.asp") && (
6699			   strncasecmp(system_cmd, "ping", 4) == 0
6700			|| strncasecmp(system_cmd, "traceroute", 10) == 0
6701			|| strncasecmp(system_cmd, "nslookup", 8) == 0
6702		)){
6703			strncpy(SystemCmd, system_cmd, sizeof(SystemCmd));
6704		}
6705		else if(!strcmp(current_url, "Main_WOL_Content.asp") && (
6706			strncasecmp(system_cmd, "ether-wake", 10) == 0
6707		)){
6708			strncpy(SystemCmd, system_cmd, sizeof(SystemCmd));
6709			sys_script("syscmd.sh");
6710		}
6711		else if(!strcmp(current_url, "Main_AdmStatus_Content.asp"))
6712		{
6713			if(strncasecmp(system_cmd, "run_telnetd", 11) == 0){
6714				strncpy(SystemCmd, system_cmd, sizeof(SystemCmd));
6715				sys_script("syscmd.sh");
6716			}else if(strncasecmp(system_cmd, "run_infosvr", 11) == 0){
6717				nvram_set("ateCommand_flag", "1");
6718			}else if(strncasecmp(system_cmd, "set_factory_mode", 16) == 0){
6719				strncpy(SystemCmd, system_cmd, sizeof(SystemCmd));
6720				sys_script("syscmd.sh");
6721			}
6722		}
6723		else{
6724			_dprintf("[httpd] Invalid SystemCmd!\n");
6725			strcpy(SystemCmd, "");
6726		}
6727		json_object_put(root);
6728		websRedirect_iframe(wp, current_url);
6729		return 0;
6730	}
6731	else if (!strcmp(action_mode," Clear "))
6732	{
6733		unlink(get_syslog_fname(1));
6734		unlink(get_syslog_fname(0));
6735		websRedirect(wp, current_url);
6736		json_object_put(root);
6737		return 0;
6738	}
6739	else if (!strcmp(action_mode, " Restart ")||!strcmp(action_mode, "reboot"))
6740	{
6741		websApply(wp, "Restarting.asp");
6742		nvram_set("freeze_duck", "15");
6743		shutdown(fileno(wp), SHUT_RDWR);
6744		sys_reboot();
6745		json_object_put(root);
6746		return (0);
6747	}
6748	else if (!strcmp(action_mode, "Restore")||!strcmp(action_mode, "restore"))
6749	{
6750		int offset = 10;
6751#ifdef RTCONFIG_RALINK
6752		if (get_model() == MODEL_RTN65U)
6753			offset = 15;
6754#endif
6755
6756		/* Stop USB application prior to counting reboot_time.
6757		 * Don't stop 3G/4G here.  If yes and end-user connect to
6758		 * administrative page through 3G/4G, he/she can't see Restarting.asp
6759		 */
6760		if (!notify_rc_and_wait_2min("stop_app"))
6761			_dprintf("%s: send stop_app rc_service fail!\n", __func__);
6762
6763		/* Enlarge reboot_time temporarily. */
6764		nvram_set_int("reboot_time", nvram_get_int("reboot_time") + offset);
6765
6766		eval("/sbin/ejusb", "-1", "0");
6767
6768		nvram_set("lan_ipaddr", "192.168.1.1");
6769		websApply(wp, "Restarting.asp");
6770		shutdown(fileno(wp), SHUT_RDWR);
6771		nvram_set("restore_defaults", "1");
6772		nvram_set("freeze_duck", "15");
6773		sys_default();
6774		json_object_put(root);
6775		return (0);
6776	}
6777	else if (!strcmp(action_mode, "logout")) // but, every one can reset it by this call
6778	{
6779		http_logout(0, "cgi_logout", 0);
6780		websRedirect(wp, "Nologin.asp");
6781		json_object_put(root);
6782		return (0);
6783	}
6784	else if (!strcmp(action_mode, "change_wl_unit"))
6785	{
6786		action_para = get_cgi_json("wl_unit",root);
6787
6788		if(action_para)
6789			nvram_set("wl_unit", action_para);
6790
6791		action_para = get_cgi_json("wl_subunit",root);
6792
6793		if(action_para)
6794			nvram_set("wl_subunit", action_para);
6795
6796		websRedirect(wp, current_url);
6797	}
6798	else if (!strcmp(action_mode, "change_wps_unit"))
6799	{
6800		action_para = get_cgi_json("wps_band",root);
6801		if(action_para)
6802			nvram_set("wps_band", action_para);
6803#if defined(RTCONFIG_WPSMULTIBAND)
6804		if ((action_para = get_cgi_json("wps_multiband",root)))
6805			nvram_set("wps_multiband", action_para);
6806#endif
6807
6808		websRedirect(wp, current_url);
6809	}
6810	else if (!strcmp(action_mode, "wps_apply"))
6811	{
6812		action_para = get_cgi_json("wps_band",root);
6813		if(action_para)
6814			nvram_set("wps_band", action_para);
6815		else goto wps_finish;
6816
6817		action_para = get_cgi_json("wps_enable",root);
6818		if(action_para)
6819			nvram_set("wps_enable", action_para);
6820		else goto wps_finish;
6821
6822		action_para = get_cgi_json("wps_sta_pin",root);
6823		if(action_para)
6824			nvram_set("wps_sta_pin", action_para);
6825		else goto wps_finish;
6826#if defined(RTCONFIG_WPSMULTIBAND)
6827		if ((action_para = get_cgi_json("wps_multiband",root)))
6828			nvram_set("wps_multiband", action_para);
6829#endif
6830
6831#ifdef RTCONFIG_WIFI_CLONE
6832		nvram_set("wps_enrollee", "0");
6833#endif
6834
6835		notify_rc("start_wps_method");
6836
6837wps_finish:
6838		websRedirect(wp, current_url);
6839	}
6840	else if (!strcmp(action_mode, "wps_reset"))
6841	{
6842		action_para = get_cgi_json("wps_band",root);
6843		if(action_para)
6844			nvram_set("wps_band", action_para);
6845#if defined(RTCONFIG_WPSMULTIBAND)
6846		if ((action_para = get_cgi_json("wps_multiband",root)))
6847			nvram_set("wps_multiband", action_para);
6848#endif
6849
6850		notify_rc("reset_wps");
6851
6852		websRedirect(wp, current_url);
6853	}
6854	else if (!strcmp(action_mode, "change_wan_unit"))
6855	{
6856		action_para = get_cgi_json("wan_unit", root);
6857
6858		if(action_para)
6859			nvram_set("wan_unit", action_para);
6860
6861		websRedirect(wp, current_url);
6862	}
6863	else if (!strcmp(action_mode, "change_dslx_transmode"))
6864	{
6865		action_para = get_cgi_json("dsltmp_transmode", root);
6866
6867		if(action_para)
6868			nvram_set("dsltmp_transmode", action_para);
6869
6870		websRedirect(wp, current_url);
6871	}
6872	else if (!strcmp(action_mode, "change_lan_unit"))
6873	{
6874		action_para = get_cgi_json("lan_unit",root);
6875
6876		if(action_para)
6877			nvram_set("lan_unit", action_para);
6878
6879		websRedirect(wp, current_url);
6880	}
6881	else if (!strcmp(action_mode, "refresh_networkmap"))
6882	{
6883		nvram_set("client_info_tmp", "");
6884		nvram_set("refresh_networkmap", "1");
6885
6886		doSystem("killall -%d networkmap", SIGUSR1);
6887#ifdef RTCONFIG_JFFS2USERICON
6888		notify_rc("start_lltdc");
6889#endif
6890#ifdef RTCONFIG_UPNPC
6891		notify_rc("start_miniupnpc");
6892#endif
6893		websRedirect(wp, current_url);
6894	}
6895        else if (!strcmp(action_mode, "update_client_list"))
6896        {
6897                action_para = get_cgi_json("client_info_tmp", root);
6898                if(action_para)
6899                        nvram_set("client_info_tmp", action_para);
6900
6901                doSystem("killall -%d networkmap", SIGUSR1);
6902
6903		websDone(wp, 200);
6904                //websRedirect(wp, current_url);
6905        }
6906	else if (!strcmp(action_mode, "restore_module"))
6907	{
6908		action_para = get_cgi_json("module_prefix",root);
6909		if(action_para) {
6910			sprintf(command, "restore %s", action_para);
6911			notify_rc(command);
6912		}
6913		websRedirect(wp, current_url);
6914	}
6915	else if (!strcmp(action_mode, "mfp_requeue")){
6916		unsigned int login_ip = (unsigned int)atoll(nvram_safe_get("login_ip"));
6917
6918		if (login_ip == 0x100007f || login_ip == 0x0)
6919			nvram_set("mfp_ip_requeue", "");
6920		else{
6921			struct in_addr addr;
6922
6923			addr.s_addr = login_ip;
6924			nvram_set("mfp_ip_requeue", inet_ntoa(addr));
6925		}
6926
6927		int u2ec_fifo = open("/var/u2ec_fifo", O_WRONLY|O_NONBLOCK);
6928
6929		write(u2ec_fifo, "q", 1);
6930		close(u2ec_fifo);
6931
6932		websRedirect(wp, current_url);
6933	}
6934	else if (!strcmp(action_mode, "mfp_monopolize")){
6935		unsigned int login_ip = (unsigned int)atoll(nvram_safe_get("login_ip"));
6936
6937		//printf("[httpd] run mfp monopolize\n");	// tmp test
6938		if (login_ip==0x100007f || login_ip==0x0)
6939			nvram_set("mfp_ip_monopoly", "");
6940		else
6941		{
6942			struct in_addr addr;
6943			addr.s_addr=login_ip;
6944			nvram_set("mfp_ip_monopoly", inet_ntoa(addr));
6945		}
6946		int u2ec_fifo = open("/var/u2ec_fifo", O_WRONLY|O_NONBLOCK);
6947		write(u2ec_fifo, "m", 1);
6948		close(u2ec_fifo);
6949
6950		websRedirect(wp, current_url);
6951	}
6952#ifdef ASUS_DDNS //2007.03.22 Yau add
6953	else if (!strcmp(action_mode, "ddnsclient"))
6954	{
6955		notify_rc("restart_ddns");
6956
6957		websRedirect(wp, current_url);
6958	}
6959	else if (!strcmp(action_mode, "ddns_hostname_check"))
6960	{
6961		notify_rc("ddns_hostname_check");
6962
6963		websRedirect(wp, current_url);
6964	}
6965#endif
6966#ifdef RTCONFIG_TRAFFIC_METER
6967	else if (!strcmp(action_mode, "reset_traffic_meter"))
6968	{
6969		printf("@@@ RESET Traffic Meter!!!\n");
6970		doSystem("killall -%d wanduck", SIGTSTP);
6971/*
6972		if (!validate_apply(wp)) {
6973			websWrite(wp, "NOT MODIFIED\n");
6974		}
6975		else {
6976			websWrite(wp, "MODIFIED\n");
6977		}
6978*/
6979		websRedirect(wp, current_url);
6980	}
6981#endif
6982//#ifdef RTCONFIG_CLOUDSYNC // get share link from lighttpd. Jerry5 added 2012.11.08
6983	else if (!strcmp(action_mode, "get_sharelink"))
6984	{
6985		FILE *fp;
6986		char buf[256];
6987		pid_t pid = 0;
6988
6989		action_para = get_cgi_json("share_link_param", root);
6990		if(action_para){
6991			nvram_set("share_link_param", action_para);
6992			nvram_set("share_link_result", "");
6993		}
6994
6995		action_para = get_cgi_json("share_link_host", root);
6996		if(action_para){
6997			nvram_set("share_link_host", action_para);
6998			nvram_commit();
6999		}
7000
7001		if ((fp = fopen("/tmp/lighttpd/lighttpd.pid", "r")) != NULL) {
7002			if (fgets(buf, sizeof(buf), fp) != NULL)
7003		   	pid = strtoul(buf, NULL, 0);
7004			fclose(fp);
7005			if (pid > 1 && kill(pid, SIGUSR2) == 0) {
7006				printf("[HTTPD] Signaling lighttpd OK!\n");
7007			}
7008			else{
7009				printf("[HTTPD] Signaling lighttpd FAIL!\n");
7010			}
7011		}
7012	}
7013//#endif
7014#ifdef RTCONFIG_OPENVPN
7015	else if (!strcmp(action_mode, "change_vpn_server_unit"))
7016	{
7017		action_para = get_cgi_json("vpn_server_unit", root);
7018
7019		if(action_para)
7020			nvram_set("vpn_server_unit", action_para);
7021
7022		websRedirect(wp, current_url);
7023	}
7024	else if (!strcmp(action_mode, "change_vpn_client_unit"))
7025	{
7026		action_para = get_cgi_json("vpn_client_unit", root);
7027
7028		if(action_para)
7029			nvram_set("vpn_client_unit", action_para);
7030
7031		websRedirect(wp, current_url);
7032	}
7033#endif
7034#ifdef  __CONFIG_NORTON__
7035	/* Trigger an NGA LiveUpdate */
7036	else if (!strcmp(action_mode, "NGAUpdate"))
7037		websWrite(wp, "Invoking LiveUpdate...");
7038		if (nga_update())
7039			websWrite(wp, "error<br>");
7040		else
7041			websWrite(wp, "done<br>");
7042	}
7043#endif /* __CONFIG_NORTON__ */
7044#ifdef RTCONFIG_INTERNAL_GOBI
7045	else if (!strcmp(action_mode, "scan_isp"))
7046	{
7047		char act_node[32], act_port_path[8];
7048
7049		snprintf(act_node, 32, "%s", nvram_safe_get("usb_modem_act_path"));
7050		if(strlen(act_node) <= 0 || get_path_by_node(act_node, act_port_path, 8) == NULL){
7051			json_object_put(root);
7052			return 0;
7053		}
7054
7055		notify_rc("start_modemscan");
7056	}
7057	else if (!strcmp(action_mode, "start_lockpin") || !strcmp(action_mode, "stop_lockpin"))
7058	{
7059		char act_node[32], act_port_path[8];
7060		char *pincode;
7061
7062		pincode = get_cgi_json("sim_pincode", root);
7063
7064		snprintf(act_node, 32, "%s", nvram_safe_get("usb_modem_act_path"));
7065		if(strlen(act_node) <= 0 || get_path_by_node(act_node, act_port_path, 8) == NULL){
7066			json_object_put(root);
7067			return 0;
7068		}
7069
7070		sprintf(command, "%s %s", action_mode, pincode);
7071		notify_rc(command);
7072	}
7073	else if (!strcmp(action_mode, "start_pwdpin"))
7074	{
7075		char act_node[32], act_port_path[8];
7076		char *pincode, *newpin;
7077
7078		pincode = get_cgi_json("sim_pincode", root);
7079		newpin = get_cgi_json("sim_newpin", root);
7080
7081		snprintf(act_node, 32, "%s", nvram_safe_get("usb_modem_act_path"));
7082		if(strlen(act_node) <= 0 || get_path_by_node(act_node, act_port_path, 8) == NULL){
7083			json_object_put(root);
7084			return 0;
7085		}
7086
7087		sprintf(command, "%s %s %s", action_mode, pincode, newpin);
7088		notify_rc(command);
7089	}
7090	else if (!strcmp(action_mode, "start_simpin"))
7091	{
7092		char act_node[32], act_port_path[8];
7093		char *pincode, *save_pin, *g3err_pin, *wan_unit;
7094		int save_nvram = 0;
7095
7096		pincode = get_cgi_json("sim_pincode", root);
7097		save_pin = get_cgi_json("save_pin", root);
7098		g3err_pin = get_cgi_json("g3err_pin", root);
7099		wan_unit = get_cgi_json("wan_unit", root);
7100
7101		snprintf(act_node, 32, "%s", nvram_safe_get("usb_modem_act_path"));
7102		if(strlen(act_node) <= 0 || get_path_by_node(act_node, act_port_path, 8) == NULL){
7103			json_object_put(root);
7104			return 0;
7105		}
7106
7107		nvram_set("g3err_pin", g3err_pin);
7108
7109		if(!strcmp(save_pin, "1")){
7110			nvram_set("modem_pincode", pincode);
7111			save_nvram = 1;
7112		}
7113		else if(strcmp(nvram_safe_get("modem_pincode"),"") && !strcmp(save_pin, "0")){
7114			nvram_set("modem_pincode", "");
7115			save_nvram = 1;
7116		}
7117
7118		sprintf(command, "%s %s", action_mode, pincode);
7119		notify_rc(command);
7120
7121		if(save_nvram)
7122			nvram_commit();
7123	}
7124	else if (!strcmp(action_mode, "start_simpuk"))
7125	{
7126		char act_node[32], act_port_path[8];
7127		char *puk, *newpin, *g3err_pin, *wan_unit;
7128
7129		puk = get_cgi_json("sim_puk", root);
7130		newpin = get_cgi_json("sim_newpin", root);
7131		g3err_pin = get_cgi_json("g3err_pin", root);
7132		wan_unit = get_cgi_json("wan_unit", root);
7133
7134		snprintf(act_node, 32, "%s", nvram_safe_get("usb_modem_act_path"));
7135		if(strlen(act_node) <= 0 || get_path_by_node(act_node, act_port_path, 8) == NULL){
7136			json_object_put(root);
7137			return 0;
7138		}
7139
7140		nvram_set("g3err_pin", g3err_pin);
7141
7142		sprintf(command, "%s %s %s", action_mode, puk, newpin);
7143		notify_rc(command);
7144	}
7145	else if (!strcmp(action_mode, "restart_simauth"))
7146	{
7147		char act_node[32], act_port_path[8];
7148
7149		snprintf(act_node, 32, "%s", nvram_safe_get("usb_modem_act_path"));
7150		if(strlen(act_node) <= 0 || get_path_by_node(act_node, act_port_path, 8) == NULL){
7151			json_object_put(root);
7152			return 0;
7153		}
7154
7155		notify_rc(action_mode);
7156	}
7157	else if (!strcmp(action_mode, "start_simdetect"))
7158	{
7159		char *simdetect;
7160
7161		simdetect = get_cgi_json("simdetect", root);
7162		sprintf(command, "%s %s", action_mode, simdetect);
7163		notify_rc(command);
7164		websApply(wp, "Restarting.asp");
7165		nvram_set("freeze_duck", "15");
7166		shutdown(fileno(wp), SHUT_RDWR);
7167		sys_reboot();
7168		json_object_put(root);
7169		return 0;
7170	}
7171	else if(!strcmp(action_mode, "update_lte_fw")){
7172		notify_rc("start_gobi_update");
7173	}
7174#if defined(RTCONFIG_JFFS2) || defined(RTCONFIG_BRCM_NAND_JFFS2) || defined(RTCONFIG_UBIFS)
7175	else if (!strcmp(action_mode, "restart_resetcount"))
7176	{
7177		notify_rc(action_mode);
7178	}
7179	else if (!strcmp(action_mode, "restart_sim_del"))
7180	{
7181		char *sim_order;
7182
7183		sim_order = get_cgi_json("sim_order", root);
7184
7185		sprintf(command, "%s %s", action_mode, sim_order);
7186		notify_rc(command);
7187	}
7188#endif
7189#endif
7190#ifdef RTCONFIG_TRAFFIC_LIMITER
7191	else if (!strcmp(action_mode, "traffic_resetcount"))
7192	{
7193		char *ifname = get_cgi_json("interface", root);
7194		char ifmap[IFNAME_MAX];	// ifname after mapping
7195		char path[IFPATH_MAX];
7196
7197		memset(ifmap, 0, sizeof(ifmap));
7198		ifname_mapping(ifname, ifmap);
7199
7200		// write database
7201		doSystem("traffic_limiter -w");
7202
7203		// delete file
7204		snprintf(path, sizeof(path), TL_PATH"%s/traffic.db", ifmap);
7205		doSystem("rm -f %s", path);
7206
7207		// reset current traffic
7208		snprintf(path, sizeof(path), TL_PATH"%s/tmp", ifmap);
7209		f_write_string(path, "0", 0, 0);
7210
7211		// update status for traffic limiter
7212		doSystem("traffic_limiter -q");
7213
7214		// recover connection
7215		notify_rc("reset_traffic_limiter_force");
7216	}
7217#endif
7218#ifdef RTCONFIG_WTFAST
7219	else if (!strcmp(action_mode, "wtfast_logout")){
7220		char *wtf_rulelist = get_cgi_json("wtf_rulelist", root);
7221
7222		nvram_set("wtf_rulelist", wtf_rulelist);
7223		nvram_set("wtf_enable_games", "");
7224		nvram_set("wtf_username", "");
7225		nvram_set("wtf_passwd", "");
7226		nvram_set("wtf_login", "2");
7227		nvram_set("wtf_account_type", "");
7228		nvram_set("wtf_max_clients", "");
7229		nvram_set("wtf_days_left", "");
7230		nvram_set("wtf_game_list", "");
7231		nvram_set("wtf_server_list", "");
7232		nvram_set("wtf_session_hash", "");
7233		nvram_commit();
7234		/*--*/
7235
7236		notify_rc("stop_wtfast");
7237		_dprintf("httpd: wtfast_logout\n");
7238	}
7239	else if (!strcmp(action_mode, "wtfast_login")){
7240		char *wtf_username, *wtf_passwd, *wtf_login, *wtf_account_type, *wtf_max_clients, *wtf_days_left;
7241		char *wtf_game_list, *wtf_server_list, *wtf_session_hash;
7242
7243		wtf_username = get_cgi_json("wtf_username", root);
7244		wtf_passwd = get_cgi_json("wtf_passwd", root);
7245		wtf_login = get_cgi_json("wtf_login", root);
7246		wtf_account_type = get_cgi_json("wtf_account_type", root);
7247		wtf_max_clients = get_cgi_json("wtf_max_clients", root);
7248		wtf_days_left = get_cgi_json("wtf_days_left", root);
7249		wtf_game_list = get_cgi_json("wtf_game_list", root);
7250		wtf_server_list = get_cgi_json("wtf_server_list", root);
7251		wtf_session_hash = get_cgi_json("wtf_session_hash", root);
7252
7253		nvram_set("wtf_username", wtf_username);
7254		nvram_set("wtf_passwd", wtf_passwd);
7255		nvram_set("wtf_login", wtf_login);
7256		nvram_set("wtf_account_type", wtf_account_type);
7257		nvram_set("wtf_max_clients", wtf_max_clients);
7258		nvram_set("wtf_days_left", wtf_days_left);
7259		nvram_set("wtf_game_list", wtf_game_list);
7260		nvram_set("wtf_server_list", wtf_server_list);
7261		nvram_set("wtf_session_hash", wtf_session_hash);
7262		//nvram_set("wtf_release", "stage");//for download new firmware
7263		/*--*/
7264
7265		notify_rc("start_wtfast");
7266		_dprintf("httpd: wtfast_login\n");
7267 	}
7268#endif
7269#ifdef RTCONFIG_DISK_MONITOR
7270	else if (!strcmp(action_mode, "change_diskmon_unit"))
7271	{
7272		action_para = get_cgi_json("diskmon_usbport", root);
7273
7274		if(action_para)
7275			nvram_set("diskmon_usbport", action_para);
7276	}
7277#endif
7278	json_object_put(root);
7279	return 1;
7280}
7281
7282
7283
7284static void
7285do_auth(char *userid, char *passwd, char *realm)
7286{
7287//	time_t tm;
7288
7289	if (strcmp(ProductID,"")==0)
7290	{
7291		strcpy(ProductID, get_productid());
7292	}
7293	if (strcmp(UserID,"")==0 || reget_passwd == 1)
7294	{
7295	   	strcpy(UserID, nvram_safe_get("http_username"));
7296	}
7297// 2008.08 magic {
7298	if (strcmp(UserPass, "") == 0 || reget_passwd == 1)
7299	{
7300// 2008.08 magic }
7301		strcpy(UserPass, nvram_safe_get("http_passwd"));
7302	}
7303
7304	reget_passwd = 0;
7305
7306	strncpy(userid, UserID, AUTH_MAX);
7307
7308	if (!is_auth())
7309	{
7310		strcpy(passwd, "");
7311	}
7312	else
7313	{
7314		strncpy(passwd, UserPass, AUTH_MAX);
7315	}
7316	strncpy(realm, ProductID, AUTH_MAX);
7317}
7318
7319//andi
7320static void
7321do_ftpServerTree_cgi(char *url, FILE *stream)
7322{
7323    ftpServerTree_cgi(stream, NULL, NULL, 0, url, NULL, NULL);
7324}
7325
7326static void
7327do_apply_cgi(char *url, FILE *stream)
7328{
7329    apply_cgi(stream, NULL, NULL, 0, url, NULL, NULL);
7330}
7331
7332/* Look for unquoted character within a string */
7333char *
7334unqstrstr_t(char *haystack, char *needle)
7335{
7336	char *cur;
7337	int q;
7338
7339	for (cur = haystack, q = 0;
7340	     cur < &haystack[strlen(haystack)] && !(!q && !strncmp(needle, cur, strlen(needle)));
7341	     cur++) {
7342		if (*cur == '"')
7343			q ? q-- : q++;
7344	}
7345	return (cur < &haystack[strlen(haystack)]) ? cur : NULL;
7346}
7347
7348char *
7349get_arg_t(char *args, char **next)
7350{
7351	char *arg, *end;
7352
7353	/* Parse out arg, ... */
7354	if (!(end = unqstrstr_t(args, ","))) {
7355		end = args + strlen(args);
7356		*next = NULL;
7357	} else
7358		*next = end + 1;
7359
7360	/* Skip whitespace and quotation marks on either end of arg */
7361	for (arg = args; isspace((int)*arg) || *arg == '"'; arg++);
7362	for (*end-- = '\0'; isspace((int)*end) || *end == '"'; end--)
7363		*end = '\0';
7364
7365	return arg;
7366}
7367
7368#ifdef TRANSLATE_ON_FLY
7369static int refresh_title_asp = 0;
7370
7371static void
7372do_lang_cgi(char *url, FILE *stream)
7373{
7374	if (refresh_title_asp)  {
7375		// Request refreshing pages from browser.
7376		websHeader(stream);
7377		websWrite(stream, "<head></head><title>REDIRECT TO INDEX.ASP</title>");
7378
7379		// The text between <body> and </body> content may be rendered in Opera browser.
7380		websWrite(stream, "<body onLoad='if (navigator.appVersion.indexOf(\"Firefox\")!=-1||navigator.appName == \"Netscape\"){top.location=\"index.asp\";}else{top.location.reload(true);}'></body>");
7381		websFooter(stream);
7382		websDone(stream, 200);
7383	} else {
7384		// Send redirect-page if and only if refresh_title_asp is true.
7385		// If we do not send Title.asp, Firefox reload web-pages again and again.
7386		// This trick had been deprecated due to compatibility issue with Netscape and Mozilla browser.
7387		websRedirect(stream, "Title.asp");
7388	}
7389}
7390
7391/*doesn't be used any more*/
7392static void
7393do_lang_post(char *url, FILE *stream, int len, char *boundary)
7394{
7395	int c;
7396	char *p, *p1;
7397	char orig_lang[4], new_lang[4];
7398
7399	if (url == NULL)
7400		return;
7401
7402	p = strstr (url, "preferred_lang_menu");
7403	if (p == NULL)
7404		return;
7405	memset (new_lang, 0, sizeof (new_lang));
7406	strncpy (new_lang, p + strlen ("preferred_lang_menu") + 1, 2);
7407
7408	memset (orig_lang, 0, sizeof (orig_lang));
7409	p1 = nvram_safe_get_x ("", "preferred_lang");
7410	if (p1[0] != '\0') {
7411		strncpy (orig_lang, p1, 2);
7412	} else {
7413		strncpy (orig_lang, "EN", 2);
7414	}
7415
7416	// read remain data
7417#if 0
7418	if (feof (stream)) {
7419		while ((c = fgetc(stream) != EOF)) {
7420			;	// fall through
7421		}
7422	}
7423#else
7424	char buf[1024];
7425	while ((c = fread(buf, 1, sizeof(buf), stream)) > 0)
7426		;		// fall through
7427#endif
7428
7429	cprintf ("lang: %s --> %s\n", orig_lang, new_lang);
7430	refresh_title_asp = 0;
7431	if (strcmp (orig_lang, new_lang) != 0 || is_firsttime ()) {
7432		// If language setting is different or first change language
7433		nvram_set_x ("", "preferred_lang", new_lang);
7434		if (is_firsttime ()){
7435			cprintf ("set x_Setting --> 1\n");
7436			nvram_set("x_Setting", "1");
7437		}
7438		cprintf ("!!!!!!!!!Commit new language settings.\n");
7439		refresh_title_asp = 1;
7440		nvram_commit();
7441	}
7442}
7443#endif // TRANSLATE_ON_FLY
7444
7445
7446
7447#define SWAP_LONG(x) \
7448	((__u32)( \
7449		(((__u32)(x) & (__u32)0x000000ffUL) << 24) | \
7450		(((__u32)(x) & (__u32)0x0000ff00UL) <<  8) | \
7451		(((__u32)(x) & (__u32)0x00ff0000UL) >>  8) | \
7452		(((__u32)(x) & (__u32)0xff000000UL) >> 24) ))
7453
7454int upgrade_err;
7455int stop_upgrade_once = 0;
7456
7457static void
7458do_upgrade_post(char *url, FILE *stream, int len, char *boundary)
7459{
7460	#define MAX_VERSION_LEN 64
7461	char upload_fifo[64] = "/tmp/linux.trx";
7462	FILE *fifo = NULL;
7463	char buf[4096];
7464	int count, ch/*, ver_chk = 0*/;
7465	int cnt;
7466	long filelen;
7467	int offset;
7468	struct sysinfo si;
7469	upgrade_err=1;
7470	/* workaround to RAM disk space issue */
7471	stop_upgrade_once = 0;
7472	nvram_set_int("upgrade_fw_status", FW_INIT);
7473	f_write_string("/tmp/detect_wrong.log", "", 0, 0);
7474	f_write_string("/tmp/usb.log", "", 0, 0);
7475#if defined(RTCONFIG_SMALL_FW_UPDATE)
7476	eval("/sbin/ejusb", "-1", "0");
7477	notify_rc("stop_upgrade");
7478	stop_upgrade_once = 1;
7479	sleep(10);
7480	/* Mount 16M ram disk to avoid out of memory */
7481	system("mkdir /tmp/mytmpfs");
7482	system("mount -t tmpfs -o size=16M,nr_inodes=10k,mode=700 tmpfs /tmp/mytmpfs");
7483	snprintf(upload_fifo, sizeof(upload_fifo), "/tmp/mytmpfs/linux.trx");
7484#endif
7485
7486	/* Look for our part */
7487	while (len > 0)
7488	{
7489		if (!fgets(buf, MIN(len + 1, sizeof(buf)), stream))
7490		{
7491			goto err;
7492		}
7493
7494		len -= strlen(buf);
7495
7496		if (!strncasecmp(buf, "Content-Disposition:", 20) && strstr(buf, "name=\"file\""))
7497			break;
7498	}
7499
7500	/* Skip boundary and headers */
7501	while (len > 0) {
7502		if (!fgets(buf, MIN(len + 1, sizeof(buf)), stream))
7503		{
7504			goto err;
7505		}
7506		len -= strlen(buf);
7507		if (!strcmp(buf, "\n") || !strcmp(buf, "\r\n"))
7508		{
7509			break;
7510		}
7511	}
7512
7513#define BYTE_TO_KB(b) ((b >> 10) + ((b & 0x2ff)?1:0))
7514	free_caches(FREE_MEM_PAGE, 5, BYTE_TO_KB(len));
7515
7516	if (!(fifo = fopen(upload_fifo, "a+"))) goto err;
7517
7518#if !defined(RTCONFIG_SMALL_FW_UPDATE)
7519	sysinfo(&si);
7520	/* free memory should be 4 * TRX_size */
7521	if ((si.freeram * si.mem_unit)/4 < len)
7522	{
7523		eval("/sbin/ejusb", "-1", "0");
7524		notify_rc("stop_upgrade");
7525		stop_upgrade_once = 1;
7526	}
7527#endif
7528
7529	filelen = len;
7530	cnt = 0;
7531	offset = 0;
7532
7533	/* Pipe the rest to the FIFO */
7534	while (len>0 && filelen>0)
7535	{
7536
7537#ifdef RTCONFIG_HTTPS
7538		//_dprintf("[httpd] SSL for upgrade!\n"); // tmp test
7539		if(do_ssl){
7540			//_dprintf("[httpd] ssl_stream_fd : %d\n", ssl_stream_fd); // tmp test
7541			if (waitfor(ssl_stream_fd, 3) <= 0)
7542				break;
7543		}
7544		else{
7545			if (waitfor (fileno(stream), 10) <= 0)
7546			{
7547				break;
7548			}
7549		}
7550#else
7551		//_dprintf("[httpd] NO SSL for upgrade!\n"); // tmp test
7552		if (waitfor (fileno(stream), 10) <= 0)
7553		{
7554			break;
7555		}
7556#endif
7557
7558		count = fread(buf + offset, 1, MIN(len, sizeof(buf)-offset), stream);
7559
7560		if(count <= 0)
7561			goto err;
7562
7563		len -= count;
7564
7565		if(cnt==0) {
7566#if defined(RTCONFIG_RALINK) || defined(RTCONFIG_QCA)
7567#define HEADER_LEN (64)
7568#else
7569#define HEADER_LEN (8)
7570#endif
7571			if(count + offset < HEADER_LEN)
7572			{
7573				offset += count;
7574				continue;
7575			}
7576
7577			count += offset;
7578			offset = 0;
7579			_dprintf("read from stream: %d\n", count);
7580			cnt++;
7581			if(!check_imageheader(buf, &filelen)) {
7582				goto err;
7583			}
7584		}
7585		filelen-=count;
7586		fwrite(buf, 1, count, fifo);
7587	}
7588
7589	/* Slurp anything remaining in the request */
7590	while (len-- > 0)
7591	{
7592		if((ch = fgetc(stream)) == EOF)
7593			break;
7594
7595		if (filelen>0)
7596		{
7597			fwrite(&ch, 1, 1, fifo);
7598			filelen--;
7599		}
7600	}
7601	fclose(fifo);
7602	fifo = NULL;
7603#ifdef RTCONFIG_DSL
7604
7605	int ret_val_sep;
7606#ifdef RTCONFIG_RALINK
7607	ret_val_sep = separate_tc_fw_from_trx();	//TODO: merge truncated_trx
7608
7609	// should router update tc fw?
7610	if (ret_val_sep)
7611	{
7612		if(check_tc_firmware_crc()) /* return 0 when pass */
7613			goto err;
7614	}
7615	//TODO: if merge truncated_trx() to separate_tc_fw_from_trx()
7616	//then all use check_imagefile(upload_fifo)
7617#else
7618	ret_val_sep = separate_tc_fw_from_trx(upload_fifo);
7619
7620	// should router update tc fw?
7621	if (ret_val_sep)
7622	{
7623		if(check_tc_firmware_crc()) /* return 0 when pass */
7624			goto err;
7625		nvram_set_int("reboot_time", nvram_get_int("reboot_time")+100);
7626	}
7627
7628	if(!check_imagefile(upload_fifo)) /* 0: illegal image; 1: legal image */
7629		goto err;
7630#endif
7631
7632#else
7633#ifdef RTAC68U
7634	if (!nvram_match("cpurev", "c0") &&
7635	    (nvram_match("bl_version", "2.1.2.2") || nvram_match("bl_version", "2.1.2.6"))) {
7636		unlink("/tmp/linux.trx");
7637		eval("/usr/sbin/webs_update.sh");
7638
7639		if (nvram_get_int("webs_state_update") &&
7640		    !nvram_get_int("webs_state_error") &&
7641		    strlen(nvram_safe_get("webs_state_info"))) {
7642			_dprintf("retrieve firmware information\n");
7643
7644			if (!nvram_get_int("webs_state_flag"))
7645			{
7646				_dprintf("no need to upgrade firmware\n");
7647				goto err;
7648			}
7649
7650			eval("/usr/sbin/webs_upgrade.sh");
7651
7652			if (nvram_get_int("webs_state_error"))
7653			{
7654				_dprintf("error execute upgrade script\n");
7655				goto err;
7656			}
7657
7658			nvram_set("restore_defaults", "1");
7659			system("nvram erase");
7660
7661		} else _dprintf("could not retrieve firmware information!\n");
7662	}
7663#endif
7664	if(!check_imagefile(upload_fifo)) /* 0: illegal image; 1: legal image */
7665		goto err;
7666#endif
7667	upgrade_err = 0;
7668
7669err:
7670	nvram_set_int("upgrade_fw_status", FW_UPLOADING_ERROR);
7671	if (fifo)
7672		fclose(fifo);
7673
7674	/* Slurp anything remaining in the request */
7675	while (len-- > 0)
7676		if((ch = fgetc(stream)) == EOF)
7677			break;
7678}
7679
7680static void
7681do_upgrade_cgi(char *url, FILE *stream)
7682{
7683	_dprintf("## [httpd] do upgrade cgi upgrade_err(%d)\n", upgrade_err);	// tmp test
7684	/* Reboot if successful */
7685
7686	if (upgrade_err == 0)
7687	{
7688#ifdef RTCONFIG_DSL
7689#ifdef RTCONFIG_RALINK
7690		int ret_val_trunc;
7691		ret_val_trunc = truncate_trx();
7692		printf("truncate_trx ret=%d\n",ret_val_trunc);
7693		if (ret_val_trunc)
7694		{
7695			int ret_val_comp;
7696
7697			do_upgrade_adsldrv();
7698			ret_val_comp = compare_linux_image();
7699			printf("compare_linux_image ret=%d\n",ret_val_comp);
7700			if (ret_val_comp == 0)
7701			{
7702				// same trx
7703				unlink("/tmp/linux.trx");
7704			}
7705			else
7706			{
7707				// different trx
7708				// it will call rc_service automatically for firmware upgrading
7709			}
7710		}
7711#endif
7712#endif
7713#if !defined(RTCONFIG_SMALL_FW_UPDATE)
7714		if (!stop_upgrade_once){
7715			eval("/sbin/ejusb", "-1", "0");
7716			notify_rc("stop_upgrade");
7717			stop_upgrade_once = 1;
7718		}
7719#endif
7720		int etry = 3, err = 0;
7721
7722#if (defined(PLN12) || defined(PLAC56))
7723		set_wifiled(6);
7724#endif
7725		websApply(stream, "Updating.asp");
7726		shutdown(fileno(stream), SHUT_RDWR);
7727		while(etry-- && (err = notify_rc_after_period_wait("start_upgrade", 60)))
7728		{
7729			_dprintf("%s, try agn upgrade...%d/3, err=%d\n", __FUNCTION__, etry, err);
7730			notify_rc_after_period_wait("stop_upgrade", 10);
7731			stop_upgrade_once = 1;
7732		}
7733	}
7734	else
7735	{
7736		if(stop_upgrade_once != 0){
7737			nvram_set_int("upgrade_fw_status", FW_WRITING_ERROR);
7738			websApply(stream, "UpdateError_reboot.asp");
7739			unlink("/tmp/linux.trx");
7740			sys_reboot();
7741		}else{
7742			nvram_set_int("upgrade_fw_status", FW_WRITING_ERROR);
7743			websApply(stream, "UpdateError.asp");
7744			unlink("/tmp/linux.trx");
7745		}
7746	}
7747}
7748
7749static void
7750do_upload_post(char *url, FILE *stream, int len, char *boundary)
7751{
7752	#define MAX_VERSION_LEN 64
7753	char upload_fifo[] = "/tmp/settings_u.prf";
7754	FILE *fifo = NULL;
7755	char buf[1024];
7756	int count, ret = EINVAL, ch;
7757	int /*eno, */cnt;
7758	long filelen, *filelenptr;
7759	char /*version[MAX_VERSION_LEN], */cmpHeader;
7760	int offset;
7761
7762	/* Look for our part */
7763	while (len > 0) {
7764		if (!fgets(buf, MIN(len + 1, sizeof(buf)), stream)) {
7765			goto err;
7766		}
7767
7768		len -= strlen(buf);
7769
7770		if (!strncasecmp(buf, "Content-Disposition:", 20)
7771				&& strstr(buf, "name=\"file\""))
7772			break;
7773	}
7774
7775	/* Skip boundary and headers */
7776	while (len > 0) {
7777		if (!fgets(buf, MIN(len + 1, sizeof(buf)), stream)) {
7778			goto err;
7779		}
7780
7781		len -= strlen(buf);
7782		if (!strcmp(buf, "\n") || !strcmp(buf, "\r\n")) {
7783			break;
7784		}
7785	}
7786
7787	if (!(fifo = fopen(upload_fifo, "a+")))
7788		goto err;
7789
7790	filelen = len;
7791	cnt = 0;
7792	offset = 0;
7793
7794	/* Pipe the rest to the FIFO */
7795	cprintf("Upgrading %d\n", len);
7796	cmpHeader = 0;
7797
7798	while (len > 0 && filelen > 0) {
7799#ifdef RTCONFIG_HTTPS
7800		//_dprintf("[httpd] SSL for upload!\n"); // tmp test
7801		if(do_ssl){
7802			//_dprintf("[httpd] ssl_stream_fd : %d\n", ssl_stream_fd); // tmp test
7803			if (waitfor(ssl_stream_fd, 3) <= 0)
7804				break;
7805		}
7806		else{
7807			if (waitfor (fileno(stream), 10) <= 0)
7808			{
7809				break;
7810			}
7811		}
7812#else
7813		//_dprintf("[httpd] NO SSL for upload!\n"); // tmp test
7814		if (waitfor (fileno(stream), 10) <= 0)
7815		{
7816			break;
7817		}
7818#endif
7819		count = fread(buf + offset, 1, MIN(len, sizeof(buf)-offset), stream);
7820		if(count <= 0)
7821			goto err;
7822
7823		len -= count;
7824
7825		if (cnt == 0)
7826		{
7827			if(count + offset < 8)
7828			{
7829				offset += count;
7830				continue;
7831			}
7832			count += offset;
7833			offset = 0;
7834
7835			if (!strncmp(buf, PROFILE_HEADER, 4))
7836			{
7837				filelenptr = (long*)(buf + 4);
7838				filelen = *filelenptr;
7839
7840			}
7841			else if (!strncmp(buf, PROFILE_HEADER_NEW, 4))
7842			{
7843				filelenptr = (long*)(buf + 4);
7844				filelen = *filelenptr;
7845				filelen = filelen & 0xffffff;
7846
7847			}
7848			else
7849			{
7850				goto err;
7851			}
7852
7853			cmpHeader = 1;
7854			++cnt;
7855		}
7856
7857		filelen -= count;
7858		fwrite(buf, 1, count, fifo);
7859	}
7860
7861	if (!cmpHeader)
7862		goto err;
7863
7864	/* Slurp anything remaining in the request */
7865	while (len-- > 0) {
7866		ch = fgetc(stream);
7867
7868		if (filelen > 0) {
7869			fwrite(&ch, 1, 1, fifo);
7870			--filelen;
7871		}
7872	}
7873
7874	ret = 0;
7875
7876	fseek(fifo, 0, SEEK_END);
7877	fclose(fifo);
7878	fifo = NULL;
7879	/*printf("done\n");*/
7880
7881err:
7882	if (fifo)
7883		fclose(fifo);
7884
7885	/* Slurp anything remaining in the request */
7886	while (len-- > 0)
7887		if((ch = fgetc(stream)) == EOF)
7888			break;
7889
7890	fcntl(fileno(stream), F_SETOWN, -ret);
7891}
7892
7893static void
7894do_upload_cgi(char *url, FILE *stream)
7895{
7896	int ret;
7897
7898#ifdef RTCONFIG_HTTPS
7899	if(do_ssl)
7900		ret = fcntl(ssl_stream_fd , F_GETOWN, 0);
7901	else
7902#endif
7903	ret = fcntl(fileno(stream), F_GETOWN, 0);
7904
7905	/* Reboot if successful */
7906	if (ret == 0)
7907	{
7908		websApply(stream, "Uploading.asp");
7909#ifdef RTCONFIG_HTTPS
7910	if(do_ssl)
7911		shutdown(ssl_stream_fd, SHUT_RDWR);
7912	else
7913#endif
7914		shutdown(fileno(stream), SHUT_RDWR);
7915		sys_upload("/tmp/settings_u.prf");
7916		nvram_commit();
7917		sys_reboot();
7918	}
7919	else
7920	{
7921		websApply(stream, "UploadError.asp");
7922	   	//unlink("/tmp/settings_u.prf");
7923	}
7924}
7925
7926#ifdef RTCONFIG_OPENVPN
7927
7928#define VPN_CLIENT_UPLOAD	"/tmp/openvpn_file"
7929
7930static void
7931do_vpnupload_post(char *url, FILE *stream, int len, char *boundary)
7932{
7933	char upload_fifo[] = VPN_CLIENT_UPLOAD;
7934	FILE *fifo = NULL;
7935	int ret = EINVAL, ch;
7936	int offset;
7937	char *name, *value, *p;
7938
7939	memset(post_buf, 0, sizeof(post_buf));
7940	nvram_set("vpn_upload_type", "");
7941	nvram_set("vpn_upload_unit", "");
7942
7943	/* Look for our part */
7944	while (len > 0) {
7945		if (!fgets(post_buf, MIN(len + 1, sizeof(post_buf)), stream)) {
7946			goto err;
7947		}
7948
7949		len -= strlen(post_buf);
7950
7951		if (!strncasecmp(post_buf, "Content-Disposition:", 20)) {
7952			if(strstr(post_buf, "name=\"file\""))
7953				break;
7954			else if(strstr(post_buf, "name=\"")) {
7955				offset = strlen(post_buf);
7956				fgets(post_buf+offset, MIN(len + 1, sizeof(post_buf)-offset), stream);
7957				len -= strlen(post_buf) - offset;
7958				offset = strlen(post_buf);
7959				fgets(post_buf+offset, MIN(len + 1, sizeof(post_buf)-offset), stream);
7960				len -= strlen(post_buf) - offset;
7961				p = post_buf;
7962				name = strstr(p, "\"") + 1;
7963				p = strstr(name, "\"");
7964				strcpy(p++, "\0");
7965				value = strstr(p, "\r\n\r\n") + 4;
7966				p = strstr(value, "\r");
7967				strcpy(p, "\0");
7968				//printf("%s=%s\n", name, value);
7969				nvram_set(name, value);
7970			}
7971		}
7972	}
7973
7974	/* Skip boundary and headers */
7975	while (len > 0) {
7976		if (!fgets(post_buf, MIN(len + 1, sizeof(post_buf)), stream)) {
7977			goto err;
7978		}
7979
7980		len -= strlen(post_buf);
7981		if (!strcmp(post_buf, "\n") || !strcmp(post_buf, "\r\n")) {
7982			break;
7983		}
7984	}
7985
7986	if (!(fifo = fopen(upload_fifo, "w")))
7987		goto err;
7988
7989	while (len > 0) {
7990		if (!fgets(post_buf, MIN(len + 1, sizeof(post_buf)), stream)) {
7991			goto err;
7992		}
7993		len -= strlen(post_buf);
7994
7995		if(boundary) {
7996			if (strstr(post_buf, boundary))
7997				break;
7998		}
7999
8000		fputs(post_buf, fifo);
8001	}
8002
8003	ret = 0;
8004
8005	fclose(fifo);
8006	fifo = NULL;
8007	/*printf("done\n");*/
8008
8009err:
8010	if (fifo)
8011		fclose(fifo);
8012
8013	/* Slurp anything remaining in the request */
8014	while (len-- > 0)
8015		if((ch = fgetc(stream)) == EOF)
8016			break;
8017
8018	fcntl(fileno(stream), F_SETOWN, -ret);
8019}
8020
8021static void
8022do_vpnupload_cgi(char *url, FILE *stream)
8023{
8024	int ret, state;
8025	char *filetype = nvram_safe_get("vpn_upload_type");
8026	char *unit = nvram_safe_get("vpn_upload_unit");
8027	char nv[32] = {0};
8028
8029	if(!filetype || !unit) {
8030		unlink(VPN_CLIENT_UPLOAD);
8031		return;
8032	}
8033
8034#ifdef RTCONFIG_HTTPS
8035	if(do_ssl)
8036		ret = fcntl(ssl_stream_fd , F_GETOWN, 0);
8037	else
8038#endif
8039	ret = fcntl(fileno(stream), F_GETOWN, 0);
8040
8041	if (ret == 0)
8042	{
8043		//websApply(stream, "OvpnChecking.asp");
8044
8045		if(!strcmp(filetype, "ovpn")) {
8046			reset_client_setting(atoi(unit));
8047			ret = read_config_file(VPN_CLIENT_UPLOAD, atoi(unit));
8048			nvram_set_int("vpn_upload_state", ret);
8049			nvram_commit();
8050		}
8051		else if(!strcmp(filetype, "ca")) {
8052			sprintf(nv, "vpn_crt_client%s_ca", unit);
8053			set_crt_parsed(nv, VPN_CLIENT_UPLOAD);
8054			state = nvram_get_int("vpn_upload_state");
8055			nvram_set_int("vpn_upload_state", state & (~VPN_UPLOAD_NEED_CA_CERT));
8056		}
8057		else if(!strcmp(filetype, "cert")) {
8058			sprintf(nv, "vpn_crt_client%s_crt", unit);
8059			set_crt_parsed(nv, VPN_CLIENT_UPLOAD);
8060			state = nvram_get_int("vpn_upload_state");
8061			nvram_set_int("vpn_upload_state", state & (~VPN_UPLOAD_NEED_CERT));
8062		}
8063		else if(!strcmp(filetype, "key")) {
8064			sprintf(nv, "vpn_crt_client%s_key", unit);
8065			set_crt_parsed(nv, VPN_CLIENT_UPLOAD);
8066			state = nvram_get_int("vpn_upload_state");
8067			nvram_set_int("vpn_upload_state", state & (~VPN_UPLOAD_NEED_KEY));
8068		}
8069		else if(!strcmp(filetype, "static")) {
8070			sprintf(nv, "vpn_crt_client%s_static", unit);
8071			set_crt_parsed(nv, VPN_CLIENT_UPLOAD);
8072			state = nvram_get_int("vpn_upload_state");
8073			nvram_set_int("vpn_upload_state", state & (~VPN_UPLOAD_NEED_STATIC));
8074		}
8075		else if(!strcmp(filetype, "ccrl")) {
8076			sprintf(nv, "vpn_crt_client%s_crl", unit);
8077			set_crt_parsed(nv, VPN_CLIENT_UPLOAD);
8078			state = nvram_get_int("vpn_upload_state");
8079			nvram_set_int("vpn_upload_state", state & (~VPN_UPLOAD_NEED_CRL));
8080		}
8081		else if(!strcmp(filetype, "scrl")) {
8082			sprintf(nv, "vpn_crt_server%s_crl", unit);
8083			set_crt_parsed(nv, VPN_CLIENT_UPLOAD);
8084		}
8085	}
8086	else
8087	{
8088		//websApply(stream, "OvpnError.asp");
8089	}
8090	unlink(VPN_CLIENT_UPLOAD);
8091}
8092#endif	//RTCONFIG_OPENVPN
8093
8094// Viz 2010.08
8095static void
8096do_update_cgi(char *url, FILE *stream)
8097{
8098	struct ej_handler *handler;
8099	const char *pattern;
8100	int argc;
8101	char *argv[16];
8102	char s[32];
8103
8104	if ((pattern = get_cgi("output")) != NULL) {
8105		for (handler = &ej_handlers[0]; handler->pattern; handler++) {
8106			if (strcmp(handler->pattern, pattern) == 0) {
8107				for (argc = 0; argc < 16; ++argc) {
8108					sprintf(s, "arg%d", argc);
8109					if ((argv[argc] = (char *)get_cgi(s)) == NULL) break;
8110				}
8111				handler->output(0, stream, argc, argv);
8112				break;
8113			}
8114		}
8115	}
8116}
8117
8118//Traffic Monitor
8119void wo_bwmbackup(char *url, webs_t wp)
8120{
8121	static const char *hfn = "/var/lib/misc/rstats-history.gz";
8122	struct stat st;
8123	time_t t;
8124	int i;
8125
8126	if (stat(hfn, &st) == 0) {
8127		t = st.st_mtime;
8128		sleep(1);
8129	}
8130	else {
8131		t = 0;
8132	}
8133	killall("rstats", SIGHUP);
8134	for (i = 10; i > 0; --i) {
8135		if ((stat(hfn, &st) == 0) && (st.st_mtime != t)) break;
8136		sleep(1);
8137	}
8138	if (i == 0) {
8139		//send_error(500, "Bad Request", (char*) 0, "Internal server error." );
8140		return;
8141	}
8142	//send_headers(200, NULL, mime_binary, 0);
8143	do_f((char *)hfn, wp);
8144}
8145// end Viz ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8146
8147#ifdef RTCONFIG_QTN  //RT-AC87U
8148static void
8149do_qtn_diagnostics(char *url, FILE *stream)
8150{
8151	char qtn_rpc_client[20] = {0};
8152
8153	unlink("/tmp/diagnostics_done");
8154	nvram_set("qtn_diagnostics", "1");
8155	printf("Do diagnostics\n");
8156	memset(qtn_rpc_client, 0, sizeof(qtn_rpc_client));
8157	snprintf(qtn_rpc_client, sizeof(qtn_rpc_client), "%s", nvram_safe_get("QTN_RPC_CLIENT"));
8158	eval("qcsapi_sockrpc", "run_script", "router_command.sh", "diagnostics", qtn_rpc_client);
8159	while(access("/tmp/diagnostics_done", R_OK ) == -1 ) {
8160		printf("run_script.log does not exist, wait\n");
8161		sleep(5);
8162	}
8163	do_file("/tmp/run_script.log", stream);
8164	unlink("/tmp/diagnostics_done");
8165	nvram_unset("qtn_diagnostics");
8166}
8167#endif
8168
8169static void
8170prf_file(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, char_t *url, char_t *path, char_t *query)
8171{
8172	char *ddns_flag;
8173	char *ddns_mac;
8174	char ddns_hostname_tmp[128];
8175	char model_name;
8176
8177	model_name = get_model();
8178#ifdef RTCONFIG_RGMII_BRCM5301X
8179	ddns_mac = nvram_get("lan_hwaddr");
8180#else
8181	if(model_name == MODEL_RTN56U){
8182		ddns_mac = nvram_get("et1macaddr");
8183	}
8184	else{
8185		ddns_mac = nvram_get("et0macaddr");
8186	}
8187#endif
8188#ifdef RTCONFIG_GMAC3
8189        if(nvram_match("gmac3_enable", "1"))
8190                ddns_mac = nvram_safe_get ("et2macaddr");
8191#endif
8192	ddns_flag = websGetVar(wp, "path", "");
8193
8194	if(strcmp(ddns_flag, "0") == 0){
8195		snprintf(ddns_hostname_tmp, sizeof(ddns_hostname_tmp), "%s", nvram_safe_get("ddns_hostname_x"));
8196		nvram_set("ddns_transfer", "");
8197		nvram_set("ddns_hostname_x", "");
8198	}
8199	else{
8200		nvram_set("ddns_transfer", ddns_mac);
8201	}
8202
8203	nvram_unset("asus_device_list");
8204	nvram_commit();
8205	sys_download("/tmp/settings");
8206
8207	if(strcmp(ddns_flag, "0") == 0){
8208		nvram_set("ddns_hostname_x", ddns_hostname_tmp);
8209		nvram_commit();
8210	}
8211
8212	do_file("/tmp/settings", wp);
8213}
8214
8215static void
8216do_prf_file(char *url, FILE *stream)
8217{
8218    prf_file(stream, NULL, NULL, 0, url, NULL, NULL);
8219}
8220
8221static void
8222do_uploadIconFile_file(char *url, FILE *stream)
8223{
8224        system("tar cvf /tmp/IconFile.tar /jffs/usericon /tmp/upnpicon");
8225        do_file("/tmp/IconFile.tar", stream);
8226        unlink("/tmp/IconFile.tar");
8227}
8228
8229static void
8230do_networkmap_file(char *url, FILE *stream)
8231{
8232	system("nvram get nmp_client_list > /tmp/nmp_client_list.log");
8233	system("nvram get asus_device_list > /tmp/asus_dev_list.log");
8234	eval("tar", "cf",
8235		"/tmp/networkmap.tar",
8236		"/tmp/upnp.log",
8237		"/tmp/smb.log",
8238		"/tmp/syslog.log",
8239		"/tmp/nmp_client_list.log",
8240		"/tmp/asus_dev_list.log",
8241#ifdef RTCONFIG_UPNPC
8242		"/tmp/upnpc_xml.log",
8243#endif
8244#ifdef RTCONFIG_BONJOUR
8245		"/tmp/mDNSNetMonitor.log",
8246#endif
8247		"/jffs/usericon",
8248		"/tmp/upnpicon");
8249	do_file("/tmp/networkmap.tar", stream);
8250	unlink("/tmp/networkmap.tar");
8251}
8252
8253static void
8254do_upnp_file(char *url, FILE *stream)
8255{
8256        do_file("/tmp/upnp.log", stream);
8257}
8258
8259static void
8260do_upnpc_xml_file(char *url, FILE *stream)
8261{
8262#ifdef RTCONFIG_UPNPC
8263        do_file("/tmp/upnpc_xml.log", stream);
8264#endif
8265}
8266
8267static void
8268do_dnsnet_file(char *url, FILE *stream)
8269{
8270#ifdef RTCONFIG_BONJOUR
8271        do_file("/tmp/mDNSNetMonitor.log", stream);
8272#endif
8273}
8274
8275static void
8276do_prf_ovpn_file(char *url, FILE *stream)
8277{
8278	nvram_commit();
8279	do_file(url, stream);
8280}
8281
8282#ifdef RTCONFIG_DSL_TCLINUX
8283static void
8284do_diag_log_file(char *url, FILE *stream)
8285{
8286	char path[128];
8287	snprintf(path, sizeof(path), "%s/asus_diagnostic/%s", nvram_safe_get("dsltmp_diag_log_path"), url);
8288	//_dprintf("Get log file %s\n", path);
8289	do_file(path, stream);
8290}
8291#endif
8292
8293static void
8294deleteOfflineClient(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, char_t *url, char_t *path, char_t *query)
8295{
8296	char *mac = NULL;
8297	char mac_str[13];
8298	mac = websGetVar(wp, "delete_offline_client","");
8299	int i, shm_client_info_id;
8300        void *shared_client_info=(void *) 0;
8301        P_CLIENT_DETAIL_INFO_TABLE p_client_info_tab;
8302        int lock;
8303
8304	i = 0;
8305	while(*mac) {
8306		if(*mac==':') {
8307			mac++;
8308			continue;
8309		}
8310		else {
8311			mac_str[i] = tolower(*mac);
8312			i++;
8313			mac++;
8314		}
8315	}
8316	if(i!=12)
8317		return;
8318
8319	mac_str[i] = '\0';
8320
8321	lock = file_lock("networkmap");
8322        shm_client_info_id = shmget((key_t)1001, sizeof(CLIENT_DETAIL_INFO_TABLE), 0666|IPC_CREAT);
8323        if (shm_client_info_id == -1){
8324            fprintf(stderr,"shmget failed\n");
8325            file_unlock(lock);
8326            return;
8327        }
8328
8329        shared_client_info = shmat(shm_client_info_id,(void *) 0,0);
8330        if (shared_client_info == (void *)-1){
8331                fprintf(stderr,"shmat failed\n");
8332                file_unlock(lock);
8333                return;
8334        }
8335
8336        p_client_info_tab = (P_CLIENT_DETAIL_INFO_TABLE)shared_client_info;
8337	strlcpy(p_client_info_tab->delete_mac, mac_str, sizeof(p_client_info_tab->delete_mac));
8338	shmdt(shared_client_info);
8339        file_unlock(lock);
8340
8341	doSystem("killall -%d networkmap", SIGUSR2);
8342}
8343static void
8344do_deleteOfflineClient_cgi(char *url, FILE *stream)
8345{
8346	deleteOfflineClient(stream, NULL, NULL, 0, url, NULL, NULL);
8347
8348}
8349
8350// 2010.09 James. {
8351static char no_cache_IE7[] =
8352"Cache-Control: no-cache\r\n"
8353"Pragma: no-cache\r\n"
8354"Expires: 0"
8355;
8356// 2010.09 James. }
8357
8358static char no_cache[] =
8359"Cache-Control: no-cache\r\n"
8360"Pragma: no-cache\r\n"
8361"Expires: 0"
8362;
8363
8364static char syslog_txt[] =
8365"Content-Disposition: attachment;\r\n"
8366"filename=syslog.txt"
8367;
8368
8369static char cache_object[] =
8370"Cache-Control: max-age=300"
8371;
8372
8373#ifdef RTCONFIG_USB_MODEM
8374static char modemlog_txt[] =
8375"Content-Disposition: attachment;\r\n"
8376"filename=modemlog.txt"
8377;
8378
8379static void
8380do_modemlog_cgi(char *path, FILE *stream)
8381{
8382	char *cmd[] = {"/usr/sbin/3ginfo.sh", NULL};
8383
8384	unlink("/tmp/3ginfo.txt");
8385	_eval(cmd, ">/tmp/3ginfo.txt", 0, NULL);
8386
8387	dump_file(stream, get_modemlog_fname());
8388	fputs("\r\n", stream); /* terminator */
8389	fputs("\r\n", stream); /* terminator */
8390}
8391#endif
8392
8393static void
8394do_log_cgi(char *path, FILE *stream)
8395{
8396	dump_file(stream, get_syslog_fname(1));
8397	dump_file(stream, get_syslog_fname(0));
8398	fputs("\r\n", stream); /* terminator */
8399	fputs("\r\n", stream); /* terminator */
8400}
8401
8402#ifdef RTCONFIG_FINDASUS
8403static int
8404findasus_cgi(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
8405		char_t *url, char_t *path, char_t *query)
8406{
8407	char *action_mode;
8408	char *action_para;
8409	char *current_url;
8410
8411	action_mode = websGetVar(wp, "action_mode","");
8412	current_url = websGetVar(wp, "current_page", "");
8413	_dprintf("apply: %s %s\n", action_mode, current_url);
8414
8415	if (!strcmp(action_mode, "refresh_networkmap"))
8416	{
8417		printf("@@@ Signal to networkmap!!!\n");
8418		doSystem("killall -%d networkmap", SIGUSR1);
8419
8420		websRedirect(wp, current_url);
8421	}
8422	return 1;
8423}
8424
8425
8426static void
8427do_findasus_cgi(char *url, FILE *stream)
8428{
8429    findasus_cgi(stream, NULL, NULL, 0, url, NULL, NULL);
8430}
8431#endif
8432
8433
8434/* Base-64 decoding.  This represents binary data as printable ASCII
8435** characters.  Three 8-bit binary bytes are turned into four 6-bit
8436** values, like so:
8437**
8438**   [11111111]  [22222222]  [33333333]
8439**
8440**   [111111] [112222] [222233] [333333]
8441**
8442** Then the 6-bit values are represented using the characters "A-Za-z0-9+/".
8443*/
8444
8445static int b64_decode_table[256] = {
8446    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 00-0F */
8447    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 10-1F */
8448    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,  /* 20-2F */
8449    52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,  /* 30-3F */
8450    -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,  /* 40-4F */
8451    15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,  /* 50-5F */
8452    -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,  /* 60-6F */
8453    41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,  /* 70-7F */
8454    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 80-8F */
8455    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 90-9F */
8456    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* A0-AF */
8457    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* B0-BF */
8458    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* C0-CF */
8459    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* D0-DF */
8460    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* E0-EF */
8461    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1   /* F0-FF */
8462    };
8463
8464/* Do base-64 decoding on a string.  Ignore any non-base64 bytes.
8465** Return the actual number of bytes generated.  The decoded size will
8466** be at most 3/4 the size of the encoded, and may be smaller if there
8467** are padding characters (blanks, newlines).
8468*/
8469static int
8470b64_decode( const char* str, unsigned char* space, int size )
8471{
8472    const char* cp;
8473    int space_idx, phase;
8474    int d, prev_d=0;
8475    unsigned char c;
8476
8477    space_idx = 0;
8478    phase = 0;
8479    for ( cp = str; *cp != '\0'; ++cp )
8480	{
8481	d = b64_decode_table[(int)*cp];
8482	if ( d != -1 )
8483	    {
8484	    switch ( phase )
8485		{
8486		case 0:
8487		++phase;
8488		break;
8489		case 1:
8490		c = ( ( prev_d << 2 ) | ( ( d & 0x30 ) >> 4 ) );
8491		if ( space_idx < size )
8492		    space[space_idx++] = c;
8493		++phase;
8494		break;
8495		case 2:
8496		c = ( ( ( prev_d & 0xf ) << 4 ) | ( ( d & 0x3c ) >> 2 ) );
8497		if ( space_idx < size )
8498		    space[space_idx++] = c;
8499		++phase;
8500		break;
8501		case 3:
8502		c = ( ( ( prev_d & 0x03 ) << 6 ) | d );
8503		if ( space_idx < size )
8504		    space[space_idx++] = c;
8505		phase = 0;
8506		break;
8507		}
8508	    prev_d = d;
8509	    }
8510	}
8511    return space_idx;
8512}
8513
8514asus_token_t* create_list(char *token)
8515{
8516	char login_timestr[32];
8517	time_t now;
8518
8519	struct in_addr login_ip_addr;
8520	char *login_ip_str;
8521
8522	login_ip_addr.s_addr = login_ip_tmp;
8523	login_ip_str = inet_ntoa(login_ip_addr);
8524
8525	now = uptime();
8526
8527	memset(login_timestr, 0, 32);
8528	sprintf(login_timestr, "%lu", now);
8529
8530	asus_token_t *ptr;
8531	ptr = (asus_token_t*)malloc(sizeof(asus_token_t));
8532	if(NULL == ptr)
8533	{
8534	        printf("\n Node creation failed \n");
8535	        return NULL;
8536	}
8537	strncpy(ptr->useragent, user_agent, 1024);
8538	strncpy(ptr->token, token, 32);
8539	strncpy(ptr->ipaddr, login_ip_str, 16);
8540	strncpy(ptr->login_timestampstr, login_timestr, 32);
8541	strncpy(ptr->host, host_name, 64);
8542	ptr->next = NULL;
8543
8544    head = curr = ptr;
8545    return ptr;
8546}
8547
8548asus_token_t* add_token_to_list(char *token, int add_to_end)
8549{
8550	if(NULL == head)
8551	{
8552		return (create_list(token));
8553	}
8554
8555	asus_token_t *ptr = (asus_token_t *)malloc(sizeof(asus_token_t));
8556	if(NULL == ptr)
8557	{
8558		_dprintf("\n Node creation failed \n");
8559		return NULL;
8560	}
8561	char login_timestr[32];
8562	time_t now;
8563
8564	struct in_addr login_ip_addr;
8565	char *login_ip_str;
8566
8567	login_ip_addr.s_addr = login_ip_tmp;
8568	login_ip_str = inet_ntoa(login_ip_addr);
8569
8570	now = uptime();
8571
8572	memset(login_timestr, 0, 32);
8573	sprintf(login_timestr, "%lu", now);
8574
8575	strncpy(ptr->useragent, user_agent, 1024);
8576	strncpy(ptr->token, token, 32);
8577	strncpy(ptr->ipaddr, login_ip_str, 16);
8578	strncpy(ptr->login_timestampstr, login_timestr, 32);
8579	strncpy(ptr->host, host_name, 64);
8580	ptr->next = NULL;
8581
8582	if(add_to_end == 1)
8583	{
8584		curr->next = ptr;
8585        	curr = ptr;
8586  	}
8587    	else
8588    	{
8589        	ptr->next = head;
8590		head = ptr;
8591    	}
8592	return ptr;
8593}
8594
8595int get_token_list_length(void){
8596
8597	asus_token_t *p = head;
8598
8599	int count=0;
8600
8601	while(p!=NULL){
8602		count++;
8603		p=p->next;
8604	}
8605
8606	return count;
8607}
8608
8609asus_token_t* search_timeout_in_list(asus_token_t **prev, int fromapp_flag)
8610{
8611	asus_token_t *ptr = head;
8612	asus_token_t *tmp = NULL;
8613	int found = 0;
8614
8615	time_t now = 0;
8616
8617	int logout_time = 30;
8618
8619	if(!nvram_match("http_autologout", "0"))
8620		logout_time = nvram_get_int("http_autologout");
8621
8622	now = uptime();
8623
8624	while(ptr != NULL)
8625	{
8626		if((unsigned long)(now-atol(ptr->login_timestampstr)) > (logout_time * 60) && check_user_agent(ptr->useragent) == 0)
8627		{
8628			found = 1;
8629			break;
8630       		}else if((unsigned long)(now-atol(ptr->login_timestampstr)) > 6000 && check_user_agent(ptr->useragent) != 0 && check_user_agent(ptr->useragent) != FROM_IFTTT)
8631		{
8632			found = 1;
8633			break;
8634	        }else if(fromapp_flag == 0 && check_user_agent(ptr->useragent) == 0)
8635		{
8636			found = 1;
8637			break;
8638       		}else
8639        	{
8640			tmp = ptr;
8641			ptr = ptr->next;
8642        	}
8643	}
8644
8645	if(found == 1)
8646	{
8647		if(prev)
8648		*prev = tmp;
8649		return ptr;
8650	}
8651	else
8652	{
8653		return NULL;
8654	}
8655}
8656
8657int check_token_timeout_in_list(void)
8658{
8659	int i;
8660	int list_len = get_token_list_length();
8661
8662	int fromapp_flag = 0;
8663
8664	fromapp_flag = check_user_agent(user_agent);
8665
8666	for(i=0; i < list_len; i++){
8667		asus_token_t *prev = NULL;
8668		asus_token_t *del = NULL;
8669		del = search_timeout_in_list(&prev, fromapp_flag);
8670
8671		if(del == NULL)
8672		{
8673			return -1;
8674		}
8675		else
8676 		{
8677        		if(prev != NULL)
8678			prev->next = del->next;
8679
8680			if(del == curr)
8681		        {
8682        		    curr = prev;
8683        		}
8684        		if(del == head)
8685        		{
8686        		    head = del->next;
8687        		}
8688		}
8689		free(del);
8690		del = NULL;
8691   	}
8692	return 0;
8693
8694}
8695
8696int check_login_in_list(void)
8697{
8698	asus_token_t *prev = NULL;
8699	asus_token_t *del = NULL;
8700
8701	int fromapp_flag = 0;
8702
8703	fromapp_flag = check_user_agent(user_agent);
8704
8705	del = search_timeout_in_list(&prev, fromapp_flag);
8706	if(del == NULL)
8707	{
8708		return -1;
8709	}
8710	else
8711		{
8712       		if(prev != NULL)
8713		prev->next = del->next;
8714
8715		if(del == curr)
8716	        {
8717       		    curr = prev;
8718       		}
8719       		if(del == head)
8720       		{
8721       		    head = del->next;
8722       		}
8723	}
8724	free(del);
8725	del = NULL;
8726	return 0;
8727}
8728
8729void print_list(void)
8730{
8731    asus_token_t *ptr = head;
8732
8733    _dprintf("\n -------Printing list Start------- \n");
8734    while(ptr != NULL)
8735    {
8736	_dprintf("%s\n",ptr->useragent);
8737        _dprintf("%s\n",ptr->token);
8738	_dprintf("%s\n",ptr->ipaddr);
8739	_dprintf("%s\n",ptr->login_timestampstr);
8740	_dprintf("%s\n",ptr->host);
8741        ptr = ptr->next;
8742    }
8743    _dprintf("\n -------Printing list End------- \n");
8744
8745    return;
8746}
8747
8748void add_asus_token(char *token){
8749	//print_list();
8750	int ret;
8751	ret = check_token_timeout_in_list();
8752
8753	add_token_to_list(token, 1);
8754
8755	//print_list();
8756}
8757
8758#define RFC1123FMT "%a, %d %b %Y %H:%M:%S GMT"
8759static int
8760login_cgi(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
8761		char_t *url, char_t *path, char_t *query)
8762{
8763	char *authorization_t;
8764	char authinfo[500];
8765	char* authpass;
8766	int l;
8767	char asus_token[32];
8768	char *next_page=NULL;
8769	int fromapp_flag = 0;
8770
8771	fromapp_flag = check_user_agent(user_agent);
8772
8773	next_page = websGetVar(wp, "next_page", "");
8774
8775	authorization_t = websGetVar(wp, "login_authorization","");
8776	/* Decode it. */
8777	l = b64_decode( &(authorization_t[0]), (unsigned char*) authinfo, sizeof(authinfo) );
8778	authinfo[l] = '\0';
8779
8780	authpass = strchr( authinfo, ':' );
8781	if ( authpass == (char*) 0 ) {
8782		websRedirect(wp, "Main_Login.asp");
8783		return 0;
8784	}
8785	*authpass++ = '\0';
8786
8787	time_t now;
8788	char timebuf[100];
8789	now = time( (time_t*) 0 );
8790
8791	time_t dt;
8792	struct in_addr temp_ip_addr;
8793	char *temp_ip_str;
8794
8795	login_timestamp_tmp = uptime();
8796	dt = login_timestamp_tmp - last_login_timestamp;
8797	if(last_login_timestamp != 0 && dt > 60){
8798		login_try = 0;
8799		last_login_timestamp = 0;
8800		lock_flag = 0;
8801	}
8802	if (MAX_login <= DEFAULT_LOGIN_MAX_NUM){
8803		MAX_login = DEFAULT_LOGIN_MAX_NUM;
8804	}
8805	if(login_try >= MAX_login){
8806		lock_flag = 1;
8807		temp_ip_addr.s_addr = login_ip_tmp;
8808		temp_ip_str = inet_ntoa(temp_ip_addr);
8809
8810		if(login_try%MAX_login == 0){
8811			logmessage("httpd login lock", "Detect abnormal logins at %d times. The newest one was from %s.", login_try, temp_ip_str);
8812		}
8813
8814		__send_login_page(fromapp_flag, LOGINLOCK, NULL, dt);
8815		return LOGINLOCK;
8816	}
8817
8818	websWrite(wp,"%s %d %s\r\n", PROTOCOL, 200, "OK" );
8819	websWrite(wp,"Server: %s\r\n", SERVER_NAME );
8820        if (fromapp_flag != 0){
8821		websWrite(wp, "Cache-Control: no-store\r\n");
8822		websWrite(wp, "Pragma: no-cache\r\n");
8823		if(fromapp_flag == FROM_DUTUtil){
8824			websWrite(wp, "AiHOMEAPILevel: %d\r\n", EXTEND_AIHOME_API_LEVEL );
8825			websWrite(wp, "Httpd_AiHome_Ver: %d\r\n", EXTEND_HTTPD_AIHOME_VER );
8826			websWrite(wp, "Model_Name: %s\r\n", get_productid() );
8827		}else if(fromapp_flag == FROM_ASSIA){
8828			websWrite(wp, "ASSIA_API_Level: %d\r\n", EXTEND_ASSIA_API_LEVEL );
8829		}
8830	}
8831	(void) strftime( timebuf, sizeof(timebuf), RFC1123FMT, gmtime( &now ) );
8832	websWrite(wp,"Date: %s\r\n", timebuf );
8833	if (fromapp_flag == 0){
8834		websWrite(wp,"Content-Type: %s\r\n", "text/html");
8835	}else{
8836		websWrite(wp,"Content-Type: %s\r\n", "application/json;charset=UTF-8");
8837	}
8838
8839	/* Is this the right user and password? */
8840	if ( strcmp( nvram_safe_get("http_username"), authinfo ) == 0 && strcmp( nvram_safe_get("http_passwd"), authpass ) == 0)
8841	{
8842		if (fromapp_flag == 0){
8843			login_try = 0;
8844			last_login_timestamp = 0;
8845			memset(referer_host, 0, sizeof(referer_host));
8846			if(strncmp(DUT_DOMAIN_NAME, host_name, strlen(DUT_DOMAIN_NAME))==0){
8847				strcpy(referer_host, nvram_safe_get("lan_ipaddr"));
8848			}else
8849				snprintf(referer_host,sizeof(host_name),"%s",host_name);
8850		}
8851
8852		strncpy(asus_token, generate_token(), sizeof(asus_token));
8853		add_asus_token(asus_token);
8854
8855		websWrite(wp,"Set-Cookie: asus_token=%s; HttpOnly;\r\n",asus_token);
8856		websWrite(wp,"Connection: close\r\n" );
8857		websWrite(wp,"\r\n" );
8858		if (fromapp_flag == 0){
8859			websWrite(wp,"<HTML><HEAD>\n" );
8860			if(!strcmp(nvram_default_get("http_passwd"), nvram_safe_get("http_passwd")) && !nvram_match("ATEMODE", "1"))
8861				websWrite(wp, T("<meta http-equiv=\"refresh\" content=\"0; url=Main_Password.asp\">\r\n"));
8862			else if(next_page == NULL || strcmp(next_page, "") == 0)
8863				websWrite(wp, T("<meta http-equiv=\"refresh\" content=\"0; url=index.asp\">\r\n"));
8864			else
8865				websWrite(wp, T("<meta http-equiv=\"refresh\" content=\"0; url=%s\">\r\n"), next_page);
8866
8867			websWrite(wp,"</HEAD></HTML>\n" );
8868		}else{
8869			websWrite(wp,"{\n" );
8870			websWrite(wp,"\"asus_token\":\"%s\"\n", asus_token);
8871			websWrite(wp,"}\n" );
8872		}
8873		return 1;
8874	}else{
8875		websWrite(wp,"Connection: close\r\n" );
8876		websWrite(wp,"\r\n" );
8877		if(fromapp_flag != 0){
8878			websWrite(wp, "{\n\"error_status\":\"%d\"\n}\n", ACCOUNTFAIL);
8879		}else{
8880			login_try++;
8881			last_login_timestamp = login_timestamp_tmp;
8882			websWrite(wp,"<HTML><HEAD>\n" );
8883			if(login_try >= MAX_login){
8884				lock_flag = 1;
8885#ifdef RTCONFIG_NOTIFICATION_CENTER
8886				temp_ip_addr.s_addr = login_ip_tmp;
8887				temp_ip_str = inet_ntoa(temp_ip_addr);
8888				NOTIFY_EVENT_T *e = initial_nt_event();
8889				e->event = LOGIN_FAIL_LAN_WEB_EVENT;
8890				snprintf(e->msg, sizeof(e->msg), "%s", temp_ip_str);
8891				send_trigger_event(e);
8892				nt_event_free(e);
8893#endif
8894				websWrite(wp,"<script>parent.location.href='/Main_Login.asp?error_status=%d&lock_time=%ld';</script>\n",LOGINLOCK, dt);
8895			}else
8896				websWrite(wp,"<script>parent.location.href='/Main_Login.asp?error_status=%d';</script>\n",ACCOUNTFAIL);
8897			websWrite(wp,"</HEAD></HTML>\n" );
8898		}
8899		return 0;
8900	}
8901}
8902
8903static void
8904do_login_cgi(char *url, FILE *stream)
8905{
8906    login_cgi(stream, NULL, NULL, 0, url, NULL, NULL);
8907}
8908
8909
8910static void
8911app_call(char *func, FILE *stream)
8912{
8913	char *args, *end, *next;
8914	int argc;
8915	char * argv[16]={NULL};
8916	int app_method_hit = 0;
8917	struct ej_handler *handler;
8918
8919	/* Parse out ( args ) */
8920	if (!(args = strchr(func, '(')))
8921		return;
8922	if (!(end = unqstrstr_t(func, ")")))
8923		return;
8924	*args++ = *end = '\0';
8925	/* Set up argv list */
8926	for (argc = 0; argc < 16 && args && *args; argc++, args = next) {
8927		if (!(argv[argc] = get_arg_t(args, &next)))
8928			break;
8929	}
8930	if(strcmp(func, "nvram_get") == 0){
8931		websWrite(stream,"\"%s\":", argv[0]);
8932		websWrite(stream,"\"" );
8933	}else if(argv[0] != NULL && strcmp(argv[0], "appobj") == 0){
8934		websWrite(stream,"\"%s\":", func);
8935		websWrite(stream,"{" );
8936	}else if(argv[0] != NULL)
8937		websWrite(stream,"\"%s-%s\":", func, argv[0]);
8938	else
8939		websWrite(stream,"\"%s\":", func);
8940
8941	/* Call handler */
8942	for (handler = &ej_handlers[0]; handler->pattern; handler++) {
8943//		if (strncmp(handler->pattern, func, strlen(handler->pattern)) == 0)
8944		if (strcmp(handler->pattern, func) == 0){
8945			handler->output(0, stream, argc, argv);
8946			app_method_hit = 1;
8947		}
8948	}
8949	if (app_method_hit == 0 && strcmp(argv[0], "appobj") != 0)
8950		websWrite(stream,"\"\"");	//Not Support
8951
8952	if(strcmp(func, "nvram_get") == 0)
8953		websWrite(stream,"\"" );
8954	else if(argv[0] != NULL && strcmp(argv[0], "appobj") == 0)
8955		websWrite(stream,"}" );
8956}
8957
8958static void
8959do_appGet_cgi(char *url, FILE *stream)
8960{
8961	char *pattern;
8962	int firstRow=1;
8963
8964	pattern = websGetVar(wp, "hook","");
8965
8966	char *pattern_t = strtok(pattern, ";");
8967
8968	websWrite(stream,"{\n" );
8969
8970	while (pattern_t != NULL){
8971		if (firstRow == 1)
8972			firstRow = 0;
8973		else
8974			websWrite(stream, ",\n");
8975
8976		//websWrite(stream,"\"%s\":", pattern_t);
8977
8978		app_call(pattern_t, stream);
8979
8980		pattern_t = strtok(NULL, ";");
8981	}
8982
8983	websWrite(stream,"\n}\n" );
8984}
8985
8986
8987static void
8988do_appGet_image_path_cgi(char *url, FILE *stream)
8989{
8990
8991	websWrite(stream,"{\n" );
8992
8993	websWrite(stream, "\"IMAGE_MODEL_PRODUCT\":\"%s\",\n", IMAGE_MODEL_PRODUCT);
8994	websWrite(stream, "\"IMAGE_WANUNPLUG\":\"%s\",\n", IMAGE_WANUNPLUG);
8995	websWrite(stream, "\"IMAGE_ROUTER_MODE\":\"%s\",\n", IMAGE_ROUTER_MODE);
8996	websWrite(stream, "\"IMAGE_REPEATER_MODE\":\"%s\",\n", IMAGE_REPEATER_MODE);
8997	websWrite(stream, "\"IMAGE_AP_MODE\":\"%s\",\n", IMAGE_AP_MODE);
8998	websWrite(stream, "\"IMAGE_MEDIA_BRIDGE_MODE\":\"%s\"\n", IMAGE_MEDIA_BRIDGE_MODE);
8999
9000	websWrite(stream,"\n}\n" );
9001}
9002
9003static void
9004do_qis_default(char *url, FILE *stream)
9005{
9006	char *flag;
9007	flag = websGetVar(wp, "flag","");
9008	if(!strcmp(flag, "sitesurvey"))
9009		websRedirect(stream, "QIS_wizard.htm?flag=sitesurvey");
9010	else
9011		websRedirect(stream, "QIS_wizard.htm?flag=welcome");
9012}
9013
9014#ifdef RTCONFIG_IFTTT
9015static void
9016do_get_IFTTTPincode_cgi(char *url, FILE *stream)
9017{
9018	char asus_token[32];
9019	char ifttt_pincode[64]={0};
9020	int fromapp_flag = 0;
9021	char *macaddr;
9022
9023#if defined(RTCONFIG_RGMII_BRCM5301X) || defined(RTCONFIG_QCA) || defined(RTAC3100)
9024	macaddr = nvram_safe_get("lan_hwaddr");
9025#else
9026	macaddr = nvram_safe_get("et0macaddr");
9027#endif
9028	strncpy(asus_token, generate_token(), sizeof(asus_token));
9029	add_asus_token(asus_token);
9030
9031	memset(ifttt_pincode, 0, 64);
9032	sprintf(ifttt_pincode, "%s_%s",macaddr ,asus_token);
9033
9034	websWrite(stream,"{\n" );
9035	websWrite(stream,"\"ifttt_pincode\":\"%s\"\n", ifttt_pincode);
9036	websWrite(stream,"}\n" );
9037}
9038#endif
9039
9040static void
9041do_check_Auth_cgi(char *url, FILE *stream)
9042{
9043	websWrite(stream,"{\n" );
9044	websWrite(stream,"\"asus_auth\":\"OK\"\n");
9045	websWrite(stream,"}\n" );
9046
9047}
9048
9049//2008.08 magic{
9050struct mime_handler mime_handlers[] = {
9051	{ "Main_Login.asp", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9052	{ "Nologin.asp", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9053	{ "error_page.htm*", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9054	{ "blocking.asp", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9055	{ "gotoHomePage.htm", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9056	{ "ure_success.htm", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9057	{ "ureip.asp", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9058	{ "remote.asp", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9059	{ "js/jquery.js", "text/javascript", no_cache_IE7, NULL, do_file, NULL }, // 2010.09 James.
9060	{ "require/require.min.js", "text/javascript", no_cache_IE7, NULL, do_file, NULL },
9061	{ "httpd_check.xml", "text/xml", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9062	{ "httpd_check.json", "application/json", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9063	{ "findasus.json", "application/json", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9064	{ "get_webdavInfo.asp", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9065	{ "appGet_image_path.cgi", "text/html", no_cache_IE7, do_html_post_and_get, do_appGet_image_path_cgi, NULL },
9066	{ "login.cgi", "text/html", no_cache_IE7, do_html_post_and_get, do_login_cgi, NULL },
9067	{ "update_clients.asp", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9068	{ "manifest.appcache", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9069	{ "offline.htm", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9070	{ "wcdma_list.js", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9071	{ "help_content.js", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9072	{ "httpd_check.htm", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9073	{ "manifest.asp", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9074	{ "update_cloudstatus.asp", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9075	{ "update_applist.asp", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9076	{ "update_appstate.asp", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9077	{ "WAN_info.asp", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9078#ifdef RTCONFIG_FINDASUS
9079	{ "findasus.cgi", "text/html", no_cache_IE7, do_html_post_and_get, do_findasus_cgi, NULL },
9080	{ "find_device.asp", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, NULL },
9081#endif
9082	{ "**.xml", "text/xml", no_cache_IE7, do_html_post_and_get, do_ej, do_auth },
9083	{ "**.htm*", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, do_auth },
9084	{ "**.asp*", "text/html", no_cache_IE7, do_html_post_and_get, do_ej, do_auth },
9085	{ "**.appcache", "text/cache-manifest", no_cache_IE7, do_html_post_and_get, do_ej, do_auth },
9086
9087#ifdef RTCONFIG_DSL_TCLINUX
9088	{ "TCC.log.*", "application/octet-stream", NULL, NULL, do_diag_log_file, do_auth },
9089#endif
9090	{ "**.gz", "application/octet-stream", NULL, NULL, do_file, NULL },
9091	{ "**.tgz", "application/octet-stream", NULL, NULL, do_file, NULL },
9092	{ "**.zip", "application/octet-stream", NULL, NULL, do_file, NULL },
9093	{ "**.ipk", "application/octet-stream", NULL, NULL, do_file, NULL },
9094	{ "**.css", "text/css", NULL, NULL, do_file, NULL },
9095	{ "**.png", "image/png", cache_object, NULL, do_file, NULL },
9096	{ "**.gif", "image/gif", cache_object, NULL, do_file, NULL },
9097	{ "**.jpg", "image/jpeg", cache_object, NULL, do_file, NULL },
9098	// Viz 2010.08
9099	{ "**.svg", "image/svg+xml", NULL, NULL, do_file, NULL },
9100	{ "**.swf", "application/x-shockwave-flash", NULL, NULL, do_file, NULL  },
9101	{ "**.htc", "text/x-component", NULL, NULL, do_file, NULL  },
9102	// end Viz
9103#ifdef TRANSLATE_ON_FLY
9104	/* Only general.js and quick.js are need to translate. (reduce translation time) */
9105	{ "general.js|quick.js",  "text/javascript", no_cache_IE7, NULL, do_ej, do_auth },
9106#endif //TRANSLATE_ON_FLY
9107
9108	{ "**.js",  "text/javascript", no_cache_IE7, NULL, do_ej, do_auth },
9109	{ "**.cab", "text/txt", NULL, NULL, do_file, do_auth },
9110	{ "**.CFG", "application/force-download", NULL, do_html_post_and_get, do_prf_file, do_auth },
9111	{ "uploadIconFile.tar", "application/force-download", NULL, NULL, do_uploadIconFile_file, do_auth },
9112	{ "networkmap.tar", "application/force-download", NULL, NULL, do_networkmap_file, do_auth },
9113	{ "upnp.log", "application/force-download", NULL, NULL, do_upnp_file, do_auth },
9114	{ "upnpc_xml.log", "application/force-download", NULL, NULL, do_upnpc_xml_file, do_auth },
9115	{ "mDNSNetMonitor.log", "application/force-download", NULL, NULL, do_dnsnet_file, do_auth },
9116	{ "ftpServerTree.cgi*", "text/html", no_cache_IE7, do_html_post_and_get, do_ftpServerTree_cgi, do_auth },//andi
9117	{ "**.ovpn", "application/force-download", NULL, NULL, do_prf_ovpn_file, do_auth },
9118	{ "QIS_default.cgi", "text/html", no_cache_IE7, do_html_post_and_get, do_qis_default, do_auth },
9119	{ "apply.cgi*", "text/html", no_cache_IE7, do_html_post_and_get, do_apply_cgi, do_auth },
9120	{ "applyapp.cgi*", "text/html", no_cache_IE7, do_html_post_and_get, do_apply_cgi, do_auth },
9121	{ "appGet.cgi*", "text/html", no_cache_IE7, do_html_post_and_get, do_appGet_cgi, do_auth },
9122	{ "upgrade.cgi*", "text/html", no_cache_IE7, do_upgrade_post, do_upgrade_cgi, do_auth},
9123	{ "upload.cgi*", "text/html", no_cache_IE7, do_upload_post, do_upload_cgi, do_auth },
9124#ifdef RTCONFIG_IFTTT
9125	{ "get_IFTTTPincode.cgi", "text/html", no_cache_IE7, do_html_post_and_get, do_get_IFTTTPincode_cgi, do_auth },
9126#endif
9127	{ "check_Auth.cgi", "text/html", no_cache_IE7, do_html_post_and_get, do_check_Auth_cgi, do_auth },
9128	{ "syslog.txt*", "application/force-download", syslog_txt, do_html_post_and_get, do_log_cgi, do_auth },
9129#ifdef RTCONFIG_QTN  //RT-AC87U
9130	{ "tmp/qtn_diagnostics.cgi*", "application/force-download", NULL, NULL, do_qtn_diagnostics, do_auth },
9131#endif
9132#ifdef RTCONFIG_USB_MODEM
9133	{ "modemlog.txt*", "application/force-download", modemlog_txt, do_html_post_and_get, do_modemlog_cgi, do_auth },
9134#endif
9135#ifdef RTCONFIG_TCPDUMP
9136	{ "udhcpc.pcap*", "application/force-download", NULL, NULL, do_file, NULL },
9137#endif
9138#ifdef RTCONFIG_DSL
9139	{ "dsllog.cgi*", "text/txt", no_cache_IE7, do_html_post_and_get, do_adsllog_cgi, do_auth },
9140#endif
9141	// Viz 2010.08 vvvvv
9142	{ "update.cgi*", "text/javascript", no_cache_IE7, do_html_post_and_get, do_update_cgi, do_auth }, // jerry5
9143	{ "bwm/*.gz", NULL, no_cache, do_html_post_and_get, wo_bwmbackup, do_auth }, // jerry5
9144	// end Viz  ^^^^^^^^
9145#ifdef TRANSLATE_ON_FLY
9146	{ "change_lang.cgi*", "text/html", no_cache_IE7, do_lang_post, do_lang_cgi, do_auth },
9147#endif //TRANSLATE_ON_FLY
9148#ifdef RTCONFIG_OPENVPN
9149	{ "vpnupload.cgi*", "text/html", no_cache_IE7, do_vpnupload_post, do_vpnupload_cgi, do_auth },
9150#endif
9151	{ "deleteOfflineClient.cgi*", "text/html", no_cache_IE7, do_html_post_and_get, do_deleteOfflineClient_cgi, do_auth },
9152	{ NULL, NULL, NULL, NULL, NULL, NULL }
9153};
9154
9155// some should be removed
9156struct except_mime_handler except_mime_handlers[] = {
9157	{ "QIS_default.cgi", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9158	{ "images/New_ui/login_bg.png", MIME_EXCEPTION_MAINPAGE},
9159	{ "images/New_ui/icon_titleName.png", MIME_EXCEPTION_MAINPAGE},
9160#if 0
9161	{ "QIS_*", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9162	{ "qis/*", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9163	{ "*.css", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9164	{ "state.js", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9165	{ "popup.js", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9166	{ "general.js", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9167	{ "help.js", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9168	{ "help_content.js", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9169	{ "validator.js", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9170	{ "form.js", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9171	{ "alttxt.js", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9172	{ "start_autodet.asp", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9173#ifdef RTCONFIG_QCA_PLC_UTILS
9174	{ "start_plcdet.asp", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9175#endif
9176	{ "start_dsl_autodet.asp", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9177	{ "start_apply.htm", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9178	{ "start_apply2.htm", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9179	{ "apply.cgi", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9180	{ "setting_lan.htm", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9181	{ "status.asp", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9182	{ "automac.asp", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9183	{ "detecWAN.asp", MIME_EXCEPTION_NORESETTIME},
9184	{ "detecWAN2.asp", MIME_EXCEPTION_NORESETTIME},
9185	{ "WPS_info.xml", MIME_EXCEPTION_NORESETTIME},
9186	{ "WAN_info.asp", MIME_EXCEPTION_NOAUTH_ALL|MIME_EXCEPTION_NORESETTIME},
9187	{ "result_of_get_changed_status.asp", MIME_EXCEPTION_NORESETTIME},
9188	{ "result_of_get_changed_status_QIS.asp", MIME_EXCEPTION_NOAUTH_FIRST|MIME_EXCEPTION_NORESETTIME},
9189	{ "result_of_detect_client.asp", MIME_EXCEPTION_NORESETTIME},
9190	{ "detect_firmware.asp", MIME_EXCEPTION_NOAUTH_ALL},
9191	{ "Nologin.asp", MIME_EXCEPTION_NOAUTH_ALL},
9192	{ "alertImg.gif", MIME_EXCEPTION_NOAUTH_ALL},
9193	{ "error_page.htm", MIME_EXCEPTION_NOAUTH_ALL},
9194	{ "jquery.js", MIME_EXCEPTION_NOAUTH_ALL},
9195	{ "require/require.min.js", MIME_EXCEPTION_NOAUTH_ALL},
9196	{ "gotoHomePage.htm", MIME_EXCEPTION_NOAUTH_ALL},
9197	{ "update_appstate.asp", MIME_EXCEPTION_NOAUTH_ALL},
9198	{ "update_applist.asp", MIME_EXCEPTION_NOAUTH_ALL},
9199	{ "update_cloudstatus.asp", MIME_EXCEPTION_NOAUTH_ALL},
9200	{ "upload.cgi", MIME_EXCEPTION_NOAUTH_FIRST},
9201	{ "Uploading.asp", MIME_EXCEPTION_NOAUTH_FIRST},
9202	{ "UploadError.asp", MIME_EXCEPTION_NOAUTH_FIRST},
9203	{ "blocking.asp", MIME_EXCEPTION_NOAUTH_ALL},
9204	{ "images/New_ui/tm_logo_1.png", MIME_EXCEPTION_NOAUTH_ALL},
9205	{ "*.gz", MIME_EXCEPTION_NOAUTH_ALL},
9206	{ "*.tgz", MIME_EXCEPTION_NOAUTH_ALL},
9207	{ "*.zip", MIME_EXCEPTION_NOAUTH_ALL},
9208	{ "*.ipk", MIME_EXCEPTION_NOAUTH_ALL},
9209#ifdef RTCONFIG_FINDASUS
9210	{ "find_device.asp", MIME_EXCEPTION_NOAUTH_ALL},
9211#endif
9212	{ "Main_Login.asp", MIME_EXCEPTION_NOAUTH_ALL},
9213	{ "manifest.appcache", MIME_EXCEPTION_NOAUTH_ALL},
9214	{ "manifest.asp", MIME_EXCEPTION_NOAUTH_ALL},
9215	{ "offline.htm", MIME_EXCEPTION_NOAUTH_ALL},
9216	{ "httpd_check.htm", MIME_EXCEPTION_NOAUTH_ALL},
9217	{ "httpd_check.json", MIME_EXCEPTION_NOAUTH_ALL},
9218	{ "findasus.json", MIME_EXCEPTION_NOAUTH_ALL},
9219	{ "help_content.js", MIME_EXCEPTION_NOAUTH_ALL},
9220	{ "wcdma_list.js", MIME_EXCEPTION_NOAUTH_ALL},
9221	{ "update_clients.asp", MIME_EXCEPTION_NOAUTH_ALL},
9222#endif
9223	{ NULL, 0 }
9224};
9225
9226// some should be referer
9227struct mime_referer mime_referers[] = {
9228	{ "start_apply.htm", CHECK_REFERER},
9229	{ "start_apply2.htm", CHECK_REFERER},
9230	{ "api.asp", CHECK_REFERER},
9231	{ "applyapp.cgi", CHECK_REFERER},
9232	{ "apply.cgi", CHECK_REFERER},
9233	{ "upgrade.cgi", CHECK_REFERER},
9234	{ "upload.cgi", CHECK_REFERER},
9235	{ "dsllog.cgi", CHECK_REFERER},
9236	{ "update.cgi", CHECK_REFERER},
9237	{ "vpnupload.cgi", CHECK_REFERER},
9238	{ "findasus.cgi", CHECK_REFERER},
9239	{ "ftpServerTree.cgi", CHECK_REFERER},
9240	{ NULL, 0 }
9241};
9242
9243//2008.08 magic}
9244#ifdef RTCONFIG_USB
9245int ej_get_AiDisk_status(int eid, webs_t wp, int argc, char **argv){
9246	disk_info_t *disks_info, *follow_disk;
9247	partition_info_t *follow_partition;
9248	int sh_num;
9249	char **folder_list = NULL;
9250	int first_pool, result, i;
9251
9252	websWrite(wp, "function get_cifs_status(){\n");
9253	//websWrite(wp, "    return %d;\n", nvram_get_int("samba_running"));
9254	websWrite(wp, "    return %d;\n", nvram_get_int("enable_samba"));
9255	websWrite(wp, "}\n\n");
9256
9257	websWrite(wp, "function get_ftp_status(){\n");
9258	//websWrite(wp, "    return %d;\n", nvram_get_int("ftp_running"));
9259	websWrite(wp, "    return %d;\n", nvram_get_int("enable_ftp"));
9260	websWrite(wp, "}\n\n");
9261
9262#ifdef RTCONFIG_WEBDAV_PENDING
9263	websWrite(wp, "function get_webdav_status(){\n");
9264	//websWrite(wp, "    return %d;\n", nvram_get_int("ftp_running"));
9265	websWrite(wp, "    return %d;\n", nvram_get_int("enable_webdav"));
9266	websWrite(wp, "}\n\n");
9267#endif
9268
9269	websWrite(wp, "function get_dms_status(){\n");
9270	websWrite(wp, "    return %d;\n", pids("ushare"));
9271	websWrite(wp, "}\n\n");
9272
9273	websWrite(wp, "function get_share_management_status(protocol){\n");
9274	websWrite(wp, "    if (protocol == \"cifs\")\n");
9275	websWrite(wp, "	return %d;\n", (nvram_get("st_samba_force_mode") == NULL && nvram_get_int("st_samba_mode") == 1)?4:nvram_get_int("st_samba_mode"));
9276	websWrite(wp, "    else if (protocol == \"ftp\")\n");
9277	websWrite(wp, "	return %d;\n", (nvram_get("st_ftp_force_mode") == NULL && nvram_get_int("st_ftp_mode") == 1)?2:nvram_get_int("st_ftp_mode"));
9278#ifdef RTCONFIG_WEBDAV_PENDING
9279	websWrite(wp, "    else if (protocol == \"webdav\")\n");
9280	websWrite(wp, "	return %d;\n", nvram_get_int("st_webdav_mode"));
9281#endif
9282	websWrite(wp, "    else\n");
9283	websWrite(wp, "	return -1;\n");
9284	websWrite(wp, "}\n\n");
9285
9286	disks_info = read_disk_data();
9287	if (disks_info == NULL){
9288		websWrite(wp, "function get_sharedfolder_in_pool(poolName){}\n");
9289		return -1;
9290	}
9291	first_pool = 1;
9292	websWrite(wp, "function get_sharedfolder_in_pool(poolName){\n");
9293	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next)
9294		for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next){
9295			if (follow_partition->mount_point != NULL && strlen(follow_partition->mount_point) > 0){
9296				websWrite(wp, "    ");
9297
9298				if (first_pool == 1)
9299					first_pool = 0;
9300				else
9301					websWrite(wp, "else ");
9302
9303#ifdef OLD_AIDISK
9304				websWrite(wp, "if (poolName == \"%s\"){\n", rindex(follow_partition->mount_point, '/')+1);
9305#else
9306				websWrite(wp, "if (poolName == \"%s\"){\n", follow_partition->device);
9307#endif
9308				websWrite(wp, "	return [\"\"");
9309
9310				result = get_all_folder(follow_partition->mount_point, &sh_num, &folder_list);
9311				if (result < 0){
9312					websWrite(wp, "];\n");
9313					websWrite(wp, "    }\n");
9314
9315					printf("get_AiDisk_status: Can't get the folder list in \"%s\".\n", follow_partition->mount_point);
9316
9317					free_2_dimension_list(&sh_num, &folder_list);
9318
9319					continue;
9320				}
9321
9322				for (i = 0; i < sh_num; ++i){
9323					websWrite(wp, ", ");
9324
9325					websWrite(wp, "\"%s\"", folder_list[i]);
9326#if 0
9327//	tmp test
9328					printf("[httpd] chk folder list[%s]:\n", folder_list[i]);
9329					for (j=0; j<strlen(folder_list[i]); ++j)
9330					{
9331						printf("[%x] ", folder_list[i][j]);
9332					}
9333					printf("\nlen:(%d)\n", strlen(folder_list[i]));
9334//	tmp test ~
9335#endif
9336
9337				}
9338
9339				websWrite(wp, "];\n");
9340				websWrite(wp, "    }\n");
9341			}
9342		}
9343
9344	websWrite(wp, "}\n\n");
9345
9346	if (disks_info != NULL){
9347		free_2_dimension_list(&sh_num, &folder_list);
9348		free_disk_data(&disks_info);
9349	}
9350
9351	return 0;
9352}
9353
9354int ej_get_all_accounts(int eid, webs_t wp, int argc, char **argv){
9355	int acc_num;
9356	char **account_list = NULL;
9357	int result, i, first;
9358	char ascii_user[64];
9359
9360	if ((result = get_account_list(&acc_num, &account_list)) < 0){
9361		printf("Failed to get the account list!\n");
9362		return -1;
9363	}
9364
9365	first = 1;
9366	for (i = 0; i < acc_num; ++i){
9367		if (first == 1)
9368			first = 0;
9369		else
9370			websWrite(wp, ", ");
9371
9372		memset(ascii_user, 0, 64);
9373		char_to_ascii_safe(ascii_user, account_list[i], 64);
9374
9375		websWrite(wp, "\"%s\"", ascii_user);
9376	}
9377
9378	free_2_dimension_list(&acc_num, &account_list);
9379	return 0;
9380}
9381
9382int
9383count_sddev_mountpoint()
9384{
9385	FILE *procpt;
9386	char line[PATH_MAX], devname[32], mpname[32], system_type[10], mount_mode[PATH_MAX];
9387	int dummy1, dummy2, count = 0;
9388
9389	if((procpt = fopen(MOUNT_FILE, "r")) != NULL){
9390		while(fgets(line, sizeof(line), procpt)){
9391			if(sscanf(line, "%s %s %s %s %d %d", devname, mpname, system_type, mount_mode, &dummy1, &dummy2) != 6)
9392				continue;
9393
9394			if(strstr(devname, "/dev/sd"))
9395				count++;
9396		}
9397	}
9398
9399	if(procpt)
9400		fclose(procpt);
9401
9402	return count;
9403}
9404
9405static int notify_rc_for_nas(char *cmd)
9406{
9407	notify_rc_and_wait(cmd);
9408	return 0;
9409}
9410
9411static int ej_safely_remove_disk(int eid, webs_t wp, int argc, char_t **argv){
9412	int result;
9413	char *disk_port = websGetVar(wp, "disk", "");
9414//	disk_info_t *disks_info = NULL, *follow_disk = NULL;
9415//	int disk_num = 0;
9416	int part_num = 0;
9417	char *fn = "safely_remove_disk_error";
9418
9419	csprintf("disk_port = %s\n", disk_port);
9420
9421	if(!strcmp(disk_port, "all")){
9422		result = eval("/sbin/ejusb", "-1", "0");
9423	}
9424	else{
9425		result = eval("/sbin/ejusb", disk_port, "0");
9426	}
9427
9428	if (result != 0){
9429		insert_hook_func(wp, fn, "alert_msg.Action9");
9430		return -1;
9431	}
9432
9433/*
9434	disks_info = read_disk_data();
9435	for(follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next, ++disk_num)
9436		;
9437	free_disk_data(&disks_info);
9438	csprintf("disk_num = %d\n", disk_num);
9439*/
9440
9441	part_num = count_sddev_mountpoint();
9442	csprintf("part_num = %d\n", part_num);
9443
9444//	if (disk_num > 1)
9445	if (part_num > 0)
9446	{
9447		result = eval("/sbin/check_proc_mounts_parts");
9448		result = notify_rc_for_nas("restart_nasapps");
9449	}
9450	else
9451	{
9452		result = notify_rc_for_nas("stop_nasapps");
9453	}
9454
9455	insert_hook_func(wp, "safely_remove_disk_success", "");
9456
9457	return 0;
9458}
9459
9460int ej_get_permissions_of_account(int eid, webs_t wp, int argc, char **argv){
9461	disk_info_t *disks_info, *follow_disk;
9462	partition_info_t *follow_partition;
9463	int acc_num = 0, sh_num = 0;
9464	char *account, **account_list = NULL, **folder_list;
9465	int samba_right, ftp_right;
9466#ifdef RTCONFIG_WEBDAV_PENDING
9467	int webdav_right;
9468#endif
9469	int result, i, j;
9470	int first_pool, first_account;
9471	char ascii_user[64];
9472
9473	disks_info = read_disk_data();
9474	if (disks_info == NULL){
9475		websWrite(wp, "function get_account_permissions_in_pool(account, pool){return [];}\n");
9476		return -1;
9477	}
9478
9479	result = get_account_list(&acc_num, &account_list);
9480	if (result < 0){
9481		printf("1. Can't get the account list.\n");
9482		free_2_dimension_list(&acc_num, &account_list);
9483		free_disk_data(&disks_info);
9484	}
9485
9486	websWrite(wp, "function get_account_permissions_in_pool(account, pool){\n");
9487
9488	first_account = 1;
9489	for (i = -1; i < acc_num; ++i){
9490		websWrite(wp, "    ");
9491		if (first_account == 1)
9492			first_account = 0;
9493		else
9494			websWrite(wp, "else ");
9495
9496		if(i == -1){ // share mode.
9497			account = NULL;
9498
9499			websWrite(wp, "if (account == null){\n");
9500		}
9501		else{
9502			account = account_list[i];
9503
9504			memset(ascii_user, 0, 64);
9505			char_to_ascii_safe(ascii_user, account, 64);
9506
9507			websWrite(wp, "if (account == \"%s\"){\n", ascii_user);
9508		}
9509
9510		first_pool = 1;
9511		for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next){
9512			for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next){
9513				if (follow_partition->mount_point != NULL && strlen(follow_partition->mount_point) > 0){
9514					websWrite(wp, "	");
9515					if (first_pool == 1)
9516						first_pool = 0;
9517					else
9518						websWrite(wp, "else ");
9519
9520#ifdef OLD_AIDISK
9521					websWrite(wp, "if (pool == \"%s\"){\n", rindex(follow_partition->mount_point, '/')+1);
9522#else
9523					websWrite(wp, "if (pool == \"%s\"){\n", follow_partition->device);
9524#endif
9525
9526					websWrite(wp, "	    return [");
9527
9528					result = get_all_folder(follow_partition->mount_point, &sh_num, &folder_list);
9529
9530					// Pool's permission.
9531					samba_right = get_permission(account, follow_partition->mount_point, NULL, "cifs");
9532					if (samba_right < 0 || samba_right > 3){
9533						printf("Can't get the CIFS permission abount the pool: %s!\n", follow_partition->device);
9534
9535						if(account == NULL || !strcmp(account, nvram_safe_get("http_username")))
9536							samba_right = DEFAULT_SAMBA_RIGHT;
9537						else
9538							samba_right = 0;
9539					}
9540
9541					ftp_right = get_permission(account, follow_partition->mount_point, NULL, "ftp");
9542					if (ftp_right < 0 || ftp_right > 3){
9543						printf("Can't get the FTP permission abount the pool: %s!\n", follow_partition->device);
9544
9545						if(account == NULL || !strcmp(account, nvram_safe_get("http_username")))
9546							ftp_right = DEFAULT_FTP_RIGHT;
9547						else
9548							ftp_right = 0;
9549					}
9550
9551#ifdef RTCONFIG_WEBDAV_PENDING
9552					webdav_right = get_permission(account, follow_partition->mount_point, NULL, "webdav");
9553					if (webdav_right < 0 || webdav_right > 3){
9554						printf("Can't get the WEBDAV  permission abount the pool: %s!\n", follow_partition->device);
9555
9556						if(account == NULL || !strcmp(account, nvram_safe_get("http_username")))
9557							webdav_right = DEFAULT_WEBDAV_RIGHT;
9558						else
9559							webdav_right = 0;
9560					}
9561#endif
9562
9563#ifdef RTCONFIG_WEBDAV_PENDING
9564					websWrite(wp, "[\"\", %d, %d, %d]", samba_right, ftp_right, webdav_right);
9565#else
9566					websWrite(wp, "[\"\", %d, %d]", samba_right, ftp_right);
9567#endif
9568					if (result == 0 && sh_num > 0)
9569						websWrite(wp, ",\n");
9570
9571					if (result != 0){
9572						websWrite(wp, "];\n");
9573						websWrite(wp, "	}\n");
9574
9575						printf("get_permissions_of_account1: Can't get all folders in \"%s\".\n", follow_partition->mount_point);
9576
9577						free_2_dimension_list(&sh_num, &folder_list);
9578
9579						continue;
9580					}
9581
9582					// Folder's permission.
9583					for (j = 0; j < sh_num; ++j){
9584						samba_right = get_permission(account, follow_partition->mount_point, folder_list[j], "cifs");
9585						ftp_right = get_permission(account, follow_partition->mount_point, folder_list[j], "ftp");
9586#ifdef RTCONFIG_WEBDAV_PENDING
9587						webdav_right = get_permission(account, follow_partition->mount_point, folder_list[j], "webdav");
9588#endif
9589
9590						if (samba_right < 0 || samba_right > 3){
9591							printf("Can't get the CIFS permission abount \"%s\"!\n", folder_list[j]);
9592
9593							if(account == NULL || !strcmp(account, nvram_safe_get("http_username")))
9594								samba_right = DEFAULT_SAMBA_RIGHT;
9595							else
9596								samba_right = 0;
9597						}
9598
9599						if (ftp_right < 0 || ftp_right > 3){
9600							printf("Can't get the FTP permission abount \"%s\"!\n", folder_list[j]);
9601
9602							if(account == NULL || !strcmp(account, nvram_safe_get("http_username")))
9603								ftp_right = DEFAULT_FTP_RIGHT;
9604							else
9605								ftp_right = 0;
9606						}
9607
9608#ifdef RTCONFIG_WEBDAV_PENDING
9609						if (webdav_right < 0 || webdav_right > 3){
9610							printf("Can't get the WEBDAV permission abount \"%s\"!\n", folder_list[j]);
9611
9612							if(account == NULL || !strcmp(account, nvram_safe_get("http_username")))
9613								webdav_right = DEFAULT_WEBDAV_RIGHT;
9614							else
9615								webdav_right = 0;
9616						}
9617#endif
9618
9619#ifdef RTCONFIG_WEBDAV_PENDING
9620						websWrite(wp, "		    [\"%s\", %d, %d, %d]", folder_list[j], samba_right, ftp_right, webdav_right);
9621#else
9622						websWrite(wp, "		    [\"%s\", %d, %d]", folder_list[j], samba_right, ftp_right);
9623#endif
9624
9625						if (j != sh_num-1)
9626							websWrite(wp, ",\n");
9627					}
9628					free_2_dimension_list(&sh_num, &folder_list);
9629
9630					websWrite(wp, "];\n");
9631					websWrite(wp, "	}\n");
9632				}
9633			}
9634		}
9635
9636		websWrite(wp, "    }\n");
9637
9638	}
9639	free_2_dimension_list(&acc_num, &account_list);
9640
9641	websWrite(wp, "}\n\n");
9642
9643	if (disks_info != NULL)
9644		free_disk_data(&disks_info);
9645
9646	return 0;
9647}
9648
9649int ej_get_folder_tree(int eid, webs_t wp, int argc, char **argv){
9650	char *layer_order = websGetVar(wp, "layer_order", "");
9651	char *follow_info, *follow_info_end, backup;
9652	int layer = 0, first;
9653	int disk_count, partition_count, folder_count;
9654	int disk_order = -1, partition_order = -1;
9655	disk_info_t *disks_info, *follow_disk;
9656	partition_info_t *follow_partition;
9657
9658	if (strlen(layer_order) <= 0){
9659		printf("No input \"layer_order\"!\n");
9660		return -1;
9661	}
9662
9663	follow_info = index(layer_order, '_');
9664	while (follow_info != NULL && *follow_info != 0){
9665		++layer;
9666		++follow_info;
9667		if (*follow_info == 0)
9668			break;
9669		follow_info_end = follow_info;
9670		while (*follow_info_end != 0 && isdigit(*follow_info_end))
9671			++follow_info_end;
9672		backup = *follow_info_end;
9673		*follow_info_end = 0;
9674
9675		if (layer == 1)
9676			disk_order = atoi(follow_info);
9677		else if (layer == 2)
9678			partition_order = atoi(follow_info);
9679		else{
9680			*follow_info_end = backup;
9681			printf("Input \"%s\" is incorrect!\n", layer_order);
9682			return -1;
9683		}
9684
9685		*follow_info_end = backup;
9686		follow_info = follow_info_end;
9687	}
9688
9689	disks_info = read_disk_data();
9690	if (disks_info == NULL){
9691		printf("Can't read the information of disks.\n");
9692		return -1;
9693	}
9694
9695	first = 1;
9696	disk_count = 0;
9697	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next, ++disk_count){
9698		partition_count = 0;
9699		for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next, ++partition_count){
9700			if (layer != 0 && follow_partition->mount_point != NULL && strlen(follow_partition->mount_point) > 0){
9701				int i;
9702				char **folder_list;
9703				int result;
9704				result = get_all_folder(follow_partition->mount_point, &folder_count, &folder_list);
9705				if (result < 0){
9706					printf("get_disk_tree: Can't get the folder list in \"%s\".\n", follow_partition->mount_point);
9707
9708					folder_count = 0;
9709				}
9710
9711				if (layer == 2 && disk_count == disk_order && partition_count == partition_order){
9712					for (i = 0; i < folder_count; ++i){
9713						if (first == 1)
9714							first = 0;
9715						else
9716							websWrite(wp, ", ");
9717
9718						websWrite(wp, "\"%s#%u#0\"", folder_list[i], i);
9719					}
9720				}
9721				else if (layer == 1 && disk_count == disk_order){
9722					if (first == 1)
9723						first = 0;
9724					else
9725						websWrite(wp, ", ");
9726
9727					follow_info = rindex(follow_partition->mount_point, '/');
9728					websWrite(wp, "\"%s#%u#%u\"", follow_info+1, partition_count, folder_count);
9729				}
9730
9731				free_2_dimension_list(&folder_count, &folder_list);
9732			}
9733		}
9734		if (layer == 0){
9735			if (first == 1)
9736				first = 0;
9737			else
9738				websWrite(wp, ", ");
9739
9740			websWrite(wp, "'%s#%u#%u'", follow_disk->tag, disk_count, partition_count);
9741		}
9742
9743		if (layer > 0 && disk_count == disk_order)
9744			break;
9745	}
9746
9747	free_disk_data(&disks_info);
9748
9749	return 0;
9750}
9751
9752int ej_get_share_tree(int eid, webs_t wp, int argc, char **argv){
9753	char *layer_order = websGetVar(wp, "layer_order", "");
9754	char *follow_info, *follow_info_end, backup;
9755	int layer = 0, first;
9756	int disk_count, partition_count, share_count;
9757	int disk_order = -1, partition_order = -1;
9758	disk_info_t *disks_info, *follow_disk;
9759	partition_info_t *follow_partition;
9760
9761	if (strlen(layer_order) <= 0){
9762		printf("No input \"layer_order\"!\n");
9763		return -1;
9764	}
9765
9766	follow_info = index(layer_order, '_');
9767	while (follow_info != NULL && *follow_info != 0){
9768		++layer;
9769		++follow_info;
9770		if (*follow_info == 0)
9771			break;
9772		follow_info_end = follow_info;
9773		while (*follow_info_end != 0 && isdigit(*follow_info_end))
9774			++follow_info_end;
9775		backup = *follow_info_end;
9776		*follow_info_end = 0;
9777
9778		if (layer == 1)
9779			disk_order = atoi(follow_info);
9780		else if (layer == 2)
9781			partition_order = atoi(follow_info);
9782		else{
9783			*follow_info_end = backup;
9784			printf("Input \"%s\" is incorrect!\n", layer_order);
9785			return -1;
9786		}
9787
9788		*follow_info_end = backup;
9789		follow_info = follow_info_end;
9790	}
9791
9792	disks_info = read_disk_data();
9793	if (disks_info == NULL){
9794		printf("Can't read the information of disks.\n");
9795		return -1;
9796	}
9797
9798	first = 1;
9799	disk_count = 0;
9800	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next, ++disk_count){
9801		partition_count = 0;
9802		for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next, ++partition_count){
9803			if (layer != 0 && follow_partition->mount_point != NULL && strlen(follow_partition->mount_point) > 0){
9804				int i;
9805				char **share_list;
9806				int result;
9807				result = get_folder_list(follow_partition->mount_point, &share_count, &share_list);
9808				if (result < 0){
9809					printf("get_disk_tree: Can't get the share list in \"%s\".\n", follow_partition->mount_point);
9810
9811					share_count = 0;
9812				}
9813
9814				if (layer == 2 && disk_count == disk_order && partition_count == partition_order){
9815					for (i = 0; i < share_count; ++i){
9816						if (first == 1)
9817							first = 0;
9818						else
9819							websWrite(wp, ", ");
9820
9821						websWrite(wp, "\"%s#%u#0\"", share_list[i], i);
9822					}
9823				}
9824				else if (layer == 1 && disk_count == disk_order){
9825					if (first == 1)
9826						first = 0;
9827					else
9828						websWrite(wp, ", ");
9829
9830					follow_info = rindex(follow_partition->mount_point, '/');
9831					websWrite(wp, "\"%s#%u#%u\"", follow_info+1, partition_count, share_count);
9832				}
9833
9834				free_2_dimension_list(&share_count, &share_list);
9835			}
9836		}
9837		if (layer == 0){
9838			if (first == 1)
9839				first = 0;
9840			else
9841				websWrite(wp, ", ");
9842
9843			websWrite(wp, "'%s#%u#%u'", follow_disk->tag, disk_count, partition_count);
9844		}
9845
9846		if (layer > 0 && disk_count == disk_order)
9847			break;
9848	}
9849
9850	free_disk_data(&disks_info);
9851
9852	return 0;
9853}
9854
9855void not_ej_initial_folder_var_file()
9856{
9857	disk_info_t *disks_info, *follow_disk;
9858	partition_info_t *follow_partition;
9859
9860	disks_info = read_disk_data();
9861	if (disks_info == NULL)
9862		return;
9863
9864	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next)
9865		for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next)
9866			if (follow_partition->mount_point != NULL && strlen(follow_partition->mount_point) > 0) {
9867				initial_folder_list(follow_partition->mount_point);
9868//				initial_all_var_file(follow_partition->mount_point);
9869			}
9870
9871	free_disk_data(&disks_info);
9872}
9873
9874int ej_initial_folder_var_file(int eid, webs_t wp, int argc, char **argv)
9875{
9876//	not_ej_initial_folder_var_file();
9877	return 0;
9878}
9879
9880int ej_set_share_mode(int eid, webs_t wp, int argc, char **argv){
9881
9882	struct json_object *root=NULL;
9883	root = json_tokener_parse(post_buf);
9884
9885	int samba_mode = nvram_get_int("st_samba_mode");
9886	int samba_force_mode = nvram_get_int("st_samba_force_mode");
9887	int ftp_mode = nvram_get_int("st_ftp_mode");
9888	int ftp_force_mode = nvram_get_int("st_ftp_force_mode");
9889#ifdef RTCONFIG_WEBDAV_PENDING
9890	int webdav_mode = nvram_get_int("st_webdav_mode");
9891#endif
9892	char *dummyShareway = get_cgi_json("dummyShareway", root);
9893	char *protocol = get_cgi_json("protocol", root);
9894	char *mode = get_cgi_json("mode", root);
9895	int result;
9896	char *fn = "set_share_mode_error";
9897
9898	if (!dummyShareway || strlen(dummyShareway) == 0){
9899		nvram_set("dummyShareway", "0");
9900	}else{
9901		nvram_set("dummyShareway", dummyShareway);
9902	}
9903
9904	if (strlen(protocol) <= 0){
9905		insert_hook_func(wp, fn, "alert_msg.Input1");
9906		json_object_put(root);
9907		return -1;
9908	}
9909	if (strlen(mode) <= 0){
9910		insert_hook_func(wp, fn, "alert_msg.Input3");
9911		json_object_put(root);
9912		return -1;
9913	}
9914	if (!strcmp(mode, "share")){
9915		if (!strcmp(protocol, "cifs")){
9916			if((samba_mode == 1 || samba_mode == 3) && samba_force_mode == 1)
9917				goto SET_SHARE_MODE_SUCCESS;
9918
9919			nvram_set("st_samba_mode", "1");	// for test
9920		}
9921		else if (!strcmp(protocol, "ftp")){
9922			if (ftp_mode == 1 && ftp_force_mode == 1)
9923				goto SET_SHARE_MODE_SUCCESS;
9924
9925			nvram_set("st_ftp_mode", "1");
9926		}
9927#ifdef RTCONFIG_WEBDAV_PENDING
9928		else if (!strcmp(protocol, "webdav")){
9929			if (webdav_mode == 1)
9930				goto SET_SHARE_MODE_SUCCESS;
9931
9932			nvram_set("st_webdav_mode", "1");
9933		}
9934#endif
9935		else{
9936			insert_hook_func(wp, fn, "alert_msg.Input2");
9937			json_object_put(root);
9938			return -1;
9939		}
9940	}
9941	else if (!strcmp(mode, "account")){
9942		if (!strcmp(protocol, "cifs")){
9943			if((samba_mode == 2 || samba_mode == 4) && samba_force_mode == 2)
9944				goto SET_SHARE_MODE_SUCCESS;
9945
9946			nvram_set("st_samba_mode", "4");
9947		}
9948		else if (!strcmp(protocol, "ftp")){
9949			if(ftp_mode == 2 && ftp_force_mode == 2)
9950				goto SET_SHARE_MODE_SUCCESS;
9951
9952			nvram_set("st_ftp_mode", "2");
9953		}
9954#ifdef RTCONFIG_WEBDAV_PENDING
9955		else if (!strcmp(protocol, "webdav")){
9956			if (webdav_mode == 2)
9957				goto SET_SHARE_MODE_SUCCESS;
9958
9959			nvram_set("st_webdav_mode", "2");
9960		}
9961#endif
9962		else {
9963			insert_hook_func(wp, fn, "alert_msg.Input2");
9964			json_object_put(root);
9965			return -1;
9966		}
9967	}
9968	else{
9969		insert_hook_func(wp, fn, "alert_msg.Input4");
9970		json_object_put(root);
9971		return -1;
9972	}
9973
9974	nvram_commit();
9975
9976	not_ej_initial_folder_var_file();
9977
9978	if (!strcmp(protocol, "cifs")) {
9979		result = notify_rc_for_nas("restart_samba_force");
9980	}
9981	else if (!strcmp(protocol, "ftp")) {
9982		result = notify_rc_for_nas("restart_ftpd_force");
9983	}
9984#ifdef RTCONFIG_WEBDAV_PENDING
9985	else if (!strcmp(protocol, "webdav")) {
9986		result = notify_rc_for_nas("restart_webdav");
9987	}
9988#endif
9989	else {
9990		insert_hook_func(wp, fn, "alert_msg.Input2");
9991		json_object_put(root);
9992		return -1;
9993	}
9994
9995	if (result != 0){
9996		insert_hook_func(wp, fn, "alert_msg.Action8");
9997		json_object_put(root);
9998		return -1;
9999	}
10000
10001SET_SHARE_MODE_SUCCESS:
10002	insert_hook_func(wp, "set_share_mode_success", "");
10003	json_object_put(root);
10004	return 0;
10005}
10006
10007
10008int ej_modify_sharedfolder(int eid, webs_t wp, int argc, char **argv){
10009	char *pool = websGetVar(wp, "pool", "");
10010	char *folder = websGetVar(wp, "folder", "");
10011	char *new_folder = websGetVar(wp, "new_folder", "");
10012	char mount_path[PATH_MAX];
10013	char *fn = "modify_sharedfolder_error";
10014
10015	if (strlen(pool) <= 0){
10016		insert_hook_func(wp, fn, "alert_msg.Input7");
10017		return -1;
10018	}
10019	if (strlen(folder) <= 0){
10020		insert_hook_func(wp, fn, "alert_msg.Input9");
10021		return -1;
10022	}
10023	if (strlen(new_folder) <= 0){
10024		insert_hook_func(wp, fn, "alert_msg.Input17");
10025		return -1;
10026	}
10027	if (get_mount_path(pool, mount_path, PATH_MAX) < 0){
10028		insert_hook_func(wp, fn, "alert_msg.System1");
10029		return -1;
10030	}
10031
10032	if (mod_folder(mount_path, folder, new_folder) < 0){
10033		insert_hook_func(wp, fn, "alert_msg.Action7");
10034		return -1;
10035	}
10036
10037	if (notify_rc_for_nas("restart_ftpsamba") != 0){
10038		insert_hook_func(wp, fn, "alert_msg.Action7");
10039		return -1;
10040	}
10041
10042	insert_hook_func(wp, "modify_sharedfolder_success", "");
10043
10044	return 0;
10045}
10046
10047int ej_delete_sharedfolder(int eid, webs_t wp, int argc, char **argv){
10048	char *pool = websGetVar(wp, "pool", "");
10049	char *folder = websGetVar(wp, "folder", "");
10050	char mount_path[PATH_MAX];
10051	char *fn = "delete_sharedfolder_error";
10052
10053	if (strlen(pool) <= 0){
10054		insert_hook_func(wp, fn, "alert_msg.Input7");
10055		return -1;
10056	}
10057	if (strlen(folder) <= 0){
10058		insert_hook_func(wp, fn, "alert_msg.Input9");
10059		return -1;
10060	}
10061
10062	if (get_mount_path(pool, mount_path, PATH_MAX) < 0){
10063		insert_hook_func(wp, fn, "alert_msg.System1");
10064		return -1;
10065	}
10066	if (del_folder(mount_path, folder) < 0){
10067		insert_hook_func(wp, fn, "alert_msg.Action6");
10068		return -1;
10069	}
10070
10071	if (notify_rc_for_nas("restart_ftpsamba") != 0){
10072		insert_hook_func(wp, fn, "alert_msg.Action6");
10073		return -1;
10074	}
10075
10076	insert_hook_func(wp, "delete_sharedfolder_success", "");
10077
10078	return 0;
10079}
10080
10081int ej_create_sharedfolder(int eid, webs_t wp, int argc, char **argv){
10082	char *account = websGetVar(wp, "account", NULL);
10083	char *pool = websGetVar(wp, "pool", "");
10084	char *folder = websGetVar(wp, "folder", "");
10085	char mount_path[PATH_MAX];
10086	char *fn = "create_sharedfolder_error";
10087
10088	if (strlen(pool) <= 0){
10089		insert_hook_func(wp, fn, "alert_msg.Input7");
10090		return -1;
10091	}
10092	if (strlen(folder) <= 0){
10093		insert_hook_func(wp, fn, "alert_msg.Input9");
10094		return -1;
10095	}
10096
10097	if (get_mount_path(pool, mount_path, PATH_MAX) < 0){
10098		fprintf(stderr, "Can't get the mount_path of %s.\n", pool);
10099
10100		insert_hook_func(wp, fn, "alert_msg.System1");
10101		return -1;
10102	}
10103	if (add_folder(account, mount_path, folder) < 0){
10104		insert_hook_func(wp, fn, "alert_msg.Action5");
10105		return -1;
10106	}
10107
10108	if (notify_rc_for_nas("restart_ftpsamba") != 0){
10109		insert_hook_func(wp, fn, "alert_msg.Action5");
10110		return -1;
10111	}
10112	insert_hook_func(wp, "create_sharedfolder_success", "");
10113
10114	return 0;
10115}
10116
10117int ej_set_AiDisk_status(int eid, webs_t wp, int argc, char **argv){
10118	char *protocol = websGetVar(wp, "protocol", "");
10119	char *flag = websGetVar(wp, "flag", "");
10120	int result = 0;
10121	char *fn = "set_AiDisk_status_error";
10122
10123	if (strlen(protocol) <= 0){
10124		insert_hook_func(wp, fn, "alert_msg.Input1");
10125		return -1;
10126	}
10127	if (strlen(flag) <= 0){
10128		insert_hook_func(wp, fn, "alert_msg.Input18");
10129		return -1;
10130	}
10131	if (!strcmp(protocol, "cifs")){
10132		if (!strcmp(flag, "on")){
10133			nvram_set("enable_samba", "1");
10134			nvram_commit();
10135			result = notify_rc_for_nas("restart_samba");
10136		}
10137		else if (!strcmp(flag, "off")){
10138			nvram_set("enable_samba", "0");
10139			nvram_commit();
10140			if (!pids("smbd"))
10141				goto SET_AIDISK_STATUS_SUCCESS;
10142
10143			result = notify_rc_for_nas("stop_samba");
10144		}
10145		else{
10146			insert_hook_func(wp, fn, "alert_msg.Input19");
10147			return -1;
10148		}
10149	}
10150	else if (!strcmp(protocol, "ftp")){
10151		if (!strcmp(flag, "on")){
10152			nvram_set("enable_ftp", "1");
10153			nvram_commit();
10154			result = notify_rc_for_nas("restart_ftpd");
10155		}
10156		else if (!strcmp(flag, "off")){
10157			nvram_set("enable_ftp", "0");
10158			nvram_commit();
10159			if (!pids("vsftpd"))
10160				goto SET_AIDISK_STATUS_SUCCESS;
10161
10162			result = notify_rc_for_nas("stop_ftpd");
10163		}
10164		else{
10165			insert_hook_func(wp, fn, "alert_msg.Input19");
10166			return -1;
10167		}
10168	}
10169#ifdef RTCONFIG_WEBDAV_PENDING
10170	else if (!strcmp(protocol, "webdav")){
10171		if (!strcmp(flag, "on")){
10172			nvram_set("enable_webdav", "1");
10173			nvram_commit();
10174			result = notify_rc_for_nas("restart_webdav");
10175		}
10176		else if (!strcmp(flag, "off")){
10177			nvram_set("enable_webdav", "0");
10178			nvram_commit();
10179			if (!pids("vsftpd"))
10180				goto SET_AIDISK_STATUS_SUCCESS;
10181
10182			result = notify_rc_for_nas("stop_webdav");
10183		}
10184		else{
10185			insert_hook_func(wp, fn, "alert_msg.Input19");
10186			return -1;
10187		}
10188	}
10189#endif
10190	else{
10191		insert_hook_func(wp, fn, "alert_msg.Input2");
10192		return -1;
10193	}
10194
10195	if (result != 0){
10196		insert_hook_func(wp, fn, "alert_msg.Action8");
10197		return -1;
10198	}
10199
10200SET_AIDISK_STATUS_SUCCESS:
10201	//insert_hook_func(wp, "set_AiDisk_status_success", "");
10202	insert_hook_func(wp, "parent.resultOfSwitchAppStatus", "");
10203
10204	return 0;
10205}
10206
10207#ifdef RTCONFIG_WEBDAV
10208
10209#define DEFAULT_WEBDAVPROXY_RIGHT 0
10210
10211int add_webdav_account(char *account)
10212{
10213	char *nv, *nvp, *b;
10214	char new[256];
10215	char *acc, *right;
10216	int i, found;
10217
10218	nv = nvp = strdup(nvram_safe_get("acc_webdavproxy"));
10219
10220	if(nv) {
10221		i = found = 0;
10222		while ((b = strsep(&nvp, "<")) != NULL) {
10223			if((vstrsep(b, ">", &acc, &right) != 2)) continue;
10224
10225			if(strcmp(acc, account)==0) {
10226				found = 1;
10227				break;
10228			}
10229			i++;
10230		}
10231		free(nv);
10232
10233		if(!found) {
10234			if(i==0) sprintf(new, "%s>%d", account, DEFAULT_WEBDAVPROXY_RIGHT);
10235			else sprintf(new, "%s<%s>%d", nvram_safe_get("acc_webdavproxy"), account, DEFAULT_WEBDAVPROXY_RIGHT);
10236
10237			nvram_set("acc_webdavproxy", new);
10238		}
10239	}
10240
10241	return 0;
10242}
10243
10244
10245int del_webdav_account(char *account)
10246{
10247	char *nv, *nvp, *b;
10248	char new[256];
10249	char *acc, *right;
10250	int i;
10251
10252	nv = nvp = strdup(nvram_safe_get("acc_webdavproxy"));
10253
10254	if(nv) {
10255		i = 0;
10256
10257		while ((b = strsep(&nvp, "<")) != NULL) {
10258			if((vstrsep(b, ">", &acc, &right) != 2)) continue;
10259
10260			if(strcmp(acc, account)!=0) {
10261				if(i==0) sprintf(new, "%s>%s", acc, right);
10262				else sprintf(new, "%s<%s>%s", new, acc, right);
10263				i++;
10264			}
10265		}
10266		free(nv);
10267
10268		if(i) nvram_set("acc_webdavproxy", new);
10269	}
10270	return 0;
10271}
10272
10273
10274int mod_webdav_account(char *account, char *newaccount)
10275{
10276	char *nv, *nvp, *b;
10277	char new[256];
10278	char *acc, *right;
10279	int i;
10280
10281	nv = nvp = strdup(nvram_safe_get("acc_webdavproxy"));
10282
10283	if(nv) {
10284		i = 0;
10285
10286		while ((b = strsep(&nvp, "<")) != NULL) {
10287			if((vstrsep(b, ">", &acc, &right) != 2)) continue;
10288
10289			if(strcmp(acc, account)!=0) {
10290				if(i==0) sprintf(new, "%s>%s", acc, right);
10291				else sprintf(new, "%s<%s>%s", new, acc, right);
10292			}
10293			else {
10294				if(i==0) sprintf(new, "%s>%s", newaccount, right);
10295				else sprintf(new, "%s<%s>%s", new, newaccount, right);
10296			}
10297			i++;
10298		}
10299		free(nv);
10300
10301		if(i) nvram_set("acc_webdavproxy", new);
10302	}
10303	return 0;
10304}
10305
10306#endif
10307
10308int ej_modify_account(int eid, webs_t wp, int argc, char **argv){
10309	char *account = websGetVar(wp, "account", "");
10310	char *new_account = websGetVar(wp, "new_account", "");
10311	char *new_password = websGetVar(wp, "new_password", "");
10312	char *fn = "modify_account_error";
10313
10314	if (strlen(account) <= 0){
10315		insert_hook_func(wp, fn, "alert_msg.Input5");
10316		return -1;
10317	}
10318	if (strlen(new_account) <= 0 && strlen(new_password) <= 0){
10319		insert_hook_func(wp, fn, "alert_msg.Input16");
10320		return -1;
10321	}
10322
10323	if (mod_account(account, new_account, new_password) < 0){
10324		insert_hook_func(wp, fn, "alert_msg.Action4");
10325		return -1;
10326	}
10327#ifdef RTCONFIG_WEBDAV_PENDING
10328	else if(mod_webdav_account(account, new_account)<0) {
10329		insert_hook_func(wp, fn, "alert_msg.Action4");
10330		return -1;
10331	}
10332#endif
10333
10334	if (notify_rc_for_nas("restart_ftpsamba") != 0){
10335		insert_hook_func(wp, fn, "alert_msg.Action4");
10336		return -1;
10337	}
10338
10339#ifdef RTCONFIG_WEBDAV_PENDING
10340	if(notify_rc_for_nas("restart_webdav") != 0) {
10341		insert_hook_func(wp, fn, "alert_msg.Action4");
10342		return -1;
10343	}
10344#endif
10345
10346	insert_hook_func(wp, "modify_account_success", "");
10347
10348	return 0;
10349}
10350
10351int ej_delete_account(int eid, webs_t wp, int argc, char **argv){
10352	char *account = websGetVar(wp, "account", "");
10353	char *fn = "delete_account_error";
10354
10355	if (strlen(account) <= 0){
10356		insert_hook_func(wp, fn, "alert_msg.Input5");
10357		return -1;
10358	}
10359
10360	not_ej_initial_folder_var_file();
10361
10362	if (del_account(account) < 0){
10363		insert_hook_func(wp, fn, "alert_msg.Action3");
10364		return -1;
10365	}
10366#ifdef RTCONFIG_WEBDAV_PENDING
10367	else if(del_webdav_account(account)<0) {
10368		insert_hook_func(wp, fn, "alert_msg.Action3");
10369		return -1;
10370	}
10371#endif
10372
10373	if (notify_rc_for_nas("restart_ftpsamba") != 0){
10374		insert_hook_func(wp, fn, "alert_msg.Action3");
10375		return -1;
10376	}
10377
10378#ifdef RTCONFIG_WEBDAV_PENDING
10379	if(notify_rc_for_nas("restart_webdav") != 0) {
10380		insert_hook_func(wp, fn, "alert_msg.Action3");
10381		return -1;
10382	}
10383#endif
10384
10385	insert_hook_func(wp, "delete_account_success", "");
10386
10387	return 0;
10388}
10389
10390int ej_initial_account(int eid, webs_t wp, int argc, char **argv){
10391	disk_info_t *disks_info, *follow_disk;
10392	partition_info_t *follow_partition;
10393	char *command;
10394	int len;
10395	char *fn = "initial_account_error";
10396
10397	nvram_set("acc_num", "0");
10398	nvram_set("acc_list", "");
10399	nvram_commit();
10400
10401	disks_info = read_disk_data();
10402	if (disks_info == NULL){
10403		insert_hook_func(wp, fn, "alert_msg.System2");
10404		return -1;
10405	}
10406
10407	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next)
10408		for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next)
10409			if (follow_partition->mount_point != NULL && strlen(follow_partition->mount_point) > 0){
10410				len = strlen("rm -f ")+strlen(follow_partition->mount_point)+strlen("/.__*");
10411				command = (char *)malloc(sizeof(char)*(len+1));
10412				if (command == NULL){
10413					insert_hook_func(wp, fn, "alert_msg.System1");
10414					return -1;
10415				}
10416				sprintf(command, "rm -f %s/.__*", follow_partition->mount_point);
10417				command[len] = 0;
10418
10419				system(command);
10420				free(command);
10421
10422				initial_folder_list(follow_partition->mount_point);
10423				initial_all_var_file(follow_partition->mount_point);
10424			}
10425
10426	free_disk_data(&disks_info);
10427
10428#if 0
10429	if (add_account(nvram_safe_get("http_username"), nvram_safe_get("http_passwd")) < 0)
10430#else
10431	// there are file_lock(), file_unlock() in add_account().
10432	// They would let the buffer of nvram_safe_get() be confused.
10433	char buf1[64], buf2[64];
10434	memset(buf1, 0, 64);
10435	memset(buf2, 0, 64);
10436	strcpy(buf1, nvram_safe_get("http_username"));
10437	strcpy(buf2, nvram_safe_get("http_passwd"));
10438
10439	if(add_account(buf1, buf2) < 0)
10440#endif
10441	{
10442		insert_hook_func(wp, fn, "alert_msg.Action2");
10443		return -1;
10444	}
10445#ifdef RTCONFIG_WEBDAV_PENDING
10446	else if(add_webdav_account(nvram_safe_get("http_username"))<0) {
10447		insert_hook_func(wp, "init_account_error", "alert_msg.Action2");
10448		return -1;
10449	}
10450#endif
10451
10452	if (notify_rc_for_nas("restart_ftpsamba") != 0){
10453		insert_hook_func(wp, fn, "alert_msg.Action2");
10454		return -1;
10455	}
10456
10457#ifdef RTCONFIG_WEBDAV_PENDING
10458	if(notify_rc_for_nas("restart_webdav") != 0) {
10459		insert_hook_func(wp, fn, "alert_msg.Action2");
10460		return -1;
10461	}
10462#endif
10463	insert_hook_func(wp, "initial_account_success", "");
10464
10465	return 0;
10466}
10467
10468int ej_create_account(int eid, webs_t wp, int argc, char **argv){
10469	char *account = websGetVar(wp, "account", "");
10470	char *password = websGetVar(wp, "password", "");
10471	char *fn = "create_account_error";
10472
10473	if (strlen(account) <= 0){
10474		insert_hook_func(wp, fn, "alert_msg.Input5");
10475		return -1;
10476	}
10477	if (strlen(password) <= 0){
10478		insert_hook_func(wp, fn, "alert_msg.Input14");
10479		return -1;
10480	}
10481
10482	not_ej_initial_folder_var_file();
10483
10484	if (add_account(account, password) < 0){
10485		insert_hook_func(wp, fn, "alert_msg.Action2");
10486		return -1;
10487	}
10488#ifdef RTCONFIG_WEBDAV_PENDING
10489	else if(add_webdav_account(account) < 0) {
10490		insert_hook_func(wp, fn, "alert_msg.Action2");
10491		return -1;
10492	}
10493#endif
10494
10495	if (notify_rc_for_nas("restart_ftpsamba") != 0){
10496		insert_hook_func(wp, fn, "alert_msg.Action2");
10497		return -1;
10498	}
10499
10500#ifdef RTCONFIG_WEBDAV_PENDING
10501	if(notify_rc_for_nas("restart_webdav") != 0) {
10502		insert_hook_func(wp, fn, "alert_msg.Action2");
10503		return -1;
10504	}
10505#endif
10506
10507	insert_hook_func(wp, "create_account_success", "");
10508	return 0;
10509}
10510
10511int ej_set_account_permission(int eid, webs_t wp, int argc, char **argv){
10512	char mount_path[PATH_MAX];
10513	char *ascii_user = websGetVar(wp, "account", NULL);
10514	char *pool = websGetVar(wp, "pool", "");
10515	char *folder = websGetVar(wp, "folder", NULL);
10516	char *protocol = websGetVar(wp, "protocol", "");
10517	char *permission = websGetVar(wp, "permission", "");
10518#ifdef RTCONFIG_WEBDAV_PENDING
10519	char *webdavproxy = websGetVar(wp, "acc_webdavproxy", "");
10520#endif
10521	int right;
10522	char char_user[64];
10523	char *fn = "set_account_permission_error";
10524
10525	memset(char_user, 0, 64);
10526	ascii_to_char_safe(char_user, ascii_user, 64);
10527
10528	if (test_if_exist_account(char_user) != 1){
10529		insert_hook_func(wp, fn, "alert_msg.Input6");
10530		return -1;
10531	}
10532
10533	if (strlen(pool) <= 0){
10534		insert_hook_func(wp, fn, "alert_msg.Input7");
10535		return -1;
10536	}
10537
10538	if (get_mount_path(pool, mount_path, PATH_MAX) < 0){
10539		fprintf(stderr, "Can't get the mount_path of %s.\n", pool);
10540
10541		insert_hook_func(wp, fn, "alert_msg.System1");
10542		return -1;
10543	}
10544
10545	if (strlen(protocol) <= 0){
10546		insert_hook_func(wp, fn, "alert_msg.Input1");
10547		return -1;
10548	}
10549	if (strcmp(protocol, "cifs") && strcmp(protocol, "ftp") && strcmp(protocol, "dms")
10550#ifdef RTCONFIG_WEBDAV_PENDING
10551&& strcmp(protocol, "webdav")
10552#endif
10553){
10554		insert_hook_func(wp, fn, "alert_msg.Input2");
10555		return -1;
10556	}
10557
10558	if (strlen(permission) <= 0){
10559		insert_hook_func(wp, fn, "alert_msg.Input12");
10560		return -1;
10561	}
10562	right = atoi(permission);
10563	if (right < 0 || right > 3){
10564		insert_hook_func(wp, fn, "alert_msg.Input13");
10565		return -1;
10566	}
10567
10568	if (set_permission(char_user, mount_path, folder, protocol, right) < 0){
10569		insert_hook_func(wp, fn, "alert_msg.Action1");
10570		return -1;
10571	}
10572#ifdef RTCONFIG_WEBDAV_PENDING
10573	else {
10574		logmessage("wedavproxy right", "%s %s %s %s %d %s", char_user, mount_path, folder, protocol, right, webdavproxy);
10575		// modify permission for webdav proxy
10576		nvram_set("acc_webdavproxy", webdavproxy);
10577	}
10578#endif
10579
10580#ifdef RTCONFIG_WEBDAV_PENDING
10581	if(strcmp(protocol, "webdav")==0) {
10582		if(notify_rc_for_nas("restart_webdav") != 0) {
10583			insert_hook_func(wp, fn, "alert_msg.Action1");
10584			return -1;
10585		}
10586	}
10587	else
10588#endif
10589	if (notify_rc_for_nas("restart_ftpsamba") != 0){
10590		insert_hook_func(wp, fn, "alert_msg.Action1");
10591		return -1;
10592	}
10593
10594	insert_hook_func(wp, "set_account_permission_success", "");
10595
10596	return 0;
10597}
10598
10599int ej_set_account_all_folder_permission(int eid, webs_t wp, int argc, char **argv)
10600{
10601	disk_info_t *disks_info, *follow_disk;
10602	partition_info_t *follow_partition;
10603	int i, result, sh_num;
10604	char **folder_list;
10605	char *ascii_user = websGetVar(wp, "account", NULL);
10606	char *protocol = websGetVar(wp, "protocol", "");
10607	char *permission = websGetVar(wp, "permission", "");
10608#ifdef RTCONFIG_WEBDAV_PENDING
10609	char *webdavproxy = websGetVar(wp, "acc_webdavproxy", "");
10610#endif
10611	int right;
10612	char char_user[64];
10613	char *fn = "set_account_all_folder_permission_error";
10614
10615	memset(char_user, 0, 64);
10616	ascii_to_char_safe(char_user, ascii_user, 64);
10617
10618	if (test_if_exist_account(char_user) != 1){
10619		insert_hook_func(wp, fn, "alert_msg.Input6");
10620		return -1;
10621	}
10622
10623	if (strlen(protocol) <= 0){
10624		insert_hook_func(wp, fn, "alert_msg.Input1");
10625		return -1;
10626	}
10627	if (strcmp(protocol, "cifs") && strcmp(protocol, "ftp") && strcmp(protocol, "dms")
10628#ifdef RTCONFIG_WEBDAV_PENDING
10629&& strcmp(protocol, "webdav")
10630#endif
10631){
10632		insert_hook_func(wp, fn, "alert_msg.Input2");
10633		return -1;
10634	}
10635
10636	if (strlen(permission) <= 0){
10637		insert_hook_func(wp, fn, "alert_msg.Input12");
10638		return -1;
10639	}
10640	right = atoi(permission);
10641	if (right < 0 || right > 3){
10642		insert_hook_func(wp, fn, "alert_msg.Input13");
10643		return -1;
10644	}
10645
10646
10647	disks_info = read_disk_data();
10648	if (disks_info == NULL){
10649		insert_hook_func(wp, fn, "alert_msg.System2");
10650		return -1;
10651	}
10652
10653	for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next) {
10654		for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next) {
10655			if (follow_partition->mount_point == NULL || strlen(follow_partition->mount_point) <= 0)
10656				continue;
10657
10658			result = get_all_folder(follow_partition->mount_point, &sh_num, &folder_list);
10659			if (result != 0) {
10660				insert_hook_func(wp, fn, "alert_msg.Action7");
10661				free_2_dimension_list(&sh_num, &folder_list);
10662				return -1;
10663			}
10664			for (i = 0; i < sh_num; ++i) {
10665				if (set_permission(char_user, follow_partition->mount_point, folder_list[i], protocol, right) < 0){
10666					insert_hook_func(wp, fn, "alert_msg.Action1");
10667					free_2_dimension_list(&sh_num, &folder_list);
10668					return -1;
10669				}
10670#ifdef RTCONFIG_WEBDAV_PENDING
10671#error FIXME
10672				else {
10673					logmessage("wedavproxy right", "%s %s %s %s %d %s", char_user, mount_path, folder, protocol, right, webdavproxy);
10674					// modify permission for webdav proxy
10675					nvram_set("acc_webdavproxy", webdavproxy);
10676				}
10677#endif
10678			}
10679			free_2_dimension_list(&sh_num, &folder_list);
10680		}
10681	}
10682
10683	free_disk_data(&disks_info);
10684
10685#ifdef RTCONFIG_WEBDAV_PENDING
10686	if(strcmp(protocol, "webdav")==0) {
10687		if(notify_rc_for_nas("restart_webdav") != 0) {
10688			insert_hook_func(wp, fn, "alert_msg.Action1");
10689			return -1;
10690		}
10691	}
10692	else
10693#endif
10694	if (notify_rc_for_nas("restart_ftpsamba") != 0){
10695		insert_hook_func(wp, fn, "alert_msg.Action1");
10696		return -1;
10697	}
10698
10699	insert_hook_func(wp, "set_account_all_folder_permission_success", "");
10700
10701	return 0;
10702}
10703
10704int ej_apps_fsck_ret(int eid, webs_t wp, int argc, char **argv)
10705{
10706#ifdef RTCONFIG_DISK_MONITOR
10707	disk_info_t *disk_list, *disk_info;
10708	partition_info_t *partition_info;
10709	FILE *fp;
10710
10711	disk_list = read_disk_data();
10712	if(disk_list == NULL){
10713		websWrite(wp, "[]");
10714		return -1;
10715	}
10716
10717	websWrite(wp, "[");
10718	for(disk_info = disk_list; disk_info != NULL; disk_info = disk_info->next){
10719		for(partition_info = disk_info->partitions; partition_info != NULL; partition_info = partition_info->next){
10720			websWrite(wp, "[\"%s\", ", partition_info->device);
10721
10722#define MAX_ERROR_CODE 3
10723			int error_code, got_code;
10724			char file_name[32];
10725
10726			for(error_code = 0, got_code = 0; error_code <= MAX_ERROR_CODE; ++error_code){
10727				memset(file_name, 0, 32);
10728				sprintf(file_name, "/tmp/fsck_ret/%s.%d", partition_info->device, error_code);
10729
10730				if((fp = fopen(file_name, "r")) != NULL){
10731					fclose(fp);
10732					websWrite(wp, "\"%d\"", error_code);
10733					got_code = 1;
10734					break;
10735				}
10736			}
10737
10738			if(!got_code)
10739				websWrite(wp, "\"\"");
10740
10741			websWrite(wp, "]%s", (partition_info->next)?", ":"");
10742		}
10743
10744		websWrite(wp, "%s", (disk_info->next)?", ":"");
10745	}
10746	websWrite(wp, "]");
10747
10748	free_disk_data(&disk_list);
10749
10750	return 0;
10751#endif
10752
10753	websWrite(wp, "[]");
10754	return 0;
10755}
10756
10757#ifdef RTCONFIG_DISK_MONITOR
10758int ej_apps_fsck_log(int eid, webs_t wp, int argc, char **argv)
10759{
10760	disk_info_t *disk_list, *disk_info;
10761	partition_info_t *partition_info;
10762	char file_name[32], d_port[16]/*, *d_dot*/;
10763	char *port_path = websGetVar(wp, "diskmon_usbport", "-1");
10764	int ret, all_disk;
10765
10766	disk_list = read_disk_data();
10767	if(disk_list == NULL){
10768		return -1;
10769	}
10770
10771	all_disk = (atoi(port_path) == -1)? 1 : 0;
10772	for(disk_info = disk_list; disk_info != NULL; disk_info = disk_info->next){
10773		/* If hub port number is not specified in port_path,
10774		 * don't compare it with hub port number in disk_info->port.
10775		 */
10776		strlcpy(d_port, disk_info->port, sizeof(d_port));
10777		/*if (!strchr(port_path, '.') && d_dot)
10778			*d_dot = '\0';*/
10779		if (!all_disk && strcmp(d_port, port_path))
10780			continue;
10781
10782		for(partition_info = disk_info->partitions; partition_info != NULL; partition_info = partition_info->next){
10783			memset(file_name, 0, 32);
10784			sprintf(file_name, "/tmp/fsck_ret/%s.log", partition_info->device);
10785			ret = dump_file(wp, file_name);
10786
10787			if(ret)
10788				websWrite(wp, "\n\n");
10789		}
10790	}
10791
10792	free_disk_data(&disk_list);
10793
10794	return 0;
10795}
10796#endif
10797
10798// argv[0] = "all" or NULL: show all lists, "asus": only show the list of ASUS, "others": show other lists.
10799// apps_info: ["Name", "Version", "New Version", "Installed", "Enabled", "Source", "URL", "Description", "Depends", "Optional Utility", "New Optional Utility", "Help Path", "New File name"].
10800int ej_apps_info(int eid, webs_t wp, int argc, char **argv)
10801{
10802	apps_info_t *follow_apps_info, *apps_info_list;
10803	char *name;
10804
10805	if (ejArgs(argc, argv, "%s", &name) < 1)
10806		name = APP_OWNER_ALL;
10807	if (strcmp(name, APP_OWNER_ALL) != 0 &&
10808	    strcmp(name, APP_OWNER_ASUS) != 0 &&
10809	    strcmp(name, APP_OWNER_OTHERS) != 0) {
10810		websWrite(wp, "[]");
10811		return 0;
10812	}
10813
10814	apps_info_list = follow_apps_info = get_apps_list(name);
10815	websWrite(wp, "[");
10816	while (follow_apps_info != NULL) {
10817		websWrite(wp, "[");
10818		websWrite(wp, "\"%s\", ", follow_apps_info->name ? : "");
10819		websWrite(wp, "\"%s\", ", follow_apps_info->version ? : "");
10820		websWrite(wp, "\"%s\", ", follow_apps_info->new_version ? : "");
10821		websWrite(wp, "\"%s\", ", follow_apps_info->installed ? : "" /* Why not FIELD_NO? */);
10822		websWrite(wp, "\"%s\", ", follow_apps_info->enabled ? : FIELD_YES);
10823		websWrite(wp, "\"%s\", ", follow_apps_info->source ? : "");
10824		websWrite(wp, "\"%s\", ", follow_apps_info->url ? : "");
10825		websWrite(wp, "\"%s\", ", follow_apps_info->description ? : "");
10826		websWrite(wp, "\"%s\", ", follow_apps_info->depends ? : "");
10827		websWrite(wp, "\"%s\", ", follow_apps_info->optional_utility ? : "");
10828		websWrite(wp, "\"%s\", ", follow_apps_info->new_optional_utility ? : "");
10829		websWrite(wp, "\"%s\", ", follow_apps_info->help_path ? : "");
10830		websWrite(wp, "\"%s\"",   follow_apps_info->new_file_name ? : "");
10831
10832		follow_apps_info = follow_apps_info->next;
10833		websWrite(wp, "]%s\n", follow_apps_info ? "," : "");
10834	}
10835	websWrite(wp, "]");
10836	free_apps_list(&apps_info_list);
10837
10838	return 0;
10839}
10840
10841int ej_apps_state_info(int eid, webs_t wp, int argc, char **argv){
10842	char *cmd[] = {"chk_app_state", NULL};
10843	int pid;
10844
10845	_eval(cmd, NULL, 0, &pid);
10846
10847	websWrite(wp, "apps_dev = \"%s\";", nvram_safe_get("apps_dev"));
10848	websWrite(wp, "apps_mounted_path = \"%s\";", nvram_safe_get("apps_mounted_path"));
10849
10850	websWrite(wp, "apps_state_upgrade = \"%s\";", nvram_safe_get("apps_state_upgrade"));
10851	websWrite(wp, "apps_state_update = \"%s\";", nvram_safe_get("apps_state_update"));
10852	websWrite(wp, "apps_state_remove = \"%s\";", nvram_safe_get("apps_state_remove"));
10853	websWrite(wp, "apps_state_enable = \"%s\";", nvram_safe_get("apps_state_enable"));
10854	websWrite(wp, "apps_state_switch = \"%s\";", nvram_safe_get("apps_state_switch"));
10855	websWrite(wp, "apps_state_autorun = \"%s\";", nvram_safe_get("apps_state_autorun"));
10856	websWrite(wp, "apps_state_install = \"%s\";", nvram_safe_get("apps_state_install"));
10857	websWrite(wp, "apps_state_error = \"%s\";", nvram_safe_get("apps_state_error"));
10858
10859	websWrite(wp, "apps_download_file = \"%s\";", nvram_safe_get("apps_download_file"));
10860	websWrite(wp, "apps_download_percent = \"%s\";", nvram_safe_get("apps_download_percent"));
10861
10862	websWrite(wp, "apps_depend_do = \"%s\";", nvram_safe_get("apps_depend_do"));
10863	websWrite(wp, "apps_depend_action = \"%s\";", nvram_safe_get("apps_depend_action"));
10864	websWrite(wp, "apps_depend_action_target = \"%s\";", nvram_safe_get("apps_depend_action_target"));
10865
10866	return 0;
10867}
10868
10869int ej_apps_action(int eid, webs_t wp, int argc, char **argv){
10870	char *apps_action = websGetVar(wp, "apps_action", "");
10871	char *apps_name = websGetVar(wp, "apps_name", "");
10872	char *apps_flag = websGetVar(wp, "apps_flag", "");
10873	char command[128];
10874
10875	if(strlen(apps_action) <= 0)
10876		return 0;
10877
10878	nvram_set("apps_state_action", apps_action);
10879
10880	memset(command, 0, sizeof(command));
10881
10882	if(!strcmp(apps_action, "install")){
10883		if(strlen(apps_name) <= 0 || strlen(apps_flag) <= 0)
10884			return 0;
10885
10886		snprintf(command, sizeof(command), "start_apps_install %s %s", apps_name, apps_flag);
10887	}
10888	else if(!strcmp(apps_action, "stop")){
10889		snprintf(command, sizeof(command), "start_apps_stop");
10890	}
10891	else if(!strcmp(apps_action, "update")){
10892		snprintf(command, sizeof(command), "start_apps_update");
10893	}
10894	else if(!strcmp(apps_action, "upgrade")){
10895		if(strlen(apps_name) <= 0)
10896			return 0;
10897
10898		snprintf(command, sizeof(command), "start_apps_upgrade %s", apps_name);
10899	}
10900	else if(!strcmp(apps_action, "remove")){
10901		if(strlen(apps_name) <= 0)
10902			return 0;
10903
10904		snprintf(command, sizeof(command), "start_apps_remove %s", apps_name);
10905	}
10906	else if(!strcmp(apps_action, "enable")){
10907		if(strlen(apps_name) <= 0 || strlen(apps_flag) <= 0)
10908			return 0;
10909
10910		if(strcmp(apps_flag, "yes") && strcmp(apps_flag, "no"))
10911			return 0;
10912
10913		snprintf(command, sizeof(command), "start_apps_enable %s %s", apps_name, apps_flag);
10914	}
10915	else if(!strcmp(apps_action, "switch")){
10916		if(strlen(apps_name) <= 0 || strlen(apps_flag) <= 0)
10917			return 0;
10918
10919		snprintf(command, sizeof(command), "start_apps_switch %s %s", apps_name, apps_flag);
10920	}
10921	else if(!strcmp(apps_action, "cancel")){
10922		snprintf(command, sizeof(command), "start_apps_cancel");
10923	}
10924
10925	if(strlen(command) > 0)
10926		notify_rc(command);
10927
10928	return 0;
10929}
10930
10931#ifdef RTCONFIG_MEDIA_SERVER
10932// dms_info: ["Scanning"] or [ "" ]
10933
10934int ej_dms_info(int eid, webs_t wp, int argc, char **argv){
10935	char *dms_dbcwd;
10936	char dms_scanfile[PATH_MAX], dms_status[32];
10937	FILE *fp;
10938
10939	dms_dbcwd = nvram_safe_get("dms_dbcwd");
10940
10941	strcpy(dms_status, "");
10942
10943	if(nvram_get_int("dms_enable") && strlen(dms_dbcwd))
10944	{
10945		sprintf(dms_scanfile, "%s/scantag", dms_dbcwd);
10946
10947		fp = fopen(dms_scanfile, "r");
10948
10949		if(fp) {
10950			strcpy(dms_status, "Scanning");
10951			fclose(fp);
10952		}
10953	}
10954
10955	websWrite(wp, "[\"%s\"]", dms_status);
10956
10957	return 0;
10958}
10959#endif
10960
10961//#ifdef RTCONFIG_CLOUDSYNC
10962static char *convert_cloudsync_status(const char *status_code){
10963	if(!strcmp(status_code, "STATUS:70"))
10964		return "INITIAL";
10965	else if(!strcmp(status_code, "STATUS:71"))
10966		return "SYNC";
10967	else if(!strcmp(status_code, "STATUS:72"))
10968		return "DOWNUP";
10969	else if(!strcmp(status_code, "STATUS:73"))
10970		return "UPLOAD";
10971	else if(!strcmp(status_code, "STATUS:74"))
10972		return "DOWNLOAD";
10973	else if(!strcmp(status_code, "STATUS:75"))
10974		return "STOP";
10975	else if(!strcmp(status_code, "STATUS:77"))
10976		return "INPUT CAPTCHA";
10977	else
10978		return "ERROR";
10979}
10980
10981// cloud_sync = "content of nvram: cloud_sync"
10982// cloud_status = "string of status"
10983// cloud_obj = "handled object"
10984// cloud_msg = "error message"
10985int ej_cloud_status(int eid, webs_t wp, int argc, char **argv){
10986	FILE *fp = fopen("/tmp/smartsync/.logs/asuswebstorage", "r");
10987	char line[PATH_MAX], buf[PATH_MAX];
10988	int line_num;
10989	char status[16], mounted_path[PATH_MAX], target_obj[PATH_MAX], error_msg[PATH_MAX];
10990
10991	websWrite(wp, "cloud_sync=\"%s\";\n", nvram_safe_get("cloud_sync"));
10992
10993	if(fp == NULL){
10994		websWrite(wp, "cloud_status=\"ERROR\";\n");
10995		websWrite(wp, "cloud_obj=\"\";\n");
10996		websWrite(wp, "cloud_msg=\"\";\n");
10997		return 0;
10998	}
10999
11000	memset(status, 0, 16);
11001	memset(mounted_path, 0, PATH_MAX);
11002	memset(target_obj, 0, PATH_MAX);
11003	memset(error_msg, 0, PATH_MAX);
11004
11005	memset(line, 0, PATH_MAX);
11006	line_num = 0;
11007	while(fgets(line, PATH_MAX, fp)){
11008		++line_num;
11009		line[strlen(line)-1] = 0;
11010
11011		switch(line_num){
11012			case 1:
11013				strncpy(status, convert_cloudsync_status(line), 16);
11014				break;
11015			case 2:
11016				memset(buf, 0, PATH_MAX);
11017				char_to_ascii(buf, line);
11018				strcpy(mounted_path, buf);
11019				break;
11020			case 3:
11021				// memset(buf, 0, PATH_MAX);
11022				// char_to_ascii(buf, line);
11023				// strcpy(target_obj, buf);
11024				strcpy(target_obj, line); // support Chinese
11025				break;
11026			case 4:
11027				strcpy(error_msg, line);
11028				break;
11029		}
11030
11031		memset(line, 0, PATH_MAX);
11032	}
11033	fclose(fp);
11034
11035	if(!line_num){
11036		websWrite(wp, "cloud_status=\"ERROR\";\n");
11037		websWrite(wp, "cloud_obj=\"\";\n");
11038		websWrite(wp, "cloud_msg=\"\";\n");
11039	}
11040	else{
11041		websWrite(wp, "cloud_status=\"%s\";\n", status);
11042		websWrite(wp, "cloud_obj=\"%s\";\n", target_obj);
11043		websWrite(wp, "cloud_msg=\"%s\";\n", error_msg);
11044	}
11045
11046	return 0;
11047}
11048
11049//Viz add to get partial string 2012.11.13
11050void substr(char *dest, const char* src, unsigned int start, unsigned int cnt) {
11051	strncpy(dest, src + start, cnt);
11052	dest[cnt] = 0;
11053}
11054
11055//use for UI to avoid variable 'cloud_sync' JavaScript error, Jieming added at 2012.09.11
11056int ej_UI_cloud_status(int eid, webs_t wp, int argc, char **argv){
11057	FILE *fp = fopen("/tmp/smartsync/.logs/asuswebstorage", "r");
11058	char line[PATH_MAX], buf[PATH_MAX], dest[PATH_MAX];
11059	int line_num;
11060	char status[16], mounted_path[PATH_MAX], target_obj[PATH_MAX], error_msg[PATH_MAX], full_capa[PATH_MAX], used_capa[PATH_MAX], captcha_url[PATH_MAX];
11061
11062	if(fp == NULL){
11063		websWrite(wp, "cloud_status=\"WAITING\";\n"); //gauss change status fromm 'ERROR' to 'WAITING' 2014.11.4
11064		websWrite(wp, "cloud_obj=\"\";\n");
11065		websWrite(wp, "cloud_msg=\"\";\n");
11066		websWrite(wp, "cloud_fullcapa=\"\";\n");
11067		websWrite(wp, "cloud_usedcapa=\"\";\n");
11068		websWrite(wp, "CAPTCHA_URL=\"\";\n");
11069		return 0;
11070	}
11071
11072	memset(status, 0, 16);
11073	memset(mounted_path, 0, PATH_MAX);
11074	memset(target_obj, 0, PATH_MAX);
11075	memset(error_msg, 0, PATH_MAX);
11076	memset(full_capa, 0, PATH_MAX);
11077	memset(used_capa, 0, PATH_MAX);
11078	memset(captcha_url, 0, PATH_MAX);
11079
11080	memset(line, 0, PATH_MAX);
11081	line_num = 0;
11082	while(fgets(line, PATH_MAX, fp)){
11083		++line_num;
11084		line[strlen(line)-1] = 0;
11085
11086		if(strstr(line, "STATUS") != NULL){
11087			strncpy(status, convert_cloudsync_status(line), 16);
11088		}
11089		else if(strstr(line, "MOUNT_PATH") != NULL){
11090			memset(buf, 0, PATH_MAX);
11091			substr(dest, line, 11, PATH_MAX);
11092			char_to_ascii(buf, dest);
11093			strcpy(mounted_path, buf);
11094		}
11095		else if(strstr(line, "FILENAME") != NULL){
11096			substr(dest, line, 9, PATH_MAX);
11097			strcpy(target_obj, dest); // support Chinese
11098		}
11099		else if(strstr(line, "ERR_MSG") != NULL){
11100			substr(dest, line, 8, PATH_MAX);
11101			strcpy(error_msg, dest);
11102		}
11103		else if(strstr(line, "TOTAL_SPACE") != NULL){
11104			substr(dest, line, 12, PATH_MAX);
11105			strcpy(full_capa, dest);
11106		}
11107		else if(strstr(line, "USED_SPACE") != NULL){
11108			substr(dest, line, 11, PATH_MAX);
11109			strcpy(used_capa, dest);
11110		}
11111		else if(strstr(line, "CAPTCHA_URL") != NULL){
11112			substr(dest, line, 12, PATH_MAX);
11113			strcpy(captcha_url, dest);
11114		}
11115
11116		memset(line, 0, PATH_MAX);
11117	}
11118	fclose(fp);
11119
11120	if(!line_num){
11121		websWrite(wp, "cloud_status=\"ERROR\";\n");
11122		websWrite(wp, "cloud_obj=\"\";\n");
11123		websWrite(wp, "cloud_msg=\"\";\n");
11124		websWrite(wp, "cloud_fullcapa=\"\";\n");
11125		websWrite(wp, "cloud_usedcapa=\"\";\n");
11126		websWrite(wp, "CAPTCHA_URL=\"\";\n");
11127	}
11128	else{
11129		websWrite(wp, "cloud_status=\"%s\";\n", status);
11130		websWrite(wp, "cloud_obj=\"%s\";\n", target_obj);
11131		if(!strcmp(status,"SYNC"))
11132		   strncpy(error_msg,"Sync has been completed",PATH_MAX);
11133		else if(!strcmp(status,"INITIAL"))
11134		   strncpy(error_msg,"Verifying",PATH_MAX);
11135		websWrite(wp, "cloud_msg=\"%s\";\n", error_msg);
11136		websWrite(wp, "cloud_fullcapa=\"%s\";\n", full_capa);
11137		websWrite(wp, "cloud_usedcapa=\"%s\";\n", used_capa);
11138		websWrite(wp, "CAPTCHA_URL=\"%s\";\n", captcha_url);
11139	}
11140
11141	return 0;
11142}
11143
11144int ej_UI_cloud_dropbox_status(int eid, webs_t wp, int argc, char **argv){
11145	FILE *fp = fopen("/tmp/smartsync/.logs/dropbox", "r");
11146	char line[PATH_MAX], buf[PATH_MAX], dest[PATH_MAX];
11147	int line_num;
11148	char status[16], mounted_path[PATH_MAX], target_obj[PATH_MAX], error_msg[PATH_MAX], full_capa[PATH_MAX], used_capa[PATH_MAX], rule_num[PATH_MAX];
11149
11150	if(fp == NULL){
11151		websWrite(wp, "cloud_dropbox_status=\"WAITING\";\n"); //gauss change status fromm 'ERROR' to 'WAITING' 2014.11.4
11152		websWrite(wp, "cloud_dropbox_obj=\"\";\n");
11153		websWrite(wp, "cloud_dropbox_msg=\"\";\n");
11154		websWrite(wp, "cloud_dropbox_fullcapa=\"\";\n");
11155		websWrite(wp, "cloud_dropbox_usedcapa=\"\";\n");
11156		websWrite(wp, "cloud_dropbox_rule_num=\"\";\n");
11157		return 0;
11158	}
11159
11160	memset(status, 0, 16);
11161	memset(mounted_path, 0, PATH_MAX);
11162	memset(target_obj, 0, PATH_MAX);
11163	memset(error_msg, 0, PATH_MAX);
11164	memset(full_capa, 0, PATH_MAX);
11165	memset(used_capa, 0, PATH_MAX);
11166	memset(rule_num, 0, PATH_MAX);
11167
11168	memset(line, 0, PATH_MAX);
11169	line_num = 0;
11170	while(fgets(line, PATH_MAX, fp)){
11171		++line_num;
11172		line[strlen(line)-1] = 0;
11173
11174		if(strstr(line, "STATUS") != NULL){
11175			strncpy(status, convert_cloudsync_status(line), 16);
11176		}
11177		else if(strstr(line, "MOUNT_PATH") != NULL){
11178			memset(buf, 0, PATH_MAX);
11179			substr(dest, line, 11, PATH_MAX);
11180			char_to_ascii(buf, dest);
11181			strcpy(mounted_path, buf);
11182		}
11183		else if(strstr(line, "FILENAME") != NULL){
11184			substr(dest, line, 9, PATH_MAX);
11185			strcpy(target_obj, dest); // support Chinese
11186		}
11187		else if(strstr(line, "ERR_MSG") != NULL){
11188			substr(dest, line, 8, PATH_MAX);
11189			strcpy(error_msg, dest);
11190		}
11191		else if(strstr(line, "TOTAL_SPACE") != NULL){
11192			substr(dest, line, 12, PATH_MAX);
11193			strcpy(full_capa, dest);
11194		}
11195		else if(strstr(line, "USED_SPACE") != NULL){
11196			substr(dest, line, 11, PATH_MAX);
11197			strcpy(used_capa, dest);
11198		}
11199		else if(strstr(line, "RULENUM") != NULL){
11200			substr(dest, line, 8, PATH_MAX);
11201			strcpy(rule_num, dest);
11202		}
11203
11204		memset(line, 0, PATH_MAX);
11205	}
11206	fclose(fp);
11207
11208	if(!line_num){
11209		websWrite(wp, "cloud_dropbox_status=\"ERROR\";\n");
11210		websWrite(wp, "cloud_dropbox_obj=\"\";\n");
11211		websWrite(wp, "cloud_dropbox_msg=\"\";\n");
11212		websWrite(wp, "cloud_dropbox_fullcapa=\"\";\n");
11213		websWrite(wp, "cloud_dropbox_usedcapa=\"\";\n");
11214		websWrite(wp, "cloud_dropbox_rule_num=\"\";\n");
11215	}
11216	else{
11217		websWrite(wp, "cloud_dropbox_status=\"%s\";\n", status);
11218		websWrite(wp, "cloud_dropbox_obj=\"%s\";\n", target_obj);
11219		if(!strcmp(status,"SYNC"))
11220		   strncpy(error_msg,"Sync has been completed",PATH_MAX);
11221		else if(!strcmp(status,"INITIAL"))
11222		   strncpy(error_msg,"Verifying",PATH_MAX);
11223		websWrite(wp, "cloud_dropbox_msg=\"%s\";\n", error_msg);
11224		websWrite(wp, "cloud_dropbox_fullcapa=\"%s\";\n", full_capa);
11225		websWrite(wp, "cloud_dropbox_usedcapa=\"%s\";\n", used_capa);
11226		websWrite(wp, "cloud_dropbox_rule_num=\"%s\";\n", rule_num);
11227	}
11228
11229	return 0;
11230}
11231
11232int ej_UI_cloud_ftpclient_status(int eid, webs_t wp, int argc, char **argv){
11233	FILE *fp = fopen("/tmp/smartsync/.logs/ftpclient", "r");
11234	char line[PATH_MAX], buf[PATH_MAX], dest[PATH_MAX];
11235	int line_num;
11236	char status[16], mounted_path[PATH_MAX], target_obj[PATH_MAX], error_msg[PATH_MAX], full_capa[PATH_MAX], used_capa[PATH_MAX], rule_num[PATH_MAX];
11237
11238	if(fp == NULL){
11239		websWrite(wp, "cloud_ftpclient_status=\"WAITING\";\n"); //gauss change status fromm 'ERROR' to 'WAITING' 2014.11.4
11240		websWrite(wp, "cloud_ftpclient_obj=\"\";\n");
11241		websWrite(wp, "cloud_ftpclient_msg=\"\";\n");
11242		websWrite(wp, "cloud_ftpclient_fullcapa=\"\";\n");
11243		websWrite(wp, "cloud_ftpclient_usedcapa=\"\";\n");
11244		websWrite(wp, "cloud_ftpclient_rule_num=\"\";\n");
11245		return 0;
11246	}
11247
11248	memset(status, 0, 16);
11249	memset(mounted_path, 0, PATH_MAX);
11250	memset(target_obj, 0, PATH_MAX);
11251	memset(error_msg, 0, PATH_MAX);
11252	memset(full_capa, 0, PATH_MAX);
11253	memset(used_capa, 0, PATH_MAX);
11254	memset(rule_num, 0, PATH_MAX);
11255
11256	memset(line, 0, PATH_MAX);
11257	line_num = 0;
11258	while(fgets(line, PATH_MAX, fp)){
11259		++line_num;
11260		line[strlen(line)-1] = 0;
11261
11262		if(strstr(line, "STATUS") != NULL){
11263			strncpy(status, convert_cloudsync_status(line), 16);
11264		}
11265		else if(strstr(line, "MOUNT_PATH") != NULL){
11266			memset(buf, 0, PATH_MAX);
11267			substr(dest, line, 11, PATH_MAX);
11268			char_to_ascii(buf, dest);
11269			strcpy(mounted_path, buf);
11270		}
11271		else if(strstr(line, "FILENAME") != NULL){
11272			substr(dest, line, 9, PATH_MAX);
11273			strcpy(target_obj, dest); // support Chinese
11274		}
11275		else if(strstr(line, "ERR_MSG") != NULL){
11276			substr(dest, line, 8, PATH_MAX);
11277			strcpy(error_msg, dest);
11278		}
11279		else if(strstr(line, "TOTAL_SPACE") != NULL){
11280			substr(dest, line, 12, PATH_MAX);
11281			strcpy(full_capa, dest);
11282		}
11283		else if(strstr(line, "USED_SPACE") != NULL){
11284			substr(dest, line, 11, PATH_MAX);
11285			strcpy(used_capa, dest);
11286		}
11287		else if(strstr(line, "RULENUM") != NULL){
11288			substr(dest, line, 8, PATH_MAX);
11289			strcpy(rule_num, dest);
11290		}
11291
11292		memset(line, 0, PATH_MAX);
11293	}
11294	fclose(fp);
11295
11296	if(!line_num){
11297		websWrite(wp, "cloud_ftpclient_status=\"ERROR\";\n");
11298		websWrite(wp, "cloud_ftpclient_obj=\"\";\n");
11299		websWrite(wp, "cloud_ftpclient_msg=\"\";\n");
11300		websWrite(wp, "cloud_ftpclient_fullcapa=\"\";\n");
11301		websWrite(wp, "cloud_ftpclient_usedcapa=\"\";\n");
11302		websWrite(wp, "cloud_ftpclient_rule_num=\"\";\n");
11303	}
11304	else{
11305		websWrite(wp, "cloud_ftpclient_status=\"%s\";\n", status);
11306		websWrite(wp, "cloud_ftpclient_obj=\"%s\";\n", target_obj);
11307		if(!strcmp(status,"SYNC"))
11308		   strncpy(error_msg,"Sync has been completed",PATH_MAX);
11309		else if(!strcmp(status,"INITIAL"))
11310		   strncpy(error_msg,"Verifying",PATH_MAX);
11311		websWrite(wp, "cloud_ftpclient_msg=\"%s\";\n", error_msg);
11312		websWrite(wp, "cloud_ftpclient_fullcapa=\"%s\";\n", full_capa);
11313		websWrite(wp, "cloud_ftpclient_usedcapa=\"%s\";\n", used_capa);
11314		websWrite(wp, "cloud_ftpclient_rule_num=\"%s\";\n", rule_num);
11315	}
11316
11317	return 0;
11318}
11319
11320int ej_UI_cloud_sambaclient_status(int eid, webs_t wp, int argc, char **argv){
11321	FILE *fp = fopen("/tmp/smartsync/.logs/sambaclient", "r");
11322	char line[PATH_MAX], buf[PATH_MAX], dest[PATH_MAX];
11323	int line_num;
11324	char status[16], mounted_path[PATH_MAX], target_obj[PATH_MAX], error_msg[PATH_MAX], full_capa[PATH_MAX], used_capa[PATH_MAX], rule_num[PATH_MAX];
11325
11326	if(fp == NULL){
11327		websWrite(wp, "cloud_sambaclient_status=\"WAITING\";\n"); //gauss change status fromm 'ERROR' to 'WAITING' 2014.11.4
11328		websWrite(wp, "cloud_sambaclient_obj=\"\";\n");
11329		websWrite(wp, "cloud_sambaclient_msg=\"\";\n");
11330		websWrite(wp, "cloud_sambaclient_fullcapa=\"\";\n");
11331		websWrite(wp, "cloud_sambaclient_usedcapa=\"\";\n");
11332		websWrite(wp, "cloud_sambaclient_rule_num=\"\";\n");
11333		return 0;
11334	}
11335
11336	memset(status, 0, 16);
11337	memset(mounted_path, 0, PATH_MAX);
11338	memset(target_obj, 0, PATH_MAX);
11339	memset(error_msg, 0, PATH_MAX);
11340	memset(full_capa, 0, PATH_MAX);
11341	memset(used_capa, 0, PATH_MAX);
11342	memset(rule_num, 0, PATH_MAX);
11343
11344	memset(line, 0, PATH_MAX);
11345	line_num = 0;
11346	while(fgets(line, PATH_MAX, fp)){
11347		++line_num;
11348		line[strlen(line)-1] = 0;
11349
11350		if(strstr(line, "STATUS") != NULL){
11351			strncpy(status, convert_cloudsync_status(line), 16);
11352		}
11353		else if(strstr(line, "MOUNT_PATH") != NULL){
11354			memset(buf, 0, PATH_MAX);
11355			substr(dest, line, 11, PATH_MAX);
11356			char_to_ascii(buf, dest);
11357			strcpy(mounted_path, buf);
11358		}
11359		else if(strstr(line, "FILENAME") != NULL){
11360			substr(dest, line, 9, PATH_MAX);
11361			strcpy(target_obj, dest); // support Chinese
11362		}
11363		else if(strstr(line, "ERR_MSG") != NULL){
11364			substr(dest, line, 8, PATH_MAX);
11365			strcpy(error_msg, dest);
11366		}
11367		else if(strstr(line, "TOTAL_SPACE") != NULL){
11368			substr(dest, line, 12, PATH_MAX);
11369			strcpy(full_capa, dest);
11370		}
11371		else if(strstr(line, "USED_SPACE") != NULL){
11372			substr(dest, line, 11, PATH_MAX);
11373			strcpy(used_capa, dest);
11374		}
11375		else if(strstr(line, "RULENUM") != NULL){
11376			substr(dest, line, 8, PATH_MAX);
11377			strcpy(rule_num, dest);
11378		}
11379
11380		memset(line, 0, PATH_MAX);
11381	}
11382	fclose(fp);
11383
11384	if(!line_num){
11385		websWrite(wp, "cloud_sambaclient_status=\"ERROR\";\n");
11386		websWrite(wp, "cloud_sambaclient_obj=\"\";\n");
11387		websWrite(wp, "cloud_sambaclient_msg=\"\";\n");
11388		websWrite(wp, "cloud_sambaclient_fullcapa=\"\";\n");
11389		websWrite(wp, "cloud_sambaclient_usedcapa=\"\";\n");
11390		websWrite(wp, "cloud_sambaclient_rule_num=\"\";\n");
11391	}
11392	else{
11393		websWrite(wp, "cloud_sambaclient_status=\"%s\";\n", status);
11394		websWrite(wp, "cloud_sambaclient_obj=\"%s\";\n", target_obj);
11395		if(!strcmp(status,"SYNC"))
11396		   strncpy(error_msg,"Sync has been completed",PATH_MAX);
11397		else if(!strcmp(status,"INITIAL"))
11398		   strncpy(error_msg,"Verifying",PATH_MAX);
11399		websWrite(wp, "cloud_sambaclient_msg=\"%s\";\n", error_msg);
11400		websWrite(wp, "cloud_sambaclient_fullcapa=\"%s\";\n", full_capa);
11401		websWrite(wp, "cloud_sambaclient_usedcapa=\"%s\";\n", used_capa);
11402		websWrite(wp, "cloud_sambaclient_rule_num=\"%s\";\n", rule_num);
11403	}
11404
11405	return 0;
11406}
11407
11408
11409int ej_UI_cloud_usbclient_status(int eid, webs_t wp, int argc, char **argv){
11410	FILE *fp = fopen("/tmp/smartsync/.logs/usbclient", "r");
11411	char line[PATH_MAX], buf[PATH_MAX], dest[PATH_MAX];
11412	int line_num;
11413	char status[16], mounted_path[PATH_MAX], target_obj[PATH_MAX], error_msg[PATH_MAX], full_capa[PATH_MAX], used_capa[PATH_MAX], rule_num[PATH_MAX];
11414
11415	if(fp == NULL){
11416		websWrite(wp, "cloud_usbclient_status=\"WAITING\";\n"); //gauss change status fromm 'ERROR' to 'WAITING' 2014.11.4
11417		websWrite(wp, "cloud_usbclient_obj=\"\";\n");
11418		websWrite(wp, "cloud_usbclient_msg=\"\";\n");
11419		websWrite(wp, "cloud_usbclient_fullcapa=\"\";\n");
11420		websWrite(wp, "cloud_usbclient_usedcapa=\"\";\n");
11421		websWrite(wp, "cloud_usbclient_rule_num=\"\";\n");
11422		return 0;
11423	}
11424
11425	memset(status, 0, 16);
11426	memset(mounted_path, 0, PATH_MAX);
11427	memset(target_obj, 0, PATH_MAX);
11428	memset(error_msg, 0, PATH_MAX);
11429	memset(full_capa, 0, PATH_MAX);
11430	memset(used_capa, 0, PATH_MAX);
11431	memset(rule_num, 0, PATH_MAX);
11432
11433	memset(line, 0, PATH_MAX);
11434	line_num = 0;
11435	while(fgets(line, PATH_MAX, fp)){
11436		++line_num;
11437		line[strlen(line)-1] = 0;
11438
11439		if(strstr(line, "STATUS") != NULL){
11440			strncpy(status, convert_cloudsync_status(line), 16);
11441		}
11442		else if(strstr(line, "MOUNT_PATH") != NULL){
11443			memset(buf, 0, PATH_MAX);
11444			substr(dest, line, 11, PATH_MAX);
11445			char_to_ascii(buf, dest);
11446			strcpy(mounted_path, buf);
11447		}
11448		else if(strstr(line, "FILENAME") != NULL){
11449			substr(dest, line, 9, PATH_MAX);
11450			strcpy(target_obj, dest); // support Chinese
11451		}
11452		else if(strstr(line, "ERR_MSG") != NULL){
11453			substr(dest, line, 8, PATH_MAX);
11454			strcpy(error_msg, dest);
11455		}
11456		else if(strstr(line, "TOTAL_SPACE") != NULL){
11457			substr(dest, line, 12, PATH_MAX);
11458			strcpy(full_capa, dest);
11459		}
11460		else if(strstr(line, "USED_SPACE") != NULL){
11461			substr(dest, line, 11, PATH_MAX);
11462			strcpy(used_capa, dest);
11463		}
11464		else if(strstr(line, "RULENUM") != NULL){
11465			substr(dest, line, 8, PATH_MAX);
11466			strcpy(rule_num, dest);
11467		}
11468
11469		memset(line, 0, PATH_MAX);
11470	}
11471	fclose(fp);
11472
11473	if(!line_num){
11474		websWrite(wp, "cloud_usbclient_status=\"ERROR\";\n");
11475		websWrite(wp, "cloud_usbclient_obj=\"\";\n");
11476		websWrite(wp, "cloud_usbclient_msg=\"\";\n");
11477		websWrite(wp, "cloud_usbclient_fullcapa=\"\";\n");
11478		websWrite(wp, "cloud_usbclient_usedcapa=\"\";\n");
11479		websWrite(wp, "cloud_usbclient_rule_num=\"\";\n");
11480	}
11481	else{
11482		websWrite(wp, "cloud_usbclient_status=\"%s\";\n", status);
11483		websWrite(wp, "cloud_usbclient_obj=\"%s\";\n", target_obj);
11484		if(!strcmp(status,"SYNC"))
11485		   strncpy(error_msg,"Sync has been completed",PATH_MAX);
11486		else if(!strcmp(status,"INITIAL"))
11487		   strncpy(error_msg,"Verifying",PATH_MAX);
11488		websWrite(wp, "cloud_usbclient_msg=\"%s\";\n", error_msg);
11489		websWrite(wp, "cloud_usbclient_fullcapa=\"%s\";\n", full_capa);
11490		websWrite(wp, "cloud_usbclient_usedcapa=\"%s\";\n", used_capa);
11491		websWrite(wp, "cloud_usbclient_rule_num=\"%s\";\n", rule_num);
11492	}
11493
11494	return 0;
11495}
11496
11497int ej_UI_rs_status(int eid, webs_t wp, int argc, char **argv){
11498	FILE *fp = fopen("/tmp/Cloud/log/WebDAV", "r");
11499	char line[PATH_MAX], buf[PATH_MAX], dest[PATH_MAX];
11500	int line_num;
11501	char rulenum[PATH_MAX], status[16], mounted_path[PATH_MAX], target_obj[PATH_MAX], error_msg[PATH_MAX], full_capa[PATH_MAX], used_capa[PATH_MAX];
11502
11503	if(fp == NULL){
11504		websWrite(wp, "rs_rulenum=\"\";\n");
11505		websWrite(wp, "rs_status=\"WAITING\";\n"); //gauss change status fromm 'ERROR' to 'WAITING' 2014.11.4
11506		websWrite(wp, "rs_obj=\"\";\n");
11507		websWrite(wp, "rs_msg=\"\";\n");
11508		websWrite(wp, "rs_fullcapa=\"\";\n");
11509		websWrite(wp, "rs_usedcapa=\"\";\n");
11510		return 0;
11511	}
11512
11513	memset(status, 0, 16);
11514	memset(rulenum, 0, PATH_MAX);
11515	memset(mounted_path, 0, PATH_MAX);
11516	memset(target_obj, 0, PATH_MAX);
11517	memset(error_msg, 0, PATH_MAX);
11518	memset(full_capa, 0, PATH_MAX);
11519	memset(used_capa, 0, PATH_MAX);
11520
11521	memset(line, 0, PATH_MAX);
11522	line_num = 0;
11523	while(fgets(line, PATH_MAX, fp)){
11524		++line_num;
11525		line[strlen(line)-1] = 0;
11526
11527		if(strstr(line, "STATUS") != NULL){
11528			strncpy(status, convert_cloudsync_status(line), 16);
11529		}
11530		else if(strstr(line, "RULENUM") != NULL){
11531			substr(dest, line, 8, PATH_MAX);
11532			strcpy(rulenum, dest);
11533		}
11534		else if(strstr(line, "MOUNT_PATH") != NULL){
11535			memset(buf, 0, PATH_MAX);
11536			substr(dest, line, 11, PATH_MAX);
11537			char_to_ascii(buf, dest);
11538			strcpy(mounted_path, buf);
11539		}
11540		else if(strstr(line, "FILENAME") != NULL){
11541			substr(dest, line, 9, PATH_MAX);
11542			strcpy(target_obj, dest); // support Chinese
11543		}
11544		else if(strstr(line, "ERR_MSG") != NULL){
11545			substr(dest, line, 8, PATH_MAX);
11546			strcpy(error_msg, dest);
11547		}
11548		else if(strstr(line, "TOTAL_SPACE") != NULL){
11549			substr(dest, line, 12, PATH_MAX);
11550			strcpy(full_capa, dest);
11551		}
11552		else if(strstr(line, "USED_SPACE") != NULL){
11553			substr(dest, line, 11, PATH_MAX);
11554			strcpy(used_capa, dest);
11555		}
11556
11557		memset(line, 0, PATH_MAX);
11558	}
11559	fclose(fp);
11560
11561	if(!line_num){
11562		websWrite(wp, "rs_rulenum=\"\";\n");
11563		websWrite(wp, "rs_status=\"ERROR\";\n");
11564		websWrite(wp, "rs_obj=\"\";\n");
11565		websWrite(wp, "rs_msg=\"\";\n");
11566		websWrite(wp, "rs_fullcapa=\"\";\n");
11567		websWrite(wp, "rs_usedcapa=\"\";\n");
11568	}
11569	else{
11570		websWrite(wp, "rs_rulenum=\"%s\";\n", rulenum);
11571		websWrite(wp, "rs_status=\"%s\";\n", status);
11572		websWrite(wp, "rs_obj=\"%s\";\n", target_obj);
11573		if(!strcmp(status,"SYNC"))
11574		   strncpy(error_msg,"Sync has been completed",PATH_MAX);
11575		else if(!strcmp(status,"INITIAL"))
11576		   strncpy(error_msg,"Verifying",PATH_MAX);
11577		websWrite(wp, "rs_msg=\"%s\";\n", error_msg);
11578		websWrite(wp, "rs_fullcapa=\"%s\";\n", full_capa);
11579		websWrite(wp, "rs_usedcapa=\"%s\";\n", used_capa);
11580	}
11581
11582	return 0;
11583}
11584
11585int ej_webdavInfo(int eid, webs_t wp, int argc, char **argv) {
11586	websWrite(wp, "// pktInfo=['PrinterInfo','SSID','NetMask','ProductID','FWVersion','OPMode','MACAddr','Regulation'];\n");
11587	websWrite(wp, "pktInfo=['','%s',", nvram_safe_get("wl0_ssid"));
11588	websWrite(wp, "'%s',", nvram_safe_get("lan_netmask"));
11589	websWrite(wp, "'%s',", nvram_safe_get("productid"));
11590	websWrite(wp, "'%s.%s',", nvram_safe_get("firmver"), nvram_safe_get("buildno"));
11591	websWrite(wp, "'%s',", nvram_safe_get("sw_mode"));
11592#if defined(RTCONFIG_RGMII_BRCM5301X) || defined(RTCONFIG_QCA) || defined(RTAC3100)
11593	websWrite(wp, "'%s',", nvram_safe_get("lan_hwaddr"));
11594#else
11595	websWrite(wp, "'%s',", nvram_safe_get("et0macaddr"));
11596#endif
11597	websWrite(wp, "''];\n");
11598
11599	websWrite(wp, "// webdavInfo=['Webdav','HTTPType','HTTPPort','DDNS','HostName','WAN0IPAddr','','xSetting','HTTPSPort'];\n");
11600	websWrite(wp, "webdavInfo=['%s',", nvram_safe_get("enable_webdav"));
11601	websWrite(wp, "'%s',", nvram_safe_get("st_webdav_mode"));
11602	websWrite(wp, "'%s',", nvram_safe_get("webdav_http_port"));
11603	websWrite(wp, "'%s',", nvram_safe_get("ddns_enable_x"));
11604	websWrite(wp, "'%s',", nvram_safe_get("ddns_hostname_x"));
11605	websWrite(wp, "'%s',", nvram_safe_get("wan0_ipaddr"));
11606	websWrite(wp, "'%s',", nvram_safe_get(""));
11607	websWrite(wp, "'%s',", nvram_safe_get("x_Setting"));
11608	websWrite(wp, "'%s',", nvram_safe_get("webdav_https_port"));
11609#ifdef RTCONFIG_WEBDAV
11610 	websWrite(wp, "'1'");
11611#else
11612	if(check_if_file_exist("/opt/etc/init.d/S50aicloud")) websWrite(wp, "'1'");
11613	else websWrite(wp, "'0'");
11614#endif
11615	websWrite(wp, "];\n");
11616
11617	return 0;
11618}
11619//#endif
11620#endif
11621
11622// 2010.09 James. {
11623int start_autodet(int eid, webs_t wp, int argc, char **argv) {
11624	nvram_set("autodet_state", "");
11625	notify_rc_after_period_wait("start_autodet", 0);
11626	return 0;
11627}
11628#ifdef RTCONFIG_QCA_PLC_UTILS
11629int start_plcdet(int eid, webs_t wp, int argc, char **argv) {
11630	nvram_set("autodet_plc_state", "");
11631	notify_rc_after_period_wait("start_plcdet", 0);
11632	return 0;
11633}
11634#endif
11635#if defined(CONFIG_BCMWL5) || (defined(RTCONFIG_RALINK) && defined(RTCONFIG_WIRELESSREPEATER)) || defined(RTCONFIG_QCA)
11636int start_wlcscan(int eid, webs_t wp, int argc, char **argv) {
11637	notify_rc("start_wlcscan");
11638	return 0;
11639}
11640#endif
11641int setting_lan(int eid, webs_t wp, int argc, char **argv){
11642	char lan_ipaddr_t[16];
11643	char lan_netmask_t[16];
11644	unsigned int lan_ip_num;
11645	unsigned int lan_mask_num;
11646	unsigned int lan_subnet;
11647	char wan_ipaddr_t[16];
11648	char wan_netmask_t[16];
11649	unsigned int wan_ip_num;
11650	unsigned int wan_mask_num;
11651	unsigned int wan_subnet;
11652	const unsigned int MAX_SUBNET = 3232300800U;
11653	const unsigned int MIN_LAN_IP = 3232235521U;
11654	struct in_addr addr;
11655	unsigned int new_lan_ip_num;
11656	unsigned int new_dhcp_start_num;
11657	unsigned int new_dhcp_end_num;
11658	char new_lan_ip_str[16];
11659	char new_dhcp_start_str[16];
11660	char new_dhcp_end_str[16];
11661	char tmp_lan[100], prefix_lan[] = "lanXXXXXXXXXX_";
11662	int unit;
11663	char tmp_wan[100], prefix_wan[] = "wanXXXXXXXXXX_";
11664
11665	snprintf(prefix_lan, sizeof(prefix_lan), "lan_");
11666
11667	memset(lan_ipaddr_t, 0, 16);
11668	strcpy(lan_ipaddr_t, nvram_safe_get(strcat_r(prefix_lan, "ipaddr", tmp_lan)));
11669	memset(&addr, 0, sizeof(addr));
11670	lan_ip_num = ntohl(inet_aton(lan_ipaddr_t, &addr));
11671	lan_ip_num = ntohl(addr.s_addr);
11672	memset(lan_netmask_t, 0, 16);
11673	strcpy(lan_netmask_t, nvram_safe_get(strcat_r(prefix_lan, "netmask", tmp_lan)));
11674	memset(&addr, 0, sizeof(addr));
11675	lan_mask_num = ntohl(inet_aton(lan_netmask_t, &addr));
11676	lan_mask_num = ntohl(addr.s_addr);
11677	lan_subnet = lan_ip_num&lan_mask_num;
11678_dprintf("http: get lan_subnet=%x!\n", lan_subnet);
11679
11680	if ((unit = get_primaryif_dualwan_unit()) < 0) {
11681_dprintf("http: Can't get the WAN's unit!\n");
11682		websWrite(wp, "0");
11683		return 0;
11684	}
11685
11686	if (!dualwan_unit__usbif(unit)) {
11687		wan_prefix(unit, prefix_wan);
11688
11689		memset(wan_ipaddr_t, 0, 16);
11690		strcpy(wan_ipaddr_t, nvram_safe_get(strcat_r(prefix_lan, "ipaddr", tmp_wan)));
11691		memset(&addr, 0, sizeof(addr));
11692		wan_ip_num = ntohl(inet_aton(wan_ipaddr_t, &addr));
11693		wan_ip_num = ntohl(addr.s_addr);
11694		memset(wan_netmask_t, 0, 16);
11695		strcpy(wan_netmask_t, nvram_safe_get(strcat_r(prefix_lan, "netmask", tmp_wan)));
11696		memset(&addr, 0, sizeof(addr));
11697		wan_mask_num = ntohl(inet_aton(wan_netmask_t, &addr));
11698		wan_mask_num = ntohl(addr.s_addr);
11699		wan_subnet = wan_ip_num&wan_mask_num;
11700_dprintf("http: get wan_subnet=%x!\n", wan_subnet);
11701
11702		if(lan_subnet != wan_subnet){
11703_dprintf("http: The subnets of WAN and LAN aren't the same already.!\n");
11704			websWrite(wp, "0");
11705			return 0;
11706		}
11707	}
11708
11709	if(lan_subnet >= MAX_SUBNET)
11710		new_lan_ip_num = MIN_LAN_IP;
11711	else
11712		new_lan_ip_num = lan_ip_num+(~lan_mask_num)+1;
11713
11714	new_dhcp_start_num = new_lan_ip_num+1;
11715	new_dhcp_end_num = new_lan_ip_num+(~inet_network(lan_netmask_t))-2;
11716_dprintf("%u, %u, %u.\n", new_lan_ip_num, new_dhcp_start_num, new_dhcp_end_num);
11717	memset(&addr, 0, sizeof(addr));
11718	addr.s_addr = htonl(new_lan_ip_num);
11719	memset(new_lan_ip_str, 0, 16);
11720	strcpy(new_lan_ip_str, inet_ntoa(addr));
11721	memset(&addr, 0, sizeof(addr));
11722	addr.s_addr = htonl(new_dhcp_start_num);
11723	memset(new_dhcp_start_str, 0, 16);
11724	strcpy(new_dhcp_start_str, inet_ntoa(addr));
11725	memset(&addr, 0, sizeof(addr));
11726	addr.s_addr = htonl(new_dhcp_end_num);
11727	memset(new_dhcp_end_str, 0, 16);
11728	strcpy(new_dhcp_end_str, inet_ntoa(addr));
11729_dprintf("%s, %s, %s.\n", new_lan_ip_str, new_dhcp_start_str, new_dhcp_end_str);
11730
11731	nvram_set(strcat_r(prefix_lan, "ipaddr", tmp_lan), new_lan_ip_str);
11732	nvram_set(strcat_r(prefix_lan, "ipaddr_rt", tmp_lan), new_lan_ip_str); // Sync to lan_ipaddr_rt, added by jerry5.
11733	nvram_set("dhcp_start", new_dhcp_start_str);
11734	nvram_set("dhcp_end", new_dhcp_end_str);
11735
11736	websWrite(wp, "1");
11737
11738	nvram_commit();
11739
11740	nvram_set("freeze_duck", "15");
11741	notify_rc("restart_net_and_phy");
11742
11743	return 0;
11744}
11745// 2010.09 James. }
11746
11747// qos svg support 2010.08 Viz vvvvvvvvvvvv
11748void asp_ctcount(webs_t wp, int argc, char_t **argv)
11749{
11750	static const char *states[10] = {
11751		"NONE", "ESTABLISHED", "SYN_SENT", "SYN_RECV", "FIN_WAIT",
11752		"TIME_WAIT", "CLOSE", "CLOSE_WAIT", "LAST_ACK", "LISTEN" };
11753	int count[13];	// tcp(10) + udp(2) + total(1) = 13 / max classes = 10
11754	FILE *f;
11755	char s[512];
11756	char *p;
11757	int i;
11758	int n;
11759	int mode;
11760	unsigned long rip;
11761	unsigned long lan;
11762	unsigned long mask;
11763	int ret=0;
11764
11765	if (argc != 1) return;
11766	mode = atoi(argv[0]);
11767
11768	memset(count, 0, sizeof(count));
11769
11770	  if ((f = fopen("/proc/net/ip_conntrack", "r")) != NULL) {
11771		// ctvbuf(f);	// if possible, read in one go
11772
11773		if (nvram_match("t_hidelr", "1")) {
11774			mask = inet_addr(nvram_safe_get("lan_netmask"));
11775			rip = inet_addr(nvram_safe_get("lan_ipaddr"));
11776			lan = rip & mask;
11777		}
11778		else {
11779			rip = lan = mask = 0;
11780		}
11781
11782		while (fgets(s, sizeof(s), f)) {
11783			if (rip != 0) {
11784				// src=x.x.x.x dst=x.x.x.x	// DIR_ORIGINAL
11785				if ((p = strstr(s + 14, "src=")) == NULL) continue;
11786				if ((inet_addr(p + 4) & mask) == lan) {
11787					if ((p = strstr(p + 13, "dst=")) == NULL) continue;
11788					if (inet_addr(p + 4) == rip) continue;
11789				}
11790			}
11791
11792			if (mode == 0) {
11793				// count connections per state
11794				if (strncmp(s, "tcp", 3) == 0) {
11795					for (i = 9; i >= 0; --i) {
11796						if (strstr(s, states[i]) != NULL) {
11797							count[i]++;
11798							break;
11799						}
11800					}
11801				}
11802				else if (strncmp(s, "udp", 3) == 0) {
11803					if (strstr(s, "[UNREPLIED]") != NULL) {
11804						count[10]++;
11805					}
11806					else if (strstr(s, "[ASSURED]") != NULL) {
11807						count[11]++;
11808					}
11809				}
11810				count[12]++;
11811			}
11812			else {
11813				// count connections per mark
11814				if ((p = strstr(s, " mark=")) != NULL) {
11815					n = atoi(p + 6) & 0xFF;
11816					if (n <= 10) count[n]++;
11817				}
11818			}
11819		}
11820
11821		fclose(f);
11822	}
11823
11824	if (mode == 0) {
11825		p = s;
11826		for (i = 0; i < 12; ++i) {
11827			p += sprintf(p, ",%d", count[i]);
11828		}
11829		ret += websWrite(wp, "\nconntrack = [%d%s];\n", count[12], s);
11830	}
11831	else {
11832		p = s;
11833		for (i = 1; i < 11; ++i) {
11834			p += sprintf(p, ",%d", count[i]);
11835		}
11836		ret += websWrite(wp, "\nnfmarks = [%d%s];\n", count[0], s);
11837	}
11838}
11839
11840int ej_qos_packet(int eid, webs_t wp, int argc, char_t **argv)
11841{
11842	FILE *f;
11843	char s[256];
11844	unsigned long rates[10];
11845	unsigned long u;
11846	char *e;
11847	int n;
11848	char comma;
11849	char *a[1];
11850	int ret=0, unit;
11851	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
11852	char wan_ifname[16];
11853
11854	unit = wan_primary_ifunit();
11855	wan_prefix(unit, prefix);
11856	memset(wan_ifname, 0, 16);
11857	strcpy(wan_ifname, strcat_r(prefix, "ifname", tmp));
11858
11859	a[0] = "1";
11860	asp_ctcount(wp, 1, a);
11861
11862	memset(rates, 0, sizeof(rates));
11863	sprintf(s, "tc -s class ls dev %s", nvram_safe_get(wan_ifname));
11864	if ((f = popen(s, "r")) != NULL) {
11865		n = 1;
11866		while (fgets(s, sizeof(s), f)) {
11867			if (strncmp(s, "class htb 1:", 12) == 0) {
11868				n = atoi(s + 12);
11869			}
11870			else if (strncmp(s, " rate ", 6) == 0) {
11871				if ((n % 10) == 0) {
11872					n /= 10;
11873					if ((n >= 1) && (n <= 10)) {
11874						u = strtoul(s + 6, &e, 10);
11875						if (*e == 'K') u *= 1000;
11876							else if (*e == 'M') u *= 1000 * 1000;
11877						rates[n - 1] = u;
11878						n = 1;
11879					}
11880				}
11881			}
11882		}
11883		pclose(f);
11884	}
11885
11886	comma = ' ';
11887	ret += websWrite(wp, "\nqrates = [0,");
11888	for (n = 0; n < 10; ++n) {
11889		ret += websWrite(wp, "%c%lu", comma, rates[n]);
11890		comma = ',';
11891	}
11892	ret += websWrite(wp, "];");
11893	return 0;
11894}
11895
11896int ej_ctdump(int eid, webs_t wp, int argc, char **argv)
11897{
11898	FILE *f;
11899	char s[512];
11900	char *p, *q;
11901	int mark;
11902	int findmark;
11903	unsigned int proto;
11904	unsigned int time;
11905	char src[16];
11906	char dst[16];
11907	char sport[16];
11908	char dport[16];
11909	unsigned long rip;
11910	unsigned long lan;
11911	unsigned long mask;
11912	char comma;
11913	int ret=0;
11914
11915	if (argc != 1) return 0;
11916
11917	findmark = atoi(argv[0]);
11918
11919	mask = inet_addr(nvram_safe_get("lan_netmask"));
11920	rip = inet_addr(nvram_safe_get("lan_ipaddr"));
11921	lan = rip & mask;
11922	if (nvram_match("t_hidelr", "0")) rip = 0;	// hide lan -> router?
11923
11924	ret += websWrite(wp, "\nctdump = [");
11925	comma = ' ';
11926	if ((f = fopen("/proc/net/ip_conntrack", "r")) != NULL) {
11927		//ctvbuf(f);
11928		while (fgets(s, sizeof(s), f)) {
11929			if ((p = strstr(s, " mark=")) == NULL) continue;
11930			if ((mark = (atoi(p + 6) & 0xFF)) > 10) mark = 0;
11931			if ((findmark != -1) && (mark != findmark)) continue;
11932
11933			if (sscanf(s, "%*s %u %u", &proto, &time) != 2) continue;
11934
11935			if ((p = strstr(s + 14, "src=")) == NULL) continue;		// DIR_ORIGINAL
11936			if ((inet_addr(p + 4) & mask) != lan) {
11937				// make sure we're seeing int---ext if possible
11938				if ((p = strstr(p + 41, "src=")) == NULL) continue;	// DIR_REPLY
11939			}
11940			else if (rip != 0) {
11941				if ((q = strstr(p + 13, "dst=")) == NULL) continue;
11942//				cprintf("%lx=%lx\n", inet_addr(q + 4), rip);
11943				if (inet_addr(q + 4) == rip) continue;
11944			}
11945
11946			if ((proto == 6) || (proto == 17)) {
11947				if (sscanf(p + 4, "%s dst=%s sport=%s dport=%s", src, dst, sport, dport) != 4) continue;
11948			}
11949			else {
11950				if (sscanf(p + 4, "%s dst=%s", src, dst) != 2) continue;
11951				sport[0] = 0;
11952				dport[0] = 0;
11953			}
11954			ret += websWrite(wp, "%c[%u,%u,'%s','%s','%s','%s',%d]", comma, proto, time, src, dst, sport, dport, mark);
11955			comma = ',';
11956		}
11957	}
11958	ret += websWrite(wp, "];\n");
11959	return 0;
11960}
11961
11962void ej_cgi_get(int eid, webs_t wp, int argc, char **argv)
11963{
11964	const char *v;
11965	int i;
11966	int ret;
11967
11968	for (i = 0; i < argc; ++i) {
11969		v = get_cgi(argv[i]);
11970		if (v) ret += websWrite(wp, v);
11971	}
11972}
11973
11974#ifdef RTCONFIG_BCM5301X_TRAFFIC_MONITOR
11975uint32_t traffic_wanlan(char *ifname, uint32_t *rx, uint32_t *tx);
11976#endif
11977
11978// traffic monitor
11979static int ej_netdev(int eid, webs_t wp, int argc, char_t **argv)
11980{
11981 FILE * fp;
11982  char buf[256];
11983  unsigned long rx, tx;
11984  unsigned long rx2, tx2;
11985#ifdef RTCONFIG_LACP
11986  unsigned long rx_lacp1, tx_lacp1;
11987  unsigned long rx2_lacp1, tx2_lacp1;
11988  unsigned long rx_lacp2, tx_lacp2;
11989  unsigned long rx2_lacp2, tx2_lacp2;
11990#endif
11991  unsigned long wl0_all_rx = 0, wl0_all_tx = 0;
11992  unsigned long wl1_all_rx = 0, wl1_all_tx = 0;
11993  char *p;
11994  char *ifname;
11995  char ifname_desc[12], ifname_desc2[12];
11996#ifdef RTCONFIG_LACP
11997  char ifname_desc2_lacp1[12];
11998  char ifname_desc2_lacp2[12];
11999#endif
12000  char comma;
12001  int wl0_valid = 0, wl1_valid = 0;
12002  int ret=0;
12003  int from_app = 0;
12004 #ifdef RTCONFIG_QTN  //RT-AC87U
12005	qcsapi_unsigned_int l_counter_value;
12006#endif
12007
12008  from_app = check_user_agent(user_agent);
12009
12010  if(from_app == 0)
12011     ret += websWrite(wp, "\nnetdev = {\n");
12012
12013  if ((fp = fopen("/proc/net/dev", "r")) != NULL) {
12014		fgets(buf, sizeof(buf), fp);
12015		fgets(buf, sizeof(buf), fp);
12016		comma = ' ';
12017			while (fgets(buf, sizeof(buf), fp)) {
12018				if ((p = strchr(buf, ':')) == NULL) continue;
12019				*p = 0;
12020				if ((ifname = strrchr(buf, ' ')) == NULL) ifname = buf;
12021			   		else ++ifname;
12022	  	   		if (sscanf(p + 1, "%lu%*u%*u%*u%*u%*u%*u%*u%lu", &rx, &tx) != 2) continue;
12023
12024#ifdef RTCONFIG_BCM5301X_TRAFFIC_MONITOR
12025				/* WAN1, WAN2, LAN */
12026				if(strncmp(ifname, "vlan", 4)==0){
12027					traffic_wanlan(ifname, (uint32_t *) &rx, (uint32_t *) &tx);
12028#ifdef RTCONFIG_LACP
12029					if(nvram_get_int("lacp_enabled") == 1 &&
12030							strcmp(ifname, "vlan1") == 0){
12031						traffic_trunk(1, &rx_lacp1, &tx_lacp1);
12032						netdev_calc("lacp1", "LACP1",
12033								&rx_lacp1, &tx_lacp1,
12034								ifname_desc2_lacp1,
12035								&rx2_lacp1, &tx2_lacp1);
12036
12037						traffic_trunk(2, &rx_lacp2, &tx_lacp2);
12038						netdev_calc("lacp2", "LACP2",
12039								&rx_lacp2, &tx_lacp2,
12040								ifname_desc2_lacp2,
12041								&rx2_lacp2, &tx2_lacp2);
12042					}
12043#endif
12044#ifdef RTCONFIG_QTN  //RT-AC87U
12045					if (nvram_contains_word("lan_ifnames", ifname)){
12046						if (rpc_qtn_ready()) {
12047							qcsapi_interface_get_counter("eth1_1", qcsapi_total_bytes_received,
12048																		&l_counter_value);
12049							rx += l_counter_value;
12050							qcsapi_interface_get_counter("eth1_1", qcsapi_total_bytes_sent,
12051																		&l_counter_value);
12052							tx += l_counter_value;
12053						}
12054					}
12055#endif
12056				}
12057				if(nvram_match("wans_dualwan", "wan none")){
12058					if(strcmp(ifname, "eth0")==0){
12059						traffic_wanlan(WAN0DEV, (uint32_t *) &rx, (uint32_t *) &tx);
12060					}
12061				}
12062#endif	/* RTCONFIG_BCM5301X_TRAFFIC_MONITOR */
12063				if (!netdev_calc(ifname, ifname_desc, &rx, &tx, ifname_desc2, &rx2, &tx2)) continue;
12064
12065
12066loopagain:
12067				if (!strncmp(ifname_desc, "WIRELESS0", 9)) {
12068					wl0_valid = 1;
12069					wl0_all_rx += rx;
12070					wl0_all_tx += tx;
12071				} else if (!strncmp(ifname_desc, "WIRELESS1", 9)) {
12072					wl1_valid = 1;
12073					wl1_all_rx += rx;
12074					wl1_all_tx += tx;
12075				} else {
12076					if(from_app == 0){
12077						ret += websWrite(wp, "%c'%s':{rx:0x%lx,tx:0x%lx}\n", comma, ifname_desc, rx, tx);
12078					}else{
12079						ret += websWrite(wp, "%c\"%s_rx\":\"0x%lx\",\"%s_tx\":\"0x%lx\"", comma, ifname_desc, rx, ifname_desc, tx);
12080					}
12081						comma = ',';
12082				}
12083
12084				if(strlen(ifname_desc2)) {
12085					strcpy(ifname_desc, ifname_desc2);
12086					rx = rx2;
12087					tx = tx2;
12088					strcpy(ifname_desc2, "");
12089					goto loopagain;
12090				}
12091
12092			}
12093#ifdef RTCONFIG_QTN  //RT-AC87U
12094			if (rpc_qtn_ready()) {
12095				qcsapi_interface_get_counter(WIFINAME, qcsapi_total_bytes_received, &l_counter_value);
12096				wl1_all_rx = l_counter_value;
12097				qcsapi_interface_get_counter(WIFINAME, qcsapi_total_bytes_sent, &l_counter_value);
12098				wl1_all_tx = l_counter_value;
12099				wl1_valid = 1;
12100			}
12101#endif
12102
12103
12104			if (wl0_valid) {
12105				if(from_app == 0){
12106					ret += websWrite(wp, "%c'%s':{rx:0x%lx,tx:0x%lx}\n", comma, "WIRELESS0", wl0_all_rx, wl0_all_tx);
12107				}else{
12108					ret += websWrite(wp, "%c\"%s_rx\":\"0x%lx\",\"%s_tx\":\"0x%lx\"", comma, "WIRELESS0", wl0_all_rx, "WIRELESS0", wl0_all_tx);
12109				}
12110				comma = ',';
12111			}
12112			if (wl1_valid) {
12113				if(from_app == 0){
12114					ret += websWrite(wp, "%c'%s':{rx:0x%lx,tx:0x%lx}\n", comma, "WIRELESS1", wl1_all_rx, wl1_all_tx);
12115				}else{
12116					ret += websWrite(wp, "%c\"%s_rx\":\"0x%lx\",\"%s_tx\":\"0x%lx\"", comma, "WIRELESS1", wl1_all_rx, "WIRELESS1",wl1_all_tx);
12117				}
12118				comma = ',';
12119			}
12120
12121#ifdef RTCONFIG_LACP
12122	if(nvram_get_int("lacp_enabled") == 1){
12123		if(from_app == 0){
12124			ret += websWrite(wp, "%c'%s':{rx:0x%lx,tx:0x%lx}\n", comma, "LACP1", rx_lacp1, tx_lacp1);
12125			ret += websWrite(wp, "%c'%s':{rx:0x%lx,tx:0x%lx}\n", comma, "LACP2", rx_lacp2, tx_lacp2);
12126		}
12127	}
12128#endif
12129
12130		fclose(fp);
12131			if(from_app == 0)
12132				ret += websWrite(wp, "}");
12133
12134  }
12135  	return 0;
12136  }
12137
12138int ej_bandwidth(int eid, webs_t wp, int argc, char_t **argv)
12139{
12140	char *name;
12141	int sig;
12142
12143	if (strcmp(argv[0], "speed") == 0) {
12144		sig = SIGUSR1;
12145		name = "/var/spool/rstats-speed.js";
12146	}
12147	else {
12148		sig = SIGUSR2;
12149		name = "/var/spool/rstats-history.js";
12150	}
12151	unlink(name);
12152	killall("rstats", sig);
12153//	eval("killall", sig, "rstats");
12154	f_wait_exists(name, 5);
12155	do_f(name, wp);
12156	unlink(name);
12157	return 0;
12158}
12159
12160//Ren.B
12161#ifdef RTCONFIG_DSL
12162
12163// 2014.02 Viz {
12164int start_dsl_autodet(int eid, webs_t wp, int argc, char **argv) {
12165	notify_rc("start_dsl_autodet");
12166	return 0;
12167}
12168// }
12169
12170int ej_spectrum(int eid, webs_t wp, int argc, char_t **argv)
12171{
12172	int sig;
12173
12174	if(nvram_match("spectrum_hook_is_running", "1"))
12175	{
12176		//on running status, skip.
12177		return 0;
12178	}
12179
12180	sig = SIGUSR1;
12181	system("/usr/sbin/check_spectrum.sh"); //check if spectrum is running.
12182	sleep(1);
12183
12184	killall("spectrum", sig);
12185
12186	return 0;
12187
12188}
12189
12190int ej_getAnnexMode(int eid, webs_t wp, int argc, char_t **argv)
12191{
12192	FILE *logFile = fopen( "/tmp/adsl/adsllog.log", "r" );
12193	char buf[256] = {0};
12194	char *ptr = NULL;
12195
12196	if( !logFile )
12197	{
12198		printf("Error: adsllog.log does not exist.\n");
12199		websWrite(wp, "Error: adsllog.log does not exist.");
12200		return -1;
12201	}
12202	while( fgets(buf, sizeof(buf), logFile) )
12203	{
12204		if( (ptr=strstr(buf, "Annex Mode :")) != NULL )
12205		{
12206			ptr += strlen("Annex Mode :")+1;
12207			if(strstr(ptr, "Annex A"))
12208			{
12209				websWrite(wp, "Annex A" );
12210			}
12211			else if(strstr(ptr, "Annex B"))
12212			{
12213				websWrite(wp, "Annex B" );
12214			}
12215			else
12216			{
12217				websWrite(wp, "Error : Unknown Annex Mode" );
12218			}
12219			break;
12220		}
12221	}
12222
12223	fclose(logFile);
12224	return 0;
12225}
12226
12227int ej_getADSLToneAmount(int eid, webs_t wp, int argc, char_t **argv)
12228{
12229	FILE *logFile = fopen( "/tmp/adsl/adsllog.log", "r" );
12230	char buf[256] = {0};
12231	char *ptr = NULL;
12232	int mode = 5;
12233	int tones = 512;
12234
12235	if( !logFile )
12236	{
12237		printf("Error: adsllog.log does not exist.\n");
12238		websWrite(wp, "%d", tones);
12239		return -1;
12240	}
12241	while( fgets(buf, sizeof(buf), logFile) )
12242	{
12243		if( (ptr=strstr(buf, "Modulation :")) != NULL )
12244		{
12245			ptr += strlen("Annex Mode :")+1;
12246			mode = atoi(ptr);
12247			break;
12248		}
12249	}
12250
12251	switch(mode)
12252	{
12253		case 0:
12254		case 1:
12255		case 2:
12256			tones = 256;
12257			break;
12258		case 3:
12259		case 4:
12260			tones = 512;
12261			break;
12262		default:
12263			tones = 512;
12264	}
12265
12266	fclose(logFile);
12267	websWrite(wp, "%d", tones);
12268	return 0;
12269}
12270
12271int show_file_content(int eid, webs_t wp, int argc, char_t **argv)
12272{
12273	char *name;
12274	char buffer[256];
12275	FILE *fp = NULL;
12276	int ret = 0;
12277
12278	if (ejArgs(argc, argv, "%s", &name) < 1) {
12279		websError(wp, 400, "Insufficient args\n");
12280		return -1;
12281	}
12282
12283	fp = fopen(name, "r");
12284	if(!fp)
12285	{
12286		ret += websWrite(wp, "");
12287		return -2;
12288	}
12289	while (fgets(buffer, sizeof(buffer), fp))
12290	{
12291		ret += websWrite(wp, "%s", buffer);
12292	}
12293
12294	fclose(fp);
12295	return ret;
12296}
12297#endif
12298//Ren.E
12299
12300int ej_backup_nvram(int eid, webs_t wp, int argc, char_t **argv)
12301{
12302	char *list;
12303	char *p, *k;
12304	const char *v;
12305
12306	if ((argc != 1) || ((list = strdup(argv[0])) == NULL)) return 0;
12307	websWrite(wp, "\nnvram = {\n");
12308	p = list;
12309	while ((k = strsep(&p, ",")) != NULL) {
12310		if (*k == 0) continue;
12311		v = nvram_get(k);
12312		if (!v) {
12313			v = "";
12314		}
12315		websWrite(wp, "\t%s: '", k);
12316		websWrite(wp, v);
12317//		web_puts((p == NULL) ? "'\n" : "',\n");
12318		websWrite(wp, "',\n");
12319	}
12320	free(list);
12321	websWrite(wp, "\thttp_id: '");
12322	websWrite(wp, nvram_safe_get("http_id"));
12323	websWrite(wp, "'};\n");
12324//	web_puts("};\n");
12325	return 0;
12326}
12327// end svg support by Viz ^^^^^^^^^^^^^^^^^^^^
12328
12329static int
12330ej_select_list(int eid, webs_t wp, int argc, char_t **argv)
12331{
12332	char *id;
12333	int ret = 0;
12334	char out[64], idxstr[12], tmpstr[64], tmpstr1[64];
12335	int i, curr, hit, noneFlag;
12336	char *ref1, *ref2, *refnum;
12337
12338	if (ejArgs(argc, argv, "%s", &id) < 1) {
12339		websError(wp, 400, "Insufficient args\n");
12340		return -1;
12341	}
12342
12343	if (strcmp(id, "Storage_x_SharedPath")==0)
12344	{
12345		ref1 = "sh_path_x";
12346		ref2 = "sh_path";
12347		refnum = "sh_num";
12348		curr = nvram_get_int(ref1);
12349		sprintf(idxstr, "%d", curr);
12350		strcpy(tmpstr1, nvram_get(strcat_r(ref2, idxstr, tmpstr)));
12351		sprintf(out, "%s", tmpstr1);
12352		ret += websWrite(wp, out);
12353		return ret;
12354	}
12355	else if (strncmp(id, "Storage_x_AccUser", 17)==0)
12356	{
12357		sprintf(tmpstr, "sh_accuser_x%s", id + 17);
12358		ref2 = "acc_username";
12359		refnum = "acc_num";
12360
12361		curr = nvram_get_int(tmpstr);
12362		noneFlag =1;
12363	}
12364	else if (strcmp(id, "Storage_x_AccAny")==0)
12365	{
12366		 ret = websWrite(wp, "<option value=\"Guest\">Guest</option>");
12367		 return ret;
12368	}
12369	else if (strcmp(id, "Storage_AllUser_List")==0)
12370	{
12371
12372		strcpy(out, "<option value=\"Guest\">Guest</option>");
12373		ret += websWrite(wp, out);
12374
12375		for (i=0;i<nvram_get_int("acc_num");i++)
12376		{
12377			 sprintf(idxstr, "%d", i);
12378			 strcpy(tmpstr1, nvram_get(strcat_r("acc_username", idxstr, tmpstr)));
12379			 sprintf(out, "<option value=\"%s\">%s</option>", tmpstr1, tmpstr1);
12380			 ret += websWrite(wp, out);
12381		}
12382		return ret;
12383	}
12384	else
12385	{
12386		 return ret;
12387	}
12388
12389	hit = 0;
12390
12391	for (i=0;i<nvram_get_int(refnum);i++)
12392	{
12393		sprintf(idxstr, "%d", i);
12394		strcpy(tmpstr1, nvram_get(strcat_r(ref2, idxstr, tmpstr)));
12395		sprintf(out, "<option value=\"%d\"", i);
12396
12397		if (i==curr)
12398		{
12399			hit = 1;
12400			sprintf(out, "%s selected", out);
12401		}
12402		sprintf(out,"%s>%s</option>", out, tmpstr1);
12403
12404		ret += websWrite(wp, out);
12405	}
12406
12407	if (noneFlag)
12408	{
12409		cprintf("hit : %d\n", hit);
12410		if (!hit) sprintf(out, "<option value=\"99\" selected>None</option>");
12411		else sprintf(out, "<option value=\"99\">None</option>");
12412
12413		ret += websWrite(wp, out);
12414	}
12415	return ret;
12416}
12417
12418static int
12419ej_radio_status(int eid, webs_t wp, int argc, char_t **argv)
12420{
12421	int retval = 0;
12422
12423	retval += websWrite(wp, "radio_2=%d;\nradio_5=%d;", get_radio(0,0), get_radio(1,0));
12424	return retval;
12425}
12426
12427static int
12428ej_sysinfo(int eid, webs_t wp, int argc, char_t **argv)
12429{
12430	char *type;
12431	char result[2048];
12432	int retval = 0;
12433
12434	strcpy(result, "-1");
12435
12436	if (ejArgs(argc, argv, "%s", &type) < 1) {
12437		websError(wp, 400, "Insufficient args\n");
12438		return retval;
12439	}
12440	//_dprintf("[sysinfo] type=%s\n", type);
12441
12442	if(strncmp(type,"pid",3) == 0 ){
12443		char service[32];
12444		sscanf(type, "pid.%31s", service);
12445
12446		if (strlen(service))
12447			sprintf(result, "%d", pidof(service));
12448
12449		//_dprintf("[sysinfo] service=%s, result=%d\n", service, result);
12450	}
12451
12452	retval += websWrite(wp, result);
12453	return retval;
12454}
12455
12456static int
12457ej_memory_usage(int eid, webs_t wp, int argc, char_t **argv){
12458	unsigned long total, used, mfree/*, shared, buffers, cached*/;
12459	char buf[80];
12460	int from_app = 0;
12461
12462	from_app = check_user_agent(user_agent);
12463
12464	FILE *fp;
12465
12466	fp = fopen("/proc/meminfo", "r");
12467
12468	if(fp == NULL)
12469		return -1;
12470
12471	fscanf(fp, "MemTotal: %lu %s\n", &total, buf);
12472	fscanf(fp, "MemFree: %lu %s\n", &mfree, buf);
12473	used = total - mfree;
12474	fclose(fp);
12475	if(from_app == 0){
12476		websWrite(wp, "<mem_info>\n");
12477		websWrite(wp, "<total>%lu</total>\n", total);
12478		websWrite(wp, "<free>%lu</free>\n", mfree);
12479		websWrite(wp, "<used>%lu</used>\n", used);
12480		websWrite(wp, "</mem_info>\n");
12481	}else{
12482		websWrite(wp, "\"mem_total\":\"%lu\",\"mem_free\":\"%lu\",\"mem_used\":\"%lu\"", total, mfree, used);
12483	}
12484	return 0;
12485}
12486
12487static int
12488ej_cpu_usage(int eid, webs_t wp, int argc, char_t **argv){
12489	unsigned long total, user, nice, system, idle, io, irq, softirq;
12490	char name[10];
12491	int from_app = 0;
12492
12493	from_app = check_user_agent(user_agent);
12494
12495	FILE *fp;
12496	fp = fopen("/proc/stat", "r");
12497	int i = 0, firstRow=1;
12498
12499	if(fp == NULL)
12500		return -1;
12501	if(from_app == 0){
12502		websWrite(wp, "<cpu_info>\n");
12503	}
12504	while(fscanf(fp, "%s %lu %lu %lu %lu %lu %lu %lu \n", name, &user, &nice, &system, &idle, &io, &irq, &softirq) != EOF){
12505		if(strncmp(name, "cpu", 3) == 0){
12506			if(i == 0){
12507				i++;
12508				continue;
12509			}
12510
12511			total = user + nice + system + idle + io + irq + softirq;
12512			if(from_app == 0){
12513				websWrite(wp, "<cpu>\n");
12514				websWrite(wp, "<total>%lu</total>\n", total);
12515				websWrite(wp, "<usage>%lu</usage>\n", total - idle);
12516				websWrite(wp, "</cpu>\n");
12517			}else{
12518				if (firstRow == 1)
12519					firstRow = 0;
12520				else
12521					websWrite(wp, ",");
12522
12523				websWrite(wp, "\"cpu%d_total\":\"%lu\",\"cpu%d_usage\":\"%lu\"", i, total, i, total - idle);
12524			}
12525			i++;
12526		}
12527	}
12528
12529	fclose(fp);
12530	if(from_app == 0)
12531		websWrite(wp, "</cpu_info>\n");
12532	return 0;
12533}
12534
12535static int
12536ej_cpu_core_num(int eid, webs_t wp, int argc, char_t **argv){
12537	char buf[MAX_LINE_SIZE];
12538	FILE *fp;
12539	int count = 0;
12540	fp = fopen("/proc/cpuinfo", "r");
12541
12542	if(fp == NULL) return -1;
12543
12544	while(fgets(buf, MAX_LINE_SIZE, fp)!=NULL){
12545		if(strncmp(buf, "processor", 9) == 0){
12546			count++;
12547		}
12548	}
12549
12550	fclose(fp);
12551	if(count == 0){		//for Braomcom ARM single core
12552		count = 1;
12553	}
12554
12555	websWrite(wp, "%d", count);
12556	return 0;
12557}
12558
12559static int
12560ej_check_pw(int eid, webs_t wp, int argc, char_t **argv)
12561{
12562	if(!strcmp(nvram_default_get("http_passwd"), nvram_safe_get("http_passwd")) && !nvram_match("ATEMODE", "1"))
12563		return websWrite(wp, "1");
12564	else
12565		return websWrite(wp, "0");
12566}
12567
12568static int
12569ej_check_acpw(int eid, webs_t wp, int argc, char_t **argv)
12570{
12571	if(!strcmp(nvram_default_get("http_username"), nvram_safe_get("http_username")) && !strcmp(nvram_default_get("http_passwd"), nvram_safe_get("http_passwd")))
12572		return websWrite(wp, "1");
12573	else
12574		return websWrite(wp, "0");
12575}
12576
12577static int
12578ej_check_acorpw(int eid, webs_t wp, int argc, char_t **argv)
12579{
12580	if(!strcmp(nvram_default_get("http_username"), nvram_safe_get("http_username")) || !strcmp(nvram_default_get("http_passwd"), nvram_safe_get("http_passwd")))
12581		return websWrite(wp, "\"1\"");
12582	else
12583		return websWrite(wp, "\"0\"");
12584}
12585
12586#ifdef RTCONFIG_BWDPI
12587static int
12588ej_bwdpi_history(int eid, webs_t wp, int argc, char_t **argv)
12589{
12590	int retval = 0;
12591	char *hwaddr;
12592	char *page;
12593
12594	// get real-time traffic of someone.
12595	hwaddr = websGetVar(wp, "client", "");
12596
12597	// get which page for listing
12598	page = websGetVar(wp, "page", "");
12599
12600	//_dprintf("[httpd] history: hwaddr=%s, page=%s.\n", hwaddr, page);
12601	get_web_hook(hwaddr, page, &retval, wp);
12602
12603	return retval;
12604}
12605
12606
12607/*
12608	get_bwdpi_hook(type, mode, name, dura, date)
12609
12610	mode : traffic / traffic_wan / app / client_apps / client_web
12611	name : NULL / appname / clientname
12612	dura : realtime / month / week / day
12613	date : NULL / day
12614*/
12615
12616static int
12617ej_bwdpi_status(int eid, webs_t wp, int argc, char_t **argv)
12618{
12619	char *mode, *name, *dura, *date;
12620	int retval = 0;
12621
12622	if (ejArgs(argc, argv, "%s %s %s %s", &mode, &name, &dura, &date) < 4) {
12623		websError(wp, 400, "Insufficient args\n");
12624		return -1;
12625	}
12626
12627	// get real-time traffic of someone.
12628	name = websGetVar(wp, "client", "");
12629
12630	//_dprintf("[httpd] bwdpi: mode=%s, name=%s, dura=%s, date=%s.\n", mode, name, dura, date);
12631	get_traffic_hook(mode, name, dura, date, &retval, wp);
12632
12633	return retval;
12634}
12635
12636static int
12637ej_bwdpi_device(int eid, webs_t wp, int argc, char_t **argv)
12638{
12639	int retval = 0;
12640	char *hwaddr;
12641
12642	// get device info of someone.
12643	hwaddr = websGetVar(wp, "client", "");
12644
12645	//_dprintf("[httpd] history: hwaddr=%s.\n", hwaddr);
12646	get_device_hook(hwaddr, &retval, wp);
12647
12648	return retval;
12649}
12650
12651static int
12652ej_bwdpi_redirect_page_status(int eid, webs_t wp, int argc, char_t **argv)
12653{
12654	int retval = 0;
12655	char *cat_id;
12656	int catid;
12657
12658	// get device info of someone.
12659	cat_id = websGetVar(wp, "cat_id", "");
12660	catid = atoi(cat_id);
12661	redirect_page_status(catid, &retval, wp);
12662
12663	return retval;
12664}
12665
12666static int
12667ej_bwdpi_appStat(int eid, webs_t wp, int argc, char_t **argv)
12668{
12669	char *client, *mode, *dura, *date;
12670	int retval = 0;
12671
12672	client = websGetVar(wp, "client", "");
12673	mode = websGetVar(wp, "mode", "");
12674	dura = websGetVar(wp, "dura", "");
12675	date = websGetVar(wp, "date", "");
12676
12677	// 0: app, 1: mac
12678	sqlite_Stat_hook(0, client, mode, dura, date, &retval, wp);
12679
12680	return retval;
12681}
12682
12683static int
12684ej_bwdpi_wanStat(int eid, webs_t wp, int argc, char_t **argv)
12685{
12686	char *client, *mode, *dura, *date;
12687	int retval = 0;
12688
12689	client = websGetVar(wp, "client", "");
12690	mode = websGetVar(wp, "mode", "");
12691	dura = websGetVar(wp, "dura", "");
12692	date = websGetVar(wp, "date", "");
12693
12694	// 0: app, 1: mac
12695	sqlite_Stat_hook(1, client, mode, dura, date, &retval, wp);
12696
12697	return retval;
12698}
12699
12700static int
12701ej_bwdpi_engine_status(int eid, webs_t wp, int argc, char_t **argv)
12702{
12703	int retval = 0;
12704
12705	retval += websWrite(wp, "{");
12706	retval += websWrite(wp, "\"DpiEngine\":%d", check_bwdpi_nvram_setting());
12707	retval += websWrite(wp, "}");
12708
12709	return retval;
12710}
12711#else
12712static int
12713ej_bwdpi_engine_status(int eid, webs_t wp, int argc, char_t **argv)
12714{
12715	int retval = 0;
12716
12717	retval += websWrite(wp, "{");
12718	retval += websWrite(wp, "}");
12719
12720	return retval;
12721}
12722
12723static int
12724ej_bwdpi_device(int eid, webs_t wp, int argc, char_t **argv)
12725{
12726	int retval = 0;
12727
12728	retval += websWrite(wp, "\"\"");
12729
12730	return retval;
12731}
12732#endif
12733
12734#ifdef RTCONFIG_TRAFFIC_LIMITER
12735static int
12736ej_traffic_limiter_wanStat(int eid, webs_t wp, int argc, char_t **argv)
12737{
12738	char *ifname, *start, *end, *unit;
12739	int retval = 0;
12740
12741	ifname = websGetVar(wp, "ifname", "");
12742	start = websGetVar(wp, "start", "");
12743	end = websGetVar(wp, "end", "");
12744	unit = websGetVar(wp, "unit", "");
12745
12746	traffic_limiter_hook(ifname, start, end, unit, &retval, wp);
12747
12748	return retval;
12749}
12750#endif
12751
12752static int
12753ej_wl_nband_info(int eid, webs_t wp, int argc, char_t **argv)
12754{
12755	int unit = 0, ret = 0, firstRow = 1;
12756	char *band, word[256], *next;
12757	char tmp[128], prefix[] = "wlXXXXXXXXXX_";
12758	ret += websWrite(wp, "[");
12759	foreach (word, nvram_safe_get("wl_ifnames"), next) {
12760		if (firstRow == 1)
12761			firstRow = 0;
12762		else
12763			ret += websWrite(wp, ", ");
12764
12765		snprintf(prefix, sizeof(prefix), "wl%d_", unit);
12766		band = nvram_safe_get(strcat_r(prefix, "nband", tmp));
12767
12768			ret += websWrite(wp, "'%s'", band);
12769
12770		unit++;
12771	}
12772	ret += websWrite(wp, "]");
12773	return ret;
12774}
12775
12776#ifdef RTCONFIG_GEOIP
12777static int
12778ej_geoiplookup(int eid, webs_t wp, int argc, char_t **argv)
12779{
12780	int unit;
12781	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
12782	char *wanip;
12783
12784	unit = wan_primary_ifunit();
12785	wan_prefix(unit, prefix);
12786	wanip = nvram_safe_get(strcat_r(prefix, "ipaddr", tmp));
12787
12788	return websWrite(wp, "%s", geoiplookup_by_ip(wanip));
12789}
12790#endif
12791
12792#ifdef RTCONFIG_JFFS2USERICON
12793static int
12794ej_get_upload_icon(int eid, webs_t wp, int argc, char **argv) {
12795	char *client_mac = websGetVar(wp, "clientmac", "");
12796	char *client_mac_tmp = NULL;
12797
12798	int from_app = 0;
12799
12800	from_app = check_user_agent(user_agent);
12801
12802	if (ejArgs(argc, argv, "%s", &client_mac_tmp) < 1) {
12803		//_dprintf("name = NULL\n");
12804	}else if(!strcmp(client_mac, "")){
12805		client_mac = client_mac_tmp;
12806	}
12807
12808	if(strcmp(client_mac, "")) {
12809		char file_name[32];
12810		memset(file_name, 0, 32);
12811
12812		//Check folder exist or not
12813		if(!check_if_dir_exist(JFFS_USERICON))
12814			mkdir(JFFS_USERICON, 0755);
12815
12816		//Write upload icon value
12817		sprintf(file_name, "/jffs/usericon/%s.log", client_mac);
12818		if(check_if_file_exist(file_name)) {
12819			if(from_app != 0)
12820				websWrite(wp, "\"");
12821			dump_file(wp, file_name);
12822			if(from_app != 0)
12823				websWrite(wp, "\"");
12824		}
12825		else {
12826			if(from_app != 0)
12827				websWrite(wp, "\"");
12828			websWrite(wp, "NoIcon");
12829			if(from_app != 0)
12830				websWrite(wp, "\"");
12831		}
12832	}
12833	else {
12834		if(from_app != 0)
12835			websWrite(wp, "\"");
12836		websWrite(wp, "NoIcon");
12837		if(from_app != 0)
12838			websWrite(wp, "\"");
12839	}
12840	return 0;
12841}
12842static int
12843ej_get_upload_icon_count_list(int eid, webs_t wp, int argc, char **argv) {
12844	int file_count = 0;
12845	DIR * dirp;
12846	struct dirent * entry;
12847	char allMacList[1500];
12848	memset(allMacList, 0, 1500);
12849	int from_app = 0;
12850
12851	from_app = check_user_agent(user_agent);
12852
12853	//Check folder exist or not
12854	if(!check_if_dir_exist(JFFS_USERICON))
12855		mkdir(JFFS_USERICON, 0755);
12856
12857	//Write /jffs/usericon/ file count and list
12858	dirp = opendir(JFFS_USERICON); /* There should be error handling after this */
12859	while ((entry = readdir(dirp)) != NULL) {
12860		if (entry->d_type == DT_REG) { /* If the entry is a regular file */
12861			strcat(allMacList, entry->d_name);
12862			strcat(allMacList, ">");
12863			file_count++;
12864		}
12865	}
12866	closedir(dirp);
12867	if(from_app == 0){
12868		websWrite(wp, "upload_icon_count=\"%d\";\n", file_count);
12869		websWrite(wp, "upload_icon_list=\"%s\";\n", allMacList);
12870	}else{
12871		websWrite(wp, "\"upload_icon_count\":\"%d\",\n", file_count);
12872		websWrite(wp, "\"upload_icon_list\":\"%s\"\n", allMacList);
12873	}
12874
12875	return 0;
12876}
12877#endif
12878
12879static int
12880ej_findasus(int eid, webs_t wp, int argc, char **argv) {
12881	char *buf, *g, *p;
12882	char strTmp[4096]={0}, retList[65536]={0};
12883	char *type, *name, *ip, *mac, *netmask, *opmode, *ssid, *submask;
12884	int isfirst=0;
12885
12886	eval("asusdiscovery");	//find asus device
12887
12888	g = buf = strdup(nvram_safe_get("asus_device_list"));
12889	strcat(retList, "[\n");
12890   	if(strcmp(buf, "") != 0){
12891		while (buf) {
12892			if ((p = strsep(&g, "<")) == NULL) break;
12893
12894			if((vstrsep(p, ">",&type ,&name, &ip, &mac, &netmask, &ssid, &submask, &opmode)) != 8) continue;
12895
12896			if(isfirst == 0){
12897				isfirst = 1;
12898			}else{
12899				strcat(retList, ",\n");
12900			}
12901
12902			strcat(retList, "{");
12903			sprintf(strTmp, "modelName:\"%s\",", name);
12904			strcat(retList, strTmp);
12905			sprintf(strTmp, "ssid:\"%s\",", ssid);
12906			strcat(retList, strTmp);
12907			sprintf(strTmp, "ipAddr:\"%s\"", ip);
12908			strcat(retList, strTmp);
12909			strcat(retList, "}");
12910		}
12911	}else{
12912		sprintf(strTmp, "{modelName:\"%s\",ssid:\"%s\",ipAddr:\"%s\"}", nvram_safe_get("productid"), nvram_safe_get("wl_ssid"), nvram_safe_get("lan_ipaddr"));
12913		strcat(retList, strTmp);
12914	}
12915	free(buf);
12916	strcat(retList, "\n]");
12917	return websWrite(wp, "%s", retList);
12918}
12919
12920#ifdef RTCONFIG_WTFAST
12921static int
12922ej_wtfast_status(int eid, webs_t wp, int argc, char **argv) {
12923	char wtfast_status[4096] = {0};
12924	char tmp[1024] = {0};
12925	char val[512] = {0};
12926
12927	strcat(wtfast_status, "{");
12928
12929	sprintf(tmp, "\"eMail\":\"%s\",", nvram_get("wtf_username"));
12930	strcat(wtfast_status, tmp);
12931
12932	sprintf(tmp, "\"Account_Type\":\"%s\",", nvram_get("wtf_account_type"));
12933	strcat(wtfast_status, tmp);
12934
12935	sprintf(tmp, "\"Max_Computers\": %d,", nvram_get_int("wtf_max_clients"));
12936	strcat(wtfast_status, tmp);
12937
12938	memset(val, 0, 512);
12939	sprintf(tmp, "\"Server_List\":[],");
12940	strcat(wtfast_status, tmp);
12941
12942	sprintf(tmp, "\"Game_List\":[],");
12943	strcat(wtfast_status, tmp);
12944
12945	sprintf(tmp, "\"Days_Left\": %d,", nvram_get_int("wtf_days_left"));
12946	strcat(wtfast_status, tmp);
12947
12948	sprintf(tmp, "\"Login_status\": %d,", nvram_get_int("wtf_login"));
12949	strcat(wtfast_status, tmp);
12950
12951	sprintf(tmp, "\"Session_Hash\":\"%s\"", nvram_get("wtf_session_hash"));
12952	strcat(wtfast_status, tmp);
12953
12954	strcat(wtfast_status, "}");
12955
12956	return websWrite(wp, "%s", wtfast_status);
12957}
12958#endif
12959
12960static int
12961ej_check_ftp_samba_anonymous(int eid, webs_t wp, int argc, char **argv){
12962
12963	char *name = NULL;
12964	int samba_mode=0, ftp_mode=0, ret=0;
12965
12966	if (ejArgs(argc, argv, "%s", &name) < 1) {
12967		//_dprintf("name = NULL\n");
12968		ret = websWrite(wp, "Not support");
12969		return ret;
12970	}
12971
12972	if(!strcmp(name,"cifs")){
12973		if((nvram_get("st_samba_force_mode") == NULL && nvram_get_int("st_samba_mode") == 1)){
12974			samba_mode = 4;
12975		}else{
12976			samba_mode = nvram_get_int("st_samba_mode");
12977		}
12978		if(samba_mode == 2 || samba_mode == 4){
12979			ret = websWrite(wp, "\"1\"");
12980		}else{
12981			ret = websWrite(wp, "\"0\"");
12982		}
12983	}else if(!strcmp(name,"ftp")){
12984		if((nvram_get("st_ftp_force_mode") == NULL && nvram_get_int("st_ftp_mode") == 1)){
12985			ftp_mode = 2;
12986		}else{
12987			ftp_mode = nvram_get_int("st_ftp_mode");
12988		}
12989		if(ftp_mode == 2){
12990			ret = websWrite(wp, "\"1\"");
12991		}else{
12992			ret = websWrite(wp, "\"0\"");
12993		}
12994	}
12995	return ret;
12996}
12997
12998char* reverse_str( char *str )
12999{
13000  int i, n;
13001  char c;
13002
13003  n = strlen( str );
13004  for( i=0; i<n/2; i++ )
13005  {
13006    c = str[i];
13007    str[i] = str[n-i-1];
13008    str[n-i-1] = c;
13009  }
13010
13011  return str;
13012}
13013
13014static int
13015ej_check_passwd_strength(int eid, webs_t wp, int argc, char **argv){
13016
13017	int ret=0;
13018	char *name = NULL;
13019	if (ejArgs(argc, argv, "%s", &name) < 1) {
13020		ret = websWrite(wp, "Not support");
13021		//_dprintf("name = NULL\n");
13022		return ret;
13023	}
13024
13025	int unit = 0;
13026	int nScore_total=0, nScore=0;
13027	char *pwd = NULL, word[256]={0}, *next = NULL;
13028	char tmp[128]={0}, prefix[] = "wlXXXXXXXXXX_";
13029	int nLength=0, nConsecAlphaUC=0, nConsecCharType=0, nAlphaUC=0, nConsecAlphaLC=0, nAlphaLC=0, nMidChar=0, nConsecNumber=0, nNumber=0, nConsecSymbol=0, nSymbol=0, nRepChar=0, nUnqChar=0, nSeqAlpha=0, nSeqNumber=0, nSeqChar = 0, nSeqSymbol=0;
13030	int nMultMidChar=2, nMultLength=4, nMultNumber=4, nMultSymbol=6, nMultConsecAlphaUC=2, nMultConsecAlphaLC=2, nMultConsecNumber=2, nMultSeqAlpha=3, nMultSeqNumber=3, nMultSeqSymbol=3;
13031	int a=0, b=0, s=0, x=0;
13032	int nTmpAlphaUC = -1, nTmpAlphaLC = -1, nTmpNumber = -1, nTmpSymbol = -1;
13033	double nRepInc = 0.0;
13034	char sAlphas[] = "abcdefghijklmnopqrstuvwxyz";
13035	char sNumerics[] = "01234567890";
13036	char sSymbols[] = "~!@#$%^&*()_+";
13037	char pwd_s[128] = {0};
13038	char *pwd_st=NULL, *arrPwd=NULL;
13039	char *auth_mode=NULL;
13040	char sFwd[4], sFwd_t[4], sRev[4];
13041	if(!strcmp(name,"wl_key")){
13042		foreach (word, nvram_safe_get("wl_ifnames"), next) {
13043			snprintf(prefix, sizeof(prefix), "wl%d_", unit);
13044			pwd = nvram_safe_get(strcat_r(prefix, "wpa_psk", tmp));
13045			auth_mode = nvram_safe_get(strcat_r(prefix, "auth_mode_x", tmp));
13046			nLength=0; nConsecAlphaUC=0; nConsecCharType=0; nAlphaUC=0; nConsecAlphaLC=0; nAlphaLC=0; nMidChar=0; nConsecNumber=0; nNumber=0; nConsecSymbol=0; nSymbol=0; nRepChar=0; nUnqChar=0; nSeqAlpha=0; nSeqNumber=0; nSeqChar = 0; nSeqSymbol=0;
13047			nTmpAlphaUC = -1; nTmpAlphaLC = -1; nTmpNumber = -1; nTmpSymbol = -1;
13048		   if(pwd != NULL && (!strcmp(auth_mode,"psk2") || !strcmp(auth_mode,"pskpsk2") || !strcmp(auth_mode,"wpa2") || !strcmp(auth_mode,"wpawpa2"))){
13049			nScore=0;
13050			nLength=0;
13051			pwd_st = pwd;
13052			arrPwd = pwd;
13053			nLength = strlen(pwd);
13054			nScore = nLength * nMultLength;
13055
13056			/* Main calculation for strength:
13057					Loop through password to check for Symbol, Numeric, Lowercase and Uppercase pattern matches */
13058			for (a=0; a <nLength; a++){
13059				if(isupper(arrPwd[a])){
13060					if(nTmpAlphaUC != -1){
13061						if((nTmpAlphaUC + 1) == a){
13062							nConsecAlphaUC++;
13063							nConsecCharType++;
13064						}
13065					}
13066					nTmpAlphaUC = a;
13067					nAlphaUC++;
13068				}
13069				else if(islower(arrPwd[a])){
13070					if(nTmpAlphaLC != -1){
13071						if((nTmpAlphaLC + 1) == a){
13072							nConsecAlphaLC++;
13073							nConsecCharType++;
13074						}
13075					}
13076					nTmpAlphaLC = a;
13077					nAlphaLC++;
13078				}
13079				else if(isdigit(arrPwd[a])){
13080					if(a > 0 && a < (nLength - 1)){
13081						nMidChar++;
13082					}
13083					if(nTmpNumber != -1){
13084						if((nTmpNumber + 1) == a){
13085							nConsecNumber++;
13086							nConsecCharType++;
13087						}
13088					}
13089					nTmpNumber = a;
13090					nNumber++;
13091				}
13092				else if(!isalnum(arrPwd[a])){
13093					if(a > 0 && a < (nLength - 1))
13094					{
13095						nMidChar++;
13096					}
13097					if(nTmpSymbol != -1){
13098						if((nTmpSymbol + 1) == a){
13099							nConsecSymbol++;
13100							nConsecCharType++;
13101						}
13102					}
13103					nTmpSymbol = a;
13104					nSymbol++;
13105				}
13106
13107				/* Internal loop through password to check for repeat characters */
13108				int bCharExists = 0;
13109				for (b=0; b < nLength; b++){
13110					if (arrPwd[a] == arrPwd[b] && a != b){ /* repeat character exists */
13111						bCharExists = 1;
13112						/*
13113						Calculate icrement deduction based on proximity to identical characters
13114						Deduction is incremented each time a new match is discovered
13115						Deduction amount is based on total password length divided by the
13116						difference of distance between currently selected match
13117						*/
13118						nRepInc += abs(nLength/(b-a));
13119					}
13120				}
13121				if (bCharExists == 1) {
13122					nRepChar++;
13123					nUnqChar = nLength-nRepChar;
13124					nRepInc = (nUnqChar > 0) ? ceil(nRepInc/(double)nUnqChar) : ceil(nRepInc);
13125				}
13126			}
13127
13128			for(x = 0; x < nLength; x++){
13129				pwd_s[x]= tolower(*pwd_st);
13130				pwd_st++;
13131			}
13132
13133			/* Check for sequential alpha string patterns (forward and reverse) */
13134			for (s=0; s < 23; s++){
13135				memset(sFwd, 0, sizeof(sFwd));
13136				memset(sFwd_t, 0, sizeof(sFwd_t));
13137				memset(sRev, 0, sizeof(sRev));
13138				if(sAlphas+s != '\0'){
13139					strncpy(sFwd, sAlphas+s, 3);
13140					strncpy(sFwd_t, sFwd, 3);
13141				}
13142				strcpy(sRev, reverse_str(sFwd));
13143
13144				if(strstr(pwd_s, sFwd_t) != NULL || strstr(pwd_s, sRev) != NULL){
13145					nSeqAlpha++;
13146					nSeqChar++;
13147				}
13148			}
13149			/* Check for sequential numeric string patterns (forward and reverse) */
13150			for (s=0; s < 8; s++) {
13151				memset(sFwd, 0, sizeof(sFwd));
13152				memset(sFwd_t, 0, sizeof(sFwd_t));
13153				memset(sRev, 0, sizeof(sRev));
13154				if(sNumerics+s != '\0'){
13155					strncpy(sFwd, sNumerics+s, 3);
13156					strncpy(sFwd_t, sFwd, 3);
13157				}
13158				strcpy(sRev, reverse_str(sFwd));
13159				if(strstr(pwd_s, sFwd_t) != NULL || strstr(pwd_s, sRev) != NULL){
13160					nSeqNumber++;
13161					nSeqChar++;
13162				}
13163			}
13164			/* Check for sequential symbol string patterns (forward and reverse) */
13165			for (s=0; s < 8; s++) {
13166				memset(sFwd, 0, sizeof(sFwd));
13167				memset(sFwd_t, 0, sizeof(sFwd_t));
13168				memset(sRev, 0, sizeof(sRev));
13169				if(sSymbols+s != '\0'){
13170					strncpy(sFwd, sSymbols+s, 3);
13171					strncpy(sFwd_t, sFwd, 3);
13172				}
13173				strcpy(sRev, reverse_str(sFwd));
13174				if(strstr(pwd_s, sFwd_t) != NULL || strstr(pwd_s, sRev) != NULL){
13175					nSeqSymbol++;
13176					nSeqChar++;
13177				}
13178			}
13179			/* Modify overall score value based on usage vs requirements */
13180
13181			/* General point assignment */
13182			if (nAlphaUC > 0 && nAlphaUC < nLength){
13183				nScore = nScore + ((nLength - nAlphaUC) * 2);
13184			}
13185			if (nAlphaLC > 0 && nAlphaLC < nLength){
13186				nScore = nScore + ((nLength - nAlphaLC) * 2);
13187			}
13188			if (nNumber > 0 && nNumber < nLength){
13189				nScore = nScore + (nNumber * nMultNumber);
13190			}
13191			if (nSymbol > 0){
13192				nScore = nScore + (nSymbol * nMultSymbol);
13193			}
13194			if (nMidChar > 0){
13195				nScore = nScore + (nMidChar * nMultMidChar);
13196			}
13197			/* Point deductions for poor practices */
13198			if ((nAlphaLC > 0 || nAlphaUC > 0) && nSymbol == 0 && nNumber == 0) {  // Only Letters
13199				nScore = nScore - nLength;
13200			}
13201			if (nAlphaLC == 0 && nAlphaUC == 0 && nSymbol == 0 && nNumber > 0) {  // Only Numbers
13202				nScore = nScore - nLength;
13203			}
13204			if (nRepChar > 0) {  // Same character exists more than once
13205				nScore = nScore - nRepInc;
13206			}
13207			if (nConsecAlphaUC > 0) {  // Consecutive Uppercase Letters exist
13208			nScore = nScore - (nConsecAlphaUC * nMultConsecAlphaUC);
13209			}
13210			if (nConsecAlphaLC > 0) {  // Consecutive Lowercase Letters exist
13211				nScore = nScore - (nConsecAlphaLC * nMultConsecAlphaLC);
13212			}
13213			if (nConsecNumber > 0) {  // Consecutive Numbers exist
13214				nScore = nScore - (nConsecNumber * nMultConsecNumber);
13215			}
13216			if (nSeqAlpha > 0) {  // Sequential alpha strings exist (3 characters or more)
13217				nScore = nScore - (nSeqAlpha * nMultSeqAlpha);
13218			}
13219			if (nSeqNumber > 0) {  // Sequential numeric strings exist (3 characters or more)
13220				nScore = nScore - (nSeqNumber * nMultSeqNumber);
13221			}
13222			if (nSeqSymbol > 0) {  // Sequential symbol strings exist (3 characters or more)
13223				nScore = nScore - (nSeqSymbol * nMultSeqSymbol);
13224			}
13225
13226			/* Determine complexity based on overall score */
13227			if (nScore > 100)
13228			{
13229				nScore = 100;
13230			}else if(nScore < 0)
13231			{
13232				nScore = 0;
13233			}
13234			nScore_total = nScore + nScore_total;
13235		   }else{
13236			nScore = 0;
13237		   }
13238		   unit++;
13239		}
13240	}
13241	websWrite(wp, "\"%d\"", (int)(nScore_total/unit));
13242	return ret;
13243}
13244
13245static int
13246ej_check_wireless_encryption(int eid, webs_t wp, int argc, char **argv){
13247
13248	int ret=0, unit=0;
13249	char *auth_mode=NULL;
13250	char word[256]={0}, *next = NULL;
13251	char tmp[128]={0}, prefix[] = "wlXXXXXXXXXX_";
13252
13253	foreach (word, nvram_safe_get("wl_ifnames"), next) {
13254		snprintf(prefix, sizeof(prefix), "wl%d_", unit);
13255		auth_mode = nvram_safe_get(strcat_r(prefix, "auth_mode_x", tmp));
13256		if(!strcmp(auth_mode,"psk2") || !strcmp(auth_mode,"pskpsk2") || !strcmp(auth_mode,"wpa2") || !strcmp(auth_mode,"wpawpa2")){
13257			ret = 1;
13258		}else{
13259			return websWrite(wp, "\"0\"");
13260		}
13261		unit++;
13262	}
13263	return websWrite(wp, "\"1\"");
13264}
13265
13266static int
13267check_macrepeat(char *maclist,char *mac){
13268	int total=0;
13269	while ( strstr(maclist,mac) != NULL )
13270   	{
13271		maclist += strlen(maclist);
13272		total++;
13273	}
13274	return total;
13275}
13276
13277static int
13278ej_get_clientlist(int eid, webs_t wp, int argc, char **argv){
13279
13280	int i, shm_client_info_id;
13281	void *shared_client_info=(void *) 0;
13282	char output_buf[2048];
13283	char maclist_buf[4096]=",\"maclist\":";
13284	char mac_buf[32], dev_name[32];
13285	char *brackets_h = "[";
13286	char *brackets_d = "]";
13287	char *dot = ",";
13288	char ipaddr[16];
13289	P_CLIENT_DETAIL_INFO_TABLE p_client_info_tab;
13290	int lock;
13291	char devname[LINE_SIZE], character;
13292	int j, len;
13293	int first_mac=1, first_info=1;
13294
13295	lock = file_lock("networkmap");
13296	shm_client_info_id = shmget((key_t)1001, sizeof(CLIENT_DETAIL_INFO_TABLE), 0666|IPC_CREAT);
13297	if (shm_client_info_id == -1){
13298	    fprintf(stderr,"shmget failed\n");
13299	    file_unlock(lock);
13300	    return 0;
13301	}
13302
13303	shared_client_info = shmat(shm_client_info_id,(void *) 0,0);
13304	if (shared_client_info == (void *)-1){
13305		fprintf(stderr,"shmat failed\n");
13306		file_unlock(lock);
13307		return 0;
13308	}
13309
13310	p_client_info_tab = (P_CLIENT_DETAIL_INFO_TABLE)shared_client_info;
13311	for(i=0; i<p_client_info_tab->ip_mac_num; i++) {
13312
13313		memset(dev_name, 0, 32);
13314		memset(output_buf, 0, 2048);
13315		memset(ipaddr, 0, 16);
13316		memset(mac_buf, 0, 32);
13317		memset(devname, 0, LINE_SIZE);
13318
13319		if(strcmp((const char *)p_client_info_tab->user_define[i], ""))
13320			strcpy(dev_name, (const char *)p_client_info_tab->user_define[i]);
13321		else
13322			strcpy(dev_name, (const char *)p_client_info_tab->device_name[i]);
13323
13324	    if(p_client_info_tab->exist[i]==1) {
13325		len = strlen(dev_name);
13326		for (j=0; (j < len) && (j < LINE_SIZE-1); j++) {
13327			character = dev_name[j];
13328			if ((isalnum(character)) || (character == ' ') || (character == '-') || (character == '_'))
13329				devname[j] = character;
13330			else
13331				devname[j] = ' ';
13332		}
13333
13334		sprintf(ipaddr, "%d.%d.%d.%d", p_client_info_tab->ip_addr[i][0],p_client_info_tab->ip_addr[i][1],
13335		p_client_info_tab->ip_addr[i][2],p_client_info_tab->ip_addr[i][3]);
13336
13337		sprintf(mac_buf, "\"%02X:%02X:%02X:%02X:%02X:%02X\"",
13338		p_client_info_tab->mac_addr[i][0],p_client_info_tab->mac_addr[i][1],
13339		p_client_info_tab->mac_addr[i][2],p_client_info_tab->mac_addr[i][3],
13340		p_client_info_tab->mac_addr[i][4],p_client_info_tab->mac_addr[i][5]
13341		);
13342		if(first_mac == 1){
13343			first_mac = 0;
13344			strcat(maclist_buf,brackets_h);
13345		}else{
13346			strcat(maclist_buf,dot);
13347		}
13348		strcat(maclist_buf,mac_buf);
13349
13350		if(first_info == 1){
13351			first_info = 0;
13352		}else{
13353			websWrite(wp, ",\n");
13354		}
13355
13356		sprintf(output_buf, "%s:{\"type\":\"%d\",\"name\":\"%s\",\"ip\":\"%s\",\"mac\":%s,\"from\":\"networkmapd\",\"macRepeat\":\"%d\",\"isGateway\":\"%s\",\"isWebServer\":\"%d\",\"isPrinter\":\"%d\",\"isITunes\":\"%d\",\"isOnline\":\"true\"}",
13357		mac_buf,
13358		p_client_info_tab->type[i],
13359		devname,
13360		ipaddr,
13361		mac_buf,
13362		check_macrepeat(maclist_buf, mac_buf),
13363		!strcmp(nvram_safe_get("lan_ipaddr"), ipaddr) ? "true" : "false",
13364		p_client_info_tab->http[i],
13365		p_client_info_tab->printer[i],
13366		p_client_info_tab->itune[i]
13367		);
13368		websWrite(wp, output_buf);
13369
13370	    }
13371	}
13372	shmdt(shared_client_info);
13373	file_unlock(lock);
13374	strcat(maclist_buf,brackets_d);
13375	websWrite(wp, maclist_buf);
13376	return 0;
13377}
13378
13379#ifdef RT4GAC55U
13380static int
13381ej_chk_lte_fw(int eid, webs_t wp, int argc, char **argv) {
13382	int i;
13383	int ret;
13384	char *dev_path;
13385	char buf[256], tmpstr[128], version[128];
13386	FILE *fp;
13387
13388	for(i = 1; i < 4; i++)
13389	{
13390		FILE *aFile;
13391
13392		sprintf(buf, "usb_path%d", i);
13393
13394		if (strcmp(nvram_safe_get(buf), "storage") != 0)
13395			continue;
13396
13397		sprintf(buf, "usb_path%d_fs_path0", i);
13398		dev_path = nvram_get(buf);
13399		if(dev_path == NULL || strlen(dev_path) <= 0)
13400			continue;
13401
13402		do {
13403			struct mntent *ent;
13404
13405			aFile = setmntent("/proc/mounts", "r");
13406			if (aFile == NULL) {
13407				perror("setmntent");
13408				break;
13409			}
13410			while (NULL != (ent = getmntent(aFile))) {
13411				char *p;
13412				p = strstr(ent->mnt_fsname, dev_path);
13413				if (p != NULL && *(p-1) == '/' && *(p + strlen(dev_path)) == '\0')
13414				{
13415#define GOBI_FW_PATH "4G-AC55U_LTE"
13416					snprintf(buf, sizeof(buf), "%s/%s/version", ent->mnt_dir, GOBI_FW_PATH);
13417					if(!check_if_file_exist(buf))
13418						continue;
13419#if 1
13420					snprintf(buf, sizeof(buf), "%s/%s/update.md5", ent->mnt_dir, GOBI_FW_PATH);
13421					if(!check_if_file_exist(buf))
13422						continue;
13423					snprintf(buf, sizeof(buf), "%s/%s/update.zip", ent->mnt_dir, GOBI_FW_PATH);
13424					if(!check_if_file_exist(buf))
13425						continue;
13426#else
13427					snprintf(buf, sizeof(buf), "cd %s/%s && md5sum -c update.md5", ent->mnt_dir, GOBI_FW_PATH);
13428					if(system(buf) == 0)
13429#endif
13430					{
13431						snprintf(buf, sizeof(buf), "%s/%s/version", ent->mnt_dir, GOBI_FW_PATH);
13432						//do_file(buf, wp);
13433						if((fp = fopen(buf, "r")) != NULL){
13434							while (fgets(tmpstr, sizeof(tmpstr), fp) != NULL)
13435							{
13436								strncpy(version, tmpstr, strlen(tmpstr)-1);
13437								version[strlen(tmpstr)-1] = '\0';
13438							}
13439							fclose(fp);
13440						}
13441					}
13442
13443					endmntent(aFile);
13444					return websWrite(wp, "%s", version);
13445				}
13446			}
13447		}while(0);
13448		endmntent(aFile);
13449	}
13450	return 0;
13451}
13452#endif	/* RT4GAC55U */
13453
13454static int
13455ej_check_asus_model(int eid, webs_t wp, int argc, char **argv)
13456{
13457	int from_app = 0;
13458
13459	from_app = check_user_agent(user_agent);
13460#ifdef RTCONFIG_HTTPS
13461	if (check_model_name()){
13462		if(from_app == 0)
13463			return websWrite(wp, "1");
13464		else
13465			return websWrite(wp, "\"1\"");
13466	}else{
13467		if(from_app == 0)
13468			return websWrite(wp, "0");
13469		else
13470			return websWrite(wp, "\"0\"");
13471	}
13472#else
13473	if(from_app == 0)
13474		return websWrite(wp, "1");
13475	else
13476		return websWrite(wp, "\"1\"");
13477#endif
13478}
13479
13480struct ej_handler ej_handlers[] = {
13481	{ "nvram_get", ej_nvram_get},
13482	{ "nvram_default_get", ej_nvram_default_get},
13483	{ "nvram_match", ej_nvram_match},
13484	{ "nvram_double_match", ej_nvram_double_match},
13485	{ "nvram_show_chinese_char", ej_nvram_show_chinese_char}, // 2012.05 Jieming add to show chinese char in mediaserver.asp
13486	// the follwoing will be removed
13487	{ "nvram_get_x", ej_nvram_get_x},
13488	{ "nvram_get_f", ej_nvram_get_f},
13489	{ "nvram_get_list_x", ej_nvram_get_list_x},
13490	{ "nvram_get_buf_x", ej_nvram_get_buf_x},
13491	{ "nvram_match_x", ej_nvram_match_x},
13492	{ "nvram_double_match_x", ej_nvram_double_match_x},
13493	{ "nvram_match_both_x", ej_nvram_match_both_x},
13494	{ "nvram_match_list_x", ej_nvram_match_list_x},
13495	{ "select_channel", ej_select_channel},
13496	{ "uptime", ej_uptime},
13497	{ "sysuptime", ej_sysuptime},
13498	{ "nvram_dump", ej_dump},
13499	{ "load_script", ej_load},
13500	{ "select_list", ej_select_list},
13501	{ "dhcpLeaseInfo", ej_dhcpLeaseInfo},
13502	{ "dhcpLeaseMacList", ej_dhcpLeaseMacList},
13503	{ "IP_dhcpLeaseInfo", ej_IP_dhcpLeaseInfo},
13504//tomato qosvvvvvvvvvvv 2010.08 Viz
13505	{ "qrate", ej_qos_packet},
13506	{ "ctdump", ej_ctdump},
13507	{ "netdev", ej_netdev},
13508	{ "bandwidth", ej_bandwidth},
13509#ifdef RTCONFIG_DSL
13510	{ "spectrum", ej_spectrum}, //Ren
13511	{ "get_annexmode", ej_getAnnexMode}, //Ren
13512	{ "get_adsltoneamount", ej_getADSLToneAmount}, //Ren
13513	{ "show_file_content", show_file_content}, //Ren
13514#endif
13515	{ "backup_nvram", ej_backup_nvram},
13516//tomato qos^^^^^^^^^^^^ end Viz
13517	{ "wl_get_parameter", ej_wl_get_parameter},
13518	{ "wl_get_guestnetwork", ej_wl_get_guestnetwork},
13519	{ "wan_get_parameter", ej_wan_get_parameter},
13520	{ "lan_get_parameter", ej_lan_get_parameter},
13521#ifdef RTCONFIG_DSL
13522	{ "dsl_get_parameter", ej_dsl_get_parameter},
13523#endif
13524
13525#ifdef ASUS_DDNS //2007.03.27 Yau add
13526	{ "nvram_get_ddns", ej_nvram_get_ddns},
13527	{ "nvram_char_to_ascii", ej_nvram_char_to_ascii},
13528	{ "load_clientlist_char_to_ascii", ej_load_clientlist_char_to_ascii}, //Rawny
13529#endif
13530//2008.08 magic{
13531	{ "update_variables", ej_update_variables},
13532#ifdef RTCONFIG_ROG
13533	{ "set_variables", ej_set_variables},
13534#endif
13535	{ "convert_asus_variables", convert_asus_variables},
13536	{ "asus_nvram_commit", asus_nvram_commit},
13537	{ "notify_services", ej_notify_services},
13538	{ "wanstate", wanstate_hook},
13539	{ "dual_wanstate", dual_wanstate_hook},
13540	{ "ajax_dualwanstate", ajax_dualwanstate_hook},
13541	{ "ajax_wanstate", ajax_wanstate_hook},
13542	{ "secondary_ajax_wanstate", secondary_ajax_wanstate_hook},
13543#ifdef RTCONFIG_DSL
13544	{ "wanlink_dsl", wanlink_hook_dsl},
13545#endif
13546	{ "wanlink", wanlink_hook},
13547	{ "first_wanlink", first_wanlink_hook},
13548	{ "secondary_wanlink", secondary_wanlink_hook},
13549	{ "wanlink_state", wanlink_state_hook},
13550	{ "wan_action", wan_action_hook},
13551	{ "get_wan_unit", get_wan_unit_hook},
13552	{ "check_hwnat", check_hwnat},
13553	{ "get_parameter", ej_get_parameter},
13554	{ "get_ascii_parameter", ej_get_ascii_parameter},
13555	{ "login_state_hook", login_state_hook},
13556#ifdef RTCONFIG_FANCTRL
13557	{ "get_fanctrl_info", get_fanctrl_info},
13558#endif
13559#ifdef RTCONFIG_BCMARM
13560	{ "get_cpu_temperature", get_cpu_temperature},
13561#endif
13562	{ "get_machine_name" , get_machine_name},
13563	{ "dhcp_leases", ej_dhcp_leases},
13564	{ "get_arp_table", ej_get_arp_table},
13565	{ "get_client_detail_info", ej_get_client_detail_info},//2011.03 Yau add for new networkmap
13566	{ "get_static_client", ej_get_static_client},
13567	{ "yadns_servers", yadns_servers_hook},
13568	{ "yadns_clients", yadns_clients_hook},
13569	{ "get_changed_status", ej_get_changed_status},
13570	{ "shown_language_css", ej_shown_language_css},
13571	{ "memory_usage", ej_memory_usage},
13572	{ "cpu_usage", ej_cpu_usage},
13573	{ "cpu_core_num", ej_cpu_core_num},
13574#ifdef RTCONFIG_RALINK
13575#elif defined(RTCONFIG_QCA)
13576#else
13577#ifdef RTCONFIG_WIRELESSWAN
13578	{ "sitesurvey", ej_SiteSurvey},
13579#endif
13580#endif
13581#if defined(CONFIG_BCMWL5) || (defined(RTCONFIG_RALINK) && defined(RTCONFIG_WIRELESSREPEATER)) || defined(RTCONFIG_QCA)
13582	{ "get_ap_info", ej_get_ap_info},
13583#endif
13584	{ "ddns_info", ej_ddnsinfo},
13585	{ "show_usb_path", ej_show_usb_path},
13586	{ "apps_fsck_ret", ej_apps_fsck_ret},
13587#ifdef RTCONFIG_USB
13588	{ "disk_pool_mapping_info", ej_disk_pool_mapping_info},
13589	{ "available_disk_names_and_sizes", ej_available_disk_names_and_sizes},
13590	{ "get_printer_info", ej_get_printer_info},
13591	{ "get_modem_info", ej_get_modem_info},
13592	{ "get_isp_scan_results", ej_get_isp_scan_results},
13593	{ "get_simact_result", ej_get_simact_result},
13594	{ "get_modemuptime", ej_modemuptime},
13595	{ "get_AiDisk_status", ej_get_AiDisk_status},
13596	{ "set_AiDisk_status", ej_set_AiDisk_status},
13597	{ "get_all_accounts", ej_get_all_accounts},
13598	{ "safely_remove_disk", ej_safely_remove_disk},
13599	{ "get_permissions_of_account", ej_get_permissions_of_account},
13600	{ "set_account_permission", ej_set_account_permission},
13601	{ "set_account_all_folder_permission", ej_set_account_all_folder_permission},
13602	{ "get_folder_tree", ej_get_folder_tree},
13603	{ "get_share_tree", ej_get_share_tree},
13604	{ "initial_account", ej_initial_account},
13605	{ "create_account", ej_create_account},	/*no ccc*/
13606	{ "delete_account", ej_delete_account}, /*n*/
13607	{ "modify_account", ej_modify_account}, /*n*/
13608	{ "create_sharedfolder", ej_create_sharedfolder},	/*y*/
13609	{ "delete_sharedfolder", ej_delete_sharedfolder},	/*y*/
13610	{ "modify_sharedfolder", ej_modify_sharedfolder},	/* no ccc*/
13611	{ "set_share_mode", ej_set_share_mode},
13612	{ "initial_folder_var_file", ej_initial_folder_var_file},
13613#ifdef RTCONFIG_DISK_MONITOR
13614	{ "apps_fsck_log", ej_apps_fsck_log},
13615#endif
13616	{ "apps_info", ej_apps_info},
13617	{ "apps_state_info", ej_apps_state_info},
13618	{ "apps_action", ej_apps_action},
13619#ifdef RTCONFIG_MEDIA_SERVER
13620	{ "dms_info", ej_dms_info},
13621#endif
13622//#ifdef RTCONFIG_CLOUDSYNC
13623	{ "cloud_status", ej_cloud_status},
13624	{ "UI_cloud_status", ej_UI_cloud_status},
13625	{ "UI_cloud_dropbox_status", ej_UI_cloud_dropbox_status},
13626	{ "UI_cloud_ftpclient_status", ej_UI_cloud_ftpclient_status},
13627	{ "UI_cloud_sambaclient_status", ej_UI_cloud_sambaclient_status},
13628	{ "UI_cloud_usbclient_status", ej_UI_cloud_usbclient_status},
13629	{ "UI_rs_status", ej_UI_rs_status},
13630	{ "getWebdavInfo", ej_webdavInfo},
13631//#endif
13632#endif
13633	{ "start_autodet", start_autodet},
13634#ifdef RTCONFIG_QCA_PLC_UTILS
13635	{ "start_plcdet", start_plcdet},
13636#endif
13637#if defined(CONFIG_BCMWL5) || (defined(RTCONFIG_RALINK) && defined(RTCONFIG_WIRELESSREPEATER)) || defined(RTCONFIG_QCA)
13638	{ "start_wlcscan", start_wlcscan},
13639#endif
13640	{ "setting_lan", setting_lan},
13641
13642	// system or solution dependant part start from here
13643	{ "wl_sta_list_2g", ej_wl_sta_list_2g},
13644	{ "wl_sta_list_5g", ej_wl_sta_list_5g},
13645#ifdef CONFIG_BCMWL5
13646#ifndef RTCONFIG_QTN
13647	{ "wl_sta_list_5g_2", ej_wl_sta_list_5g_2},
13648#endif
13649#endif
13650#ifdef RTCONFIG_STAINFO
13651	{ "wl_stainfo_list_2g", ej_wl_stainfo_list_2g},
13652	{ "wl_stainfo_list_5g", ej_wl_stainfo_list_5g},
13653#ifndef RTCONFIG_QTN
13654	{ "wl_stainfo_list_5g_2", ej_wl_stainfo_list_5g_2},
13655#endif
13656#endif
13657	{ "wl_auth_list", ej_wl_auth_list},
13658#ifdef CONFIG_BCMWL5
13659	{ "wl_control_channel", ej_wl_control_channel},
13660#endif
13661#ifdef RTCONFIG_DSL
13662	{ "start_dsl_autodet", start_dsl_autodet},
13663	{ "get_isp_list", ej_get_isp_list},
13664	{ "get_isp_dhcp_opt_list", ej_get_isp_dhcp_opt_list},
13665	{ "get_DSL_WAN_list", ej_get_DSL_WAN_list},
13666#endif
13667	{ "wl_scan_2g", ej_wl_scan_2g},
13668	{ "wl_scan_5g", ej_wl_scan_5g},
13669#ifdef CONFIG_BCMWL5
13670	{ "wl_scan_5g_2", ej_wl_scan_5g_2},
13671#endif
13672	{ "channel_list_2g", ej_wl_channel_list_2g},
13673	{ "channel_list_5g", ej_wl_channel_list_5g},
13674#ifdef RTCONFIG_QTN
13675	{ "channel_list_5g_20m", ej_wl_channel_list_5g_20m},
13676	{ "channel_list_5g_40m", ej_wl_channel_list_5g_40m},
13677	{ "channel_list_5g_80m", ej_wl_channel_list_5g_80m},
13678#else
13679	{ "channel_list_5g_20m", ej_wl_channel_list_5g},
13680	{ "channel_list_5g_40m", ej_wl_channel_list_5g},
13681	{ "channel_list_5g_80m", ej_wl_channel_list_5g},
13682#endif
13683#ifdef CONFIG_BCMWL5
13684	{ "channel_list_5g_2", ej_wl_channel_list_5g_2},
13685	{ "chanspecs_2g", ej_wl_chanspecs_2g},
13686	{ "chanspecs_5g", ej_wl_chanspecs_5g},
13687	{ "chanspecs_5g_2", ej_wl_chanspecs_5g_2},
13688#endif
13689#if defined(CONFIG_BCMWL5) || (defined(RTCONFIG_RALINK) && defined(RTCONFIG_WIRELESSREPEATER)) || defined(RTCONFIG_QCA)
13690	{ "wl_rate_2g", ej_wl_rate_2g},
13691	{ "wl_rate_5g", ej_wl_rate_5g},
13692#ifdef CONFIG_BCMWL5
13693	{ "wl_rate_5g_2", ej_wl_rate_5g_2},
13694#endif
13695#endif
13696#ifdef RTCONFIG_PROXYSTA
13697	{ "wlc_psta_state", ej_wl_auth_psta},
13698#endif
13699	{ "get_default_reboot_time", ej_get_default_reboot_time},
13700	{ "radio_status", ej_radio_status},
13701	{ "sysinfo", ej_sysinfo},
13702#ifdef RTCONFIG_OPENVPN
13703	{ "vpn_server_get_parameter", ej_vpn_server_get_parameter},
13704	{ "vpn_client_get_parameter", ej_vpn_client_get_parameter},
13705	{ "vpn_crt_server", ej_vpn_crt_server},
13706	{ "vpn_crt_client", ej_vpn_crt_client},
13707#endif
13708	{ "nvram_clean_get", ej_nvram_clean_get},
13709	{ "check_pw", ej_check_pw},
13710	{ "check_acpw", ej_check_acpw},
13711	{ "check_acorpw", ej_check_acorpw},
13712	{ "check_ftp_samba_anonymous", ej_check_ftp_samba_anonymous},
13713	{ "check_passwd_strength", ej_check_passwd_strength},
13714	{ "check_wireless_encryption", ej_check_wireless_encryption},
13715	{ "get_clientlist", ej_get_clientlist},
13716#ifdef RTCONFIG_BWDPI
13717	{ "bwdpi_status", ej_bwdpi_status},
13718	{ "bwdpi_history", ej_bwdpi_history},
13719	{ "bwdpi_device_info", ej_bwdpi_device},
13720	{ "bwdpi_redirect_info", ej_bwdpi_redirect_page_status},
13721	{ "bwdpi_appStat", ej_bwdpi_appStat},
13722	{ "bwdpi_wanStat", ej_bwdpi_wanStat},
13723	{ "bwdpi_engine_status", ej_bwdpi_engine_status},
13724#else
13725	{ "bwdpi_engine_status", ej_bwdpi_engine_status},
13726	{ "bwdpi_device_info", ej_bwdpi_device},
13727#endif
13728#ifdef RTCONFIG_TRAFFIC_LIMITER
13729	{ "traffic_limiter_wanStat", ej_traffic_limiter_wanStat},
13730#endif
13731	{ "wl_nband_info", ej_wl_nband_info},
13732#ifdef RTCONFIG_GEOIP
13733	{ "geoiplookup", ej_geoiplookup},
13734#endif
13735#ifdef RTCONFIG_JFFS2USERICON
13736	{ "get_upload_icon", ej_get_upload_icon},
13737	{ "get_upload_icon_count_list", ej_get_upload_icon_count_list},
13738#endif
13739	{ "findasus", ej_findasus},
13740#ifdef RTCONFIG_WTFAST
13741	{ "wtfast_status", ej_wtfast_status },
13742#endif
13743#ifdef RT4GAC55U
13744	{ "chk_lte_fw", ej_chk_lte_fw},
13745#endif
13746	{ "check_asus_model", ej_check_asus_model},
13747	{ "generate_region", ej_generate_region},
13748	{ NULL, NULL }
13749};
13750
13751void websSetVer(void)
13752{
13753	FILE *fp;
13754	unsigned long *imagelen;
13755	char dataPtr[4];
13756	char verPtr[64];
13757	char productid[13];
13758	char fwver[12];
13759
13760	strcpy(productid, "WLHDD");
13761	strcpy(fwver, "0.1.0.1");
13762
13763	if ((fp = fopen("/dev/mtd3", "rb"))!=NULL)
13764	{
13765		if (fseek(fp, 4, SEEK_SET)!=0) goto write_ver;
13766		fread(dataPtr, 1, 4, fp);
13767		imagelen = (unsigned long *)dataPtr;
13768
13769		cprintf("image len %x\n", *imagelen);
13770		if (fseek(fp, *imagelen - 64, SEEK_SET)!=0) goto write_ver;
13771		cprintf("seek\n");
13772		if (!fread(verPtr, 1, 64, fp)) goto write_ver;
13773		cprintf("ver %x %x", verPtr[0], verPtr[1]);
13774		strncpy(productid, verPtr + 4, 12);
13775		productid[12] = 0;
13776		sprintf(fwver, "%d.%d.%d.%d", verPtr[0], verPtr[1], verPtr[2], verPtr[3]);
13777
13778		cprintf("get fw ver: %s\n", productid);
13779		fclose(fp);
13780	}
13781write_ver:
13782	nvram_set_f("general.log", "productid", productid);
13783	nvram_set_f("general.log", "firmver", fwver);
13784}
13785
13786int
13787get_nat_vserver_table(int eid, webs_t wp, int argc, char_t **argv)
13788{
13789	FILE *fp;
13790	char *nat_argv[] = {"iptables", "-t", "nat", "-nxL", NULL};
13791	char line[256], tmp[256];
13792	char target[16], proto[16];
13793	char src[sizeof("255.255.255.255")];
13794	char dst[sizeof("255.255.255.255")];
13795	char *range, *host, *port, *ptr, *val;
13796	int ret = 0;
13797
13798	/* dump nat table including VSERVER and VUPNP chains */
13799	_eval(nat_argv, ">/tmp/vserver.log", 10, NULL);
13800
13801	ret += websWrite(wp,
13802#ifdef NATSRC_SUPPORT
13803		"Source          "
13804#endif
13805		"Destination     Proto. Port range  Redirect to     Local port\n");
13806	/*	 255.255.255.255 other  65535:65535 255.255.255.255 65535:65535 */
13807
13808	fp = fopen("/tmp/vserver.log", "r");
13809	if (fp == NULL)
13810		return ret;
13811
13812	while (fgets(line, sizeof(line), fp) != NULL)
13813	{
13814		_dprintf("HTTPD: %s\n", line);
13815
13816		tmp[0] = '\0';
13817		if (sscanf(line,
13818		    "%15s%*[ \t]"		// target
13819		    "%15s%*[ \t]"		// prot
13820		    "%*s%*[ \t]"		// opt
13821		    "%15[^/]/%*d%*[ \t]"	// source
13822		    "%15[^/]/%*d%*[ \t]"	// destination
13823		    "%255[^\n]",		// options
13824		    target, proto, src, dst, tmp) < 4) continue;
13825
13826		/* TODO: add port trigger, portmap, etc support */
13827		if (strcmp(target, "DNAT") != 0)
13828			continue;
13829
13830		/* uppercase proto */
13831		for (ptr = proto; *ptr; ptr++)
13832			*ptr = toupper(*ptr);
13833#ifdef NATSRC_SUPPORT
13834		/* parse source */
13835		if (strcmp(src, "0.0.0.0") == 0)
13836			strcpy(src, "ALL");
13837#endif
13838		/* parse destination */
13839		if (strcmp(dst, "0.0.0.0") == 0)
13840			strcpy(dst, "ALL");
13841
13842		/* parse options */
13843		port = host = range = "";
13844		ptr = tmp;
13845		while ((val = strsep(&ptr, " ")) != NULL) {
13846			if (strncmp(val, "dpt:", 4) == 0)
13847				range = val + 4;
13848			else if (strncmp(val, "dpts:", 5) == 0)
13849				range = val + 5;
13850			else if (strncmp(val, "to:", 3) == 0) {
13851				port = host = val + 3;
13852				strsep(&port, ":");
13853			}
13854		}
13855
13856		ret += websWrite(wp,
13857#ifdef NATSRC_SUPPORT
13858			"%-15s "
13859#endif
13860			"%-15s %-6s %-11s %-15s %-11s\n",
13861#ifdef NATSRC_SUPPORT
13862			src,
13863#endif
13864			dst, proto, range, host, port ? : range);
13865	}
13866	fclose(fp);
13867	unlink("/tmp/vserver.log");
13868
13869	return ret;
13870}
13871
13872/* remove space in the end of string */
13873char *trim_r(char *str)
13874{
13875	int i;
13876
13877	i = strlen(str);
13878
13879	while (i >= 1)
13880	{
13881		if (*(str+i-1) == ' ' || *(str+i-1) == 0x0a || *(str+i-1) == 0x0d)
13882			*(str+i-1)=0x0;
13883		else
13884			break;
13885
13886		i--;
13887	}
13888
13889	return (str);
13890}
13891
13892int
13893ej_get_default_reboot_time(int eid, webs_t wp, int argc, char_t **argv)
13894{
13895	int retval = 0;
13896
13897	retval += websWrite(wp, nvram_safe_get("reboot_time"));
13898	return retval;
13899}
13900
13901int is_wlif_up(const char *ifname)
13902{
13903	struct ifreq ifr;
13904	int skfd;
13905
13906	if (!ifname)
13907		return -1;
13908
13909	skfd = socket(AF_INET, SOCK_DGRAM, 0);
13910	if (skfd == -1)
13911	{
13912		perror("socket");
13913		return -1;
13914	}
13915
13916	strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
13917	if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0)
13918	{
13919		perror("ioctl");
13920		close(skfd);
13921		return -1;
13922	}
13923	close(skfd);
13924
13925	if (ifr.ifr_flags & IFF_UP)
13926		return 1;
13927	else
13928		return 0;
13929}
13930