add S300AI

Change-Id: Ice89434e8dc7b3be506380729d716f50aa75df14
diff --git a/lynq/S300AI/ap/app/goahead/server/Makefile b/lynq/S300AI/ap/app/goahead/server/Makefile
new file mode 100755
index 0000000..aaf3788
--- /dev/null
+++ b/lynq/S300AI/ap/app/goahead/server/Makefile
@@ -0,0 +1,249 @@
+# /*****************************************************************************
+#* °æÈ¨ËùÓÐ (C)2015, ÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
+#* 
+#* ÎļþÃû³Æ:     Makefile
+#* Îļþ±êʶ:     Makefile
+#* ÄÚÈÝÕªÒª:     Makefile of ZTE applications
+#* ʹÓ÷½·¨:     void
+#* 
+#* ÐÞ¸ÄÈÕÆÚ        °æ±¾ºÅ      Ð޸ıê¼Ç        ÐÞ¸ÄÈË          ÐÞ¸ÄÄÚÈÝ
+#* -----------------------------------------------------------------------------
+#* 2015/02/10      V1.0        Create          ÁõÑÇÄÏ          ´´½¨
+#* 
+# ******************************************************************************/
+
+#*******************************************************************************
+# include ZTE application makefile
+#*******************************************************************************
+include $(zte_app_mak)
+
+#*******************************************************************************
+# execute
+#*******************************************************************************
+EXEC    = goahead
+
+
+# User Management switch
+#UMSW	= -DUSER_MANAGEMENT_SUPPORT
+CPU_PUB_ROOT=$(TOPDIR_AP)/../pub
+INTERFACEDIR = ../interface5.0
+INTERFACELIB = $(INTERFACEDIR)/libwebinterface.a
+#*******************************************************************************
+# objects asp.o ejlex.o ejparse.o umui.o
+#*******************************************************************************
+OBJS    =		  balloc.o base64.o cgi.o default.o \
+				  form.o \
+				  h.o handler.o mime.o misc.o page.o  \
+				  ringq.o \
+				  sock.o sockGen.o \
+				  sym.o uemf.o value.o \
+				  webs.o websuemf.o goahead.o
+
+#*******************************************************************************
+# include path
+#*******************************************************************************
+CFLAGS	+= -DWEBS -DUEMF -DOS="LINUX" -DLINUX $(UMSW) $(DASW) $(SSLSW) $(IFMODSW)
+CFLAGS  += -Wall -fno-strict-aliasing -I../interface5.0/net -I.
+#CFLAGS	+= -I$(ROOTDIR)/lib/libnvram -I$(ROOTDIR)/$(LINUXDIR)/drivers/char -I$(ROOTDIR)/$(LINUXDIR)/include
+#CFLAGS  += -I$(ROOTDIR)/$(LINUXDIR)/drivers/flash -I$(INTERFACEDIR)
+
+#OTHERS	= -DB_STATS -DB_FILL -DDEBUG
+CFLAGS	+= -I../../include -g
+#CFLAGS	+= -I../../zte_sqlite
+#CFLAGS  += -I../../soft_timer
+CFLAGS	+= -I$(zte_lib_path)/libsqlite
+CFLAGS	+= -I$(zte_lib_path)/libsoft_timer
+CFLAGS  += -I../../at_server
+CFLAGS	+= -I$(zte_lib_path)/libnvram
+CFLAGS  += -I$(zte_lib_path)/libezxml
+CFLAGS  += -I$(zte_lib_path)/libmxml
+ifeq ($(CONFIG_USE_WEBUI_SSL),yes)
+OBJS += websSSL.o
+CFLAGS  += -I$(zte_lib_path)/libssl/install/include
+CFLAGS  += -I$(CPU_PUB_ROOT)/project/zx297520v3/include/nv
+CFLAGS	+= -DWEBS_SSL_SUPPORT -DOPENSSL
+LDLIBS += -L$(zte_lib_path)/libssl/install/lib -lssl -lcrypto
+LDLIBS += -ldl
+endif
+CFLAGS	+= -DWEBINSPECT_FIX
+LDLIBS += -lpthread
+LDLIBS += -lsoftap -L$(zte_lib_path)/libsoftap
+LDLIBS  += -lsoft_timer -L$(zte_lib_path)/libsoft_timer
+#LDLIBS  += -lkey -L$(zte_lib_path)/libkey
+LDLIBS  += -lamt -L$(zte_lib_path)/libamt
+LDLIBS  += -lcpnv -L$(zte_lib_path)/libcpnv
+LDLIBS  += -latutils -L$(zte_lib_path)/libatutils
+
+ifeq ($(CONFIG_USE_WEBUI_SECURITY),yes)
+CFLAGS	+= -DWEBS_SECURITY
+endif
+#*******************************************************************************
+# macro definition
+#*******************************************************************************
+ifeq ($(CONFIG_USE_WEBUI_ZIP),yes)
+OBJS += ioapi.o unzip.o
+CFLAGS	+= -D_USE_WEBUI_ZIP
+CFLAGS  += -I$(zte_lib_path)/zlib/install/include
+LDFLAGS += -L$(zte_lib_path)/zlib/install/lib -lz
+endif
+
+ifeq ($(CUSTOM_MODEL), MF253S2)
+ifeq ($(CUSTOM_OPERATOR), CM_CN)
+CFLAGS	+= -DCUSTOM_VERSION_MF253S2_CM_CN
+endif
+endif
+
+##changed by huangmin10103007 for new partition, 20130116 begin
+ifeq ($(FEATURE_ZTE_CPE_CFG), YES)
+CFLAGS += -D_ZTE_CFG_
+endif
+##changed by huangmin10103007 for new partition, 20130116 end
+# Digest Access switch
+# DASW	= -DDIGEST_ACCESS_SUPPORT
+
+# SSL switches
+ifeq ("$(CONFIG_USER_GOAHEAD_SSL)", "y")
+SSLPATCHFILE = matrix_ssl.o sslSocket.o
+MATRIXDIR = $(ROOTDIR)/user/matrixssl-1.8.3
+SSLINC = $(MATRIXDIR)
+SSLLIB = $(MATRIXDIR)/src/libmatrixsslstatic.a
+SSLSW = -DWEBS_SSL_SUPPORT -DMATRIX_SSL -I$(SSLINC)
+endif
+
+#CONF_H	= $(ROOTDIR)/$(LINUXDIR)/include/linux/autoconf.h
+#CONF_H	= $(LINUX_DIR)/include/linux/autoconf.h
+#UCONF_H	= $(ROOTDIR)/config/autoconf.h
+
+#BUSYCONF_H = $(USR_DIR)/busybox-1.15.0/include/autoconf.h
+#UCONF_H	= $(CFG_DIR)/autoconf.h
+
+ifeq ($(FEATURE_DLNA), YES)
+# DLNA settings(libztedlna.so)
+LDLIBS += -L../../DMS -lztedlna -lpthread
+endif
+
+#*******************************************************************************
+# library
+#*******************************************************************************
+LDLIBS	+= -lnvram -lzte_pbm -lsqlite -lwlan_interface
+ifeq ($(LINUX_TYPE),uClinux)
+LDLIBS	+= -lpthread
+else
+LDLIBS	+= -lpthread
+endif
+
+
+ifeq ($(FEATURE_DLNA), YES)
+LDLIBS	+= -L../../DMS -lztedlna
+endif
+
+LDFLAGS	+= $(SSLLIB) $(IFMODLIB) $(INTERFACELIB) -lm -lgcc_s
+
+#LDFLAGS += -Wl,-elf2flt=-s131072
+
+CFLAGS += -I$(zte_lib_path)/libssl/install/include
+LDLIBS += -L$(zte_lib_path)/libssl/install/lib -lcrypto
+CFLAGS += -I$(zte_lib_path)/libcurl/install/include
+LDLIBS += -L$(zte_lib_path)/libcurl/install/lib -lcurl
+
+#*******************************************************************************
+# library path
+#*******************************************************************************
+LDLIBS  += -L$(zte_lib_path)/libnvram
+#LDLIBS  += -L$(zte_lib_path)/libsoft_timer
+LDLIBS  += -L$(zte_lib_path)/libsqlite
+LDLIBS  += -L$(zte_lib_path)/libzte_pbm
+LDLIBS  += -L$(zte_lib_path)/libmxml
+LDLIBS  += -L$(zte_lib_path)/libwlan_interface
+
+#*******************************************************************************
+# targets
+#*******************************************************************************
+all:$(EXEC)
+
+#
+#	Primary link
+#
+#$(CC) -o $@ $(OBJS) $(LDFLAGS) $(EXTRALIBS) $(LDLIBS)
+$(EXEC): $(OBJS) $(INTERFACELIB)
+	#$(LD)  -o $@ $(OBJS) $(LDFLAGS)  $(LDLIBS)
+	$(CC) -o $@ $(OBJS) $(LDFLAGS) $(EXTRALIBS) $(LDLIBS)
+
+root_fs:
+	cp $(EXEC) $(EXEC).elf
+	$(ROMFSINST) /bin/$(EXEC)
+
+romfs:
+	cp $(EXEC) $(EXEC).elf
+	$(ROMFSINST)  /bin/$(EXEC)
+
+clean:
+	-rm -f $(EXEC) *.o *.elf
+
+#
+#	Dependencies
+#
+asp.o:  webs.h wsIntrn.h ej.h ejIntrn.h uemf.h
+
+balloc.o: balloc.c uemf.h
+
+base64.o:  base64.c webs.h wsIntrn.h  ej.h ejIntrn.h uemf.h
+
+cgi.o:  webs.h wsIntrn.h uemf.h
+
+default.o:  default.c webs.h wsIntrn.h ej.h ejIntrn.h uemf.h $(CONF_H)
+
+ejlex.o:  ejlex.c ej.h ejIntrn.h uemf.h
+
+ejparse.o:  ejparse.c ej.h ejIntrn.h uemf.h
+
+emfdb.o:  emfdb.h wsIntrn.h uemf.h
+
+form.o:  form.c webs.h wsIntrn.h ej.h ejIntrn.h uemf.h
+
+h.o:  h.c uemf.h
+
+handler.o:  handler.c webs.h wsIntrn.h ej.h ejIntrn.h uemf.h
+
+md5c.o:  md5.h wsIntrn.h uemf.h
+
+mime.o:  mime.c webs.h wsIntrn.h ej.h ejIntrn.h uemf.h
+
+misc.o:  misc.c uemf.h
+
+page.o:  page.c webs.h wsIntrn.h ej.h ejIntrn.h uemf.h
+
+ringq.o:  ringq.c uemf.h
+
+rom.o:  rom.c webs.h wsIntrn.h ej.h ejIntrn.h uemf.h
+
+security.o:  security.c webs.h wsIntrn.h ej.h ejIntrn.h uemf.h
+
+sock.o:  sock.c uemf.h
+
+sockGen.o:  sockGen.c uemf.h $(CONF_H)
+
+sym.o:  sym.c uemf.h
+
+uemf.o:  uemf.c uemf.h
+
+um.o:  webs.h wsIntrn.h um.h uemf.h
+
+umui.o:  webs.h wsIntrn.h um.h uemf.h
+
+url.o:  url.c webs.h wsIntrn.h ej.h ejIntrn.h uemf.h
+
+value.o:  value.c uemf.h
+
+webrom.o:  webrom.c webs.h wsIntrn.h uemf.h
+
+webs.o:  webs.c webs.h wsIntrn.h ej.h ejIntrn.h uemf.h $(CONF_H)
+
+websda.o:  webs.h wsIntrn.h websda.h uemf.h
+
+websuemf.o:  websuemf.c webs.h wsIntrn.h ej.h ejIntrn.h uemf.h
+
+websSSL.o:  websSSL.c websSSL.h wsIntrn.h ej.h ejIntrn.h uemf.h
+
+#goahead.o:  goahead.c wsIntrn.h webs.h ej.h ejIntrn.h uemf.h $(CONF_H) $(UCONF_H) $(BUSYCONF_H)
+goahead.o:  goahead.c wsIntrn.h webs.h ej.h ejIntrn.h uemf.h $(CONF_H) $(BUSYCONF_H)
diff --git a/lynq/S300AI/ap/app/goahead/server/cgi.c b/lynq/S300AI/ap/app/goahead/server/cgi.c
new file mode 100755
index 0000000..8bf5bb3
--- /dev/null
+++ b/lynq/S300AI/ap/app/goahead/server/cgi.c
@@ -0,0 +1,313 @@
+#include	"wsIntrn.h"
+#include	<sys/types.h>
+#include	<sys/wait.h>
+#include	"uemf.h"
+
+static int		cgiMax;			
+typedef struct {				
+	webs_t	wp;					
+	long	fplacemark;			
+	int		handle;				
+	char_t	**envp;				
+	char_t	**argp;				
+	char_t	*cgiPath;			
+	char_t	*stdOut;			
+	char_t	*stdIn;				
+} cgiRec;
+static cgiRec	**cgiList;		
+
+int websCgiProcess(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, 
+		char_t *url, char_t *path, char_t* query)
+{
+	
+		int 		n, envpsize, argpsize, pHandle, cid;
+		char_t		*cp, *cgiName, *cgiPath, **argp, **envp, **ep;
+		char_t		cgiBuf[FNAMESIZE], *stdIn, *stdOut, cwd[FNAMESIZE];
+		sym_t		*s;
+		cgiRec		*cgip;
+		a_assert(path && *path == '/');
+		a_assert(url && *url);
+		a_assert(websValid(wp));
+		websStats.cgiHits++;
+		char *cgipath_temp = NULL;
+		gstrncpy(cgiBuf, path, TSZ(cgiBuf)-1);
+		cgipath_temp = gstrchr(&cgiBuf[1], '/');
+		if(cgipath_temp!=NULL)
+		{
+			cgipath_temp++;
+		}else
+		{
+			websError(wp, 200, T("cgiBuf error,check path"));
+						
+			return 1;
+		}
+		printf("[goahead]cgipath_temp->%s.\n",cgipath_temp);
+		//if ((cgiName = gstrchr(&cgiBuf[1], '/')) == NULL) {
+		if ((cgiName = gstrchr(cgipath_temp, '/')) == NULL) {
+	
+			if((cgiName = gstrchr(&cgiBuf[1], '/')) == NULL)
+			{
+				websError(wp, 200, T("Missing CGI name"));
+				
+				return 1;
+			}
+		}
+		cgiName++;
+		printf("[goahead]cgiName->%s.\n",cgiName);
+		if ((cp = gstrchr(cgiName, '/')) != NULL) {
+			*cp = '\0';
+		}
+	//	fmtAlloc(&cgiPath, FNAMESIZE, T("%s/%s/%s"), websGetDefaultDir(),
+	//		CGI_BIN, cgiName);
+		fmtAlloc(&cgiPath, FNAMESIZE, T("%s/%s"),"/sbin", cgiName);
+		{
+			gstat_t 	sbuf;
+			if (gstat(cgiPath, &sbuf) != 0 || (sbuf.st_mode & S_IFREG) == 0) {
+				system("rm -rf /tmp/firmware_tmp_file");
+				websError(wp, 200, T("CGI process file does not exist"));
+				bfree(B_L, cgiPath);
+				return 1;
+			}
+			if (gaccess(cgiPath, X_OK) != 0) {
+				websError(wp, 200, T("CGI process file is not executable"));
+				bfree(B_L, cgiPath);
+				return 1;
+			}
+		}
+		ggetcwd(cwd, FNAMESIZE);
+		if ((cp = gstrrchr(cgiPath, '/')) != NULL) {
+			*cp = '\0';
+			gchdir(cgiPath);
+			*cp = '/';
+		}
+		argpsize = 10;
+		argp = balloc(B_L, argpsize * sizeof(char_t *));
+		if(argp == NULL){
+			bfreeSafe(B_L, cgiPath);
+			return 1;
+		}
+		*argp = cgiPath;
+		n = 1;
+		if (gstrchr(query, '=') == NULL) {
+			websDecodeUrl(query, query, gstrlen(query));
+			for (cp = gstrtok(query, T(" ")); cp != NULL; ) {
+				*(argp+n) = cp;
+				n++;
+				if (n >= argpsize) {
+					argpsize *= 2;
+					argp = brealloc(B_L, argp, argpsize * sizeof(char_t *));
+					if(argp == NULL){
+						bfreeSafe(B_L, cgiPath);
+						return 1;
+					}
+				}
+				cp = gstrtok(NULL, T(" "));
+			}
+		}
+		*(argp+n) = NULL;
+		envpsize = WEBS_SYM_INIT;
+		envp = balloc(B_L, envpsize * sizeof(char_t *));
+		if(envp == NULL){
+			bfreeSafe(B_L, cgiPath);
+			bfreeSafe(B_L, argp);
+			return 1;
+		}
+		n = 0;
+		fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"),T("PATH_TRANSLATED"), cgiPath);
+		n++;
+		fmtAlloc(envp+n, FNAMESIZE, T("%s=%s/%s"),T("SCRIPT_NAME"),
+			CGI_BIN, cgiName);
+		n++;
+		fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"),T("REMOTE_USER"), wp->userName);
+		n++;
+		fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"),T("AUTH_TYPE"), wp->authType);
+		n++;
+		for (s = symFirst(wp->cgiVars); s != NULL; s = symNext(wp->cgiVars)) {
+			if (s->content.valid && s->content.type == string &&
+				gstrcmp(s->name.value.string, T("REMOTE_HOST")) != 0 &&
+				gstrcmp(s->name.value.string, T("HTTP_AUTHORIZATION")) != 0) {
+				fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"), s->name.value.string,
+					s->content.value.string);
+				n++;
+				if (n >= envpsize) {
+					envpsize *= 2;
+					envp = brealloc(B_L, envp, envpsize * sizeof(char_t *));
+					if(envp == NULL){
+						bfreeSafe(B_L, cgiPath);
+						bfreeSafe(B_L, argp);
+						return 1;
+					}
+				}
+			}
+		}
+		if (wp->flags & WEBS_CGI_UPLOAD)
+		{
+	
+			if((wp->has_firmware_upload_clean)||(wp->flags & WEBS_CGI_FIRMWARE_UPLOAD))
+			{
+				fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"), T("UPLOAD_FILENAME"), FIRMWARE_TMP_FILE); 
+			}
+			else
+			{					
+				fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"), T("UPLOAD_FILENAME"), wp->cgiStdin);		
+			}
+			n++;
+		}
+		*(envp+n) = NULL;
+		if (wp->cgiStdin == NULL) {
+			wp->cgiStdin = websGetCgiCommName(wp);
+		} 
+		stdIn = wp->cgiStdin;
+		stdOut = websGetCgiCommName(wp);
+		printf("[goahead]cgiPath->%s.\n",cgiPath);
+	
+		if ((pHandle = websLaunchCgiProc(cgiPath, argp, envp, stdIn, stdOut)) 
+			== -1) {
+			system("rm -rf /tmp/firmware_tmp_file");
+			websError(wp, 200, T("failed to spawn CGI task"));
+			for (ep = envp; *ep != NULL; ep++) {
+				bfreeSafe(B_L, *ep);
+			}
+			bfreeSafe(B_L, cgiPath);
+			bfreeSafe(B_L, argp);
+			bfreeSafe(B_L, envp);
+			bfreeSafe(B_L, stdOut);
+		} else {
+			cid = hAllocEntry((void***) &cgiList, &cgiMax, sizeof(cgiRec));
+			if(cgiList){
+			cgip = cgiList[cid];
+			cgip->handle = pHandle;
+			cgip->stdIn = stdIn;
+			cgip->stdOut = stdOut;
+			cgip->cgiPath = cgiPath;
+			cgip->argp = argp;
+			cgip->envp = envp;
+			cgip->wp = wp;
+			cgip->fplacemark = 0;
+			websTimeoutCancel(wp);
+			}
+			else
+			{
+				bfreeSafe(B_L, cgiPath);
+				bfreeSafe(B_L, argp);
+				bfreeSafe(B_L, envp);
+				bfreeSafe(B_L, stdOut);
+			}
+		}
+		gchdir(cwd);
+		return 1;
+
+}
+
+int websCgiHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, 
+		char_t *url, char_t *path, char_t* query)
+{
+	if(!(wp->flags & WEBS_POST_REQUEST))
+	{
+		//websError(wp, 200, T("NOT POST REQUEST"));
+		printf("[goahead]NOT POST REQUEST.\n");
+		websDone(wp, 0);
+		return 1;
+	}
+
+	if (wp->flags & WEBS_CGI_HTTPSHARE_UPLOAD)
+	{
+		printf("[httpshare]call zte_process_cgi_end.\n");
+		return zte_process_cgi_end(wp);
+	}else if(wp->flags & WEBS_CGI_UPLOAD)
+	{
+		printf("[goahead]call upload cgi.\n");
+		return websCgiProcess(wp, urlPrefix, webDir, arg,url, path, query);
+	}else
+	{
+		//websError(wp, 200, T("NOT CGI OR HTTPSHARE,RETURN ERROR"));
+		printf("[goahead]wrong cgi request.\n");
+		websDone(wp, 0);
+		return 1;
+	}
+
+}
+
+void websCgiGatherOutput (cgiRec *cgip)
+{
+	gstat_t	sbuf;
+	char_t	cgiBuf[FNAMESIZE];
+	if ((gstat(cgip->stdOut, &sbuf) == 0) && 
+		(sbuf.st_size > cgip->fplacemark)) {
+		int fdout;
+		fdout = gopen(cgip->stdOut, O_RDONLY | O_BINARY, 0444 );
+		if (fdout >= 0) {
+			webs_t	wp = cgip->wp;
+			int		nRead;
+			int		rc;
+			if (cgip->fplacemark == 0) {
+				websWrite(wp, T("HTTP/1.0 200 OK\n"));
+			}	
+			if(glseek(fdout, cgip->fplacemark, SEEK_SET) < 0)
+			{
+			    printf("[goahead]glseek fail.\n");
+			}
+			while ((nRead = gread(fdout, cgiBuf, FNAMESIZE)) > 0) {
+				rc = websWriteBlock(wp, cgiBuf, nRead);
+				if (rc < 0) {
+					//todo: cov m
+				}
+				cgip->fplacemark += nRead;
+			}
+			gclose(fdout);
+		}
+	}
+}
+
+void websCgiCleanup()
+{
+	cgiRec	*cgip;
+	webs_t	wp;
+	char_t	**ep;
+	int		cid, nTries;
+	for (cid = 0; cid < cgiMax; cid++) {
+		if ((cgip = cgiList[cid]) != NULL) {
+			int exit_status;
+			wp = cgip->wp;
+			websCgiGatherOutput (cgip);
+			if ( websCheckCgiProc(cgip->handle, &exit_status) == 0) {
+				nTries = 0;
+				while ((cgip->fplacemark == 0) && (nTries < 100)) {
+					websCgiGatherOutput(cgip);
+					if (cgip->fplacemark == 0) {
+					}
+					nTries++;
+				}
+				gunlink(cgip->stdIn);
+				gunlink(cgip->stdOut);
+				cgiMax = hFree((void***) &cgiList, cid);
+				for (ep = cgip->envp; ep != NULL && *ep != NULL; ep++) {
+					bfreeSafe(B_L, *ep);
+				}
+				bfreeSafe(B_L, cgip->cgiPath);
+				bfreeSafe(B_L, cgip->argp);
+				bfreeSafe(B_L, cgip->envp);
+				bfreeSafe(B_L, cgip->stdOut);
+				bfreeSafe(B_L, cgip);
+				if(wp->has_firmware_upload_clean){
+					if (WIFEXITED(exit_status) && WEXITSTATUS(exit_status) != 0) {
+						if (cgip->fplacemark == 0) { //cov h
+							websError(wp, 200, T("CGI generated no output"));
+						} else {
+							websDone(wp, 200);
+						}
+						return;
+					}
+					sync();
+					//doSystem("sleep 3 && reboot &");
+				}
+				if (cgip->fplacemark == 0) { //cov h
+					websError(wp, 200, T("CGI generated no output"));
+				} else {
+					websDone(wp, 200);
+				}
+			}
+		}
+	}
+}
+
diff --git a/lynq/S300AI/ap/app/goahead/server/goahead.c b/lynq/S300AI/ap/app/goahead/server/goahead.c
new file mode 100755
index 0000000..3fe84c3
--- /dev/null
+++ b/lynq/S300AI/ap/app/goahead/server/goahead.c
@@ -0,0 +1,339 @@
+#include	"uemf.h"
+#include	"wsIntrn.h"
+#include	<signal.h>
+#include	<unistd.h> 
+#include	<sys/types.h>
+#include	<sys/wait.h>
+#include    <sched.h>
+#ifdef WEBS_SSL_SUPPORT
+#include	"websSSL.h"
+#endif
+#include "../interface5.0/zte_web_interface.h"
+
+static char_t		*rootWeb = T("etc_ro/web");			/* Root web directory */
+static int			port = 80;						/* Server port */
+static int			retries = 5;					/* Server port retries */
+static int			finished;						/* Finished flag */
+
+/****************************** Forward Declarations **************************/
+
+static int 	initWebs();
+static int  websHomePageHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
+				int arg, char_t *url, char_t *path, char_t *query);
+extern void defaultErrorHandler(int etype, char_t *msg);
+extern void defaultTraceHandler(int level, char_t *buf);
+
+//added by liuyingnan for PC Client begin, 20120829
+extern int websXMLPostHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, char_t *url, char_t *path, char_t *query);
+//added by liuyingnan for PC Client end, 20120829
+
+int main(int argc, char** argv)
+{
+    int rs;
+    struct sched_param param;
+
+    loglevel_init();
+	slog(MISC_PRINT, SLOG_DEBUG, "goahead main\n");
+	bopen(NULL, (60 * 1024), B_USE_MALLOC);
+	signal(SIGPIPE, SIG_IGN);
+	if (initWebs() < 0) {
+		slog(MISC_PRINT, SLOG_ERR, "goahead initWebs failed.");
+		return -1;
+	}
+
+#ifdef WEBS_SSL_SUPPORT
+	websSSLOpen();
+#endif
+	web_init_pwd();
+	web_aes_init();
+
+	slog(MISC_PRINT, SLOG_NORMAL,"[goahead] enter working\n");
+	while (!finished) {
+		if (socketReady(-1) || socketSelect(-1, 1000)) {         
+			socketProcess(-1);
+		}
+		websCgiCleanup();
+		emfSchedProcess();
+	}
+
+#ifdef WEBS_SSL_SUPPORT
+	websSSLClose();
+#endif
+
+	websCloseServer();
+	socketClose();
+	bclose();
+	return 0;
+}
+
+static int initWebs()
+{
+	struct in_addr	intaddr;
+	const char			lan_ip[128] = {0};
+	char			host[128], dir[128], webdir[128];
+	char			*cp;
+	char_t			wbuf[128];
+	socketOpen();
+
+	cfg_get_item("lan_ipaddr", lan_ip, sizeof(lan_ip));
+	if (0 == strcmp(lan_ip, "")) {
+		slog(MISC_PRINT, SLOG_ERR, "goahead initWebs failed: lan_ip is NULL!");
+		return -1;
+	}
+	intaddr.s_addr = inet_addr(lan_ip);
+	if (intaddr.s_addr == INADDR_NONE) {
+		slog(MISC_PRINT, SLOG_ERR, "goahead initWebs failed: lan_ip is %s, INADDR_NONE!", lan_ip);
+		return -1;
+	}
+	getcwd(dir, sizeof(dir)); 
+	if ((cp = strrchr(dir, '/'))) {
+		*cp = '\0';
+	}
+    snprintf(webdir, sizeof(webdir), "%s/%s", dir, rootWeb);
+    slog(MISC_PRINT,SLOG_DEBUG, "goahead initWebs info: webdir is %s!",webdir);
+	websSetDefaultDir(webdir);
+	cp = inet_ntoa(intaddr);
+	ascToUni(wbuf, cp, min(strlen(cp) + 1, sizeof(wbuf)));
+	websSetIpaddr(wbuf);
+	websSetHost(wbuf);
+	websSetDefaultPage(T(ZTE_WEB_PAGE_LOGIN_NAME));
+	websOpenServer(port, retries);
+	//websUrlHandlerDefine(T(""), NULL, 0, websSecurityHandler, WEBS_HANDLER_FIRST);
+	websUrlHandlerDefine(T("/reqproc"), NULL, 0, websFormHandler, 0);
+#ifndef WEBS_SECURITY
+	websUrlHandlerDefine(T("/cgi-bin"), NULL, 0, websCgiHandler, 0);
+    //websUrlHandlerDefine(T("/api/xmlclient/post"), NULL, 0, websXMLPostHandler, 0);
+	websUrlHandlerDefine(T("/mmc2"), NULL, 0, websCgiDownLoadHandler, 0);//http share
+#endif	
+	websUrlHandlerDefine(T(""), NULL, 0, websDefaultHandler, WEBS_HANDLER_LAST); 
+	zte_web_init();
+	zte_httpshare_init();//httpshare
+	websUrlHandlerDefine(T("/"), NULL, 0, websHomePageHandler, 0); 
+
+	system("rm -rf /tmp/firmware_tmp_file");
+	return 0;
+}
+
+static int websHomePageHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
+                               int arg, char_t *url, char_t *path, char_t *query)
+{
+    if (*url == '\0' || gstrcmp(url, T("/")) == 0) 
+    {
+        websRedirect(wp, zte_web_get_login_page(wp)); /*×ÔÊÊÓ¦ÖÕ¶Ëä¯ÀÀÆ÷*/
+        return 1;
+    }
+    return 0;
+}
+
+void defaultErrorHandler(int etype, char_t *msg)
+{
+	printf("[goahead]e %s\n",msg);
+}
+
+void defaultTraceHandler(int level, char_t *buf)
+{
+	if (buf) {
+		printf("[goahead]t %s\n",buf);
+	}
+}
+
+char_t *websGetCgiCommName(webs_t wp)
+{
+	char_t	*pname1, *pname2;
+
+	pname1 = (char_t *)tempnam(T("/var"), T("cgi"));
+	pname2 = bstrdup(B_L, pname1);
+	free(pname1);
+	return pname2;
+}
+
+int websLaunchCgiProc(char_t *cgiPath, char_t **argp, char_t **envp,
+					  char_t *stdIn, char_t *stdOut)
+{
+	int	pid, fdin, fdout, hstdin, hstdout, rc;
+
+	fdin = fdout = hstdin = hstdout = rc = -1; 
+	if ((fdin = open(stdIn, O_RDWR | O_CREAT, 0666)) < 0 ||
+		(fdout = open(stdOut, O_RDWR | O_CREAT, 0666)) < 0 ||
+		(hstdin = dup(0)) == -1 ||
+		(hstdout = dup(1)) == -1 ||
+		dup2(fdin, 0) == -1 ||
+		dup2(fdout, 1) == -1) {
+		goto DONE;
+	}
+		
+ 	rc = pid = fork();
+ 	if (pid == 0) {
+        int result = execve(cgiPath, argp, envp);
+        slog(MISC_PRINT,SLOG_DEBUG, "content-type: text/html Execution of cgi process :%d", result);
+		exit (0);
+	} 
+
+DONE:
+	if (hstdout >= 0) {
+		dup2(hstdout, 1);
+      close(hstdout);
+	}
+	if (hstdin >= 0) {
+		dup2(hstdin, 0);
+      close(hstdin);
+	}
+	if (fdout >= 0) {
+		close(fdout);
+	}
+	if (fdin >= 0) {
+		close(fdin);
+	}
+	return rc;
+}
+
+int websCheckCgiProc(int handle, int *status)
+{
+	if (waitpid(handle, status, WNOHANG) == handle) {
+		return 0;
+	} else {
+		return 1;
+	}
+}
+
+static int i64c(int i)
+{
+	i &= 0x3f;
+	if (i == 0)
+		return '.';
+	if (i == 1)
+		return '/';
+	if (i < 12)
+		return ('0' - 2 + i);
+	if (i < 38)
+		return ('A' - 12 + i);
+	return ('a' - 38 + i);
+}
+
+static int web_make_salt(char *p, int cnt /*, int x */)
+{
+	/* was: x += ... */
+	int x = getpid() + (int)time(0);
+	do {
+		/* x = (x*1664525 + 1013904223) % 2^32 generator is lame
+		 * (low-order bit is not "random", etc...),
+		 * but for our purposes it is good enough */
+		x = x*1664525 + 1013904223;
+		/* BTW, Park and Miller's "minimal standard generator" is
+		 * x = x*16807 % ((2^31)-1)
+		 * It has no problem with visibly alternating lowest bit
+		 * but is also weak in cryptographic sense + needs div,
+		 * which needs more code (and slower) on many CPUs */
+		*p++ = i64c(x >> 16);
+		*p++ = i64c(x >> 22);
+	} while (--cnt);
+	*p = '\0';
+	return x;
+}
+
+int web_set_pwd(char *buf)
+{
+	if(buf == NULL)
+		return -1;
+	int bufLen = strlen(buf);
+	if(bufLen <= 0 || bufLen > LOGIN_PSW_MAX_LEN)
+		return -1;
+#ifdef WEBS_SSL_SUPPORT
+	char salt[LOGIN_PSW_MAX_LEN+1]={0};
+	web_make_salt(salt,(sizeof(salt)-1)/2);
+	slog(MISC_PRINT,SLOG_DEBUG, "[goahead]salt %s\n",salt);
+	unsigned char md[LOGIN_PSW_MAX_LEN] = {0};
+	{
+		unsigned char src[LOGIN_PSW_MAX_LEN*2+1] = {0};
+		memcpy(src,salt,LOGIN_PSW_MAX_LEN);
+		memcpy(src+LOGIN_PSW_MAX_LEN,buf,bufLen);
+		SHA256((const unsigned char *)src, bufLen+LOGIN_PSW_MAX_LEN, md);
+	}
+	{
+		char i = 0; 
+		char str_md[LOGIN_PSW_MAX_LEN*2+1] = {0};
+		for(i = 0; i < LOGIN_PSW_MAX_LEN; i++)
+		{
+			sprintf(str_md+i+i,"%02x", md[i]);
+		}
+		char psw_buf[100] = {0};
+		snprintf(psw_buf,sizeof(psw_buf),"%s%s",salt,str_md);
+		slog(MISC_PRINT,SLOG_DEBUG, "goahead]set_pw %s\n",psw_buf);
+		return cfg_set("admin_Password", psw_buf);
+	}
+#else
+	return cfg_set("admin_Password", buf);
+#endif
+}
+
+void web_init_pwd(void)
+{
+#ifdef WEBS_SSL_SUPPORT
+	char psw_buf[LOGIN_PSW_MAX_LEN*3+1] = {0};
+	cfg_get_item("admin_Password", psw_buf, sizeof(psw_buf));
+	slog(MISC_PRINT,SLOG_DEBUG, "[goahead]init_pw %s\n",psw_buf);
+	if(strlen(psw_buf) <= LOGIN_PSW_MAX_LEN)
+	{
+		web_set_pwd(psw_buf);
+	}
+#endif	
+}
+
+int web_check_pwd(char* buf)
+{
+	char psw_buf[LOGIN_PSW_MAX_LEN*3+1] = {0};
+	if(buf == NULL)
+		return -1;
+	int bufLen = strlen(buf);
+	if(bufLen <= 0 || bufLen > LOGIN_PSW_MAX_LEN)
+		return -1;
+	cfg_get_item("admin_Password", psw_buf, sizeof(psw_buf));
+	slog(MISC_PRINT,SLOG_DEBUG, "[goahead]check_pw in %s\n",buf);
+	slog(MISC_PRINT,SLOG_DEBUG, "[goahead]check_pw src %s\n",psw_buf);
+#ifdef WEBS_SSL_SUPPORT
+	unsigned char md[LOGIN_PSW_MAX_LEN] = {0};
+	{
+		unsigned char src[LOGIN_PSW_MAX_LEN*2+1] = {0};
+		memcpy(src,psw_buf,LOGIN_PSW_MAX_LEN);
+		memcpy(src+LOGIN_PSW_MAX_LEN,buf,bufLen);
+		SHA256((const unsigned char *)src, bufLen+LOGIN_PSW_MAX_LEN, md);
+	}
+	{
+		char i = 0;	
+		char str_md[65] = {0};
+		for(i = 0; i < LOGIN_PSW_MAX_LEN; i++)
+		{
+			sprintf(str_md+i+i,"%02x", md[i]);
+		}
+		return strncmp(str_md,psw_buf+LOGIN_PSW_MAX_LEN,sizeof(str_md)-1);
+	}
+#else
+	if(bufLen != strlen(psw_buf))
+		return -1;
+
+	return strncmp(buf,psw_buf,bufLen);;
+#endif
+}
+
+int web_make_salt_base64(char *buf, int len)
+{
+	int salt_len;
+	char *salt;
+	if(buf == NULL || len < 5)
+	{
+		return 0;
+	}
+	salt_len = (len - 1)/4*3;
+	salt = balloc(B_L, salt_len+1);
+	if(salt == NULL)
+	{
+		return 0;
+	}
+	web_make_salt(salt,salt_len/2);
+	websEncode64(buf, salt, len);
+	bfree(B_L, salt);
+	*(buf + len -1) = '\0';
+	slog(MISC_PRINT,SLOG_DEBUG, "[goahead]salt_base64=%s\n",buf);
+	return strlen(buf);
+}
+
diff --git a/lynq/S300AI/ap/app/goahead/server/webs.c b/lynq/S300AI/ap/app/goahead/server/webs.c
new file mode 100755
index 0000000..93d50e0
--- /dev/null
+++ b/lynq/S300AI/ap/app/goahead/server/webs.c
@@ -0,0 +1,2303 @@
+#include	"wsIntrn.h"
+#ifdef DIGEST_ACCESS_SUPPORT
+	#include	"websda.h"
+#endif
+#include "../interface5.0/zte_web_interface.h"
+//#include "../interface5.0/zte_rest_comm_interface.h"
+
+websStatsType	websStats;				
+webs_t			*webs;					
+sym_fd_t		websMime;				
+int				websMax;				
+int				websPort;				
+char_t			websHost[64];			
+char_t			websIpaddr[64];			
+char_t			*websHostUrl = NULL;	
+char_t			*websIpaddrUrl = NULL;	
+//added by liuyingnan for PC Client begin, 20120829
+char websRecvHttpBuffer[HTTP_BUFFER_SIZE] = {0};
+char websRecvHttpBuffer_XML[HTTP_BUFFER_SIZE] = {0};
+
+extern void zte_change_wp_query(webs_t wp,char_t *xml_str);
+//added by liuyingnan for PC Client begin, 20120829
+
+websErrorType websErrors[] = {
+	{ 200, T("Data follows") },
+	{ 204, T("No Content") },
+	{ 301, T("Redirect") },
+	{ 302, T("Redirect") },
+	{ 304, T("Use local copy") },
+	{ 400, T("Page not found") },
+	{ 401, T("Unauthorized") },
+	{ 403, T("Forbidden") },
+	{ 404, T("Site or Page Not Found") },
+	{ 405, T("Access Denied") },
+	{ 500, T("Web Error") },
+	{ 501, T("Not Implemented") },
+	{ 503, T("Site Temporarily Unavailable. Try again.") },
+	{ 0, NULL }
+};
+
+typedef enum { 
+	RET_DATA_ERROR = -1,
+	RET_FAILED = 0, 
+	RET_OK = 1, 
+} ERROR_CODE;
+
+
+#ifdef FEATURE_ZTE_WEB_TCARD
+//added by guo shoupeng 10124224 for http share 20111001 start
+
+typedef enum { 
+	RET_FAILED = 0, 
+	RET_OK = 1, 
+	RET_UNKNOWN = 3,	
+	MALLOC_FIALED = 4,
+	SD_NONE = 5,
+	USB_OUT = 6,
+	USER_MALLOC_FAILED = 7,
+	UPLOAD_FILE_LIMITED = 8,
+	USER_UNKNOWN = 9,	
+} ERROR_CODE;
+
+//added by guo shoupeng 10124224 for http share 20111001 end
+#endif
+
+
+
+static int 		websGetInput(webs_t wp, char_t **ptext, int *nbytes);
+static int 		websParseFirst(webs_t wp, char_t *text);
+static int 	websParseRequest(webs_t wp);
+static void		websSocketEvent(int sid, int mask, int data);
+static int		websGetTimeSinceMark(webs_t wp);
+
+static int		websListenSock;					
+static char_t	websRealm[64] = T("GoAhead");	
+
+static int		websOpenCount = 0;		
+
+
+int websOpenServer(int port, int retries)
+{
+	websMimeType	*mt;
+
+	if (++websOpenCount != 1) {
+		return websPort;
+	}
+
+	a_assert(port > 0);
+	a_assert(retries >= 0);
+
+	webs = NULL;
+	websMax = 0;
+
+	websMime = symOpen(WEBS_SYM_INIT * 4);
+	a_assert(websMime >= 0);
+	if(websMime < 0)  // cov M NEGATIVE_RETURNS
+	{
+	    return -1;
+	}
+	for (mt = websMimeList; mt->type; mt++) {
+		symEnter(websMime, mt->ext, valueString(mt->type, 0), 0);
+	}
+
+#if 1
+    // kw 3 INVARIANT_CONDITION.UNREACH websUrlHandlerOpen only return 0
+    websUrlHandlerOpen();
+#else
+	if (websUrlHandlerOpen() < 0) {
+		return -1;
+	}
+#endif	
+	websFormOpen();
+
+	return websOpenListen(port, retries);
+}
+
+
+
+void websCloseServer()
+{
+	webs_t	wp;
+	int		wid;
+
+	if (--websOpenCount > 0) {
+		return;
+	}
+
+	websCloseListen();
+
+	for (wid = websMax; webs && wid >= 0; wid--) {
+		if ((wp = webs[wid]) == NULL) {
+			continue;
+		}
+		socketCloseConnection(wp->sid);
+		websFree(wp);
+	}
+
+	symClose(websMime);
+	websFormClose();
+	websUrlHandlerClose();
+}
+
+
+void websCloseListen()
+{
+	if (websListenSock >= 0) {
+		socketCloseConnection(websListenSock);
+		websListenSock = -1;
+	}
+	bfreeSafe(B_L, websHostUrl);
+	bfreeSafe(B_L, websIpaddrUrl);
+	websIpaddrUrl = websHostUrl = NULL;
+}
+
+
+int websOpenListen(int port, int retries)
+{
+	int		i, orig;
+
+	a_assert(port > 0);
+	a_assert(retries >= 0);
+	
+	orig = port;
+
+	for (i = 0; i <= retries; i++) {
+		websListenSock = socketOpenConnection6(NULL, port, websAccept, 0);
+		if (websListenSock >= 0) {
+			break;
+		}
+		port++;
+	}
+	if (i > retries) {
+		error(E_L, E_USER, T("Couldn't open a socket on ports %d - %d"),
+			orig, port - 1);
+		return -1;
+	} 
+
+	websPort = port;
+	bfreeSafe(B_L, websHostUrl);
+	bfreeSafe(B_L, websIpaddrUrl);
+	websIpaddrUrl = websHostUrl = NULL;
+
+	if (port == 80) {
+		websHostUrl = bstrdup(B_L, websHost);
+		websIpaddrUrl = bstrdup(B_L, websIpaddr);
+	} else {
+		fmtAlloc(&websHostUrl, WEBS_MAX_URL + 80, T("%s:%d"), websHost, port);
+		fmtAlloc(&websIpaddrUrl, WEBS_MAX_URL + 80, T("%s:%d"), 
+			websIpaddr, port);
+	}
+	trace(0, T("webs: Listening for HTTP requests at address %s\n"),
+		websIpaddrUrl);
+
+	return port;
+}
+
+
+static void websSocketEvent(int sid, int mask, int iwp)
+{
+	webs_t	wp;
+
+	wp = (webs_t) iwp;
+	a_assert(wp);
+
+	if (! websValid(wp)) {
+		return;
+	}
+
+	if (mask & SOCKET_READABLE) {
+		websReadEvent(wp);
+	} 
+	if (mask & SOCKET_WRITABLE) {
+		if (websValid(wp) && wp->writeSocket) {
+			(*wp->writeSocket)(wp);
+		}
+	} 
+}
+
+int websAccept(int sid, char *ipaddr, int port, int listenSid)
+{
+	webs_t	wp;
+	int		wid;
+
+	a_assert(ipaddr && *ipaddr);
+	a_assert(sid >= 0);
+	a_assert(port >= 0);
+
+	if ((wid = websAlloc(sid)) < 0) {
+		return -1;
+	}
+	wp = webs[wid];
+	a_assert(wp);
+	wp->listenSid = listenSid;
+
+	ascToUni(wp->ipaddr, ipaddr, min(sizeof(wp->ipaddr), strlen(ipaddr) + 1));
+
+	if (gstrcmp(wp->ipaddr, T("127.0.0.1")) == 0 || 
+			gstrcmp(wp->ipaddr, websIpaddr) == 0 || 
+			gstrcmp(wp->ipaddr, websHost) == 0) {
+		wp->flags |= WEBS_LOCAL_REQUEST;
+	}
+
+	socketCreateHandler(sid, SOCKET_READABLE, websSocketEvent, (int) wp);
+
+	wp->timeout = emfSchedCallback(WEBS_TIMEOUT, websTimeout, (void *) wp);
+	//trace(8, T("webs: accept request\n"));
+	return 0;
+}
+
+
+
+#ifdef FEATURE_ZTE_WEB_TCARD
+//added by guo shoupeng 10124224 for http share 20120110 start
+static int read_bytes = 0;
+//added by guo shoupeng 10124224 for http share 20120110 end
+#endif
+
+void websReadEvent(webs_t wp)
+{
+	char_t 	*text;
+	int		rc, nbytes, len, done, fd;
+
+	a_assert(wp);
+	a_assert(websValid(wp));
+
+	websSetTimeMark(wp);
+	
+	static unsigned int timer = 0;
+
+	text = NULL;
+	fd = -1;
+	for (done = 0; !done; ) {
+		if (text) {
+			bfree(B_L, text);
+			text = NULL;
+		}
+
+
+#ifdef FEATURE_ZTE_WEB_TCARD
+//added by guo shoupeng 10124224 for http share 20120110 start
+		if( read_bytes > UPLOAD_INTERVAL)
+		{
+			read_bytes = 0;
+			break;
+		}
+//added by guo shoupeng 10124224 for http share 20120110 end
+#endif
+		assert(wp);
+		assert(websValid(wp));		
+		while ((rc = websGetInput(wp, &text, &nbytes)) == 0) {
+			;
+		}
+
+
+		if (rc < 0) {
+            if(websValid(wp) && (wp->flags & WEBS_CGI_REQUEST ))
+            {
+                //printf("\n +++sockettt upload websSetTimeMark+++ \n");
+                websSetTimeMark(wp);
+            }
+			break;
+		}
+		if(text == NULL)
+			break;//for kw
+
+		switch(wp->state) {
+		case WEBS_BEGIN:
+
+			if (websParseFirst(wp, text) < 0) {
+				done++;
+				break;
+			}
+			wp->state = WEBS_HEADER;
+			break;
+		
+		case WEBS_HEADER:
+
+			if (ringqLen(&wp->header) > 0) {
+				ringqPutStr(&wp->header, T("\n"));
+			}
+			ringqPutStr(&wp->header, text);
+			break;
+
+		case WEBS_POST_CLEN:
+
+#ifndef __NO_CGI_BIN
+			if (wp->flags & WEBS_CGI_REQUEST) {
+
+				//if(!(wp->flags & WEBS_CGI_FIRMWARE_UPLOAD))
+				if(wp->flags & WEBS_CGI_HTTPSHARE_UPLOAD)
+				{
+					if( timer ==0)
+                    {
+                        websSetLoginTimemark(wp);
+						printf("[httpshare]upload reset login state~\n");
+                    }
+					ERROR_CODE ret = zte_process_cgi_recv(wp, wp->clen,text, nbytes);	
+
+					if(RET_DATA_ERROR == ret || RET_FAILED == ret)
+					{												  
+						websError(wp, 404, T("Bad state"));
+						printf("[httpshare]ret->%d\n",ret);
+						done++; 						  
+						break;		  
+					} 
+					
+					timer++;
+					timer=timer-(timer>>11<<11);  //timer%2^11
+				}else if(wp->flags & WEBS_CGI_UPLOAD)
+				{
+					if (fd == -1) 
+					{
+						if(wp->flags & WEBS_CGI_FIRMWARE_UPLOAD )
+						{
+							fd = gopen(FIRMWARE_TMP_FILE, O_CREAT | O_WRONLY | O_BINARY | O_APPEND, 0666);
+							printf("[goahead]open cgi temp file\n");
+						}
+						else
+					  	{
+							fd = gopen(wp->cgiStdin, O_CREAT | O_WRONLY | O_BINARY | O_APPEND, 0666);
+	                    }
+					}
+                    if(fd < 0){
+                        break;
+					}
+						
+					
+					gwrite(fd, text, nbytes);
+				}else
+				{
+					websError(wp, 404, T("Bad state"));
+					printf("[goahead]bad cgi request\n");
+					done++; 						  
+					break;
+				}
+
+
+			} else 
+#endif
+			//added by liuyingnan for PC Client begin, 20120829
+            if(wp->flags & WEBS_REST_CLIENT_REQUEST){
+                printf("%s", "websReadEvent: pc client post");
+                if (nbytes > (HTTP_BUFFER_SIZE-gstrlen(websRecvHttpBuffer)-1))
+                {
+                    gstrncpy(websRecvHttpBuffer+gstrlen(websRecvHttpBuffer), text, HTTP_BUFFER_SIZE-gstrlen(websRecvHttpBuffer)-1);
+                }
+                else
+                {
+                    gstrncpy(websRecvHttpBuffer+gstrlen(websRecvHttpBuffer), text, nbytes);
+                }
+            } else  if(wp->flags & WEBS_XML_CLIENT_REQUEST){
+            if (nbytes > (HTTP_BUFFER_SIZE-gstrlen(websRecvHttpBuffer_XML)-1))
+            {
+                gstrncpy(websRecvHttpBuffer_XML+gstrlen(websRecvHttpBuffer_XML), text, HTTP_BUFFER_SIZE-gstrlen(websRecvHttpBuffer_XML)-1);
+            }
+            else
+            {
+                gstrncpy(websRecvHttpBuffer_XML+gstrlen(websRecvHttpBuffer_XML), text, nbytes);
+            }
+            } else    
+			//added by liuyingnan for PC Client end, 20120829
+
+
+
+			if (wp->query) {
+				if (wp->query[0] && !(wp->flags & WEBS_POST_DATA)) {
+
+					len = gstrlen(wp->query);
+					wp->query = brealloc(B_L, wp->query, (len + gstrlen(text) +
+						2) * sizeof(char_t));
+					if(wp->query == NULL)
+						break;//for kw
+					wp->query[len++] = '&';
+					gstrcpy(&wp->query[len], text);
+
+				} else {
+
+               //if (text != NULL)//for kw
+               {
+                  len = gstrlen(wp->query);
+                  wp->query = brealloc(B_L, wp->query, (len +	gstrlen(text) +
+                     1) * sizeof(char_t));
+                  if (wp->query) {
+                     gstrcpy(&wp->query[len], text);
+                  }
+               }
+				}
+
+			} else {
+				wp->query = bstrdup(B_L, text);
+			}
+#if 0 //for kw			
+            //Add By liuyingnan for XML COMM API START
+            if(wp->flags & WEBS_XML_CLIENT_REQUEST)
+            {
+                slog(MISC_PRINT,SLOG_DEBUG,"[websReadEvent]:zte_change_wp_query function:%s\n",websRecvHttpBuffer_XML);
+                //zte_change_wp_query(wp,websRecvHttpBuffer_Json);
+                zte_change_wp_query(wp,websRecvHttpBuffer_XML);
+                memset(websRecvHttpBuffer_XML,0,HTTP_BUFFER_SIZE);
+                slog(MISC_PRINT,SLOG_DEBUG,"[out the function]:wp->query:%s\n",wp->query);
+            } 
+            //Add By liuyingnan for XML COMM API END
+#endif
+            
+			wp->flags |= WEBS_POST_DATA;
+			wp->clen -= nbytes;
+			if (wp->clen > 0) {
+				if (nbytes > 0) {
+					break;
+				}
+				done++;
+				break;
+			}
+#ifdef FEATURE_ZTE_WEB_TCARD
+//added by guo shoupeng 10124224 for http share 20120110 start
+			else
+			{
+			    zte_efs_write(wp);
+			}
+//added by guo shoupeng 10124224 for http share 20120110 end
+#endif	
+
+			if (fd != -1) {
+				gclose (fd);
+				fd = -1;
+			}
+			websUrlHandlerRequest(wp);
+			done++;
+			break;
+
+		case WEBS_POST:
+
+
+#ifndef __NO_CGI_BIN
+			if (wp->flags & WEBS_CGI_REQUEST) {
+				if (fd == -1) {
+					fd = gopen(wp->cgiStdin, O_CREAT | O_WRONLY | O_BINARY,
+						0666);
+				}
+
+				if(fd < 0){
+                    break;
+				}
+				gwrite(fd, text, gstrlen(text));
+				gwrite(fd, T("\n"), sizeof(char_t));
+			} else
+#endif
+			if (wp->query && *wp->query && !(wp->flags & WEBS_POST_DATA)) {
+				len = gstrlen(wp->query);
+				wp->query = brealloc(B_L, wp->query, (len + gstrlen(text) +
+					2) * sizeof(char_t));
+				if (wp->query) {
+					wp->query[len++] = '&';
+					gstrcpy(&wp->query[len], text);
+				}
+
+			} else {
+				wp->query = bstrdup(B_L, text);
+			}
+			wp->flags |= WEBS_POST_DATA;
+			done++;
+			break;
+
+		default:
+			websError(wp, 404, T("Bad state"));
+			done++;
+			break;
+		}
+	}
+
+	if (fd != -1) {
+		fd = gclose (fd);
+	}
+
+	if (text) {
+		bfree(B_L, text);
+	}
+}
+char_t	htmExt[] = T(".htm");
+int websUrlParse(char_t *url, char_t **pbuf, char_t **phost, char_t **ppath, 
+	char_t **pport, char_t **pquery, char_t **pproto, char_t **ptag, 
+	char_t **pext)
+{
+	char_t		*hostbuf, *portbuf, *buf;
+	int			c, len, ulen;
+	char_t		*tok, *cp, *host, *path, *port, *proto, *tag, *query, *ext;
+
+	a_assert(url);
+	a_assert(pbuf);
+
+	ulen = gstrlen(url);
+
+	len = ulen * 2 + MAX_PORT_LEN + 3;
+	if ((buf = balloc(B_L, len * sizeof(char_t))) == NULL) {
+		return -1;
+	}
+	portbuf = &buf[len - MAX_PORT_LEN - 1];
+	hostbuf = &buf[ulen+1];
+
+ 	websDecodeUrl(buf, url, ulen);
+
+	url = buf;
+
+	if(portbuf == NULL) //for kw 20210312
+		return -1;
+	
+	stritoa(websGetPort(), portbuf, MAX_PORT_LEN);
+	port = portbuf;
+	path = T("/");
+	proto = T("http");
+	host = T("localhost");
+	query = T("");
+	ext = htmExt;
+	tag = T("");
+
+	if (gstrncmp(url, T("http://"), 7) == 0) {
+		tok = &url[7];
+		tok[-3] = '\0';
+		proto = url;
+		host = tok;
+		for (cp = tok; *cp; cp++) {
+			if (*cp == '/') {
+				break;
+			}
+			if (*cp == ':') {
+				*cp++ = '\0';
+				port = cp;
+				tok = cp;
+			}
+		}
+		if ((cp = gstrchr(tok, '/')) != NULL) {
+
+			c = *cp;
+			*cp = '\0';
+			gstrncpy(hostbuf, host, ulen);
+			gstrncpy(portbuf, port, MAX_PORT_LEN);
+			*cp = c;
+			host = hostbuf;
+			port = portbuf;
+			path = cp;
+			tok = cp;
+		}
+
+	} else {
+		path = url;
+		tok = url;
+	}
+
+	if ((cp = gstrchr(tok, '?')) != NULL) {
+		*cp++ = '\0';
+		query = cp;
+		path = tok;
+		tok = query;
+	} 
+
+	if ((cp = gstrchr(tok, '#')) != NULL) {
+		*cp++ = '\0';
+		if (*query == 0) {
+			path = tok;
+		}
+	}
+
+	if (pext) {
+
+		if ((cp = gstrrchr(path, '.')) != NULL) {
+			const char_t* garbage = T("/\\");
+			int length = gstrcspn(cp, garbage);
+			int garbageLength = gstrspn(cp + length, garbage);
+			int ok = (length + garbageLength == (int) gstrlen(cp));
+
+			if (ok) {
+				cp[length] = '\0';
+				ext = cp;
+			}
+		}
+	}
+
+	if (phost)
+		*phost = host;
+	if (ppath)
+		*ppath = path;
+	if (pport)
+		*pport = port;
+	if (pproto)
+		*pproto = proto;
+	if (pquery)
+		*pquery = query;
+	if (ptag)
+		*ptag = tag;
+	if (pext)
+		*pext = ext;
+	*pbuf = buf;
+	return 0;
+}
+
+char_t *websUrlType(char_t *url, char_t *buf, int charCnt)
+{
+	char_t	*ext = NULL; //cov
+	char_t	*tmp_buf;
+	sym_t	*psym;
+
+	a_assert(url && *url);
+	a_assert(buf && charCnt > 0);
+
+	if (url == NULL || *url == '\0') {
+		gstrcpy(buf, T("text/plain"));
+		return buf;
+	}
+	if (websUrlParse(url, &tmp_buf, NULL, NULL, NULL, NULL, NULL, 
+			NULL, &ext) < 0) {
+		gstrcpy(buf, T("text/plain"));
+		return buf;
+	}
+	strlower(ext);
+
+	if ((psym = symLookup(websMime, ext)) != NULL) {
+		gstrncpy(buf, psym->content.value.string, charCnt);
+	} else {
+		gstrcpy(buf, T("text/plain"));
+	}
+	bfree(B_L, tmp_buf);
+	return buf;
+}
+
+static int websParseFirst(webs_t wp, char_t *text)
+{
+	char_t 	*op, *proto, *protoVer, *url, *host, *query, *path, *port, *ext;
+	char_t	*buf;
+	int		testPort;
+
+#ifdef FEATURE_ZTE_WEB_TCARD
+//added by guo shoupeng 10124224 for http share 20111001 start
+	char *page_att=NULL;
+//added by guo shoupeng 10124224 for http share 20111001 end
+#endif
+	a_assert(websValid(wp));
+	a_assert(text && *text);
+#ifdef WEBINSPECT_FIX	
+	if(text && (!is_print_str(text,strlen(text)) || strstr(text, "HTTP") == NULL))
+	{
+		websDone(wp, 0);
+		slog(MISC_PRINT, SLOG_ERR,"[goahead]es\n");
+		return -1;
+	}
+#endif
+	op = gstrtok(text, T(" \t"));
+	if (op == NULL || *op == '\0') {
+		websError(wp, 400, T("Bad HTTP request"));
+		return -1;
+	}
+	if (gstrcmp(op, T("GET")) != 0) {
+		if (gstrcmp(op, T("POST")) == 0) {
+			wp->flags |= WEBS_POST_REQUEST;
+		} else if (gstrcmp(op, T("HEAD")) == 0) {
+			wp->flags |= WEBS_HEAD_REQUEST;
+		} else {
+			websError(wp, 400, T("Bad request type"));
+			return -1;
+		}
+	}
+
+	websSetVar(wp, T("REQUEST_METHOD"), op);
+
+	url = gstrtok(NULL, T(" \t\n"));
+	if (url == NULL || *url == '\0') {
+		websError(wp, 400, T("Bad HTTP request"));
+		return -1;
+	}
+	protoVer = gstrtok(NULL, T(" \t\n"));
+
+	host = path = port = proto = query = ext = NULL;
+	if (websUrlParse(url, &buf, &host, &path, &port, &query, &proto, 
+			NULL, &ext) < 0) {
+		websError(wp, 400, T("Bad URL format"));
+		return -1;
+	}
+
+	wp->url = bstrdup(B_L, url);
+
+#ifndef __NO_CGI_BIN
+
+
+	if ((gstrstr(url, CGI_BIN) != NULL)&&((wp->flags & WEBS_POST_REQUEST))) {
+		wp->flags |= WEBS_CGI_REQUEST;
+		
+		printf("[goahead]set WEBS_CGI_REQUEST \n");
+
+		// special case: upload.cgi
+		
+		if(gstrstr(url, CGI_BIN_UPLOAD) != NULL)
+		{
+			if(gstrstr(url, CGI_FIRMWARE_UPLOAD) != NULL){
+				wp->flags |= WEBS_CGI_FIRMWARE_UPLOAD;
+				system("rm -rf /tmp/firmware_tmp_file");
+				zte_mgmt_login_timemark_set();
+				printf("[goahead]set WEBS_CGI_FIRMWARE_UPLOAD \n");
+			}
+			wp->cgiStdin = websGetCgiCommName(wp);
+			printf("[goahead]get cgi name.\n");
+			// ex: upload_setting....
+			wp->flags |= WEBS_CGI_UPLOAD;
+		}
+
+		if(gstrstr(url, CGI_BIN_HTTPSHARE) != NULL)
+		{
+			printf("[httpshare]upload file.\n"); 
+
+			if(!zte_reset_cgi_state(wp))	
+			{
+				printf("[httpshare]upload file.reset cgi state error.\n");
+				bfree(B_L, buf);
+				return -1;
+			}
+			wp->flags |= WEBS_CGI_HTTPSHARE_UPLOAD;
+		}
+	            
+
+	}
+#endif
+
+	wp->query = bstrdup(B_L, query);
+	wp->host = bstrdup(B_L, host);
+	wp->path = bstrdup(B_L, path);
+	wp->protocol = bstrdup(B_L, proto);
+	wp->protoVersion = bstrdup(B_L, protoVer);
+	
+	//added by liuyingnan for PC Client begin, 20120829
+    if (gstrstr(url, "api/client/post") != NULL) {
+        printf("%s", "websParseFirst: pc client post");
+        wp->flags |= WEBS_REST_CLIENT_REQUEST;
+    }
+    //added by huangmin for PC Client end, 20120829
+    if (gstrstr(url, "api/xmlclient/post") != NULL) {
+        wp->flags |= WEBS_XML_CLIENT_REQUEST;
+    }
+	
+	if ((testPort = socketGetPort(wp->listenSid)) >= 0) {
+		wp->port = testPort;
+	} else {
+		wp->port = gatoi(port);
+	}
+
+	if (gstrcmp(ext, T(".asp")) == 0) {
+		wp->flags |= WEBS_ASP;
+	}
+	bfree(B_L, buf);
+
+	websUrlType(url, wp->type, TSZ(wp->type));
+
+	ringqFlush(&wp->header);
+	return 0;
+}
+
+static int websGetInput(webs_t wp, char_t **ptext, int *pnbytes) 
+{
+	char_t	*text;
+	char	buf[WEBS_SOCKET_BUFSIZ+1];
+	int		nbytes, len, clen;
+
+	a_assert(websValid(wp));
+	a_assert(ptext);
+	a_assert(pnbytes);
+
+	if(websValid(wp) == 0 || ptext == NULL || pnbytes == NULL){
+		softap_assert("websGetInput 1");
+		return -1;//for kw
+	}
+
+	*ptext = text = NULL;
+	*pnbytes = 0;
+
+	if (wp->state == WEBS_POST_CLEN) {
+		len = (wp->clen > WEBS_SOCKET_BUFSIZ) ? WEBS_SOCKET_BUFSIZ : wp->clen;
+	} else {
+		len = 0;
+	}
+
+	if (len > 0) {
+
+#ifdef WEBS_SSL_SUPPORT
+		if (wp->flags & WEBS_SECURE) {
+			nbytes = websSSLRead(wp->wsp, buf, len);
+		} else {
+			nbytes = socketRead(wp->sid, buf, len);
+		}
+#else
+		nbytes = socketRead(wp->sid, buf, len);
+#endif
+		if (nbytes < 0) {						/* Error */
+			websDone(wp, 0);
+			return -1;
+
+		}  else if (nbytes == 0) {				/* EOF or No data available */
+			//trace(8, T("@@@@webs 0x%x 0x%x: websGetInput read 0\n"),wp,wp->sid);
+			if (socketEof(wp->sid)) {
+				websDone(wp, 0);
+			}
+			return -1;
+
+		} else {								/* Valid data */
+
+			buf[nbytes] = '\0';
+			if ((text = ballocAscToUni(buf, nbytes)) == NULL) {
+				websError(wp, 503, T("Insufficient memory"));
+				return -1;
+			}
+		}
+
+	} else {
+#ifdef WEBS_SSL_SUPPORT
+		if (wp->flags & WEBS_SECURE) {
+			nbytes = websSSLGets(wp->wsp, &text);
+		} else {
+			nbytes = socketGets(wp->sid, &text);
+		}
+#else
+		nbytes = socketGets(wp->sid, &text);
+#endif
+
+		if (nbytes < 0) {
+			int eof;
+
+#ifdef WEBS_SSL_SUPPORT
+			if (wp->flags & WEBS_SECURE) {
+
+				if (wp->state == WEBS_BEGIN) {
+					eof = 1;
+				} else {
+					eof = websSSLEof(wp->wsp);
+				}
+			} else {
+				eof = socketEof(wp->sid);
+			}
+#else
+			eof = socketEof(wp->sid);
+#endif
+
+			if (eof) {
+
+				if (wp->state == WEBS_POST) {
+					websUrlHandlerRequest(wp);
+				} else {
+					websDone(wp, 0);
+				}
+			} else {
+					trace(8, T("@@@@webs 0x%x 0x%x: websGetInput no eof\n"),wp,wp->sid);
+
+#if 1//def HP_FIX
+				websDone(wp, 0);
+#endif /*HP_FIX*/
+
+			}
+
+#if 0 //def UNUSED
+			if (wp->state == WEBS_HEADER && ringqLen(&wp->header) <= 0) {
+				websParseRequest(wp);
+				websUrlHandlerRequest(wp);
+			}
+#endif
+			bfreeSafe(B_L,text);//for kw
+			return -1;
+
+		} else if (nbytes == 0) {
+			if (wp->state == WEBS_HEADER) {
+
+				if(websParseRequest(wp) != 0){
+					return -1;
+				}
+				if (wp->flags & WEBS_POST_REQUEST) {
+					if (wp->flags & WEBS_CLEN) {
+						wp->state = WEBS_POST_CLEN;
+						clen = wp->clen;
+					} else {
+						wp->state = WEBS_POST;
+						clen = 1;
+					}
+					if (clen > 0) {
+
+						return 0;
+					}
+					return 1;
+				}
+
+				websUrlHandlerRequest(wp);
+			}
+			return -1;
+		}
+	}
+
+//	if(text == NULL || nbytes <= 0){ // kw 3 nbytes <= 0 already return
+    if(text == NULL){
+		softap_assert("websGetInput 2");
+	}
+	a_assert(text);
+	a_assert(nbytes > 0);
+	*ptext = text;
+	*pnbytes = nbytes;
+	return 1;
+}
+
+
+#define isgoodchar(s) (gisalnum((s)) || ((s) == '/') || ((s) == '_') || \
+						((s) == '.')  || ((s) == '-') )
+
+static int websParseRequest(webs_t wp)
+{
+	char_t	*authType, *upperKey, *cp, *browser, *lp, *key, *value;
+	int smugglingFlag = 0;
+	a_assert(websValid(wp));
+
+	websSetVar(wp, T("HTTP_AUTHORIZATION"), T(""));
+
+	browser = NULL;
+	char tmp[4] = T("");
+	for (lp = (char_t*) wp->header.servp; lp && *lp; ) {
+		cp = lp;
+		if ((lp = gstrchr(lp, '\n')) != NULL) {
+			lp++;
+		}
+
+		if ((key = gstrtok(cp, T(": \t\n"))) == NULL) {
+			continue;
+		}
+
+		if ((value = gstrtok(NULL, T("\n"))) == NULL) {
+			//value = T("");
+			value = tmp;// kw OVERWRITE_CONST_CHAR
+		}
+
+		while (gisspace(*value)) {
+			value++;
+		}
+		strlower(key);
+
+		fmtAlloc(&upperKey, (gstrlen(key) + 6), T("HTTP_%s"), key);
+		for (cp = upperKey; *cp; cp++) {
+			if (*cp == '-')
+				*cp = '_';
+		}
+		strupper(upperKey);
+		websSetVar(wp, upperKey, value);
+		bfree(B_L, upperKey);
+
+		if (gstrcmp(key, T("user-agent")) == 0) {
+			if (wp->userAgent)
+				bfree(B_L, wp->userAgent);
+			wp->userAgent = bstrdup(B_L, value);
+
+		} else if (gstricmp(key, T("authorization")) == 0) {
+
+			authType = bstrdup (B_L, value);
+			a_assert (authType);
+
+			cp = authType;
+			while (gisalpha(*cp)) {
+				cp++;
+			}
+			*cp = '\0';
+			if (wp->authType)
+				bfree(B_L, wp->authType);
+			wp->authType = bstrdup(B_L, authType);
+			bfree(B_L, authType);
+
+			if (gstricmp(wp->authType, T("basic")) == 0) {
+				char_t	userAuth[FNAMESIZE];
+
+				if ((cp = gstrchr(value, ' ')) != NULL) {
+					*cp = '\0';
+
+               bfree(B_L, wp->authType);
+					wp->authType = bstrdup(B_L, value);
+					websDecode64(userAuth, ++cp, sizeof(userAuth));
+				} else {
+					websDecode64(userAuth, value, sizeof(userAuth));
+				}
+
+				if ((cp = gstrchr(userAuth, ':')) != NULL) {
+					*cp++ = '\0';
+				}
+				if (wp->password)
+					bfree(B_L, wp->password);
+				if (wp->userName)
+					bfree(B_L, wp->userName);
+				if (cp) {
+					wp->userName = bstrdup(B_L, userAuth);
+					wp->password = bstrdup(B_L, cp);
+				} else {
+					wp->userName = bstrdup(B_L, T(""));
+					wp->password = bstrdup(B_L, T(""));
+				}
+
+				wp->flags |= WEBS_AUTH_BASIC;
+			} else {
+#ifdef DIGEST_ACCESS_SUPPORT
+
+				char_t *np;		
+				char_t tp;		
+				char_t *vp;		
+				char_t *npv;	
+				char_t tpv;		
+
+				wp->flags |= WEBS_AUTH_DIGEST;
+
+ 				cp = value;
+				while (isgoodchar(*cp)) {
+					cp++;
+				}
+				while (!isgoodchar(*cp)) {
+					cp++;
+				}
+
+
+				vp = gstrchr(cp, '=');
+				while (vp) {
+
+					np = cp;
+					while (isgoodchar(*np)) {
+						np++;
+					}
+					tp = *np;
+					*np = 0;
+
+					vp++;
+					while (!isgoodchar(*vp)) {
+						vp++;
+					}
+
+					npv = vp;
+					while (isgoodchar(*npv)) {
+						npv++;
+					}
+					tpv = *npv;
+					*npv = 0;
+
+					if (gstricmp(cp, T("username")) == 0) {
+						wp->userName = bstrdup(B_L, vp);
+					} else if (gstricmp(cp, T("response")) == 0) {
+						wp->digest = bstrdup(B_L, vp);
+					} else if (gstricmp(cp, T("opaque")) == 0) {
+						wp->opaque = bstrdup(B_L, vp);
+					} else if (gstricmp(cp, T("uri")) == 0) {
+						wp->uri = bstrdup(B_L, vp);
+					} else if (gstricmp(cp, T("realm")) == 0) {
+						wp->realm = bstrdup(B_L, vp);
+					} else if (gstricmp(cp, T("nonce")) == 0) {
+						wp->nonce = bstrdup(B_L, vp);
+					} else if (gstricmp(cp, T("nc")) == 0) {
+						wp->nc = bstrdup(B_L, vp);
+					} else if (gstricmp(cp, T("cnonce")) == 0) {
+						wp->cnonce = bstrdup(B_L, vp);
+					} else if (gstricmp(cp, T("qop")) == 0) {
+						wp->qop = bstrdup(B_L, vp);
+					}
+
+					*np = tp;
+					*npv = tpv;
+
+ 					cp = npv;
+					while (*cp && isgoodchar(*cp)) {
+						cp++;
+					}
+					while (*cp && !isgoodchar(*cp)) {
+						cp++;
+					}
+
+					if (*cp) {
+						vp = gstrchr(cp, '=');
+					} else {
+						vp = NULL;
+					}
+				}
+#endif /* DIGEST_ACCESS_SUPPORT */
+			} /* if (gstrcmp(wp->authType)) */
+#ifdef WEBS_SECURITY
+		} else if (gstrcmp(key, T("x-http-method")) == 0) {
+			printf("websParseRequest: key=%s\n",key);
+			websError(wp, 405, T(""));
+			return -1;
+		} else if (gstrcmp(key, T("x-http-method-override")) == 0) {
+			printf("websParseRequest: key=%s\n",key);
+			websError(wp, 405, T(""));
+			return -1;
+		} else if (gstrcmp(key, T("x-method-override")) == 0) {
+			printf("websParseRequest: key=%s\n",key);
+			websError(wp, 405, T(""));
+			return -1;
+		} else if (gstrcmp(key, T("transfer-encoding")) == 0) {
+			printf("websParseRequest: key=%s\n",key);
+			if(smugglingFlag) {
+				websError(wp, 403, T(""));
+				return -1;
+			}
+			smugglingFlag = 1;
+#endif
+
+		} else if (gstrcmp(key, T("content-length")) == 0) {
+
+#ifdef WEBS_SECURITY
+		 if(smugglingFlag) {
+			 websError(wp, 403, T(""));
+			 return -1;
+		 }
+		 smugglingFlag = 1;
+#endif		 
+         wp->clen = gatoi(value);
+         if (wp->clen > 0)
+         {
+			   wp->flags |= WEBS_CLEN;			
+			   websSetVar(wp, T("CONTENT_LENGTH"), value);
+         }
+         else
+         {
+            wp->clen = 0;
+         }
+
+		} else if (gstrcmp(key, T("content-type")) == 0) {
+			websSetVar(wp, T("CONTENT_TYPE"), value);
+
+#ifdef WEBS_KEEP_ALIVE_SUPPORT
+		} else if (gstrcmp(key, T("connection")) == 0) {
+			strlower(value);
+			if (gstrcmp(value, T("keep-alive")) == 0) {
+				wp->flags |= WEBS_KEEP_ALIVE;
+			}
+#endif
+
+#ifdef WEBS_PROXY_SUPPORT
+
+		} else if (gstrcmp(key, T("pragma")) == 0) {
+			char_t	tmp[256];
+			gstrncpy(tmp, value, TSZ(tmp));
+			strlower(tmp);
+			if (gstrstr(tmp, T("no-cache"))) {
+				wp->flags |= WEBS_DONT_USE_CACHE;
+			}
+#endif /* WEBS_PROXY_SUPPORT */
+
+
+		} else if (gstrcmp(key, T("cookie")) == 0) {
+			wp->flags |= WEBS_COOKIE;
+			if (wp->cookie)
+				bfree(B_L, wp->cookie);
+			wp->cookie = bstrdup(B_L, value);
+		} else if (gstrcmp(key, T("referer")) == 0) {
+			if (wp->referer)
+				bfree(B_L, wp->referer);
+			wp->referer = bstrdup(B_L, value);
+
+		}
+	}
+	return 0;
+}
+
+
+int websTestVar(webs_t wp, char_t *var)
+{
+	sym_t		*sp;
+
+	a_assert(websValid(wp));
+
+	if (var == NULL || *var == '\0') {
+		return 0;
+	}
+
+	if ((sp = symLookup(wp->cgiVars, var)) == NULL) {
+		return 0;
+	}
+	return 1;
+}
+
+void websSetVar(webs_t wp, char_t *var, char_t *value)
+{
+	value_t		 v;
+
+	a_assert(websValid(wp));
+
+	if (value) {
+		v = valueString(value, VALUE_ALLOCATE);
+	} else {
+		v = valueString(T(""), VALUE_ALLOCATE);
+	}
+	symEnter(wp->cgiVars, var, v, 0);
+}
+
+
+void websSetEnv(webs_t wp)
+{
+	char_t	portBuf[8];
+	char_t	*keyword, *value, *valCheck, *valNew;
+
+	a_assert(websValid(wp));
+
+	websSetVar(wp, T("QUERY_STRING"), wp->query);
+	websSetVar(wp, T("GATEWAY_INTERFACE"), T("CGI/1.1"));
+	websSetVar(wp, T("SERVER_HOST"), websHost);
+	websSetVar(wp, T("SERVER_NAME"), websHost);
+	websSetVar(wp, T("SERVER_URL"), websHostUrl);
+	websSetVar(wp, T("REMOTE_HOST"), wp->ipaddr);
+	websSetVar(wp, T("REMOTE_ADDR"), wp->ipaddr);
+	websSetVar(wp, T("PATH_INFO"), wp->path);
+	stritoa(websPort, portBuf, sizeof(portBuf));
+	websSetVar(wp, T("SERVER_PORT"), portBuf);
+	websSetVar(wp, T("SERVER_ADDR"), websIpaddr);
+	fmtAlloc(&value, FNAMESIZE, T("%s/%s"), WEBS_NAME, WEBS_VERSION);
+	websSetVar(wp, T("SERVER_SOFTWARE"), value);
+	bfreeSafe(B_L, value);
+	websSetVar(wp, T("SERVER_PROTOCOL"), wp->protoVersion);
+
+	wp->decodedQuery = bstrdup(B_L, wp->query);
+	keyword = gstrtok(wp->decodedQuery, T("&"));
+	char tmp[4] = T("");
+	while (keyword != NULL) {
+		if ((value = gstrchr(keyword, '=')) != NULL) {
+			*value++ = '\0';
+			websDecodeUrl(keyword, keyword, gstrlen(keyword));
+			websDecodeUrl(value, value, gstrlen(value));
+		} else {
+			//value = T("");
+			value = tmp;// kw OVERWRITE_CONST_CHAR
+		}
+
+		if (*keyword) {
+
+			if ((valCheck = websGetVar(wp, keyword, NULL)) != 0) {
+				fmtAlloc(&valNew, 256, T("%s %s"), valCheck, value);
+				websSetVar(wp, keyword, valNew);
+				bfreeSafe(B_L, valNew);
+			} else {
+				websSetVar(wp, keyword, value);
+			}
+		}
+		keyword = gstrtok(NULL, T("&"));
+	}
+
+#ifdef EMF
+
+	websSetEmfEnvironment(wp);
+#endif
+}
+
+
+int websCompareVar(webs_t wp, char_t *var, char_t *value)
+{
+	a_assert(websValid(wp));
+	a_assert(var && *var);
+ 
+	if (gstrcmp(value, websGetVar(wp, var, T(" __UNDEF__ "))) == 0) {
+		return 1;
+	}
+	return 0;
+}
+
+char_t *websGetVar(webs_t wp, char_t *var, char_t *defaultGetValue)
+{
+	sym_t	*sp;
+
+	a_assert(websValid(wp));
+	a_assert(var && *var);
+ 
+	if ((sp = symLookup(wp->cgiVars, var)) != NULL) {
+		a_assert(sp->content.type == string);
+		if (sp->content.value.string) {
+			return sp->content.value.string;
+		} else {
+			return T("");
+		}
+	}
+	return defaultGetValue;
+}
+
+
+void websResponse(webs_t wp, int code, char_t *message, char_t *redirect)
+{
+	char_t		*date;
+
+	a_assert(websValid(wp));
+
+	wp->flags &= ~WEBS_KEEP_ALIVE;
+
+	if ( !(wp->flags & WEBS_HEADER_DONE)) {
+		wp->flags |= WEBS_HEADER_DONE;
+
+		if (redirect != NULL) {
+			websWrite(wp, T("HTTP/1.0 %d %s\r\n"), code, websErrorMsg(code));
+		} else {
+			websWrite(wp, T("HTTP/1.1 %d %s\r\n"), code, websErrorMsg(code));
+		}
+
+
+		websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);
+
+		if ((date = websGetDateString(NULL)) != NULL) {
+			websWrite(wp, T("Date: %s\r\n"), date);
+			bfree(B_L, date);
+		}
+
+		if (code == 401) {
+			if (!(wp->flags & WEBS_AUTH_DIGEST)) {
+				websWrite(wp, T("WWW-Authenticate: Basic realm=\"%s\"\r\n"), 
+					websGetRealm());
+#ifdef DIGEST_ACCESS_SUPPORT
+			} else {
+				char_t *nonce, *opaque;
+
+            /* $$$ before... (note commas instead of semicolons...)
+				nonce = websCalcNonce(wp), 
+				opaque = websCalcOpaque(wp), 
+            $$$ after */
+				nonce = websCalcNonce(wp);
+				opaque = websCalcOpaque(wp); 
+            /* ...$$$ end */
+				websWrite(wp, 
+					T("WWW-Authenticate: Digest realm=\"%s\", domain=\"%s\",")
+					T("qop=\"%s\", nonce=\"%s\", opaque=\"%s\",")
+					T("algorithm=\"%s\", stale=\"%s\"\r\n"), 
+					websGetRealm(),
+					websGetHostUrl(),
+					T("auth"),
+					nonce,
+					opaque, T("MD5"), T("FALSE"));
+				bfree(B_L, nonce);
+				bfree(B_L, opaque);
+#endif
+			}
+		}
+
+		if (wp->flags & WEBS_KEEP_ALIVE) {
+			websWrite(wp, T("Connection: keep-alive\r\n"));
+		}
+#ifdef WEBINSPECT_FIX
+		websWrite(wp, T("X-Frame-Options: SAMEORIGIN\r\n"));
+#endif
+		websWrite(wp, T("Pragma: no-cache\r\nCache-Control: no-cache\r\n"));
+		websWrite(wp, T("Content-Type: text/html\r\n"));
+
+		if (redirect) {
+			websWrite(wp, T("Location: %s\r\n"), redirect);
+		}
+		websWrite(wp, T("\r\n"));
+	}
+
+
+	if ((wp->flags & WEBS_HEAD_REQUEST) == 0 && message && *message) {
+		websWrite(wp, T("%s\r\n"), message);
+	}
+	websDone(wp, code);
+}
+
+void websTimeoutCancel(webs_t wp)
+{
+	a_assert(websValid(wp));
+
+	if (wp->timeout >= 0) {
+		emfUnschedCallback(wp->timeout);
+		wp->timeout = -1;
+	}
+}
+
+void websRedirect(webs_t wp, char_t *url)
+{
+	char_t	*msgbuf, *urlbuf, *redirectFmt;
+
+	a_assert(websValid(wp));
+	a_assert(url);
+
+	websStats.redirects++;
+	msgbuf = urlbuf = NULL;
+	
+	if (gstrstr(url, T("%0D")) || gstrstr(url, T("%0A")) 
+		|| gstrstr(url, T("%0d")) || gstrstr(url, T("%0a"))
+		|| gstrstr(url, T("\r")) || gstrstr(url, T("\n"))) {
+		printf("[goahead]Redirect injo %s\n",url);
+		url = T(ZTE_WEB_PAGE_LOGIN_NAME);
+		/*ÓÃÓÚÖØ¶¨ÏòµÄÊäÈë²ÎÊý²»Äܰüº¬»Ø³µºÍ»»ÐÐ×Ö·û£¬ÒÔ·ÀÖ¹HTTPÏìÓ¦²ð·Ö¹¥»÷*/
+	}
+
+
+	if (gstrstr(url, T("http://")) == NULL && gstrstr(url, T("https://")) == NULL) {
+		if (*url == '/') {
+			url++;
+		}
+
+		//redirectFmt = T("http://%s/%s");
+
+#ifdef WEBS_SSL_SUPPORT
+		//if (wp->flags & WEBS_SECURE) {			
+		if (websSSLIsOpen()) {
+			//redirectFmt = T("https://%s/%s");// kw OVERWRITE_CONST_CHAR
+			fmtAlloc(&urlbuf, WEBS_MAX_URL + 80, "https://%s/%s",
+				websGetVar(wp, T("HTTP_HOST"),	websHostUrl), url);
+		}
+		else
+#endif
+		{
+			fmtAlloc(&urlbuf, WEBS_MAX_URL + 80, "http://%s/%s",
+				websGetVar(wp, T("HTTP_HOST"), 	websHostUrl), url);
+		}
+		url = urlbuf;
+		printf("[goahead]Redirect %s\n",url);
+	}
+
+
+	fmtAlloc(&msgbuf, WEBS_MAX_URL + 80, 
+		T("<html><head></head><body>\r\n\
+		This document has moved to a new <a href=\"%s\">location</a>.\r\n\
+		Please update your documents to reflect the new location.\r\n\
+		</body></html>\r\n"), url);
+
+	websResponse(wp, 302, msgbuf, url);
+
+	bfreeSafe(B_L, msgbuf);
+	bfreeSafe(B_L, urlbuf);
+}
+
+static int charCount(const char_t* str, char_t ch);
+
+#define kLt '<'
+#define kLessThan T("&lt;")
+#define kGt '>'
+#define kGreaterThan T("&gt;")
+
+static char_t* websSafeUrl(const char_t* url)
+{
+
+   int ltCount = charCount(url, kLt);
+   int gtCount = charCount(url, kGt);
+   int safeLen = 0;
+   char_t* safeUrl = NULL;
+   char_t* src = NULL;
+   char_t* dest = NULL;
+
+   if (NULL != url)
+   {
+      safeLen = gstrlen(url);
+      if (ltCount == 0 && gtCount == 0)
+      {
+         safeUrl = bstrdup(B_L, (char_t*) url);
+      }
+      else
+      {
+         safeLen += (ltCount * 4);
+         safeLen += (gtCount * 4);
+
+         safeUrl = balloc(B_L, safeLen);
+         if (safeUrl != NULL)
+         {
+            src = (char_t*) url;
+            dest = safeUrl;
+            while (*src)
+            {
+               if (*src == kLt)
+               {
+                  gstrcpy(dest, kLessThan);
+                  dest += gstrlen(kLessThan);
+               }
+               else if (*src == kGt)
+               {
+                  gstrcpy(dest, kGreaterThan);
+                  dest += gstrlen(kGreaterThan);
+               }
+               else
+               {
+                  *dest++ = *src;
+               }
+               ++src;
+            }
+            /* don't forget to terminate the string...*/
+            *dest = '\0';
+         }
+      }
+   }
+   return safeUrl;
+}
+
+static int charCount(const char_t* str, char_t ch)
+{
+   int count = 0;
+   char_t* p = (char_t*) str;
+   
+   if (NULL == str)
+   {
+      return 0;
+   }
+
+   while (1)
+   {
+      p = gstrchr(p, ch);
+      if (NULL == p)
+      {
+         break;
+      }
+
+      ++count;
+      ++p;
+   }
+   return count;
+}
+
+
+char_t *websErrorMsg(int code)
+{
+	websErrorType	*ep;
+
+	for (ep = websErrors; ep->code; ep++) {
+		if (code == ep->code) {
+			return ep->msg;
+		}
+	}
+	a_assert(0);
+	return T("");
+}
+
+
+#ifdef qRichErrorPage
+extern int dmfRichError(webs_t wp, int code, char_t* userMsg);
+#endif
+void websError(webs_t wp, int code, char_t *fmt, ...)
+{
+	va_list		args = {0};
+	char_t		*msg, *userMsg, *buf;
+   char_t*     safeUrl = NULL;
+   char_t*     safeMsg = NULL;
+#ifdef qRichErrorPage
+   static int reEntry = 0;
+   int errorOk;
+#endif
+
+	a_assert(websValid(wp));
+	a_assert(fmt);
+
+	websStats.errors++;
+
+   safeUrl = websSafeUrl(wp->url);
+   bfreeSafe(B_L, wp->url);
+   wp->url = safeUrl;
+
+	va_start(args, fmt);
+	userMsg = NULL;
+	fmtValloc(&userMsg, WEBS_BUFSIZE, fmt, args);
+	va_end(args);
+   safeMsg = websSafeUrl(userMsg);
+   bfreeSafe(B_L, userMsg);
+   userMsg = safeMsg;
+   safeMsg  = NULL;
+
+
+
+#ifdef qRichErrorPage
+   if (!reEntry)
+   {
+
+      reEntry = 1;
+      errorOk = dmfRichError(wp, code, userMsg);
+      reEntry = 0;
+      if (errorOk)
+      {
+         bfreeSafe(B_L, userMsg);
+         return;
+      }
+      
+   }
+   
+#endif
+
+/*	msg = T("<html><head><title>Document Error: %s</title></head>\r\n\
+		<body><h2>Access Error: %s</h2>\r\n\
+		<p>%s</p></body></html>\r\n");*/
+// kw OVERWRITE_CONST_CHAR
+
+	buf = NULL;
+	fmtAlloc(&buf, WEBS_BUFSIZE, "<html><head><title>Document Error: %s</title></head>\r\n\
+		<body><h2>Access Error: %s</h2>\r\n\
+		<p>%s</p></body></html>\r\n", websErrorMsg(code), 
+		websErrorMsg(code), userMsg);
+
+	websResponse(wp, code, buf, NULL);
+	bfreeSafe(B_L, buf);
+	bfreeSafe(B_L, userMsg);
+}
+
+
+int websWriteBlock(webs_t wp, char_t *buf, int nChars)
+{
+	int		len, done;
+	char	*asciiBuf, *pBuf;
+
+	a_assert(wp);
+	a_assert(websValid(wp));
+	a_assert(buf);
+	a_assert(nChars >= 0);
+	if(wp == NULL)
+		return -1;//for kw
+
+	done = len = 0;
+
+	pBuf = asciiBuf = ballocUniToAsc(buf, nChars);
+	if(asciiBuf == NULL)
+		return -1;//for kw
+
+	while (nChars > 0) {  
+#ifdef WEBS_SSL_SUPPORT
+		if (wp->flags & WEBS_SECURE) {
+			if ((len = websSSLWrite(wp->wsp, pBuf, nChars)) < 0) {
+				bfree(B_L, asciiBuf);
+				return -1;
+			}
+			websSSLFlush(wp->wsp);
+		} else {
+			if ((len = socketWrite(wp->sid, pBuf, nChars)) < 0) {
+				bfree(B_L, asciiBuf);
+				return -1;
+			}
+			socketFlush(wp->sid);
+		}
+#else /* ! WEBS_SSL_SUPPORT */
+		if ((len = socketWrite(wp->sid, pBuf, nChars)) < 0) {
+			bfree(B_L, asciiBuf);
+			return -1;
+		}
+		socketFlush(wp->sid);
+#endif /* WEBS_SSL_SUPPORT */
+		nChars -= len;
+		pBuf += len;
+		done += len;
+	}
+
+	bfree(B_L, asciiBuf);
+	return done;
+}
+
+int websWrite(webs_t wp, char_t *fmt, ...)
+{
+	va_list		 vargs = {0};
+	char_t		*buf;
+	int			 rc;
+	
+	a_assert(websValid(wp));
+
+	va_start(vargs, fmt);
+
+	buf = NULL;
+	rc = 0;
+
+	if (fmtValloc(&buf, WEBS_BUFSIZE, fmt, vargs) >= WEBS_BUFSIZE) {
+		trace(0, T("webs: websWrite lost data, buffer overflow\n"));
+	}
+   
+	va_end(vargs);
+	a_assert(buf);
+	if (buf) {
+		rc = websWriteBlock(wp, buf, gstrlen(buf));
+		bfree(B_L, buf);
+	}
+	return rc;
+}
+
+
+void websDecodeUrl(char_t *decoded, char_t *token, int len)
+{
+	char_t	*ip,  *op;
+	int		num, i, c;
+	
+	a_assert(decoded);
+	a_assert(token);
+
+	op = decoded;
+	for (ip = token; *ip && len > 0; ip++, op++) {
+		if (*ip == '+') {
+			*op = ' ';
+		} else if (*ip == '%' && gisxdigit(ip[1]) && gisxdigit(ip[2])) {
+
+			ip++;
+			for (i = 0, num = 0; i < 2; i++, ip++) {
+				c = tolower(*ip);
+				if (c >= 'a' && c <= 'f') {
+					num = (num * 16) + 10 + c - 'a';
+				} else {
+					num = (num * 16) + c - '0';
+				}
+			}
+			*op = (char_t) num;
+			ip--;
+
+		} else {
+			*op = *ip;
+		}
+		len--;
+	}
+	*op = '\0';
+}
+
+int websWriteDataNonBlock(webs_t wp, char *buf, int nChars)
+{
+	int r;
+
+	a_assert(wp);
+	a_assert(websValid(wp));
+	a_assert(buf);
+	a_assert(nChars >= 0);
+
+#ifdef WEBS_SSL_SUPPORT
+	if (wp->flags & WEBS_SECURE) {
+		r = websSSLWrite(wp->wsp, buf, nChars);
+		websSSLFlush(wp->wsp);
+	} else {
+		r = socketWrite(wp->sid, buf, nChars);
+		socketFlush(wp->sid);
+	}
+#else
+	r = socketWrite(wp->sid, buf, nChars);
+	socketFlush(wp->sid);
+#endif
+
+	return r;
+}
+
+
+void websTimeout(void *arg, int id)
+{
+	webs_t		wp;
+	int			delay, tm;
+
+	wp = (webs_t) arg;
+	a_assert(websValid(wp));
+
+	tm = websGetTimeSinceMark(wp) * 1000;
+	trace(8, T("@@websTimeout %d ip:%s url:%s\n"),tm,wp->ipaddr,wp->url);
+	if (tm >= WEBS_TIMEOUT) {
+		websStats.timeouts++;
+		emfUnschedCallback(id);
+
+		wp->timeout = -1;
+		websDone(wp, 404);
+	} else {
+		delay = WEBS_TIMEOUT - tm;
+		a_assert(delay > 0);
+		emfReschedCallback(id, delay);
+	}
+}
+
+void websDone(webs_t wp, int code)
+{
+	a_assert(websValid(wp));
+
+	socketDeleteHandler(wp->sid);
+
+	if (code != 200) {
+		wp->flags &= ~WEBS_KEEP_ALIVE;
+	}
+
+	websPageClose(wp);
+
+#ifdef WEBS_SSL_SUPPORT
+	if (wp->flags & WEBS_SECURE) {
+		websTimeoutCancel(wp);
+		websSSLFlush(wp->wsp);
+		socketCloseConnection(wp->sid);
+		websFree(wp);
+		return;
+	}
+#endif
+
+	if (wp->flags & WEBS_KEEP_ALIVE) {
+		if (socketFlush(wp->sid) == 0) {
+			wp->state = WEBS_BEGIN;
+			wp->flags |= WEBS_REQUEST_DONE;
+			if (wp->header.buf) {
+				ringqFlush(&wp->header);
+			}
+			socketCreateHandler(wp->sid, SOCKET_READABLE, websSocketEvent, 
+				(int) wp);
+			websTimeoutCancel(wp);
+			wp->timeout = emfSchedCallback(WEBS_TIMEOUT, websTimeout,
+				(void *) wp);
+			return;
+		}
+	} else {
+		websTimeoutCancel(wp);
+		socketSetBlock(wp->sid, 1);
+		socketFlush(wp->sid);
+		socketCloseConnection(wp->sid);
+	}
+	websFree(wp);
+}
+
+void websFree(webs_t wp)
+{
+	a_assert(websValid(wp));
+
+	if (wp->path)
+		bfree(B_L, wp->path);
+	if (wp->url)
+		bfree(B_L, wp->url);
+	if (wp->host)
+		bfree(B_L, wp->host);
+	if (wp->lpath)
+		bfree(B_L, wp->lpath);
+	if (wp->query)
+		bfree(B_L, wp->query);
+	if (wp->decodedQuery)
+		bfree(B_L, wp->decodedQuery);
+	if (wp->authType)
+		bfree(B_L, wp->authType);
+	if (wp->password)
+		bfree(B_L, wp->password);
+	if (wp->userName)
+		bfree(B_L, wp->userName);
+	if (wp->cookie)
+		bfree(B_L, wp->cookie);
+	if (wp->referer)
+		bfree(B_L, wp->referer);
+	if (wp->userAgent)
+		bfree(B_L, wp->userAgent);
+	if (wp->dir)
+		bfree(B_L, wp->dir);
+	if (wp->protocol)
+		bfree(B_L, wp->protocol);
+	if (wp->protoVersion)
+		bfree(B_L, wp->protoVersion);
+	if (wp->cgiStdin)
+		bfree(B_L, wp->cgiStdin);
+
+
+#ifdef DIGEST_ACCESS_SUPPORT
+	if (wp->realm)
+		bfree(B_L, wp->realm);
+	if (wp->uri)
+		bfree(B_L, wp->uri);
+	if (wp->digest)
+		bfree(B_L, wp->digest);
+	if (wp->opaque)
+		bfree(B_L, wp->opaque);
+	if (wp->nonce)
+		bfree(B_L, wp->nonce);
+	if (wp->nc)
+		bfree(B_L, wp->nc);
+	if (wp->cnonce)
+		bfree(B_L, wp->cnonce);
+	if (wp->qop)
+		bfree(B_L, wp->qop);
+#endif
+#ifdef WEBS_SSL_SUPPORT
+	websSSLFree(wp->wsp);
+#endif
+	symClose(wp->cgiVars);
+
+	if (wp->header.buf) {
+		ringqClose(&wp->header);
+	}
+
+	websMax = hFree((void***) &webs, wp->wid);
+	bfree(B_L, wp);
+	a_assert(websMax >= 0);
+}
+
+
+int websAlloc(int sid)
+{
+	webs_t		wp;
+	int			wid;
+
+	if ((wid = hAllocEntry((void***) &webs, &websMax,
+			sizeof(struct websRec))) < 0) {
+		return -1;
+	}
+	wp = webs[wid];
+
+	wp->wid = wid;
+	wp->sid = sid;
+	wp->state = WEBS_BEGIN;
+	wp->docfd = -1;
+	wp->timeout = -1;
+	wp->dir = NULL;
+	wp->authType = NULL;
+	wp->protocol = NULL;
+	wp->protoVersion = NULL;
+	wp->password = NULL;
+	wp->userName = NULL;
+	wp->cookie = NULL;
+	wp->referer = NULL;
+	wp->has_firmware_upload_clean = 0;
+    wp->has_firmware_upload_shell = 0;
+#ifdef DIGEST_ACCESS_SUPPORT
+	wp->realm = NULL;
+	wp->nonce = NULL;
+	wp->digest = NULL;
+	wp->uri = NULL;
+	wp->opaque = NULL;
+	wp->nc = NULL;
+	wp->cnonce = NULL;
+	wp->qop = NULL;
+#endif
+#ifdef WEBS_SSL_SUPPORT
+	wp->wsp = NULL;
+#endif
+
+	ringqOpen(&wp->header, WEBS_HEADER_BUFINC, WEBS_MAX_HEADER);
+
+	wp->cgiVars = symOpen(WEBS_SYM_INIT);
+
+	return wid;
+}
+
+
+char_t *websGetIpaddrUrl()
+{
+	return websIpaddrUrl;
+}
+
+
+char_t *websGetHostUrl()
+{
+	return websHostUrl;
+}
+
+
+int websGetPort()
+{
+	return websPort;
+}
+
+char_t *websGetHost()
+{
+	return websHost;
+}
+
+
+int websGetRequestBytes(webs_t wp)
+{
+	a_assert(websValid(wp));
+
+	return wp->numbytes;
+}
+
+
+int websGetRequestFlags(webs_t wp)
+{
+	a_assert(websValid(wp));
+
+	return wp->flags;
+}
+
+char_t *websGetRequestDir(webs_t wp)
+{
+	a_assert(websValid(wp));
+
+	if (wp->dir == NULL) {
+		return T("");
+	}
+
+	return wp->dir;
+}
+
+
+int websGetSid(webs_t wp)
+{
+	a_assert(websValid(wp));
+
+	return wp->sid;
+}
+
+
+char_t *websGetRequestIpaddr(webs_t wp)
+{
+	a_assert(websValid(wp));
+	return wp->ipaddr;
+}
+
+
+#ifdef FEATURE_ZTE_WEB_TCARD
+//added by guo shoupeng 10124224 for http share 20111001 start
+char_t * websGetURL(webs_t wp)
+{
+	a_assert(websValid(wp));
+
+	return wp->url;
+}
+
+char_t *websGetFileName(webs_t wp)
+{
+	a_assert(websValid(wp));
+
+	return wp->cgiStdin;
+}
+
+
+int websGetState(webs_t wp)
+{
+	a_assert(websValid(wp));
+
+	return wp->state;
+}
+
+int websGetlen(webs_t wp)
+{
+	a_assert(websValid(wp));
+
+	return wp->clen;
+}
+
+//added by guo shoupeng 10124224 for http share 20111001 end
+#endif
+
+
+char_t *websGetRequestLpath(webs_t wp)
+{
+	a_assert(websValid(wp));
+
+	return wp->lpath;
+}
+
+
+char_t *websGetRequestPassword(webs_t wp)
+{
+	a_assert(websValid(wp));
+
+	return wp->password;
+}
+
+char_t *websGetRequestPath(webs_t wp)
+{
+	a_assert(websValid(wp));
+
+	if (wp->path == NULL) {
+		return T("");
+	}
+
+	return wp->path;
+}
+
+
+char_t *websGetRequestType(webs_t wp)
+{
+	a_assert(websValid(wp));
+
+	return wp->type;
+}
+
+
+int websGetRequestWritten(webs_t wp)
+{
+	a_assert(websValid(wp));
+
+	return wp->written;
+}
+
+
+char_t *websGetRequestUserName(webs_t wp)
+{
+	a_assert(websValid(wp));
+
+	return wp->userName;
+}
+
+void websSetHost(char_t *host)
+{
+	gstrncpy(websHost, host, TSZ(websHost)-1);
+}
+
+
+void websSetIpaddr(char_t *ipaddr)
+{
+	a_assert(ipaddr && *ipaddr);
+
+	gstrncpy(websIpaddr, ipaddr, TSZ(websIpaddr)-1);
+}
+
+void websSetHostUrl(char_t *url)
+{
+	a_assert(url && *url);
+
+	bfreeSafe(B_L, websHostUrl);
+	websHostUrl = gstrdup(B_L, url);
+}
+
+
+void websSetRequestBytes(webs_t wp, int bytes)
+{
+	a_assert(websValid(wp));
+	a_assert(bytes >= 0);
+
+	wp->numbytes = bytes;
+}
+
+
+void websSetRequestLpath(webs_t wp, char_t *lpath)
+{
+	a_assert(websValid(wp));
+	a_assert(lpath && *lpath);
+
+	if (wp->lpath) {
+		bfree(B_L, wp->lpath);
+	}
+	wp->lpath = bstrdup(B_L, lpath);
+	websSetVar(wp, T("PATH_TRANSLATED"), wp->lpath);
+}
+
+void websSetRequestFlags(webs_t wp, int flags)
+{
+	a_assert(websValid(wp));
+
+	wp->flags = flags;
+}
+
+
+void websSetRequestPath(webs_t wp, char_t *dir, char_t *path)
+{
+	char_t	*tmp;
+
+	a_assert(websValid(wp));
+
+	if (dir) { 
+		tmp = wp->dir;
+		wp->dir = bstrdup(B_L, dir);
+		if (tmp) {
+			bfree(B_L, tmp);
+		}
+	}
+	if (path) {
+		tmp = wp->path;
+		wp->path = bstrdup(B_L, path);
+		websSetVar(wp, T("PATH_INFO"), wp->path);
+		if (tmp) {
+			bfree(B_L, tmp);
+		}
+	}
+}
+
+
+void websSetRequestWritten(webs_t wp, int written)
+{
+	a_assert(websValid(wp));
+
+	wp->written = written;
+}
+
+
+void websSetRequestSocketHandler(webs_t wp, int mask, void (*fn)(webs_t wp))
+{
+	a_assert(websValid(wp));
+
+	wp->writeSocket = fn;
+	socketCreateHandler(wp->sid, SOCKET_WRITABLE, websSocketEvent, (int) wp);
+}
+
+
+char_t *websGetDateString(websStatType *sbuf)
+{
+	char_t*	cp, *r;
+	time_t	now;
+
+	if (sbuf == NULL) {
+		time(&now);
+	} else {
+		now = sbuf->mtime;
+	}
+	if ((cp = gctime(&now)) != NULL) {
+		cp[gstrlen(cp) - 1] = '\0';
+		r = bstrdup(B_L, cp);
+		return r;
+	}
+	return NULL;
+}
+
+
+int websValid(webs_t wp)
+{
+	int		wid;
+
+	for (wid = 0; wid < websMax; wid++) {
+		if (wp == webs[wid]) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+
+void websSetTimeMark(webs_t wp)
+{
+	wp->timestamp = get_sys_uptime();
+}
+
+
+void websSetRealm(char_t *realmName)
+{
+	a_assert(realmName);
+
+	gstrncpy(websRealm, realmName, TSZ(websRealm)-1);
+}
+
+
+char_t *websGetRealm()
+{
+	return websRealm;
+}
+
+
+static int websGetTimeSinceMark(webs_t wp)
+{
+	return get_sys_uptime() - wp->timestamp;
+}
+
+void websSetLoginTimemark(webs_t wp)
+{
+
+    char_t login_timemark[64] = {0};
+    char_t login_info[20] = {0};
+    char_t nv_ipaddr[40] = {0};
+    char_t *ip_address = NULL;
+    zte_topsw_state_e_type status = ZTE_NVIO_MAX;
+    long timemark = 0;    
+    char_t user_login_timemark[64] = {0};
+    long timemark_check = 0;
+	long luser_login_timemark = 0;
+
+  
+    status = zte_web_read(NV_LOGINFO, login_info);
+
+    if(0 == strcmp(login_info,"ok"))
+    {
+
+        zte_web_read("user_login_timemark", user_login_timemark);
+
+        luser_login_timemark = atol(user_login_timemark);
+		if(luser_login_timemark < 0 || luser_login_timemark > LONG_MAX-1){
+            luser_login_timemark = LONG_MAX;
+		}
+		
+        timemark_check = time(0) - luser_login_timemark;  
+        if(timemark_check > LOGIN_TIMEOUT)
+        {
+            (void)zte_web_write(NV_USER_IP_ADDR,"");
+            (void)zte_web_write(NV_LOGINFO,"timeout");
+			(void)zte_web_write(NV_COOKIE_ID, "");
+            (void)zte_web_write(NV_USER_LOGIN_TIMEMARK,"0");
+            slog(MISC_PRINT,SLOG_ERR,"zte_mgmt_login_timemark_check: the login is timeout .\n");
+        }
+        else
+        {
+            ip_address = websGetRequestIpaddr(wp);
+#if 0		 // kw 3 INVARIANT_CONDITION.UNREACH	  wp->ipaddr is array, address can not be null
+            if (NULL == ip_address)
+            {
+                slog(MISC_PRINT,SLOG_ERR,"websSetLoginTimemark: ip_address is null.\n");
+                return ;
+            }
+#endif
+            zte_web_read(NV_USER_IP_ADDR, nv_ipaddr);
+           
+
+            if (0 == strcmp(ip_address,nv_ipaddr))
+            {
+                timemark = time(0);
+                sprintf(login_timemark,"%ld",timemark);  
+                (void)zte_web_write(NV_USER_LOGIN_TIMEMARK, login_timemark);
+            }
+
+         }
+    }  
+
+}
+
diff --git a/lynq/S300AI/ap/app/goahead/server/webs.h b/lynq/S300AI/ap/app/goahead/server/webs.h
new file mode 100755
index 0000000..ed80948
--- /dev/null
+++ b/lynq/S300AI/ap/app/goahead/server/webs.h
@@ -0,0 +1,267 @@
+#ifndef _h_WEBS
+#define _h_WEBS 1
+
+#include	"ej.h"
+#ifdef WEBS_SSL_SUPPORT
+	#include	"websSSL.h"
+#else	
+static inline int websSSLIsOpen()
+{
+	return 0;
+}
+#endif
+
+
+#ifdef WEBINSPECT_FIX 
+#define WEBS_NAME				T("Demo-Webs")
+#else
+#define WEBS_NAME				T("GoAhead-Webs")
+#endif
+#define WEBS_VERSION			T("2.1.8")
+
+#define WEBS_HEADER_BUFINC 		512			
+#define WEBS_ASP_BUFINC			512			
+#define WEBS_MAX_PASS			32			
+
+#define WEBS_BUFSIZE			(8*1024)
+
+#define WEBS_MAX_HEADER			(5 * 1024)	
+#define WEBS_MAX_URL			4096		
+#ifdef FEATURE_ZTE_WEB_TCARD
+//added for http share 20111001 start
+#define WEBS_SOCKET_BUFSIZ		4*1024		
+#else
+#define WEBS_SOCKET_BUFSIZ		4*1024		
+//added for http share 20111001 end
+#endif
+//added for PC Client begin, 20120829
+#define HTTP_BUFFER_SIZE    (5*1024)
+//added for PC Client end, 20120829
+#define WEBS_HTTP_PORT			T("httpPort")
+#define CGI_BIN					T("cgi-bin")
+#define CGI_BIN_UPLOAD			T("cgi-bin/upload/")
+#define CGI_BIN_HTTPSHARE		T("cgi-bin/httpshare/")
+
+
+#define WEBS_LOCAL_PAGE			0x1			
+#define WEBS_KEEP_ALIVE			0x2			
+#define WEBS_DONT_USE_CACHE		0x4			
+#define WEBS_COOKIE				0x8			
+#define WEBS_IF_MODIFIED		0x10		
+#define WEBS_POST_REQUEST		0x20		
+#define WEBS_LOCAL_REQUEST		0x40		
+#define WEBS_HOME_PAGE			0x80		
+#define WEBS_ASP				0x100		 
+#define WEBS_HEAD_REQUEST		0x200		
+#define WEBS_CLEN				0x400		
+#define WEBS_FORM				0x800		
+#define WEBS_REQUEST_DONE		0x1000		
+#define WEBS_POST_DATA			0x2000		
+#define WEBS_CGI_REQUEST		0x4000		
+#define WEBS_SECURE				0x8000		
+#define WEBS_AUTH_BASIC			0x10000		
+#define WEBS_AUTH_DIGEST		0x20000		
+#define WEBS_HEADER_DONE		0x40000		
+#define WEBS_CGI_UPLOAD			0x80000		
+#define WEBS_CGI_FIRMWARE_UPLOAD 0x100000	
+#define WEBS_CGI_HTTPSHARE_UPLOAD 0x200000	
+
+
+#define CGI_UPLOAD				T("upload")
+#define CGI_FIRMWARE_UPLOAD		T("upload.cgi")
+#define CGI_FIRMWARE_WRITE      T("upload.write")
+#define CGI_HTTPSHARE_UPLOAD      T("httpshare.up")
+
+#define FIRMWARE_TMP_FILE                  T("/tmp/firmware_tmp_file")
+//#define FIRMWARE_TMP_FILE                  T("/firmware_tmp_file")
+
+//added by liuyingnan for PC Client begin, 20120829
+#define WEBS_REST_CLIENT_REQUEST       0x200000
+#define WEBS_XML_CLIENT_REQUEST       0x400000
+//added by liuyingnan for PC Client end, 20120829
+
+
+#define WEBS_HANDLER_FIRST	0x1			
+#define WEBS_HANDLER_LAST	0x2			
+
+typedef struct websRec {
+	ringq_t			header;				
+	time_t			since;				
+	sym_fd_t		cgiVars;			
+	sym_fd_t		cgiQuery;			
+	time_t			timestamp;			
+	int				timeout;			
+	char_t			ipaddr[40];			
+	char_t			ifaddr[32];			
+	char_t			type[64];			
+	char_t			*dir;				
+	char_t			*path;				
+	char_t			*url;				
+	char_t			*host;				
+	char_t			*lpath;				
+	char_t			*query;				
+	char_t			*decodedQuery;		
+	char_t			*authType;			
+	char_t			*password;			
+	char_t			*userName;			
+	char_t			*cookie;			
+	char_t			*referer;			
+	char_t			*userAgent;			
+	char_t			*protocol;			
+	char_t			*protoVersion;		
+	int				sid;				
+	int				listenSid;			
+	int				port;				
+	int				state;				
+	int				flags;				
+	int				code;				
+	int				clen;				
+	int				wid;				
+	char_t			*cgiStdin;			
+	int				docfd;				
+	int				numbytes;			
+	int				written;			
+	int				has_firmware_upload_clean; 
+    int				has_firmware_upload_shell; 
+	void			(*writeSocket)(struct websRec *wp);
+#ifdef DIGEST_ACCESS_SUPPORT
+    char_t			*realm;		
+    char_t			*nonce;		
+    char_t			*digest;	
+    char_t			*uri;		
+    char_t			*opaque;	
+    char_t			*nc;		
+    char_t			*cnonce;	
+    char_t			*qop;		
+#endif
+#ifdef WEBS_SSL_SUPPORT
+	websSSL_t		*wsp;		
+#endif
+} websRec;
+
+typedef websRec	*webs_t;
+typedef websRec websType;
+
+extern void 	 websSetDefaultDir(char_t *dir);
+extern void 	 websSetDefaultPage(char_t *page);
+
+extern int		 websAccept(int sid, char *ipaddr, int port, int listenSid);
+extern int 		 websAspDefine(char_t *name, 
+					int (*fn)(int ejid, webs_t wp, int argc, char_t **argv));
+extern int 		 websAspRequest(webs_t wp, char_t *lpath);
+
+extern void  	 websFooter(webs_t wp);
+extern int 		 websFormDefine(char_t *name, void (*fn)(webs_t wp, 
+					char_t *path, char_t *query));
+
+extern int 		 websDecode64(char_t *outbuf, char_t *string, int buflen);
+extern void		 websDecodeUrl(char_t *token, char_t *decoded, int len);
+
+extern void 	 websEncode64(char_t *outbuf, char_t *string, int buflen);
+
+
+extern void		 websCloseListen();
+extern void  	 websDone(webs_t wp, int code);
+
+extern void  	 websError(webs_t wp, int code, char_t *msg, ...);
+extern char_t 	*websErrorMsg(int code);
+
+extern char_t 	*websGetDefaultDir();
+extern char_t 	*websGetDefaultPage();
+
+extern char_t 	*websGetRealm();
+extern int 		 websGetRequestBytes(webs_t wp);
+extern char_t	*websGetRequestDir(webs_t wp);
+extern int		 websGetRequestFlags(webs_t wp);
+
+extern char_t 	*websGetHostUrl();
+extern char_t 	*websGetIpaddrUrl();
+extern char_t 	*websGetPassword();
+extern int		 websGetPort();
+
+extern char_t 	*websGetPublishDir(char_t *path, char_t **urlPrefix);
+extern char_t	*websGetRequestType(webs_t wp);
+extern int 		 websGetRequestWritten(webs_t wp);
+
+extern char_t	*websGetRequestIpaddr(webs_t wp);
+extern int 		websGetSid(webs_t wp);
+extern char_t 	*websGetRequestLpath(webs_t wp);
+extern char_t	*websGetRequestPath(webs_t wp);
+extern char_t	*websGetRequestPassword(webs_t wp);
+
+extern char_t 	*websGetVar(webs_t wp, char_t *var, char_t *def);
+extern int 		 websCompareVar(webs_t wp, char_t *var, char_t *value);
+
+
+extern int 		 websPublish(char_t *urlPrefix, char_t *path);
+extern void		 websRedirect(webs_t wp, char_t *url);
+extern void 	 websSecurityDelete();
+extern int 		 websSecurityHandler(webs_t wp, char_t *urlPrefix, 
+					char_t *webDir, int arg, char_t *url, char_t *path, 
+					char_t *query);
+
+extern void 	 websHeader(webs_t wp);
+extern int		 websOpenListen(int port, int retries);
+extern int 		 websPageOpen(webs_t wp, char_t *lpath, char_t *path,
+					int mode, int perm);
+extern void 	 websPageClose(webs_t wp);
+
+extern void 	 websSetEnv(webs_t wp);
+extern void 	 websSetHost(char_t *host);
+extern void 	 websSetIpaddr(char_t *ipaddr);
+extern void 	 websSetPassword(char_t *password);
+extern void 	 websSetRealm(char_t *realmName);
+
+extern void 	 websSetVar(webs_t wp, char_t *var, char_t *value);
+extern int 		 websTestVar(webs_t wp, char_t *var);
+
+extern int 		 websUrlHandlerDefine(char_t *urlPrefix, char_t *webDir, 
+					int arg, int (*fn)(webs_t wp, char_t *urlPrefix, 
+					char_t *webDir, int arg, char_t *url, char_t *path, 
+					char_t *query), int flags);
+extern int 		 websUrlHandlerDelete(int (*fn)(webs_t wp, char_t *urlPrefix,
+					char_t *webDir, int arg, char_t *url, char_t *path, 
+					char_t *query));
+extern int		 websUrlHandlerRequest(webs_t wp);
+extern int 		 websUrlParse(char_t *url, char_t **buf, char_t **host, 
+					char_t **path, char_t **port, char_t **query, 
+					char_t **proto, char_t **tag, char_t **ext);
+extern char_t 	*websUrlType(char_t *webs, char_t *buf, int charCnt);
+
+extern int 		 websValid(webs_t wp);
+extern int 		 websValidateUrl(webs_t wp, char_t *path);
+
+extern void 	 websSetRequestBytes(webs_t wp, int bytes);
+extern void		 websSetRequestFlags(webs_t wp, int flags);
+extern void 	 websSetRequestLpath(webs_t wp, char_t *lpath);
+extern void 	 websSetRequestPath(webs_t wp, char_t *dir, char_t *path);
+extern char_t	*websGetRequestUserName(webs_t wp);
+extern void 	 websSetRequestWritten(webs_t wp, int written);
+
+extern int 		 websWrite(webs_t wp, char_t* fmt, ...);
+extern int 		 websWriteBlock(webs_t wp, char_t *buf, int nChars);
+extern int 		 websWriteDataNonBlock(webs_t wp, char *buf, int nChars);
+
+
+extern void 	websTimeout(void *arg, int id);
+extern void		websSetTimeMark(webs_t wp);
+extern void		 websTimeoutCancel(webs_t wp);
+
+
+extern int 		websAlloc(int sid);
+extern void 	websFree(webs_t wp);
+
+extern void 	websReadEvent(webs_t wp);
+
+
+extern char websRecvHttpBuffer[HTTP_BUFFER_SIZE];
+extern int is_print_str(char *str, int len);
+
+#ifdef EMF
+extern void 	 websFormExplain(webs_t wp, char_t *path, char_t *query);
+#endif
+
+extern int web_make_salt_base64(char *id, int len);
+
+#endif /* _h_WEBS */
+