zte's code,first commit
Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/ap/app/goahead/server/Makefile b/ap/app/goahead/server/Makefile
new file mode 100755
index 0000000..1e209f7
--- /dev/null
+++ b/ap/app/goahead/server/Makefile
@@ -0,0 +1,246 @@
+# /*****************************************************************************
+#* °æÈ¨ËùÓÐ (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
+
+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
+
+#*******************************************************************************
+# 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/ap/app/goahead/server/balloc.c b/ap/app/goahead/server/balloc.c
new file mode 100755
index 0000000..da56e39
--- /dev/null
+++ b/ap/app/goahead/server/balloc.c
@@ -0,0 +1,206 @@
+#define IN_BALLOC
+
+#include "uemf.h"
+#include <stdarg.h>
+#include <stdlib.h>
+
+static bType *bQhead[B_MAX_CLASS];
+static char *bFreeBuf;
+static char *bFreeNext;
+static int bFreeSize;
+static int bFreeLeft;
+static int bFlags = B_USE_MALLOC;
+static int bopenCount = 0;
+
+static int ballocGetSize(int size, int *q);
+
+int bopen(void *buf, int bufsize, int flags)
+{
+ bFlags = flags;
+
+ if (++bopenCount > 1) {
+ return 0;
+ }
+
+ if (buf == NULL) {
+ if (bufsize == 0) {
+ bufsize = B_DEFAULT_MEM;
+ }
+ if ((buf = malloc(bufsize)) == NULL) {
+ --bopenCount;
+ return -1;
+ }
+ } else {
+ bFlags |= B_USER_BUF;
+ }
+
+ bFreeSize = bFreeLeft = bufsize;
+ bFreeBuf = bFreeNext = buf;
+ memset(bQhead, 0, sizeof(bQhead));
+ return 0;
+}
+
+void bclose()
+{
+ if (--bopenCount <= 0 && !(bFlags & B_USER_BUF)) {
+ free(bFreeBuf);
+ bopenCount = 0;
+ }
+}
+
+bType *balloc_tmp;
+void *balloc(B_ARGS_DEC, int size)
+{
+ bType *bp;
+ int q, memSize;
+
+ if (bFreeBuf == NULL) {
+ if (bopen(NULL, B_DEFAULT_MEM, 0) < 0) {
+ return NULL;
+ }
+ }
+ if (size < 0) {
+ return NULL;
+ }
+
+ memSize = ballocGetSize(size+1, &q);
+
+ if (q >= B_MAX_CLASS) {
+ if (bFlags & B_USE_MALLOC) {
+ bp = (bType*) malloc(memSize);
+ if (bp == NULL) {
+ traceRaw(T("B: malloc failed\n"));
+ return NULL;
+ }
+
+ } else {
+ traceRaw(T("B: malloc failed\n"));
+ return NULL;
+ }
+ bp->u.size = memSize - sizeof(bType);
+ bp->flags = B_MALLOCED;
+
+ } else if ((bp = bQhead[q]) != NULL) {
+#ifdef WEBS_SECURITY
+ bType *tmp = bp->u.next;
+ if(tmp != NULL)
+ balloc_tmp = tmp->u.next;
+#endif
+ bQhead[q] = bp->u.next;
+
+ bp->u.size = memSize - sizeof(bType);
+ bp->flags = 0;
+
+ } else {
+ if (bFreeLeft > memSize) {
+
+ bp = (bType*) bFreeNext;
+
+ bFreeNext += memSize;
+ bFreeLeft -= memSize;
+
+ bp->u.size = memSize - sizeof(bType);
+ bp->flags = 0;
+
+ } else if (bFlags & B_USE_MALLOC) {
+
+ if ((bp = (bType*) malloc(memSize)) == NULL) {
+ traceRaw(T("B: malloc failed\n"));
+ return NULL;
+ }
+ bp->u.size = memSize - sizeof(bType);
+ bp->flags = B_MALLOCED;
+
+ } else {
+ traceRaw(T("B: malloc failed\n"));
+ return NULL;
+ }
+ }
+
+ bp->flags |= B_INTEGRITY;
+
+ return (void*) ((char*) bp + sizeof(bType));
+}
+
+void bfree(B_ARGS_DEC, void *mp)
+{
+ bType *bp;
+ int q, memSize;
+
+ bp = (bType*) ((char*) mp - sizeof(bType));
+
+ a_assert((bp->flags & B_INTEGRITY_MASK) == B_INTEGRITY);
+
+ if ((bp->flags & B_INTEGRITY_MASK) != B_INTEGRITY) {
+ return;
+ }
+
+ memSize = ballocGetSize(bp->u.size, &q);
+
+ if (bp->flags & B_MALLOCED) {
+ free(bp);
+ return;
+ }
+
+ bp->u.next = bQhead[q];
+ bQhead[q] = bp;
+
+ bp->flags = B_FILL_WORD;
+}
+
+
+void bfreeSafe(B_ARGS_DEC, void *mp)
+{
+ if (mp) {
+ bfree(B_ARGS, mp);
+ }
+}
+
+char_t *bstrdup(B_ARGS_DEC, char_t *s)
+{
+ char_t *cp;
+ int len;
+
+ if (s == NULL) {
+ s = T("");
+ }
+ len = gstrlen(s) + 1;
+ if ((cp = balloc(B_ARGS, len * sizeof(char_t))) != NULL) {
+ gstrcpy(cp, s);
+ }
+ return cp;
+}
+
+void *brealloc(B_ARGS_DEC, void *mp, int newsize)
+{
+ bType *bp;
+ void *newbuf;
+
+ if (mp == NULL) {
+ return balloc(B_ARGS, newsize);
+ }
+ bp = (bType*) ((char*) mp - sizeof(bType));
+ a_assert((bp->flags & B_INTEGRITY_MASK) == B_INTEGRITY);
+
+ if (bp->u.size >= newsize) {
+ return mp;
+ }
+ if ((newbuf = balloc(B_ARGS, newsize)) != NULL) {
+ memcpy(newbuf, mp, bp->u.size);
+ bfree(B_ARGS, mp);
+ }
+ return newbuf;
+}
+
+static int ballocGetSize(int size, int *q)
+{
+ int mask;
+
+ mask = (size == 0) ? 0 : (size-1) >> B_SHIFT;
+ for (*q = 0; mask; mask >>= 1) {
+ *q = *q + 1;
+ }
+ return ((1 << (B_SHIFT + *q)) + sizeof(bType));
+}
+
+
diff --git a/ap/app/goahead/server/base64.c b/ap/app/goahead/server/base64.c
new file mode 100755
index 0000000..b05e21b
--- /dev/null
+++ b/ap/app/goahead/server/base64.c
@@ -0,0 +1,95 @@
+
+static char map64[] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+};
+
+static char alphabet64[] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+ 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3',
+ '4', '5', '6', '7', '8', '9', '+', '/',
+};
+
+int websDecode64(char *outbuf, char *string, int outlen)
+{
+ unsigned long shiftbuf;
+ char *cp, *op;
+ int c, i, j, shift;
+
+ op = outbuf;
+ *op = '\0';
+ cp = string;
+ while (*cp && *cp != '=') {
+ shiftbuf = 0;
+ shift = 18;
+ for (i = 0; i < 4 && *cp && *cp != '='; i++, cp++) {
+ c = map64[*cp & 0xff];
+ if (c == -1) {
+ return -1;
+ }
+ shiftbuf = shiftbuf | (c << shift);
+ shift -= 6;
+ }
+ --i;
+ if ((op + i) >= &outbuf[outlen]) {
+ strcpy(outbuf, "String too big");
+ return -1;
+ }
+ for (j = 0; j < i; j++) {
+ *op++ = (char) ((shiftbuf >> (8 * (2 - j))) & 0xff);
+ }
+ *op = '\0';
+ }
+ return 0;
+}
+
+void websEncode64(char *outbuf, char *string, int outlen)
+{
+ unsigned long shiftbuf;
+ char *cp, *op;
+ int x, i, j, shift;
+
+ op = outbuf;
+ *op = '\0';
+ cp = string;
+ while (*cp) {
+ shiftbuf = 0;
+ for (j = 2; j >= 0 && *cp; j--, cp++) {
+ shiftbuf |= ((*cp & 0xff) << (j * 8));
+ }
+ shift = 18;
+ for (i = ++j; i < 4 && op < &outbuf[outlen] ; i++) {
+ x = (shiftbuf >> shift) & 0x3f;
+ *op++ = alphabet64[(shiftbuf >> shift) & 0x3f];
+ shift -= 6;
+ }
+ while (j-- > 0) {
+ *op++ = '=';
+ }
+ *op = '\0';
+ }
+}
+
diff --git a/ap/app/goahead/server/cgi.c b/ap/app/goahead/server/cgi.c
new file mode 100755
index 0000000..c9286c6
--- /dev/null
+++ b/ap/app/goahead/server/cgi.c
@@ -0,0 +1,311 @@
+#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"),"/etc_ro/cgi-bin", cgiName);
+ {
+ gstat_t sbuf;
+ if (gstat(cgiPath, &sbuf) != 0 || (sbuf.st_mode & S_IFREG) == 0) {
+ 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) {
+ 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/ap/app/goahead/server/default.c b/ap/app/goahead/server/default.c
new file mode 100755
index 0000000..cd8aec1
--- /dev/null
+++ b/ap/app/goahead/server/default.c
@@ -0,0 +1,826 @@
+#include "wsIntrn.h"
+
+static char_t *websDefaultPage; /* Default page name */
+static char_t *websDefaultDir; /* Default Web page directory */
+
+static void websCgiDownLoadWriteEvent(webs_t wp);
+static void websDefaultWriteEvent(webs_t wp);
+
+static int web_check_url(char *buf, char *nv_name, int is_ipv6)
+{
+ if(buf && nv_name) {
+ char url[40] = {0};
+ char full_url[50] = {0};
+ cfg_get_item(nv_name, url, sizeof(url));
+ if (websSSLIsOpen()){
+ if(is_ipv6)
+ snprintf(full_url, sizeof(full_url),"https://[%s]",url);
+ else
+ snprintf(full_url, sizeof(full_url),"https://%s",url);
+ } else {
+ if(is_ipv6)
+ snprintf(full_url, sizeof(full_url),"http://[%s]",url);
+ else
+ snprintf(full_url, sizeof(full_url),"http://%s",url);
+ }
+ if(strlen(buf) > strlen(full_url) && strstr(buf,full_url)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int websDefaultHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
+ char_t *url, char_t *path, char_t *query)
+{
+ websStatType sbuf;
+ char_t *lpath, *tmp, *date;
+ int bytes, flags, nchars;
+ char wifi_png__path[256] = {0};
+ char *wifi_ptr = NULL;
+ char wifi_root_dir[20] = {0};
+ a_assert(websValid(wp));
+ a_assert(url && *url);
+ a_assert(path);
+ a_assert(query);
+#ifdef WEBINSPECT_FIX
+ if (strstr(query,"txtPwd")) {
+ websDone(wp, 0);
+ return 1;
+ }
+#ifdef WEBS_SECURITY
+ if (strstr(query,"_method")) {
+ printf("websDH: qry=%s\n",query);
+ websError(wp, 405, T(""));
+ return 1;
+ }
+#endif
+#endif
+
+ flags = websGetRequestFlags(wp);
+
+ if (websValidateUrl(wp, path) < 0)
+ {
+ websError(wp, 500, T("Invalid URL"));
+ return 1;
+ }
+ lpath = websGetRequestLpath(wp);
+
+//qrcode_ssid_wifikey.png qrcode_multi_ssid_wifikey.png
+ if((strstr(lpath,"pic/qrcode_ssid_wifikey.png")!=NULL)||(strstr(lpath,"pic/qrcode_multi_ssid_wifikey.png")!=NULL))
+ {
+ cfg_get_item("wifi_root_dir",wifi_root_dir,sizeof(wifi_root_dir));
+ wifi_ptr=strstr(lpath,"pic/qrcode_");
+ wifi_ptr+=4;
+ //printf("[wifi_png]wifi_ptr:%s\n",wifi_ptr);
+ snprintf(wifi_png__path,sizeof(wifi_png__path),"%s/wifi/%s",wifi_root_dir,wifi_ptr);
+ //printf("[wifi_png]wifi_png_path:%s\n",wifi_png__path);
+ lpath=wifi_png__path;
+ }
+
+ if(strstr(lpath,"web/messages"))
+ {
+ //lpath="/var/log/webshow_messages";
+ snprintf(wifi_png__path,sizeof(wifi_png__path),"%s","/var/log/webshow_messages");
+ lpath=wifi_png__path;// kw OVERWRITE_CONST_CHAR
+ }
+ if(strstr(lpath,"/webshow_messages"))
+ {
+ //lpath="/etc_ro/web/webshow_messages";
+ snprintf(wifi_png__path,sizeof(wifi_png__path),"%s","/etc_ro/web/webshow_messages");
+ lpath=wifi_png__path;// kw OVERWRITE_CONST_CHAR
+ }
+ nchars = gstrlen(lpath) - 1;
+ if (lpath[nchars] == '/' || lpath[nchars] == '\\') {
+ lpath[nchars] = '\0';
+ }
+ if(lpath != websGetRequestLpath(wp))
+ {
+ websSetRequestLpath(wp,lpath);
+ lpath = websGetRequestLpath(wp);
+ }
+
+ if (websPageIsDirectory(lpath)) {
+ nchars = gstrlen(path);
+ if (path[nchars-1] == '/' || path[nchars-1] == '\\') {
+ path[--nchars] = '\0';
+ }
+ nchars += gstrlen(websDefaultPage) + 2;
+ fmtAlloc(&tmp, nchars, T("%s/%s"), path, websDefaultPage);
+ websRedirect(wp, tmp);
+ bfreeSafe(B_L, tmp);
+ return 1;
+ }
+#ifdef WEBS_SECURITY
+ if (strstr(path,websDefaultPage)){
+ if (!(wp->flags & WEBS_SECURE) && websSSLIsOpen()){
+ printf("[goahead]no https Redirect\n");
+ websRedirect(wp, zte_web_get_login_page(wp));
+ return 1;
+ }
+ } else {
+#if 0
+ if(wp->cookie == NULL) {
+ printf("[goahead]no cookie Redirect\n");
+ websRedirect(wp, zte_web_get_login_page(wp));
+ return 1;
+ }
+#endif
+ if(wp->referer)
+ {
+ if(web_check_url(wp->referer, "LocalDomain", 0) == 0
+ && web_check_url(wp->referer, "lan_ipaddr", 0) == 0
+ && web_check_url(wp->referer, "lan_ipv6addr", 1) == 0) {
+ printf("[goahead]referer=%s Redirect\n",wp->referer);
+ websRedirect(wp, zte_web_get_login_page(wp));
+ return 1;
+ }
+ }
+ }
+#endif
+/*
+ * Open the document. Stat for later use.
+ */
+
+ if (websPageOpen(wp, lpath, path, SOCKET_RDONLY | SOCKET_BINARY,
+ 0666) < 0)
+ {
+ /*
+ * <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html>
+ */
+
+ websError(wp, 404, T("Cannot open URL"));
+ return 1;
+ }
+
+ if (websPageStat(wp, lpath, path, &sbuf) < 0) {
+ websError(wp, 400, T("Cannot stat page for URL"));
+ return 1;
+ }
+
+ websStats.localHits++;
+#ifdef WEBS_IF_MODIFIED_SUPPORT
+ if (flags & WEBS_IF_MODIFIED && !(flags & WEBS_ASP)) {
+ if (sbuf.mtime <= wp->since) {
+ websWrite(wp, T("HTTP/1.0 304 Use local copy\r\n"));
+
+ websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);
+
+ if (flags & WEBS_KEEP_ALIVE) {
+ websWrite(wp, T("Connection: keep-alive\r\n"));
+ }
+ websWrite(wp, T("\r\n"));
+ websSetRequestFlags(wp, flags |= WEBS_HEADER_DONE);
+ websDone(wp, 304);
+ return 1;
+ }
+ }
+#endif
+
+ if ((date = websGetDateString(NULL)) != NULL) {
+ websWrite(wp, T("HTTP/1.0 200 OK\r\nDate: %s\r\n"), date);
+
+ websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);
+ bfree(B_L, date);
+ }
+ flags |= WEBS_HEADER_DONE;
+
+ if (flags & WEBS_ASP) {
+ bytes = 0;
+#ifndef WEBINSPECT_FIX
+ websWrite(wp, T("Pragma: no-cache\r\nCache-Control: no-cache\r\n"));
+#endif
+ } else {
+ if ((date = websGetDateString(&sbuf)) != NULL) {
+ websWrite(wp, T("Last-modified: %s\r\n"), date);
+ bfree(B_L, date);
+ }
+ bytes = sbuf.size;
+ }
+#ifdef WEBINSPECT_FIX
+ websWrite(wp, T("X-Frame-Options: SAMEORIGIN\r\nPragma: no-cache\r\nCache-Control: no-cache\r\n"));
+#endif
+#ifdef WEBS_SECURITY
+ websWrite(wp, T("Expires: 0\n"));
+ if (strstr(path,websDefaultPage)){
+ char id[33] = {0};
+ int ret = web_make_salt_base64(id, sizeof(id));
+ if(ret > 0)
+ {
+ if (websSSLIsOpen())
+ websWrite(wp, T("Set-Cookie: id=%s; secure; HttpOnly; SameSite=Lax;\r\n"),id);
+ else
+ websWrite(wp, T("Set-Cookie: id=%s; HttpOnly; SameSite=Lax;\r\n"),id);
+ }
+ }
+#endif
+
+ if (bytes) {
+#ifdef WEBINSPECT_FIX
+ if (strstr(path,"/tmpl/"))
+ websWrite(wp, T("Content-length: %d\r\n"), bytes+86);
+ else
+#endif
+ websWrite(wp, T("Content-length: %d\r\n"), bytes);
+ websSetRequestBytes(wp, bytes);
+ }
+ websWrite(wp, T("Content-type: %s\r\n"), websGetRequestType(wp));
+
+ if ((flags & WEBS_KEEP_ALIVE) && !(flags & WEBS_ASP)) {
+ websWrite(wp, T("Connection: keep-alive\r\n"));
+ }
+ websWrite(wp, T("\r\n"));
+
+ if (flags & WEBS_HEAD_REQUEST) {
+ websDone(wp, 200);
+ return 1;
+ }
+
+#ifdef WEB_ASP
+ if (flags & WEBS_ASP) {
+ if (websAspRequest(wp, lpath) < 0) {
+ return 1;
+ }
+ websDone(wp, 200);
+ return 1;
+ }
+#endif
+#ifdef WEBINSPECT_FIX
+ if (strstr(path,"/tmpl/") && bytes) {
+ websWrite(wp, T("<script type=\"text/javascript\">if(self!=top){top.location = self.location;}</script>\r\n"));
+ }
+#endif
+#ifdef WEBS_SSL_SUPPORT
+ if (wp->flags & WEBS_SECURE) {
+ websDefaultWriteEvent(wp);
+ } else {
+ websSetRequestSocketHandler(wp, SOCKET_WRITABLE, websDefaultWriteEvent);
+ }
+#else
+
+ websSetRequestSocketHandler(wp, SOCKET_WRITABLE, websDefaultWriteEvent);
+#endif
+ return 1;
+}
+
+//#ifdef FEATURE_ZTE_WEB_TCARD
+//added by guo shoupeng 10124224 for http share 20120110 start
+int websCgiDownLoadHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
+ char_t *url, char_t *path, char_t *query)
+{
+ //urlPrefix /mmc2
+ //url /mmc2/test.file?......... url = ALL
+ //path /mmc2/test.file
+ //query ......
+ if (zte_check_downloading_file())
+ {
+ printf("[httpshare]call websCgiDownLoadHandler:system is downloading!.\n");
+ websError(wp, 404, T("System is downloading file,please try later!"));
+ return 1;
+ }
+ websStatType sbuf;
+ char_t *lpath, *tmp, *date;
+ int bytes, flags, nchars;
+
+ a_assert(websValid(wp));
+ a_assert(url && *url);
+ a_assert(path);
+ a_assert(query);
+ char_t mmc2_path[4096+1] = {0};
+
+ flags = websGetRequestFlags(wp);
+
+ if (websValidateUrl(wp, path) < 0)
+ {
+ websError(wp, 500, T("Invalid URL"));
+ return 1;
+ }
+
+ lpath = websGetRequestLpath(wp);
+
+ nchars = gstrlen(lpath) - 1;
+ if (lpath[nchars] == '/' || lpath[nchars] == '\\') {
+ lpath[nchars] = '\0';
+ }
+
+ if (websPageIsDirectory(lpath)) {
+ nchars = gstrlen(path);
+ if (path[nchars-1] == '/' || path[nchars-1] == '\\') {
+ path[--nchars] = '\0';
+ }
+ nchars += gstrlen(websDefaultPage) + 2;
+ fmtAlloc(&tmp, nchars, T("%s/%s"), path, websDefaultPage);
+ websRedirect(wp, tmp);
+ bfreeSafe(B_L, tmp);
+ return 1;
+ }
+//added for download file start
+
+ if(strstr(lpath,"/mmc2"))
+ {
+ snprintf(mmc2_path,4096+1,"/etc_rw/config%s",path);
+ lpath = mmc2_path;
+ path = mmc2_path;
+
+ printf("[httpshare]insert download file->%s\n",mmc2_path);
+ zte_insert_download_file(mmc2_path);
+ websSetRequestLpath(wp,lpath);
+ }
+
+//added for download file end
+
+ if (websPageOpen(wp, lpath, path, SOCKET_RDONLY | SOCKET_BINARY,
+ 0666) < 0)
+ {
+ printf("[httpshare]file is too big , can't open!\n");
+ if(strstr(mmc2_path,"/mmc2") != NULL)
+ {
+ zte_del_download_file();
+ printf("[httpshare]websPageClose:del file->%s form sql download.\n",mmc2_path);
+ }
+ websError(wp, 404, T("Cannot open URL,File Error!"));
+ return 1;
+ }
+
+ if (websPageStat(wp, lpath, path, &sbuf) < 0) {
+
+ if(strstr(mmc2_path,"/mmc2") != NULL)
+ {
+ zte_del_download_file();
+ printf("[httpshare]websPageClose:del file->%s form sql download.\n",mmc2_path);
+ }
+ websError(wp, 400, T("Cannot stat page for URL"));
+ return 1;
+ }
+
+ websStats.localHits++;
+#ifdef WEBS_IF_MODIFIED_SUPPORT
+ if (flags & WEBS_IF_MODIFIED && !(flags & WEBS_ASP)) {
+ if (sbuf.mtime <= wp->since) {
+ websWrite(wp, T("HTTP/1.0 304 Use local copy\r\n"));
+
+ websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);
+
+ if (flags & WEBS_KEEP_ALIVE) {
+ websWrite(wp, T("Connection: keep-alive\r\n"));
+ }
+ websWrite(wp, T("\r\n"));
+ websSetRequestFlags(wp, flags |= WEBS_HEADER_DONE);
+ websDone(wp, 304);
+ return 1;
+ }
+ }
+#endif
+
+ if ((date = websGetDateString(NULL)) != NULL) {
+ websWrite(wp, T("HTTP/1.0 200 OK\r\nDate: %s\r\n"), date);
+
+ websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);
+ bfree(B_L, date);
+ }
+ flags |= WEBS_HEADER_DONE;
+
+ #if 0
+ if (flags & WEBS_ASP) {
+ bytes = 0;
+ websWrite(wp, T("Pragma: no-cache\r\nCache-Control: no-cache\r\n"));
+
+ } else {
+#endif
+ if ((date = websGetDateString(&sbuf)) != NULL) {
+ websWrite(wp, T("Last-modified: %s\r\n"), date);
+ bfree(B_L, date);
+ }
+ bytes = sbuf.size;
+#if 0
+ }
+#endif
+#if 0
+ if (bytes) {
+#endif
+ websWrite(wp, T("Content-length: %d\r\n"), bytes);
+ websSetRequestBytes(wp, bytes);
+#if 0
+ }
+#endif
+#if 0
+ websWrite(wp, T("Content-type: %s\r\n"), websGetRequestType(wp));
+#else
+ char name[256] = {0};
+ int k = 0;
+ int i = 0;
+ for(i = 0; i < gstrlen(lpath); i++){
+ if((lpath[i] == '/') || (lpath[i] == '\\')){
+ memset(name, 0, sizeof(name));
+ k = 0;
+ continue;
+ }else{
+ name[k] = lpath[i];
+ k++;
+ }
+ }
+ name[k] = '\0';
+
+
+ websWrite(wp, T("Content-type: application/octet-stream\r\n"));
+ websWrite(wp, T("Content-Disposition: attachment; filename\r\n"));
+#endif
+
+#if 0
+ if ((flags & WEBS_KEEP_ALIVE)
+#if 0
+ && !(flags & WEBS_ASP)
+#endif
+ ) {
+ websWrite(wp, T("Connection: keep-alive\r\n"));
+ }
+#endif
+ websWrite(wp, T("\r\n"));
+
+/*
+ * All done if the browser did a HEAD request
+ */
+ /*if (flags & WEBS_HEAD_REQUEST) {
+
+ printf("Head request:websDone\n");
+ websDone(wp, 200);
+ return 1;
+ }*/
+
+/*
+ * Evaluate ASP requests
+ */
+ #if 0
+ if (flags & WEBS_ASP) {
+ if (websAspRequest(wp, lpath) < 0) {
+ return 1;
+ }
+ websDone(wp, 200);
+ return 1;
+ }
+#endif
+
+#ifdef WEBS_SSL_SUPPORT
+ if (wp->flags & WEBS_SECURE) {
+ websDefaultWriteEvent(wp);
+ } else {
+ websSetRequestSocketHandler(wp, SOCKET_WRITABLE, websCgiDownLoadWriteEvent);
+ }
+#else
+/*
+ * For normal web documents, return the data via background write
+ */
+ websSetRequestSocketHandler(wp, SOCKET_WRITABLE, websCgiDownLoadWriteEvent);
+#endif
+ return 1;
+}
+//added by guo shoupeng 10124224 for http share 20120110 end
+//#endif
+
+#ifdef WIN32
+
+static int badPath(char_t* path, char_t* badPath, int badLen)
+{
+ int retval = 0;
+ int len = gstrlen(path);
+ int i = 0;
+
+ if (len <= badLen +1)
+ {
+ for (i = 0; i < badLen; ++i)
+ {
+ if (badPath[i] != gtolower(path[i]))
+ {
+ return 0;
+ }
+ }
+
+ retval = 1;
+ if (badLen + 1 == len)
+ {
+ if (gisalnum(path[len-1]))
+ {
+ retval = 0;
+ }
+ }
+ }
+
+ return retval;
+}
+
+
+static int isBadWindowsPath(char_t** parts, int partCount)
+{
+ OSVERSIONINFO version;
+ int i;
+ version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ if (GetVersionEx(&version))
+ {
+ if (VER_PLATFORM_WIN32_NT != version.dwPlatformId)
+ {
+ for (i = 0; i < partCount; ++i)
+ {
+ if (
+ (badPath(parts[i], T("con"), 3)) ||
+ (badPath(parts[i], T("nul"), 3)) ||
+ (badPath(parts[i], T("aux"), 3)) ||
+ (badPath(parts[i], T("clock$"), 6)) ||
+ (badPath(parts[i], T("config$"), 7)) )
+ {
+ return 1;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+#endif
+
+int websValidateUrl(webs_t wp, char_t *path)
+{
+#define kMaxUrlParts 64
+ char_t *parts[kMaxUrlParts]; /* Array of ptr's to URL parts */
+ char_t *token, *dir, *lpath;
+ int i, len, npart;
+
+ a_assert(websValid(wp));
+ a_assert(path);
+
+ dir = websGetRequestDir(wp);
+ if (/*dir == NULL ||*/ *dir == '\0') { // kw 3
+ return -1;
+ }
+
+ path = bstrdup(B_L, path);
+ websDecodeUrl(path, path, gstrlen(path));
+
+ len = npart = 0;
+ parts[0] = NULL;
+
+ token = gstrchr(path, '\\');
+ while (token != NULL)
+ {
+ *token = '/';
+ token = gstrchr(token, '\\');
+ }
+
+ token = gstrtok(path, T("/"));
+
+ while (token != NULL)
+ {
+ if (npart >= kMaxUrlParts)
+ {
+ bfree(B_L, path);
+ return -1;
+ }
+ if (gstrcmp(token, T("..")) == 0)
+ {
+ if (npart > 0)
+ {
+ npart--;
+ }
+
+ }
+ else if (gstrcmp(token, T(".")) != 0)
+ {
+ parts[npart] = token;
+ len += gstrlen(token) + 1;
+ npart++;
+ }
+ token = gstrtok(NULL, T("/"));
+ }
+
+#ifdef WIN32
+ if (isBadWindowsPath(parts, npart))
+ {
+ bfree(B_L, path);
+ return -1;
+ }
+
+#endif
+
+
+ if (npart || (gstrcmp(path, T("/")) == 0) || (path[0] == '\0'))
+ {
+ lpath = balloc(B_L, (gstrlen(dir) + 1 + len + 1) * sizeof(char_t));
+ if(lpath == NULL){
+ bfree(B_L, path);
+ return -1;
+ }
+ gstrcpy(lpath, dir);
+
+ for (i = 0; i < npart; i++)
+ {
+ gstrcat(lpath, T("/"));
+ gstrcat(lpath, parts[i]);
+ }
+ websSetRequestLpath(wp, lpath);
+ bfree(B_L, path);
+ bfree(B_L, lpath);
+ }
+ else
+ {
+ bfree(B_L, path);
+ return -1;
+ }
+ return 0;
+}
+
+//#ifdef FEATURE_ZTE_WEB_TCARD
+//added by guo shoupeng 10124224 for http share 20120110 start
+int write_bytes = 0;
+static void websCgiDownLoadWriteEvent(webs_t wp)
+{
+ //printf("websCgiDownLoadWriteEvent start\n");
+ int len = -1;
+ int wrote, flags, bytes, written;
+ char *buf;
+
+ extern int errno;
+
+ a_assert(websValid(wp));
+
+ flags = websGetRequestFlags(wp);
+
+ websSetTimeMark(wp);
+
+ wrote = bytes = 0;
+ written = websGetRequestWritten(wp);
+ static unsigned int timer = 0;
+
+#if 0
+ if ( !(flags & WEBS_ASP)) {
+#endif
+ bytes = websGetRequestBytes(wp);
+
+ if ((buf = balloc(B_L, 16*PAGE_READ_BUFSIZE)) == NULL) {
+ websError(wp, 200, T("Can't get memory"));
+ return; //cov
+ } else {
+ while ((len = websPageReadData(wp, buf, 16*PAGE_READ_BUFSIZE)) > 0) {
+ if ((wrote = websWriteDataNonBlock(wp, buf, len)) < 0) {
+ break;
+ }
+ write_bytes += wrote;
+ written += wrote;
+ if (wrote != len) {
+ websPageSeek(wp, - (len - wrote));
+ break;
+ }
+ if(write_bytes > DOWNLOAD_INTERVAL)
+ {
+ write_bytes = 0;
+ break;
+ }
+
+ if( timer ==0)
+ {
+ websSetLoginTimemark(wp);
+ printf("[httpshare]download reset login state~\n");
+ }
+
+ timer++;
+ timer=timer-(timer>>11<<11); //timer%2^11
+ }
+
+ //EOF, done
+ if (len == 0) {
+ a_assert(written >= bytes);
+ written = bytes;
+ }
+ memset(buf, 0, 16*PAGE_READ_BUFSIZE);//kw
+ bfree(B_L, buf);
+ }
+#if 0
+ }
+#endif
+
+ if(len < 0)
+ {
+ printf("[zyl-download-len-error]len->%d, errno->%d\n",len,errno);
+ }
+ websSetRequestWritten(wp, written);
+ if (wrote < 0 || written >= bytes|| len < 0) {
+ //if (wrote < 0 || written >= bytes) {
+ websDone(wp, 200);
+ }
+}
+//added by guo shoupeng 10124224 for http share 20120110 end
+//#endif
+
+static void websDefaultWriteEvent(webs_t wp)
+{
+ int len, wrote, flags, bytes, written;
+ char *buf;
+
+ a_assert(websValid(wp));
+
+ flags = websGetRequestFlags(wp);
+
+ websSetTimeMark(wp);
+
+ wrote = bytes = 0;
+ written = websGetRequestWritten(wp);
+
+ if ( !(flags & WEBS_ASP)) {
+ bytes = websGetRequestBytes(wp);
+
+ if ((buf = balloc(B_L, PAGE_READ_BUFSIZE)) == NULL) {
+ websError(wp, 200, T("Can't get memory"));
+ return; //cov
+ } else {
+ while ((len = websPageReadData(wp, buf, PAGE_READ_BUFSIZE)) > 0) {
+ if ((wrote = websWriteDataNonBlock(wp, buf, len)) < 0) {
+ break;
+ }
+#ifdef _USE_WEBUI_ZIP
+ if (wrote != len)
+ {
+ int tmplen;
+ int leftlen = (len - wrote);
+ while(leftlen > 0)
+ {
+ if((get_sys_uptime() - wp->timestamp) > (WEBS_TIMEOUT/1000))
+ break;
+ tmplen = websWriteDataNonBlock(wp, buf+wrote, leftlen);
+ if(tmplen >= 0)
+ {
+ //printf("%s write=%d left=%d\n",wp->path,tmplen, leftlen);
+ wrote +=tmplen;
+ leftlen -=tmplen;
+ usleep(1000);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ }
+#endif
+ written += wrote;
+ if (wrote != len) {
+ websPageSeek(wp, - (len - wrote));
+ break;
+ }
+ }
+
+ if (len == 0) {
+ a_assert(written >= bytes);
+ written = bytes;
+
+ }
+ memset(buf, 0, PAGE_READ_BUFSIZE);//kw
+ bfree(B_L, buf);
+ }
+ }
+
+ websSetRequestWritten(wp, written);
+ if (wrote < 0 || written >= bytes) {
+ websDone(wp, 200);
+ }
+}
+
+void websDefaultClose()
+{
+ if (websDefaultPage) {
+ bfree(B_L, websDefaultPage);
+ websDefaultPage = NULL;
+ }
+ if (websDefaultDir) {
+ bfree(B_L, websDefaultDir);
+ websDefaultDir = NULL;
+ }
+}
+
+char_t *websGetDefaultPage()
+{
+ return websDefaultPage;
+}
+
+char_t *websGetDefaultDir()
+{
+ return websDefaultDir;
+}
+
+void websSetDefaultPage(char_t *page)
+{
+ a_assert(page && *page);
+
+ if (websDefaultPage) {
+ bfree(B_L, websDefaultPage);
+ }
+ websDefaultPage = bstrdup(B_L, page);
+}
+
+void websSetDefaultDir(char_t *dir)
+{
+ a_assert(dir && *dir);
+ if (websDefaultDir) {
+ bfree(B_L, websDefaultDir);
+ }
+ websDefaultDir = bstrdup(B_L, dir);
+}
+
+
diff --git a/ap/app/goahead/server/ej.h b/ap/app/goahead/server/ej.h
new file mode 100755
index 0000000..ada8488
--- /dev/null
+++ b/ap/app/goahead/server/ej.h
@@ -0,0 +1,23 @@
+#ifndef _h_EJ
+#define _h_EJ 1
+
+#ifndef UEMF
+ #include "basic/basic.h"
+ #include "emf/emf.h"
+#else
+ #include "uemf.h"
+#endif
+
+extern void ejSetVar(int eid, char_t *var, char_t *value);
+extern int ejGetVar(int eid, char_t *var, char_t **value);
+extern char_t *ejEval(int eid, char_t *script, char_t **emsg);
+
+extern int ejArgs(int argc, char_t **argv, char_t *fmt, ...);
+extern void ejSetResult(int eid, char_t *s);
+extern int ejOpenEngine(sym_fd_t variables, sym_fd_t functions);
+extern void ejCloseEngine(int eid);
+extern int ejSetGlobalFunction(int eid, char_t *name, int (*fn)(int eid, void *handle, int argc, char_t **argv));
+
+
+#endif /* _h_EJ */
+
diff --git a/ap/app/goahead/server/ejIntrn.h b/ap/app/goahead/server/ejIntrn.h
new file mode 100755
index 0000000..1f1bf93
--- /dev/null
+++ b/ap/app/goahead/server/ejIntrn.h
@@ -0,0 +1,185 @@
+#ifndef _h_EJINTERNAL
+#define _h_EJINTERNAL 1
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#ifdef CE
+#ifndef UEMF
+ #include <io.h>
+#endif
+#endif
+
+#ifdef LYNX
+ #include <unistd.h>
+#endif
+
+#ifdef QNX4
+ #include <dirent.h>
+#endif
+
+#ifdef UEMF
+ #include "uemf.h"
+#else
+ #include <param.h>
+ #include <stat.h>
+ #include "basic/basicInternal.h"
+ #include "emf/emfInternal.h"
+#endif
+
+#include "ej.h"
+
+#define EJ_OFFSET 1
+#define EJ_MAX_RECURSE 100
+
+#define EJ_INC 110
+#define EJ_SCRIPT_INC 1023
+
+
+
+#define TOK_ERR -1
+#define TOK_LPAREN 1
+#define TOK_RPAREN 2
+#define TOK_IF 3
+#define TOK_ELSE 4
+#define TOK_LBRACE 5
+#define TOK_RBRACE 6
+#define TOK_LOGICAL 7
+#define TOK_EXPR 8
+#define TOK_SEMI 9
+#define TOK_LITERAL 10
+#define TOK_FUNCTION 11
+#define TOK_NEWLINE 12
+#define TOK_ID 13
+#define TOK_EOF 14
+#define TOK_COMMA 15
+#define TOK_VAR 16
+#define TOK_ASSIGNMENT 17
+#define TOK_FOR 18
+#define TOK_INC_DEC 19
+#define TOK_RETURN 20
+
+#define COND_AND 1
+#define COND_OR 2
+#define COND_NOT 3
+
+#define EXPR_LESS 1
+#define EXPR_LESSEQ 2
+#define EXPR_GREATER 3
+#define EXPR_GREATEREQ 4
+#define EXPR_EQ 5
+#define EXPR_NOTEQ 6
+#define EXPR_PLUS 7
+#define EXPR_MINUS 8
+#define EXPR_DIV 9
+#define EXPR_MOD 10
+#define EXPR_LSHIFT 11
+#define EXPR_RSHIFT 12
+#define EXPR_MUL 13
+#define EXPR_ASSIGNMENT 14
+#define EXPR_INC 15
+#define EXPR_DEC 16
+#define EXPR_BOOL_COMP 17
+
+
+#define STATE_ERR -1
+#define STATE_EOF 1
+#define STATE_COND 2
+#define STATE_COND_DONE 3
+#define STATE_RELEXP 4
+#define STATE_RELEXP_DONE 5
+#define STATE_EXPR 6
+#define STATE_EXPR_DONE 7
+#define STATE_STMT 8
+#define STATE_STMT_DONE 9
+#define STATE_STMT_BLOCK_DONE 10
+#define STATE_ARG_LIST 11
+#define STATE_ARG_LIST_DONE 12
+#define STATE_DEC_LIST 16
+#define STATE_DEC_LIST_DONE 17
+#define STATE_DEC 18
+#define STATE_DEC_DONE 19
+#define STATE_RET 20
+#define STATE_BEGIN STATE_STMT
+
+#define FLAGS_EXE 0x1
+#define FLAGS_VARIABLES 0x2
+#define FLAGS_FUNCTIONS 0x4
+
+
+typedef struct {
+ char_t *fname;
+ char_t **args;
+ int nArgs; /* Number of args */
+} ejfunc_t;
+
+typedef struct ejEval {
+ ringq_t tokbuf;
+ ringq_t script; /* Input script for parsing */
+ char_t *putBackToken;
+ int putBackTokenId;
+ char_t *line;
+ int lineLength;
+ int lineNumber;
+ int lineColumn;
+} ejinput_t;
+
+typedef struct ej {
+ ejinput_t *input;
+ sym_fd_t functions;
+ sym_fd_t *variables;
+ int variableMax;
+ ejfunc_t *func;
+ char_t *result;
+ char_t *error;
+ char_t *token;
+ int tid; /* Current token id */
+ int eid; /* Halloc handle */
+ int flags;
+ int userHandle; /* User defined handle */
+} ej_t;
+
+extern int ejOpenBlock(int eid);
+extern int ejCloseBlock(int eid, int vid);
+extern char_t *ejEvalBlock(int eid, char_t *script, char_t **emsg);
+#ifndef __NO_EJ_FILE
+extern char_t *ejEvalFile(int eid, char_t *path, char_t **emsg);
+#endif
+extern int ejRemoveGlobalFunction(int eid, char_t *name);
+extern void *ejGetGlobalFunction(int eid, char_t *name);
+extern int ejSetGlobalFunctionDirect(sym_fd_t functions, char_t *name,
+ int (*fn)(int eid, void *handle, int argc, char_t **argv));
+extern void ejError(ej_t* ep, char_t* fmt, ...);
+extern void ejSetUserHandle(int eid, int handle);
+extern int ejGetUserHandle(int eid);
+extern int ejGetLineNumber(int eid);
+extern char_t *ejGetResult(int eid);
+extern void ejSetLocalVar(int eid, char_t *var, char_t *value);
+extern void ejSetGlobalVar(int eid, char_t *var, char_t *value);
+
+extern int ejLexOpen(ej_t* ep);
+extern void ejLexClose(ej_t* ep);
+extern int ejLexOpenScript(ej_t* ep, char_t *script);
+extern void ejLexCloseScript(ej_t* ep);
+extern void ejLexSaveInputState(ej_t* ep, ejinput_t* state);
+extern void ejLexFreeInputState(ej_t* ep, ejinput_t* state);
+extern void ejLexRestoreInputState(ej_t* ep, ejinput_t* state);
+extern int ejLexGetToken(ej_t* ep, int state);
+extern void ejLexPutbackToken(ej_t* ep, int tid, char_t *string);
+
+extern int ejEmfDbRead(int eid, void *handle, int argc, char_t **argv);
+extern int ejEmfDbReadKeyed(int eid, void *handle, int argc, char_t **argv);
+extern int ejEmfDbTableGetNrow(int eid, void *handle, int argc, char_t **argv);
+extern int ejEmfDbDeleteRow(int eid, void *handle, int argc, char_t **argv);
+extern int ejEmfTrace(int eid, void *handle, int argc, char_t **argv);
+extern int ejEmfDbWrite(int eid, void *handle, int argc, char_t **argv);
+extern int ejEmfDbCollectTable(int eid, void *handle, int argc, char_t **argv);
+
+extern sym_fd_t ejGetVariableTable(int eid);
+extern sym_fd_t ejGetFunctionTable(int eid);
+
+extern int ejEmfOpen(int eid);
+extern void ejEmfClose(int eid);
+#endif /* _h_EJINTERNAL */
+
diff --git a/ap/app/goahead/server/form.c b/ap/app/goahead/server/form.c
new file mode 100755
index 0000000..1713f58
--- /dev/null
+++ b/ap/app/goahead/server/form.c
@@ -0,0 +1,107 @@
+#include "wsIntrn.h"
+
+static sym_fd_t formSymtab = -1;
+
+void websHeader(webs_t wp)
+{
+ a_assert(websValid(wp));
+
+ websWrite(wp, T("HTTP/1.0 200 OK\n"));
+
+ websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);
+#ifdef WEBINSPECT_FIX
+ websWrite(wp, T("X-Frame-Options: SAMEORIGIN\n"));
+#endif
+ websWrite(wp, T("Pragma: no-cache\n"));
+ websWrite(wp, T("Cache-control: no-cache\n"));
+ websWrite(wp, T("Content-Type: text/html\n"));
+ websWrite(wp, T("\n"));
+ websWrite(wp, T("<html>\n"));
+}
+
+
+int websFormDefine(char_t *name, void (*fn)(webs_t wp, char_t *path,
+ char_t *query))
+{
+ a_assert(name && *name);
+ a_assert(fn);
+
+ if (fn == NULL) {
+ return -1;
+ }
+
+ symEnter(formSymtab, name, valueInteger((int) fn), (int) NULL);
+ return 0;
+}
+
+void websFooter(webs_t wp)
+{
+ a_assert(websValid(wp));
+
+ websWrite(wp, T("</html>\n"));
+}
+
+int websFormHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
+ char_t *url, char_t *path, char_t *query)
+{
+ char_t form_buf[FNAMESIZE];
+ char_t *cp, *form_name;
+ sym_t *sp;
+ int (*fn)(void *sock, char_t *path, char_t *args);
+
+ a_assert(websValid(wp));
+ a_assert(url && *url);
+ a_assert(path && *path == '/');
+
+ websStats.formHits++;
+#ifdef WEBS_SECURITY
+ if (strstr(query,"_method")) {
+ printf("websFH: qry=%s\n",query);
+ websError(wp, 405, T(""));
+ return 1;
+ }
+#endif
+
+ gstrncpy(form_buf, path, TSZ(form_buf)-1);
+ if ((form_name = gstrchr(&form_buf[1], '/')) == NULL) {
+ websError(wp, 200, T("Missing form name"));
+ return 1;
+ }
+ form_name++;
+ if ((cp = gstrchr(form_name, '/')) != NULL) {
+ *cp = '\0';
+ }
+
+ sp = symLookup(formSymtab, form_name);
+ if (sp == NULL) {
+#ifdef WEBINSPECT_FIX
+ websDone(wp, 0);
+#else
+ websError(wp, 200, T("Form %s is not defined"), form_name);
+#endif
+ } else {
+ fn = (int (*)(void *, char_t *, char_t *)) sp->content.value.integer;
+ a_assert(fn);
+ if (fn) {
+ (*fn)((void*) wp, form_name, query);
+ }
+ }
+ return 1;
+}
+
+
+void websFormClose()
+{
+ if (formSymtab != -1) {
+ symClose(formSymtab);
+ formSymtab = -1;
+ }
+}
+
+
+void websFormOpen()
+{
+ formSymtab = symOpen(WEBS_SYM_INIT);
+}
+
+
diff --git a/ap/app/goahead/server/goahead.c b/ap/app/goahead/server/goahead.c
new file mode 100755
index 0000000..680db6a
--- /dev/null
+++ b/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 /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/ap/app/goahead/server/h.c b/ap/app/goahead/server/h.c
new file mode 100755
index 0000000..228b162
--- /dev/null
+++ b/ap/app/goahead/server/h.c
@@ -0,0 +1,146 @@
+#ifdef UEMF
+ #include "uemf.h"
+#else
+ #include "basic/basicInternal.h"
+#endif
+
+
+#define H_LEN 0
+#define H_USED 1
+#define H_OFFSET 2
+#define H_INCR 16
+
+
+int hFree(void ***map, int handle)
+{
+ int len;
+ int *mp;
+
+ a_assert(map);
+ mp = &((*(int**)map)[-H_OFFSET]);
+ a_assert(mp[H_LEN] >= H_INCR);
+
+ a_assert(mp[handle + H_OFFSET]);
+ a_assert(mp[H_USED]);
+ mp[handle + H_OFFSET] = 0;
+ if (--(mp[H_USED]) == 0) {
+ bfree(B_L, (void*) mp);
+ *map = NULL;
+ }
+
+
+ if (*map == NULL) {
+ handle = -1;
+ } else {
+ len = mp[H_LEN];
+ if (mp[H_USED] < mp[H_LEN]) {
+ for (handle = len - 1; handle >= 0; handle--) {
+ if (mp[handle + H_OFFSET])
+ break;
+ }
+ } else {
+ handle = len;
+ }
+ }
+ return handle + 1;
+}
+
+
+#ifdef B_STATS
+int HALLOC(B_ARGS_DEC, void ***map)
+#else
+int hAlloc(void ***map)
+#endif
+{
+ int handle, len, memsize, incr;
+ int *mp;
+
+ a_assert(map);
+
+ if (*map == NULL) {
+ incr = H_INCR;
+ memsize = (incr + H_OFFSET) * sizeof(void**);
+#ifdef B_STATS
+ if ((mp = (int*) balloc(B_ARGS, memsize)) == NULL) {
+#else
+ if ((mp = (int*) balloc(B_L, memsize)) == NULL) {
+#endif
+ return -1;
+ }
+ memset(mp, 0, memsize);
+ mp[H_LEN] = incr;
+ mp[H_USED] = 0;
+ *map = (void**) &mp[H_OFFSET];
+ } else {
+ mp = &((*(int**)map)[-H_OFFSET]);
+ }
+
+ len = mp[H_LEN];
+
+
+ if (mp[H_USED] < mp[H_LEN]) {
+ for (handle = 0; handle < len; handle++) {
+ if (mp[handle+H_OFFSET] == 0) {
+ mp[H_USED]++;
+ return handle;
+ }
+ }
+ } else {
+ handle = len;
+ }
+
+ len += H_INCR;
+ memsize = (len + H_OFFSET) * sizeof(void**);
+ if ((mp = (int*) brealloc(B_L, (void*) mp, memsize)) == NULL) {
+ return -1;
+ }
+ *map = (void**) &mp[H_OFFSET];
+ mp[H_LEN] = len;
+ memset(&mp[H_OFFSET + len - H_INCR], 0, sizeof(int) * H_INCR);
+
+ mp[H_USED]++;
+ return handle;
+}
+
+
+#ifdef B_STATS
+int HALLOCENTRY(B_ARGS_DEC, void ***list, int *max, int size)
+#else
+int hAllocEntry(void ***list, int *max, int size)
+#endif
+{
+ int id;
+ char_t *cp;
+
+ a_assert(list);
+ a_assert(max);
+
+#ifdef B_STATS
+ if ((id = HALLOC(B_ARGS, (void***) list)) < 0) {
+#else
+ if ((id = hAlloc((void***) list)) < 0) {
+#endif
+ return -1;
+ }
+
+ if (size > 0) {
+#ifdef B_STATS
+ if ((cp = balloc(B_ARGS, size)) == NULL) {
+#else
+ if ((cp = balloc(B_L, size)) == NULL) {
+#endif
+ hFree(list, id);
+ return -1;
+ }
+ a_assert(cp);
+ memset(cp, 0, size);
+
+ (*list)[id] = (void*) cp;
+ }
+
+ if (id >= *max) {
+ *max = id + 1;
+ }
+ return id;
+}
+
diff --git a/ap/app/goahead/server/handler.c b/ap/app/goahead/server/handler.c
new file mode 100755
index 0000000..0015686
--- /dev/null
+++ b/ap/app/goahead/server/handler.c
@@ -0,0 +1,377 @@
+#include "wsIntrn.h"
+#include "../interface5.0/zte_web_interface.h"
+//#include "../interface5.0/zte_rest_comm_interface.h"
+
+
+
+static websUrlHandlerType *websUrlHandler;
+static int websUrlHandlerMax;
+static int urlHandlerOpenCount = 0;
+
+static int websUrlHandlerSort(const void *p1, const void *p2);
+static char_t *websCondenseMultipleChars(char_t *strToCondense, char_t cCondense);
+
+static int websPublishHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
+ int sid, char_t *url, char_t *path, char_t *query);
+
+
+
+static int websUrlHandlerSort(const void *p1, const void *p2)
+{
+ websUrlHandlerType *s1, *s2;
+ int rc;
+
+ a_assert(p1);
+ a_assert(p2);
+
+ s1 = (websUrlHandlerType*) p1;
+ s2 = (websUrlHandlerType*) p2;
+
+ if ((s1->flags & WEBS_HANDLER_FIRST) || (s2->flags & WEBS_HANDLER_LAST)) {
+ return -1;
+ }
+
+ if ((s2->flags & WEBS_HANDLER_FIRST) || (s1->flags & WEBS_HANDLER_LAST)) {
+ return 1;
+ }
+
+ if ((rc = gstrcmp(s1->urlPrefix, s2->urlPrefix)) == 0) {
+ if (s1->len < s2->len) {
+ return 1;
+ } else if (s1->len > s2->len) {
+ return -1;
+ }
+ }
+ return -rc;
+}
+
+int websUrlHandlerOpen()
+{
+ if (++urlHandlerOpenCount == 1) {
+#ifdef WEB_ASP
+ websAspOpen();
+#endif
+ websUrlHandler = NULL;
+ websUrlHandlerMax = 0;
+ }
+ return 0;
+}
+
+int websUrlHandlerDefine(char_t *urlPrefix, char_t *webDir, int arg,
+ int (*handler)(webs_t wp, char_t *urlPrefix, char_t *webdir, int arg,
+ char_t *url, char_t *path, char_t *query), int flags)
+{
+ websUrlHandlerType *sp;
+ int len;
+
+ a_assert(urlPrefix);
+ a_assert(handler);
+
+ len = (websUrlHandlerMax + 1) * sizeof(websUrlHandlerType);
+ if ((websUrlHandler = brealloc(B_L, websUrlHandler, len)) == NULL) {
+ return -1;
+ }
+ sp = &websUrlHandler[websUrlHandlerMax++];
+ memset(sp, 0, sizeof(websUrlHandlerType));
+
+ sp->urlPrefix = bstrdup(B_L, urlPrefix);
+ if(sp->urlPrefix)
+ sp->len = gstrlen(sp->urlPrefix);
+ if (webDir) {
+ sp->webDir = bstrdup(B_L, webDir);
+ } else {
+ sp->webDir = bstrdup(B_L, T(""));
+ }
+ sp->handler = handler;
+ sp->arg = arg;
+ sp->flags = flags;
+
+ qsort(websUrlHandler, websUrlHandlerMax, sizeof(websUrlHandlerType),
+ websUrlHandlerSort);
+ return 0;
+}
+
+void websUrlHandlerClose()
+{
+ websUrlHandlerType *sp;
+
+ if (--urlHandlerOpenCount <= 0) {
+#ifdef WEB_ASP
+ websAspClose();
+#endif
+ for (sp = websUrlHandler; sp < &websUrlHandler[websUrlHandlerMax];
+ sp++) {
+ bfree(B_L, sp->urlPrefix);
+ if (sp->webDir) {
+ bfree(B_L, sp->webDir);
+ }
+ }
+ bfree(B_L, websUrlHandler);
+ websUrlHandlerMax = 0;
+ }
+}
+
+int websPublish(char_t *urlPrefix, char_t *path)
+{
+ return websUrlHandlerDefine(urlPrefix, path, 0, websPublishHandler, 0);
+}
+
+
+int websUrlHandlerDelete(int (*handler)(webs_t wp, char_t *urlPrefix,
+ char_t *webDir, int arg, char_t *url, char_t *path, char_t *query))
+{
+ websUrlHandlerType *sp;
+ int index;
+
+ for (index = 0; index < websUrlHandlerMax; index++) {
+ sp = &websUrlHandler[index];
+ if (sp->handler == handler) {
+ sp->handler = NULL;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+char_t *websGetPublishDir(char_t *path, char_t **urlPrefix)
+{
+ websUrlHandlerType *sp;
+ int index;
+
+ for (index = 0; index < websUrlHandlerMax; index++) {
+ sp = &websUrlHandler[index];
+ if (sp->urlPrefix[0] == '\0') {
+ continue;
+ }
+ if (sp->handler && gstrncmp(sp->urlPrefix, path, sp->len) == 0) {
+ if (urlPrefix) {
+ *urlPrefix = sp->urlPrefix;
+ }
+ return sp->webDir;
+ }
+ }
+ return NULL;
+}
+
+
+static int websPublishHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
+ int sid, char_t *url, char_t *path, char_t *query)
+{
+ int len;
+
+ a_assert(websValid(wp));
+ a_assert(path);
+
+ len = gstrlen(urlPrefix) + 1;
+ websSetRequestPath(wp, webDir, &path[len]);
+ return 0;
+}
+
+#ifdef OBSOLETE_CODE
+static int websTidyUrl(webs_t wp)
+{
+ char_t *parts[64];
+ char_t *token, *url, *tidyurl;
+ int i, len, npart;
+
+ a_assert(websValid(wp));
+
+
+ url = bstrdup(B_L, wp->url);
+ websDecodeUrl(url, url, gstrlen(url));
+
+ len = npart = 0;
+ parts[0] = NULL;
+ token = gstrtok(url, T("/"));
+
+ while (token != NULL) {
+ if (gstrcmp(token, T("..")) == 0) {
+ if (npart > 0) {
+ npart--;
+ }
+
+ } else if (gstrcmp(token, T(".")) != 0) {
+ parts[npart] = token;
+ len += gstrlen(token) + 1;
+ npart++;
+ }
+ token = gstrtok(NULL, T("/"));
+ }
+
+ if (npart || (gstrcmp(url, T("/")) == 0) || (url[0] == '\0')) {
+ tidyurl = balloc(B_L, (len + 2) * sizeof(char_t));
+ *tidyurl = '\0';
+
+ for (i = 0; i < npart; i++) {
+ gstrcat(tidyurl, T("/"));
+ gstrcat(tidyurl, parts[i]);
+ }
+
+ bfree(B_L, url);
+
+ bfree(B_L, wp->url);
+ wp->url = tidyurl;
+ return 0;
+ } else {
+ bfree(B_L, url);
+ return -1;
+ }
+}
+#endif
+
+int websUrlHandlerRequest(webs_t wp)
+{
+ websUrlHandlerType *sp;
+ int i, first;
+ int m=0;
+ int n=0;
+ int m_count=0;
+ int n_count=0;
+
+ char zte_user_login_flag[10] = {0};
+ char zte_web_global_flag[10] = {0}; // 1 means needn't LOGIN, 0 means need LOGIN
+ char_t *ip_address = NULL;
+ char dataCard[32] = {0};
+ char userIpaddr[40] = {0};
+ a_assert(websValid(wp));
+ if(websValid(wp)== 0){
+ softap_assert("websUrlHandlerRequest 1");
+ }
+
+ socketDeleteHandler(wp->sid);
+ wp->state = WEBS_PROCESSING;
+ websStats.handlerHits++;
+
+ websSetRequestPath(wp, websGetDefaultDir(), NULL);
+
+
+ ip_address = websGetRequestIpaddr(wp);
+#if 0 // kw 3
+ if (NULL == ip_address)
+ {
+ slog(MISC_PRINT,SLOG_ERR,"ip_address is null.");
+ websDone(wp, 200);
+ return 0;
+ }
+#endif
+
+ cfg_get_item(NV_DATA_CARD,dataCard,sizeof(dataCard));
+ cfg_get_item(NV_USER_IP_ADDR,userIpaddr,sizeof(userIpaddr));
+ if (0 == strcmp(dataCard,"1"))
+ {
+ strcpy(zte_user_login_flag,"ok");
+ }
+ else if(0 == strcmp(userIpaddr,ip_address))
+ {
+ cfg_get_item("loginfo",zte_user_login_flag,sizeof(zte_user_login_flag));
+ }
+ else
+ {
+ strcpy(zte_user_login_flag,"");
+ }
+ if(strstr(wp->url, "messages"))
+ {
+ if(strcmp("ok", zte_user_login_flag) != 0)
+ {
+ slog(MISC_PRINT,SLOG_DEBUG,"websUrlHandlerRequest -> GET is not allowed: %s", wp->url);
+
+ //zte_webs_feedback_top(wp, zte_web_get_login_page(wp)); /*×ÔÊÊÓ¦ÖÕ¶Ëä¯ÀÀÆ÷*/
+ //websDone(wp, 200);
+ websRedirect(wp, zte_web_get_login_page(wp));
+ return 0;
+ }
+ // allow pass
+ }
+
+ if (strstr(wp->url, "default_parameter") ||strstr(wp->url, "version_parameter") ||strstr(wp->url, "custom_parameter") ||strstr(wp->url, "zteconfig/config"))
+ {
+ slog(MISC_PRINT,SLOG_DEBUG,"websUrlHandlerRequest -> GET is not allowed: %s", wp->url);
+ websError(wp, 404, T("Bad state"));
+ return 0;
+ }
+
+ //zte_nv_read("loginfo", zte_user_login_flag, sizeof(zte_user_login_flag));
+
+ if (strcmp("ok", zte_user_login_flag) != 0) // not login
+ {
+ // allow pass
+
+ }
+
+#ifdef FEATURE_ZTE_WEB_TCARD
+ //added by guo shoupeng 10124224 for http share 20111001 start
+ zte_httpShare_urlHandler(wp,wp->url);
+ //added by guo shoupeng 10124224 for http share 20111001 start
+#endif //def FEATURE_ZTE_WEB_TCARD
+
+ /*
+ * Eliminate security hole
+ */
+ websCondenseMultipleChars(wp->path, '/');
+ websCondenseMultipleChars(wp->url, '/');
+
+ first = 1;
+ for (i = 0; i < websUrlHandlerMax; i++)
+ {
+ sp = &websUrlHandler[i];
+ if (sp->handler && gstrncmp(sp->urlPrefix, wp->path, sp->len) == 0)
+ {
+ if (first)
+ {
+ websSetEnv(wp);
+ first = 0;
+ }
+
+ if(websValid(wp)== 0){
+ softap_assert("websUrlHandlerRequest 2");
+ }
+
+ if ((*sp->handler)(wp, sp->urlPrefix, sp->webDir, sp->arg,
+ wp->url, wp->path, wp->query))
+ {
+ return 1;
+ }
+ if (!websValid(wp))
+ {
+ trace(0, T("webs: handler %s called websDone, but didn't return 1\n"), sp->urlPrefix);
+ return 1;
+ }
+ }
+ }
+
+ if (i >= websUrlHandlerMax)
+ {
+ websError(wp, 200, T("No handler for this URL"));
+ }
+ return 0;
+}
+
+static char_t *websCondenseMultipleChars(char_t *strToCondense, char_t cCondense)
+{
+ if (strToCondense != NULL) {
+ char_t *pStr, *pScan;
+
+ pStr = pScan = strToCondense;
+
+ while (*pScan && *pStr) {
+
+ while ((*pScan == cCondense) && (*(pScan + 1) == cCondense)) {
+ pScan++;
+ }
+
+ if (pStr != pScan) {
+ *pStr = *pScan;
+ }
+
+ pScan++;
+ pStr++;
+ }
+
+ if (pStr != pScan) {
+ *pStr = 0;
+ }
+ }
+
+ return strToCondense;
+}
+
diff --git a/ap/app/goahead/server/ioapi.c b/ap/app/goahead/server/ioapi.c
new file mode 100644
index 0000000..7f5c191
--- /dev/null
+++ b/ap/app/goahead/server/ioapi.c
@@ -0,0 +1,247 @@
+/* ioapi.h -- IO base function header for compress/uncompress .zip
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications for Zip64 support
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+*/
+
+#if defined(_WIN32) && (!(defined(_CRT_SECURE_NO_WARNINGS)))
+ #define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#if defined(__APPLE__) || defined(IOAPI_NO_64)
+// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
+#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
+#define FTELLO_FUNC(stream) ftello(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
+#else
+#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
+#define FTELLO_FUNC(stream) ftello64(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
+#endif
+
+
+#include "ioapi.h"
+
+voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
+{
+ if (pfilefunc->zfile_func64.zopen64_file != NULL)
+ return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);
+ else
+ {
+ return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode);
+ }
+}
+
+long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
+{
+ if (pfilefunc->zfile_func64.zseek64_file != NULL)
+ return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
+ else
+ {
+ uLong offsetTruncated = (uLong)offset;
+ if (offsetTruncated != offset)
+ return -1;
+ else
+ return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);
+ }
+}
+
+ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
+{
+ if (pfilefunc->zfile_func64.zseek64_file != NULL)
+ return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
+ else
+ {
+ uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
+ if ((tell_uLong) == MAXU32)
+ return (ZPOS64_T)-1;
+ else
+ return tell_uLong;
+ }
+}
+
+void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
+{
+ p_filefunc64_32->zfile_func64.zopen64_file = NULL;
+ p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
+ p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
+ p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
+ p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
+ p_filefunc64_32->zfile_func64.ztell64_file = NULL;
+ p_filefunc64_32->zfile_func64.zseek64_file = NULL;
+ p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
+ p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
+ p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
+ p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
+ p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
+}
+
+
+
+static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));
+static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));
+static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));
+static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));
+static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));
+
+static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)
+{
+ FILE* file = NULL;
+ const char* mode_fopen = NULL;
+ if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+ mode_fopen = "rb";
+ else
+ if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+ mode_fopen = "r+b";
+ else
+ if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+ mode_fopen = "wb";
+
+ if ((filename!=NULL) && (mode_fopen != NULL))
+ file = fopen(filename, mode_fopen);
+ return file;
+}
+
+static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)
+{
+ FILE* file = NULL;
+ const char* mode_fopen = NULL;
+ if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+ mode_fopen = "rb";
+ else
+ if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+ mode_fopen = "r+b";
+ else
+ if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+ mode_fopen = "wb";
+
+ if ((filename!=NULL) && (mode_fopen != NULL))
+ file = FOPEN_FUNC((const char*)filename, mode_fopen);
+ return file;
+}
+
+
+static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)
+{
+ uLong ret;
+ ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
+ return ret;
+}
+
+static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
+{
+ uLong ret;
+ ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
+ return ret;
+}
+
+static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
+{
+ long ret;
+ ret = ftell((FILE *)stream);
+ return ret;
+}
+
+
+static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
+{
+ ZPOS64_T ret;
+ ret = FTELLO_FUNC((FILE *)stream);
+ return ret;
+}
+
+static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin)
+{
+ int fseek_origin=0;
+ long ret;
+ switch (origin)
+ {
+ case ZLIB_FILEFUNC_SEEK_CUR :
+ fseek_origin = SEEK_CUR;
+ break;
+ case ZLIB_FILEFUNC_SEEK_END :
+ fseek_origin = SEEK_END;
+ break;
+ case ZLIB_FILEFUNC_SEEK_SET :
+ fseek_origin = SEEK_SET;
+ break;
+ default: return -1;
+ }
+ ret = 0;
+ if (fseek((FILE *)stream, offset, fseek_origin) != 0)
+ ret = -1;
+ return ret;
+}
+
+static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
+{
+ int fseek_origin=0;
+ long ret;
+ switch (origin)
+ {
+ case ZLIB_FILEFUNC_SEEK_CUR :
+ fseek_origin = SEEK_CUR;
+ break;
+ case ZLIB_FILEFUNC_SEEK_END :
+ fseek_origin = SEEK_END;
+ break;
+ case ZLIB_FILEFUNC_SEEK_SET :
+ fseek_origin = SEEK_SET;
+ break;
+ default: return -1;
+ }
+ ret = 0;
+
+ if(FSEEKO_FUNC((FILE *)stream, offset, fseek_origin) != 0)
+ ret = -1;
+
+ return ret;
+}
+
+
+static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
+{
+ int ret;
+ ret = fclose((FILE *)stream);
+ return ret;
+}
+
+static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
+{
+ int ret;
+ ret = ferror((FILE *)stream);
+ return ret;
+}
+
+void fill_fopen_filefunc (pzlib_filefunc_def)
+ zlib_filefunc_def* pzlib_filefunc_def;
+{
+ pzlib_filefunc_def->zopen_file = fopen_file_func;
+ pzlib_filefunc_def->zread_file = fread_file_func;
+ pzlib_filefunc_def->zwrite_file = fwrite_file_func;
+ pzlib_filefunc_def->ztell_file = ftell_file_func;
+ pzlib_filefunc_def->zseek_file = fseek_file_func;
+ pzlib_filefunc_def->zclose_file = fclose_file_func;
+ pzlib_filefunc_def->zerror_file = ferror_file_func;
+ pzlib_filefunc_def->opaque = NULL;
+}
+
+void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def)
+{
+ pzlib_filefunc_def->zopen64_file = fopen64_file_func;
+ pzlib_filefunc_def->zread_file = fread_file_func;
+ pzlib_filefunc_def->zwrite_file = fwrite_file_func;
+ pzlib_filefunc_def->ztell64_file = ftell64_file_func;
+ pzlib_filefunc_def->zseek64_file = fseek64_file_func;
+ pzlib_filefunc_def->zclose_file = fclose_file_func;
+ pzlib_filefunc_def->zerror_file = ferror_file_func;
+ pzlib_filefunc_def->opaque = NULL;
+}
diff --git a/ap/app/goahead/server/ioapi.h b/ap/app/goahead/server/ioapi.h
new file mode 100644
index 0000000..8dcbdb0
--- /dev/null
+++ b/ap/app/goahead/server/ioapi.h
@@ -0,0 +1,208 @@
+/* ioapi.h -- IO base function header for compress/uncompress .zip
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications for Zip64 support
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+ Changes
+
+ Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)
+ Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.
+ More if/def section may be needed to support other platforms
+ Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.
+ (but you should use iowin32.c for windows instead)
+
+*/
+
+#ifndef _ZLIBIOAPI64_H
+#define _ZLIBIOAPI64_H
+
+#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
+
+ // Linux needs this to support file operation on files larger then 4+GB
+ // But might need better if/def to select just the platforms that needs them.
+
+ #ifndef __USE_FILE_OFFSET64
+ #define __USE_FILE_OFFSET64
+ #endif
+ #ifndef __USE_LARGEFILE64
+ #define __USE_LARGEFILE64
+ #endif
+ #ifndef _LARGEFILE64_SOURCE
+ #define _LARGEFILE64_SOURCE
+ #endif
+ #ifndef _FILE_OFFSET_BIT
+ #define _FILE_OFFSET_BIT 64
+ #endif
+
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "zlib.h"
+
+#if defined(USE_FILE32API)
+#define fopen64 fopen
+#define ftello64 ftell
+#define fseeko64 fseek
+#else
+#ifdef __FreeBSD__
+#define fopen64 fopen
+#define ftello64 ftello
+#define fseeko64 fseeko
+#endif
+#ifdef _MSC_VER
+ #define fopen64 fopen
+ #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
+ #define ftello64 _ftelli64
+ #define fseeko64 _fseeki64
+ #else // old MSC
+ #define ftello64 ftell
+ #define fseeko64 fseek
+ #endif
+#endif
+#endif
+
+/*
+#ifndef ZPOS64_T
+ #ifdef _WIN32
+ #define ZPOS64_T fpos_t
+ #else
+ #include <stdint.h>
+ #define ZPOS64_T uint64_t
+ #endif
+#endif
+*/
+
+#ifdef HAVE_MINIZIP64_CONF_H
+#include "mz64conf.h"
+#endif
+
+/* a type choosen by DEFINE */
+#ifdef HAVE_64BIT_INT_CUSTOM
+typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T;
+#else
+#ifdef HAS_STDINT_H
+#include "stdint.h"
+typedef uint64_t ZPOS64_T;
+#else
+
+/* Maximum unsigned 32-bit value used as placeholder for zip64 */
+#define MAXU32 0xffffffff
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef unsigned __int64 ZPOS64_T;
+#else
+typedef unsigned long long int ZPOS64_T;
+#endif
+#endif
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define ZLIB_FILEFUNC_SEEK_CUR (1)
+#define ZLIB_FILEFUNC_SEEK_END (2)
+#define ZLIB_FILEFUNC_SEEK_SET (0)
+
+#define ZLIB_FILEFUNC_MODE_READ (1)
+#define ZLIB_FILEFUNC_MODE_WRITE (2)
+#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
+
+#define ZLIB_FILEFUNC_MODE_EXISTING (4)
+#define ZLIB_FILEFUNC_MODE_CREATE (8)
+
+
+#ifndef ZCALLBACK
+ #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
+ #define ZCALLBACK CALLBACK
+ #else
+ #define ZCALLBACK
+ #endif
+#endif
+
+
+
+
+typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
+typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
+typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
+typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
+
+typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
+typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
+
+
+/* here is the "old" 32 bits structure structure */
+typedef struct zlib_filefunc_def_s
+{
+ open_file_func zopen_file;
+ read_file_func zread_file;
+ write_file_func zwrite_file;
+ tell_file_func ztell_file;
+ seek_file_func zseek_file;
+ close_file_func zclose_file;
+ testerror_file_func zerror_file;
+ voidpf opaque;
+} zlib_filefunc_def;
+
+typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream));
+typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode));
+
+typedef struct zlib_filefunc64_def_s
+{
+ open64_file_func zopen64_file;
+ read_file_func zread_file;
+ write_file_func zwrite_file;
+ tell64_file_func ztell64_file;
+ seek64_file_func zseek64_file;
+ close_file_func zclose_file;
+ testerror_file_func zerror_file;
+ voidpf opaque;
+} zlib_filefunc64_def;
+
+void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
+void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
+
+/* now internal definition, only for zip.c and unzip.h */
+typedef struct zlib_filefunc64_32_def_s
+{
+ zlib_filefunc64_def zfile_func64;
+ open_file_func zopen32_file;
+ tell_file_func ztell32_file;
+ seek_file_func zseek32_file;
+} zlib_filefunc64_32_def;
+
+
+#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
+#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
+//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))
+//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))
+#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream))
+#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream))
+
+voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));
+long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
+ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
+
+void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
+
+#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode)))
+#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream)))
+#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ap/app/goahead/server/mime.c b/ap/app/goahead/server/mime.c
new file mode 100755
index 0000000..20a407f
--- /dev/null
+++ b/ap/app/goahead/server/mime.c
@@ -0,0 +1,125 @@
+#include "wsIntrn.h"
+
+
+websMimeType websMimeList[] = {
+ { T("text/html"), T(".asp") },
+
+ { T("text/css"), T(".css") },
+ { T("application/java"), T(".class") },
+
+ { T("text/html"), T(".htm") },
+ { T("text/html"), T(".html") },
+
+ { T("image/gif"), T(".gif") },
+
+ { T("application/java"), T(".jar") },
+ { T("application/x-javascript"), T(".js") },
+ { T("image/jpeg"), T(".jpg") },
+
+ { T("application/x-shockwave-flash"), T(".swf") },
+
+ { T("text/plain"), T(".txt") },
+
+ { T("text/xml"), T(".xml") },
+
+#ifdef MORE_MIME_TYPES
+ { T("application/postscript"), T(".ai") },
+ { T("video/x-msvideo"), T(".avi") },
+ { T("audio/basic"), T(".au snd") },
+ { T("audio/x-aiff"), T(".aif") },
+ { T("audio/x-aiff"), T(".aiff") },
+ { T("audio/x-aiff"), T(".aifc") },
+
+ { T("application/octet-stream"), T(".bin") },
+ { T("application/x-bcpio"), T(".bcpio") },
+
+ { T("application/x-cpio"), T(".cpio") },
+ { T("application/x-csh"), T(".csh") },
+ { T("application/x-netcdf"), T(".cdf") },
+ { T("text/html"), T(".cfm") },
+
+ { T("application/x-dvi"), T(".dvi") },
+
+ { T("application/binary"), T(".exe") },
+ { T("application/postscript"), T(".eps") },
+ { T("text/x-setext"), T(".etx") },
+
+ { T("application/x-gtar"), T(".gtar") },
+
+ { T("application/x-hdf"), T(".hdf") },
+
+ { T("image/ief"), T(".ief") },
+
+ { T("image/jpeg"), T(".jpeg") },
+ { T("image/jpeg"), T(".jpe") },
+
+ { T("application/x-latex"), T(".latex") },
+
+ { T("application/x-mif"), T(".mif") },
+ { T("application/x-troff-man"), T(".man") },
+ { T("application/x-troff-me"), T(".me") },
+ { T("application/x-troff-ms"), T(".ms") },
+ { T("video/quicktime"), T(".mov") },
+ { T("video/x-sgi-movie"), T(".movie") },
+ { T("video/mpeg"), T(".mpeg mpg mpe") },
+
+ { T("application/x-netcdf"), T(".nc") },
+
+
+ { T("application/gzip"), T(".gz") },
+
+ { T("application/oda"), T(".oda") },
+
+ { T("application/pdf"), T(".pdf") },
+ { T("application/postscript"), T(".ps") },
+ { T("application/x-ns-proxy-autoconfig"), T(".pac") },
+ { T("application/x-patch"), T(".patch") },
+ { T("image/x-portable-anymap"), T(".pnm") },
+ { T("image/x-portable-bitmap"), T(".pbm") },
+ { T("image/x-portable-graymap"), T(".pgm") },
+ { T("image/x-portable-pixmap"), T(".ppm") },
+
+ { T("video/quicktime"), T(".qt") },
+
+ { T("application/rtf"), T(".rtf") },
+ { T("image/x-rgb"), T(".rgb") },
+ { T("application/x-troff"), T(".roff") },
+ { T("image/x-cmu-raster"), T(".ras") },
+ { T("audio/x-wav"), T(".ram") },
+
+ { T("application/x-sh"), T(".sh") },
+ { T("text/html"), T(".shtm") },
+ { T("text/html"), T(".shtml") },
+ { T("application/x-shar"), T(".shar") },
+ { T("application/x-wais-source"), T(".src") },
+ { T("application/x-sv4cpio"), T(".sv4cpio") },
+ { T("application/x-sv4crc"), T(".sv4crc") },
+
+ { T("application/x-tar"), T(".tar") },
+ { T("application/x-tcl"), T(".tcl") },
+ { T("application/x-tex"), T(".tex") },
+ { T("text/richtext"), T(".rtx") },
+ { T("application/x-troff"), T(".t") },
+ { T("application/x-troff"), T(".tr") },
+ { T("application/x-texinfo"), T(".texinfo") },
+ { T("application/x-texinfo"), T(".texi") },
+ { T("text/tab-separated-values"), T(".tsv") },
+ { T("image/tiff"), T(".tiff") },
+ { T("image/tiff"), T(".tif") },
+
+ { T("application/x-ustar"), T(".ustar") },
+
+ { T("audio/x-wav"), T(".wav") },
+
+ { T("image/x-xbitmap"), T(".xbm") },
+ { T("image/x-xpixmap"), T(".xpm") },
+ { T("image/x-xwindowdump"), T(".xwd") },
+
+ { T("application/compress"), T(".z") },
+ { T("application/zip"), T(".zip") },
+#endif
+ { NULL, NULL},
+};
+
+/*****************************************************************************/
+
diff --git a/ap/app/goahead/server/misc.c b/ap/app/goahead/server/misc.c
new file mode 100755
index 0000000..9e03368
--- /dev/null
+++ b/ap/app/goahead/server/misc.c
@@ -0,0 +1,450 @@
+#ifdef UEMF
+ #include "uemf.h"
+#else
+ #include "basic/basicInternal.h"
+#endif
+
+#define kUseMemcopy
+
+#define STR_REALLOC 0x1
+#define STR_INC 64
+
+typedef struct {
+ char_t *s;
+ int size;
+ int max;
+ int count;
+ int flags;
+} strbuf_t;
+
+enum flag {
+ flag_none = 0,
+ flag_minus = 1,
+ flag_plus = 2,
+ flag_space = 4,
+ flag_hash = 8,
+ flag_zero = 16,
+ flag_short = 32,
+ flag_long = 64
+};
+
+static int dsnprintf(char_t **s, int size, char_t *fmt, va_list arg, int msize);
+static int strnlen(char_t *s, unsigned int n);
+
+static void put_ulong(strbuf_t *buf, unsigned long int value, int base,
+ int upper, char_t *prefix, int width, int prec, enum flag f);
+
+static void put_char(strbuf_t *buf, char_t c);
+static void put_string(strbuf_t *buf, char_t *s, int len,
+ int width, int prec, enum flag f);
+
+static void put_char(strbuf_t *buf, char_t c)
+{
+ if (buf->count >= (buf->size - 1)) {
+ if (! (buf->flags & STR_REALLOC)) {
+ return;
+ }
+ buf->size += STR_INC;
+ if (buf->size > buf->max && buf->size > STR_INC) {
+
+ buf->size -= STR_INC;
+ return;
+ }
+ if (buf->s == NULL) {
+ buf->s = balloc(B_L, buf->size * sizeof(char_t));
+ } else {
+ buf->s = brealloc(B_L, buf->s, buf->size * sizeof(char_t));
+ }
+ }
+ if(buf->s){
+ buf->s[buf->count] = c;
+ if (c != '\0') {
+ ++buf->count;
+ }
+ }
+}
+
+static void put_string(strbuf_t *buf, char_t *s, int len, int width,
+ int prec, enum flag f)
+{
+ int index;
+
+ if (len < 0) {
+ len = strnlen(s, prec >= 0 ? prec : ULONG_MAX);
+ } else if (prec >= 0 && prec < len) {
+ len = prec;
+ }
+ if (width > len && !(f & flag_minus)) {
+ for (index = len; index < width; ++index) {
+ put_char(buf, ' ');
+ }
+ }
+ for (index = 0; index < len; ++index) {
+ put_char(buf, s[index]);
+ }
+ if (width > len && f & flag_minus) {
+ for (index = len; index < width; ++index) {
+ put_char(buf, ' ');
+ }
+ }
+}
+
+int fmtAlloc(char_t **s, int n, char_t *fmt, ...)
+{
+ va_list ap = {0};
+ int result;
+
+ a_assert(s);
+ a_assert(fmt);
+
+ *s = NULL;
+ va_start(ap, fmt);
+ result = dsnprintf(s, n, fmt, ap, 0);
+ va_end(ap);
+ return result;
+}
+
+int fmtValloc(char_t **s, int n, char_t *fmt, va_list arg)
+{
+ a_assert(s);
+ a_assert(fmt);
+
+ *s = NULL;
+ return dsnprintf(s, n, fmt, arg, 0);
+}
+
+int fmtRealloc(char_t **s, int n, int msize, char_t *fmt, ...)
+{
+ va_list ap = {0};
+ int result;
+
+ a_assert(s);
+ a_assert(fmt);
+
+ if (msize == -1) {
+ *s = NULL;
+ }
+ va_start(ap, fmt);
+ result = dsnprintf(s, n, fmt, ap, msize);
+ va_end(ap);
+ return result;
+}
+
+static int dsnprintf(char_t **s, int size, char_t *fmt, va_list arg, int msize)
+{
+ char_t tmp_c;
+ strbuf_t tmp_buf;
+
+ a_assert(s);
+ a_assert(fmt);
+
+ memset(&tmp_buf, 0, sizeof(tmp_buf));
+ tmp_buf.s = *s;
+
+ if (*s == NULL || msize != 0) {
+ tmp_buf.max = size;
+ tmp_buf.flags |= STR_REALLOC;
+ if (msize != 0) {
+ tmp_buf.size = max(msize, 0);
+ }
+ if (*s != NULL && msize != 0) {
+ tmp_buf.count = gstrlen(*s);
+ }
+ } else {
+ tmp_buf.size = size;
+ }
+
+ while ((tmp_c = *fmt++) != '\0') {
+ if (tmp_c != '%' || (tmp_c = *fmt++) == '%') {
+ put_char(&tmp_buf, tmp_c);
+ } else {
+ enum flag f = flag_none;
+ int width = 0;
+ int prec = -1;
+ for ( ; tmp_c != '\0'; tmp_c = *fmt++) {
+ if (tmp_c == '-') {
+ f |= flag_minus;
+ } else if (tmp_c == '+') {
+ f |= flag_plus;
+ } else if (tmp_c == ' ') {
+ f |= flag_space;
+ } else if (tmp_c == '#') {
+ f |= flag_hash;
+ } else if (tmp_c == '0') {
+ f |= flag_zero;
+ } else {
+ break;
+ }
+ }
+ if (tmp_c == '*') {
+ width = va_arg(arg, int);
+ if (width < 0) {
+ f |= flag_minus;
+ width = -width;
+ }
+ tmp_c = *fmt++;
+ } else {
+ for ( ; gisdigit((int)tmp_c); tmp_c = *fmt++) {
+ width = width * 10 + (tmp_c - '0');
+ }
+ }
+ if (tmp_c == '.') {
+ f &= ~flag_zero;
+ tmp_c = *fmt++;
+ if (tmp_c == '*') {
+ prec = va_arg(arg, int);
+ tmp_c = *fmt++;
+ } else {
+ for (prec = 0; gisdigit((int)tmp_c); tmp_c = *fmt++) {
+ prec = prec * 10 + (tmp_c - '0');
+ }
+ }
+ }
+ if (tmp_c == 'h' || tmp_c == 'l') {
+ f |= (tmp_c == 'h' ? flag_short : flag_long);
+ tmp_c = *fmt++;
+ }
+ if (tmp_c == 'd' || tmp_c == 'i') {
+ long int value;
+ if (f & flag_short) {
+ value = (short int) va_arg(arg, int);
+ } else if (f & flag_long) {
+ value = va_arg(arg, long int);
+ } else {
+ value = va_arg(arg, int);
+ }
+ if (value >= 0) {
+ if (f & flag_plus) {
+ put_ulong(&tmp_buf, value, 10, 0, T("+"), width, prec, f);
+ } else if (f & flag_space) {
+ put_ulong(&tmp_buf, value, 10, 0, T(" "), width, prec, f);
+ } else {
+ put_ulong(&tmp_buf, value, 10, 0, NULL, width, prec, f);
+ }
+ } else {
+ put_ulong(&tmp_buf, -value, 10, 0, T("-"), width, prec, f);
+ }
+ } else if (tmp_c == 'o' || tmp_c == 'u' || tmp_c == 'x' || tmp_c == 'X') {
+ unsigned long int value;
+ if (f & flag_short) {
+ value = (unsigned short int) va_arg(arg, unsigned int);
+ } else if (f & flag_long) {
+ value = va_arg(arg, unsigned long int);
+ } else {
+ value = va_arg(arg, unsigned int);
+ }
+ if (tmp_c == 'o') {
+ if (f & flag_hash && value != 0) {
+ put_ulong(&tmp_buf, value, 8, 0, T("0"), width, prec, f);
+ } else {
+ put_ulong(&tmp_buf, value, 8, 0, NULL, width, prec, f);
+ }
+ } else if (tmp_c == 'u') {
+ put_ulong(&tmp_buf, value, 10, 0, NULL, width, prec, f);
+ } else {
+ if (f & flag_hash && value != 0) {
+ if (tmp_c == 'x') {
+ put_ulong(&tmp_buf, value, 16, 0, T("0x"), width, prec, f);
+ } else {
+ put_ulong(&tmp_buf, value, 16, 1, T("0X"), width, prec, f);
+ }
+ } else {
+ put_ulong(&tmp_buf, value, 16, ('X' == tmp_c) , NULL, width, prec, f);
+ }
+ }
+
+ } else if (tmp_c == 'c') {
+ char_t value = va_arg(arg, int);
+ put_char(&tmp_buf, value);
+
+ } else if (tmp_c == 's' || tmp_c == 'S') {
+ char_t *value = va_arg(arg, char_t *);
+ if (value == NULL) {
+ put_string(&tmp_buf, T("(null)"), -1, width, prec, f);
+ } else if (f & flag_hash) {
+ put_string(&tmp_buf,
+ value + 1, (char_t) *value, width, prec, f);
+ } else {
+ put_string(&tmp_buf, value, -1, width, prec, f);
+ }
+ } else if (tmp_c == 'p') {
+ void *value = va_arg(arg, void *);
+ put_ulong(&tmp_buf,
+ (unsigned long int) value, 16, 0, T("0x"), width, prec, f);
+ } else if (tmp_c == 'n') {
+ if (f & flag_short) {
+ short int *value = va_arg(arg, short int *);
+ *value = tmp_buf.count;
+ } else if (f & flag_long) {
+ long int *value = va_arg(arg, long int *);
+ *value = tmp_buf.count;
+ } else {
+ int *value = va_arg(arg, int *);
+ *value = tmp_buf.count;
+ }
+ } else {
+ put_char(&tmp_buf, tmp_c);
+ }
+ }
+ }
+ if (tmp_buf.s == NULL) {
+ put_char(&tmp_buf, '\0');
+ }
+
+ if (*s == NULL || msize != 0) {
+ *s = tmp_buf.s;
+ }
+
+ if (*s != NULL && size > 0) {
+ if (tmp_buf.count < size) {
+ (*s)[tmp_buf.count] = '\0';
+ } else {
+ (*s)[tmp_buf.size - 1] = '\0';
+ }
+ }
+
+ if (msize != 0) {
+ return tmp_buf.size;
+ }
+ return tmp_buf.count;
+}
+
+static int strnlen(char_t *s, unsigned int n)
+{
+ unsigned int len;
+
+ len = gstrlen(s);
+ return min(len, n);
+}
+
+
+static void put_ulong(strbuf_t *buf, unsigned long int value, int base,
+ int upper, char_t *prefix, int width, int prec, enum flag f)
+{
+ unsigned long x, x2;
+ int len, zeros, index;
+
+ for (len = 1, x = 1; x < ULONG_MAX / base; ++len, x = x2) {
+ x2 = x * base;
+ if (x2 > value) {
+ break;
+ }
+ }
+ zeros = (prec > len) ? prec - len : 0;
+ width -= zeros + len;
+ if (prefix != NULL) {
+ width -= strnlen(prefix, ULONG_MAX);
+ }
+ if (!(f & flag_minus)) {
+ if (f & flag_zero) {
+ for (index = 0; index < width; ++index) {
+ put_char(buf, '0');
+ }
+ } else {
+ for (index = 0; index < width; ++index) {
+ put_char(buf, ' ');
+ }
+ }
+ }
+ if (prefix != NULL) {
+ put_string(buf, prefix, -1, 0, -1, flag_none);
+ }
+ for (index = 0; index < zeros; ++index) {
+ put_char(buf, '0');
+ }
+ for ( ; x > 0; x /= base) {
+ int digit = (value / x) % base;
+ put_char(buf, (char)((digit < 10 ? '0' : (upper ? 'A' : 'a') - 10) + digit));
+ }
+ if (f & flag_minus) {
+ for (index = 0; index < width; ++index) {
+ put_char(buf, ' ');
+ }
+ }
+}
+
+char_t *ascToUni(char_t *ubuf, char *str, int nBytes)
+{
+ memcpy(ubuf, str, nBytes);
+ return ubuf;
+}
+
+
+char_t *ballocAscToUni(char *cp, int alen)
+{
+ char_t *unip;
+ int ulen;
+
+ ulen = (alen + 1) * sizeof(char_t);
+ if ((unip = balloc(B_L, ulen)) == NULL) {
+ return NULL;
+ }
+ ascToUni(unip, cp, ulen);
+ unip[alen] = 0;
+ return unip;
+}
+
+unsigned int hextoi(char_t *hexstring)
+{
+ register char_t *h;
+ register unsigned int c, v;
+
+ v = 0;
+ h = hexstring;
+ if (*h == '0' && (*(h+1) == 'x' || *(h+1) == 'X')) {
+ h += 2;
+ }
+ while ((c = (unsigned int)*h++) != 0) {
+ if (c >= '0' && c <= '9') {
+ c -= '0';
+ } else if (c >= 'a' && c <= 'f') {
+ c = (c - 'a') + 10;
+ } else if (c >= 'A' && c <= 'F') {
+ c = (c - 'A') + 10;
+ } else {
+ break;
+ }
+ v = (v * 0x10) + c;
+ }
+ return v;
+}
+
+char *uniToAsc(char *buf, char_t *ustr, int nBytes)
+{
+#ifdef UNICODE
+ if (WideCharToMultiByte(CP_ACP, 0, ustr, nBytes, buf, nBytes,
+ NULL, NULL) < 0)
+ {
+ return (char*) ustr;
+ }
+#else
+#ifdef kUseMemcopy
+ memcpy(buf, ustr, nBytes);
+#else
+ strncpy(buf, ustr, nBytes);
+#endif /* kUseMemcopy */
+#endif
+ return (char*) buf;
+}
+
+char *ballocUniToAsc(char_t *unip, int ulen)
+{
+ char * cp;
+
+ if ((cp = balloc(B_L, ulen+1)) == NULL) {
+ return NULL;
+ }
+ uniToAsc(cp, unip, ulen);
+ cp[ulen] = '\0';
+ return cp;
+}
+
+unsigned int gstrtoi(char_t *s)
+{
+ if (*s == '0' && (*(s+1) == 'x' || *(s+1) == 'X')) {
+ s += 2;
+ return hextoi(s);
+ }
+ return gatoi(s);
+}
+
diff --git a/ap/app/goahead/server/page.c b/ap/app/goahead/server/page.c
new file mode 100755
index 0000000..b5d7bf8
--- /dev/null
+++ b/ap/app/goahead/server/page.c
@@ -0,0 +1,219 @@
+#include "wsIntrn.h"
+#include <sys/stat.h>
+#include <unistd.h>
+#ifdef _USE_WEBUI_ZIP
+#include "unzip.h"
+#define WEB_ZIP_PATH "etc_ro/web.zip"
+#define WEB_ZIP_PATH_HEAD "web/"
+#endif
+
+int websPageOpen(webs_t wp, char_t *lpath, char_t *path, int mode, int perm)
+{
+ a_assert(websValid(wp));
+
+#ifdef WEBS_PAGE_ROM
+ return websRomPageOpen(wp, path, mode, perm);
+#else
+#ifdef _USE_WEBUI_ZIP
+ char *filename = strstr(lpath,WEB_ZIP_PATH_HEAD);
+ if(filename != NULL)
+ {
+ unzFile uzFile = unzOpen(WEB_ZIP_PATH);
+ if(unzLocateFile(uzFile,filename,0) == UNZ_OK
+ && unzOpenCurrentFile(uzFile) == UNZ_OK)
+ {
+ wp->docfd = uzFile;
+ }
+ else
+ {
+ unzClose(uzFile);
+ wp->docfd = -1;
+ }
+ return wp->docfd;
+ }
+ else
+ {
+ printf("[zpr]erropen %s\n", lpath);
+ }
+#endif
+ //printf("[httpshare]lpath->%s\n",lpath);
+
+ if(strstr(lpath,"/mmc2") != NULL)
+ {
+#if 0 // cov M
+ unsigned long filesize = -1;
+#else
+ long filesize = -1;
+#endif
+ struct stat statbuff;
+
+ if(stat(lpath, &statbuff) < 0)
+ {
+ return filesize;
+ }
+ else
+ {
+ filesize = statbuff.st_size;
+ }
+
+ printf("[httpshare]websPageOpen:size->%d\n", filesize);
+
+#if 0 // cov M
+ if(filesize<2*1024*1024*1024)
+ {
+ return (wp->docfd = gopen(lpath, mode, perm));
+ }
+ else
+ return -1;
+#else
+ if(filesize > 0 && filesize <= LONG_MAX-1)
+ {
+ return (wp->docfd = gopen(lpath, mode, perm));
+ }
+ else
+ return -1;
+
+#endif
+ }
+
+ return (wp->docfd = gopen(lpath, mode, perm));
+#endif /* WEBS_PAGE_ROM */
+}
+
+void websPageClose(webs_t wp)
+{
+ a_assert(websValid(wp));
+
+#ifdef WEBS_PAGE_ROM
+ websRomPageClose(wp->docfd);
+#else
+#ifdef _USE_WEBUI_ZIP
+ if(wp->docfd > 0 && wp->lpath != NULL && strstr(wp->lpath,WEB_ZIP_PATH_HEAD) != NULL)
+ {
+ unzCloseCurrentFile(wp->docfd);
+ unzClose(wp->docfd);
+ wp->docfd = -1;
+ return;
+ }
+#endif
+ if (wp->docfd >= 0) {
+ close(wp->docfd);
+ wp->docfd = -1;
+ //printf("[httpsahre]lpath->%s,path->%s\n",wp->lpath,wp->path);
+ if(strstr(wp->path,"/mmc2") != NULL)
+ {
+ zte_del_download_file();
+ }
+ }
+#endif
+}
+
+int websPageStat(webs_t wp, char_t *lpath, char_t *path, websStatType* sbuf)
+{
+ if(lpath == NULL)
+ return -1;
+#ifdef WEBS_PAGE_ROM
+ return websRomPageStat(path, sbuf);
+#else
+#ifdef _USE_WEBUI_ZIP
+ if(strstr(lpath,WEB_ZIP_PATH_HEAD) != NULL)
+ {
+ unz_file_info file_info = {0};
+ if(unzGetCurrentFileInfo(wp->docfd, &file_info, NULL, 0, NULL, 0, NULL, 0)< 0)
+ {
+ printf("[webzip]errStat %s\n", lpath);
+ return -1;
+ }
+ sbuf->size = file_info.uncompressed_size;
+ sbuf->mtime = file_info.dosDate;
+ sbuf->isDir = websPageIsDirectory(lpath);
+ return 0;
+ }
+#endif
+ gstat_t s;
+
+ if (gstat(lpath, &s) < 0) {
+ return -1;
+ }
+ sbuf->size = s.st_size;
+ sbuf->mtime = s.st_mtime;
+ sbuf->isDir = s.st_mode & S_IFDIR;
+ return 0;
+#endif
+}
+
+int websPageIsDirectory(char_t *lpath)
+{
+ if(lpath == NULL)
+ return 0;
+#ifdef WEBS_PAGE_ROM
+ websStatType sbuf;
+
+ if (websRomPageStat(lpath, &sbuf) >= 0) {
+ return(sbuf.isDir);
+ } else {
+ return 0;
+ }
+#else
+#ifdef _USE_WEBUI_ZIP
+ if(strstr(lpath,WEB_ZIP_PATH_HEAD) != NULL)
+ {
+ char *p = lpath;
+ int is_dir = 0;
+ while ((*p) != '\0') {
+ p++;
+ }
+ p--;
+
+ if (((*p) == '/') || ((*p) == '\\')) {
+ is_dir = 1;
+ }
+ return is_dir;
+ }
+#endif
+ gstat_t sbuf;
+
+ if (gstat(lpath, &sbuf) >= 0) {
+ return(sbuf.st_mode & S_IFDIR);
+ } else {
+ return 0;
+ }
+#endif
+}
+
+int websPageReadData(webs_t wp, char *buf, int nBytes)
+{
+ a_assert(websValid(wp));
+#ifdef WEBS_PAGE_ROM
+ return websRomPageReadData(wp, buf, nBytes);
+#else
+#ifdef _USE_WEBUI_ZIP
+ if(wp->lpath != NULL && strstr(wp->lpath,WEB_ZIP_PATH_HEAD) != NULL)
+ {
+ return unzReadCurrentFile(wp->docfd, buf, nBytes);
+ }
+#endif
+ return read(wp->docfd, buf, nBytes);
+#endif
+}
+
+void websPageSeek(webs_t wp, long offset)
+{
+ a_assert(websValid(wp));
+#ifdef WEBS_PAGE_ROM
+ websRomPageSeek(wp, offset, SEEK_CUR);
+#else
+#ifdef _USE_WEBUI_ZIP
+ if(wp->lpath != NULL && strstr(wp->lpath,WEB_ZIP_PATH_HEAD) != NULL)
+ {
+ printf("[webzip]seek %s\n",wp->lpath);
+ return;
+ }
+#endif
+ if(lseek(wp->docfd, offset, SEEK_CUR) < 0)
+ {
+ return;
+ }
+#endif
+}
+
diff --git a/ap/app/goahead/server/ringq.c b/ap/app/goahead/server/ringq.c
new file mode 100755
index 0000000..e6ba5f3
--- /dev/null
+++ b/ap/app/goahead/server/ringq.c
@@ -0,0 +1,403 @@
+#ifdef UEMF
+ #include "uemf.h"
+#else
+ #include "basic/basicInternal.h"
+#endif
+
+static int getBinBlockSize(int size);
+static int ringqGrow(ringq_t *rq);
+
+#define RINGQ_LEN(rq) \
+ ((rq->servp > rq->endp) ? \
+ (rq->buflen + (rq->endp - rq->servp)) : \
+ (rq->endp - rq->servp))
+
+
+
+int ringqGrowCalls = 0;
+
+int ringqOpen(ringq_t *rq, int initSize, int maxsize)
+{
+ int increment;
+
+ a_assert(rq);
+ a_assert(initSize >= 0);
+
+ increment = getBinBlockSize(initSize);
+ if ((rq->buf = balloc(B_L, (increment))) == NULL) {
+ return -1;
+ }
+ rq->maxsize = maxsize;
+ rq->buflen = increment;
+ rq->increment = increment;
+ rq->endbuf = &rq->buf[rq->buflen];
+ rq->servp = rq->buf;
+ rq->endp = rq->buf;
+ *rq->servp = '\0';
+ return 0;
+}
+
+int ringqInsertc(ringq_t *rq, char_t c)
+{
+ char_t *cp;
+
+ a_assert(rq);
+ a_assert(rq->buflen == (rq->endbuf - rq->buf));
+
+ if (ringqPutBlkMax(rq) < (int) sizeof(char_t) && !ringqGrow(rq)) {
+ return -1;
+ }
+ if (rq->servp <= rq->buf) {
+ rq->servp = rq->endbuf;
+ }
+ cp = (char_t*) rq->servp;
+ *--cp = (char_t) c;
+ rq->servp = (unsigned char *) cp;
+ return 0;
+}
+
+int ringqPutc(ringq_t *rq, char_t c)
+{
+ char_t *cp;
+
+ a_assert(rq);
+ a_assert(rq->buflen == (rq->endbuf - rq->buf));
+
+ if ((ringqPutBlkMax(rq) < (int) sizeof(char_t)) && !ringqGrow(rq)) {
+ return -1;
+ }
+
+ cp = (char_t*) rq->endp;
+ *cp++ = (char_t) c;
+ rq->endp = (unsigned char *) cp;
+ if (rq->endp >= rq->endbuf) {
+ rq->endp = rq->buf;
+ }
+ return 0;
+}
+
+int ringqGetc(ringq_t *rq)
+{
+ char_t c;
+ char_t* cp;
+
+ a_assert(rq);
+ a_assert(rq->buflen == (rq->endbuf - rq->buf));
+
+ if (rq->servp == rq->endp) {
+ return -1;
+ }
+
+ cp = (char_t*) rq->servp;
+ c = *cp++;
+ rq->servp = (unsigned char *) cp;
+ if (rq->servp >= rq->endbuf) {
+ rq->servp = rq->buf;
+ }
+ return (int) ((unsigned char) c);
+}
+
+int ringqLen(ringq_t *rq)
+{
+ a_assert(rq);
+ a_assert(rq->buflen == (rq->endbuf - rq->buf));
+
+ if (rq->servp > rq->endp) {
+ return rq->buflen + rq->endp - rq->servp;
+ } else {
+ return rq->endp - rq->servp;
+ }
+}
+
+void ringqAddNull(ringq_t *rq)
+{
+ a_assert(rq);
+ a_assert(rq->buflen == (rq->endbuf - rq->buf));
+
+ *((char_t*) rq->endp) = (char_t) '\0';
+}
+
+int ringqPutStr(ringq_t *rq, char_t *str)
+{
+ int rc;
+
+ a_assert(rq);
+ a_assert(str);
+ a_assert(rq->buflen == (rq->endbuf - rq->buf));
+
+ rc = ringqPutBlk(rq, (unsigned char*) str, gstrlen(str) * sizeof(char_t));
+ *((char_t*) rq->endp) = (char_t) '\0';
+ return rc;
+}
+
+
+void ringqClose(ringq_t *rq)
+{
+ a_assert(rq);
+ a_assert(rq->buflen == (rq->endbuf - rq->buf));
+
+ if (rq == NULL) {
+ return;
+ }
+
+ ringqFlush(rq);
+ bfree(B_L, (char*) rq->buf);
+ rq->buf = NULL;
+}
+
+
+void ringqFlush(ringq_t *rq)
+{
+ a_assert(rq);
+ a_assert(rq->servp);
+
+ rq->servp = rq->buf;
+ rq->endp = rq->buf;
+ if (rq->servp) {
+ *rq->servp = '\0';
+ }
+}
+
+
+#ifdef UNICODE
+int ringqPutStrA(ringq_t *rq, char *str)
+{
+ int rc;
+
+ a_assert(rq);
+ a_assert(str);
+ a_assert(rq->buflen == (rq->endbuf - rq->buf));
+
+ rc = ringqPutBlk(rq, (unsigned char*) str, strlen(str));
+ rq->endp[0] = '\0';
+ return rc;
+}
+
+int ringqGetcA(ringq_t *rq)
+{
+ unsigned char c;
+
+ a_assert(rq);
+ a_assert(rq->buflen == (rq->endbuf - rq->buf));
+
+ if (rq->servp == rq->endp) {
+ return -1;
+ }
+
+ c = *rq->servp++;
+ if (rq->servp >= rq->endbuf) {
+ rq->servp = rq->buf;
+ }
+ return c;
+}
+
+int ringqInsertcA(ringq_t *rq, char c)
+{
+ a_assert(rq);
+ a_assert(rq->buflen == (rq->endbuf - rq->buf));
+
+ if (ringqPutBlkMax(rq) == 0 && !ringqGrow(rq)) {
+ return -1;
+ }
+ if (rq->servp <= rq->buf) {
+ rq->servp = rq->endbuf;
+ }
+ *--rq->servp = (unsigned char) c;
+ return 0;
+}
+
+int ringqPutcA(ringq_t *rq, char c)
+{
+ a_assert(rq);
+ a_assert(rq->buflen == (rq->endbuf - rq->buf));
+
+ if (ringqPutBlkMax(rq) == 0 && !ringqGrow(rq)) {
+ return -1;
+ }
+
+ *rq->endp++ = (unsigned char) c;
+ if (rq->endp >= rq->endbuf) {
+ rq->endp = rq->buf;
+ }
+ return 0;
+}
+
+#endif /* UNICODE */
+
+void ringqGetBlkAdj(ringq_t *rq, int size)
+{
+ a_assert(rq);
+ a_assert(rq->buflen == (rq->endbuf - rq->buf));
+ a_assert(0 < size && size < rq->buflen);
+
+ rq->servp += size;
+ if (rq->servp >= rq->endbuf) {
+ rq->servp -= rq->buflen;
+ }
+
+ if (rq->servp >= rq->endbuf) {
+ error(E_L, E_LOG, T("Bad serv pointer"));
+ ringqFlush(rq);
+ }
+}
+
+int ringqGetBlkMax(ringq_t *rq)
+{
+ int len, in_a_line;
+
+ a_assert(rq);
+ a_assert(rq->buflen == (rq->endbuf - rq->buf));
+
+ len = RINGQ_LEN(rq);
+ in_a_line = rq->endbuf - rq->servp;
+
+ return min(in_a_line, len);
+}
+
+int ringqGetBlk(ringq_t *rq, unsigned char *buf, int size)
+{
+ int this, bytes_read;
+
+ a_assert(rq);
+ a_assert(rq->buflen == (rq->endbuf - rq->buf));
+ a_assert(buf);
+ a_assert(0 <= size && size < rq->buflen);
+
+ bytes_read = 0;
+ while (size > 0) {
+ this = ringqGetBlkMax(rq);
+ this = min(this, size);
+ if (this <= 0) {
+ break;
+ }
+
+ memcpy(buf, rq->servp, this);
+ buf += this;
+ rq->servp += this;
+ size -= this;
+ bytes_read += this;
+
+ if (rq->servp >= rq->endbuf) {
+ rq->servp = rq->buf;
+ }
+ }
+ return bytes_read;
+}
+
+int ringqPutBlk(ringq_t *rq, unsigned char *buf, int size)
+{
+ int this, bytes_put;
+
+ a_assert(rq);
+ a_assert(rq->buflen == (rq->endbuf - rq->buf));
+ a_assert(buf);
+ a_assert(0 <= size);
+
+ bytes_put = 0;
+ while (size > 0) {
+ this = min(ringqPutBlkMax(rq), size);
+ if (this <= 0) {
+ if (! ringqGrow(rq)) {
+ break;
+ }
+ this = min(ringqPutBlkMax(rq), size);
+ }
+
+ memcpy(rq->endp, buf, this);
+ buf += this;
+ rq->endp += this;
+ size -= this;
+ bytes_put += this;
+
+ if (rq->endp >= rq->endbuf) {
+ rq->endp = rq->buf;
+ }
+ }
+ return bytes_put;
+}
+
+
+int ringqPutBlkMax(ringq_t *rq)
+{
+ int space, in_a_line;
+
+ a_assert(rq);
+ a_assert(rq->buflen == (rq->endbuf - rq->buf));
+
+ space = rq->buflen - RINGQ_LEN(rq) - 1;
+ in_a_line = rq->endbuf - rq->endp;
+
+ return min(in_a_line, space);
+}
+
+
+void ringqPutBlkAdj(ringq_t *rq, int size)
+{
+ a_assert(rq);
+ a_assert(rq->buflen == (rq->endbuf - rq->buf));
+ a_assert(0 <= size && size < rq->buflen);
+
+ rq->endp += size;
+ if (rq->endp >= rq->endbuf) {
+ rq->endp -= rq->buflen;
+ }
+
+ if (rq->endp >= rq->endbuf) {
+ error(E_L, E_LOG, T("Bad end pointer"));
+ ringqFlush(rq);
+ }
+}
+
+
+
+static int ringqGrow(ringq_t *rq)
+{
+ int rq_len;
+ unsigned char *reall_buf;
+
+
+ a_assert(rq);
+
+ if (rq->maxsize >= 0 && rq->buflen >= rq->maxsize) {
+ return 0;
+ }
+
+ rq_len = ringqLen(rq);
+
+ if ((reall_buf = balloc(B_L, rq->buflen + rq->increment)) == NULL) {
+ return 0;
+ }
+ ringqGetBlk(rq, reall_buf, ringqLen(rq));
+ bfree(B_L, (char*) rq->buf);
+
+#ifdef OLD
+ rq->endp = &reall_buf[endp];
+ rq->servp = &reall_buf[servp];
+ rq->endbuf = &reall_buf[rq->buflen];
+ rq->buf = reall_buf;
+#endif
+
+ rq->buflen += rq->increment;
+ rq->endp = reall_buf;
+ rq->servp = reall_buf;
+ rq->buf = reall_buf;
+ rq->endbuf = &rq->buf[rq->buflen];
+
+ ringqPutBlk(rq, reall_buf, rq_len);
+
+ rq->increment = getBinBlockSize(2 * rq->increment);
+
+ return 1;
+}
+
+static int getBinBlockSize(int size)
+{
+ int q;
+
+ size = size >> B_SHIFT;
+ for (q = 0; size; size >>= 1) {
+ q++;
+ }
+ return (1 << (B_SHIFT + q));
+}
+
diff --git a/ap/app/goahead/server/sock.c b/ap/app/goahead/server/sock.c
new file mode 100755
index 0000000..1990f71
--- /dev/null
+++ b/ap/app/goahead/server/sock.c
@@ -0,0 +1,499 @@
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef UEMF
+ #include "uemf.h"
+#else
+ #include <socket.h>
+ #include <types.h>
+ #include <unistd.h>
+ #include "emfInternal.h"
+#endif
+
+static int socketDoOutput(socket_t *sp, char *buf, int toWrite, int *errCode);
+static int tryAlternateSendTo(int sock, char *buf, int toWrite, int i,
+ struct sockaddr *server);
+
+int socketHighestFd = -1;
+
+socket_t **socketList;
+int socketMax;
+
+
+int socketWriteString(int sid, char_t *buf)
+{
+ #ifdef UNICODE
+ char *byteBuf;
+ int r, buf_len;
+
+ buf_len = gstrlen(buf);
+ byteBuf = ballocUniToAsc(buf, buf_len);
+ r = socketWrite(sid, byteBuf, buf_len);
+ bfreeSafe(B_L, byteBuf);
+ return r;
+ #else
+ return socketWrite(sid, buf, strlen(buf));
+ #endif /* UNICODE */
+}
+
+
+int socketWrite(int sid, char *buf, int bufsize)
+{
+ socket_t *sp;
+ ringq_t *rq;
+ int buf_len, bytesWritten, room;
+
+ a_assert(buf);
+ a_assert(bufsize >= 0);
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return -1;
+ }
+
+ rq = &sp->outBuf;
+ for (bytesWritten = 0; bufsize > 0; ) {
+ if ((room = ringqPutBlkMax(rq)) == 0) {
+ if (socketFlush(sid) < 0) {
+ return -1;
+ }
+ if ((room = ringqPutBlkMax(rq)) == 0) {
+ if (sp->flags & SOCKET_BLOCK) {
+#if (defined (WIN) || defined (CE))
+ int errCode;
+ if (! socketWaitForEvent(sp, FD_WRITE | SOCKET_WRITABLE, &errCode)) {
+ return -1;
+ }
+#endif
+ continue;
+ }
+ break;
+ }
+ continue;
+ }
+ buf_len = min(room, bufsize);
+ ringqPutBlk(rq, (unsigned char *) buf, buf_len);
+ bytesWritten += buf_len;
+ bufsize -= buf_len;
+ buf += buf_len;
+ }
+ return bytesWritten;
+}
+
+
+int socketRead(int sid, char *buf, int bufsize)
+{
+ socket_t *sp;
+ ringq_t *rq;
+ int buf_len, room, errCode, bytesRead;
+
+ a_assert(buf);
+ a_assert(bufsize > 0);
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return -1;
+ }
+
+ if (sp->flags & SOCKET_EOF) {
+ return 0;
+ }
+
+ rq = &sp->inBuf;
+ for (bytesRead = 0; bufsize > 0; ) {
+ buf_len = min(ringqLen(rq), bufsize);
+ if (buf_len <= 0) {
+
+ if ((sp->flags & SOCKET_BLOCK) &&
+ (bytesRead > 0)) {
+ break;
+ }
+
+ ringqFlush(rq);
+ room = ringqPutBlkMax(rq);
+ buf_len = socketGetInput(sid, (char *) rq->endp, room, &errCode);
+ if (buf_len < 0) {
+ if (errCode == EWOULDBLOCK) {
+ if ((sp->flags & SOCKET_BLOCK) &&
+ (bytesRead == 0)) {
+ continue;
+ }
+// if (bytesRead >= 0) { // kw 3 ; bytesRead>=0 always be true
+ return bytesRead;
+// }
+ }
+ return -1;
+
+ } else if (buf_len == 0) {
+
+ if (bytesRead == 0) {
+ sp->flags |= SOCKET_EOF;
+ }
+ return bytesRead;
+ }
+ ringqPutBlkAdj(rq, buf_len);
+ buf_len = min(buf_len, bufsize);
+ }
+ memcpy(&buf[bytesRead], rq->servp, buf_len);
+ ringqGetBlkAdj(rq, buf_len);
+ bufsize -= buf_len;
+ bytesRead += buf_len;
+ }
+ return bytesRead;
+}
+
+int socketFlush(int sid)
+{
+ socket_t *sp;
+ ringq_t *rq;
+ int rq_len, bytesWritten, errCode;
+ int errEINTRNum = 0; /* myp: ÓÃÓÚ¹æ±Üsocket´íÎó */
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return -1;
+ }
+ rq = &sp->outBuf;
+
+ if (! (sp->flags & SOCKET_BLOCK)) {
+ sp->flags |= SOCKET_FLUSHING;
+ }
+
+ while (ringqLen(rq) > 0) {
+ rq_len = ringqGetBlkMax(&sp->outBuf);
+ bytesWritten = socketDoOutput(sp, (char*) rq->servp, rq_len, &errCode);
+ if (bytesWritten < 0) {
+ if (errCode == EINTR && errEINTRNum++ < 1000) {
+ continue;
+// } else if (errCode == EWOULDBLOCK || errCode == EAGAIN) { kw 3 // #define EWOULDBLOCK EAGAIN
+ } else if (errCode == EAGAIN) {
+ if (sp->saveMask < 0 ) {
+ sp->saveMask = sp->handlerMask;
+ socketRegisterInterest(sp,
+ sp->handlerMask | SOCKET_WRITABLE);
+ }
+ return 0;
+ }
+ return -1;
+ }
+ ringqGetBlkAdj(rq, bytesWritten);
+ }
+
+ if (ringqLen(rq) == 0) {
+ ringqFlush(rq);
+ }
+
+ if (sp->saveMask >= 0) {
+ socketRegisterInterest(sp, sp->saveMask);
+ sp->saveMask = -1;
+ }
+ sp->flags &= ~SOCKET_FLUSHING;
+ return 0;
+}
+
+int socketGets(int sid, char_t **buf)
+{
+ socket_t *sp;
+ ringq_t *lq;
+ char c = '\0'; //cov
+ int rc, rq_len;
+
+ a_assert(buf);
+ *buf = NULL;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return -1;
+ }
+ lq = &sp->lineBuf;
+
+ while (ringqLen(lq) < 1536) {
+
+ if ((rc = socketRead(sid, &c, 1)) < 0) {
+ return rc;
+ }
+
+ if (rc == 0) {
+ if (ringqLen(lq) > 0 && (sp->flags & SOCKET_EOF)) {
+ c = '\n';
+ } else {
+ return -1;
+ }
+ }
+
+ if (c == '\n') {
+ rq_len = ringqLen(lq);
+ if (rq_len > 0) {
+ *buf = ballocAscToUni((char *)lq->servp, rq_len);
+ } else {
+ *buf = NULL;
+ }
+ ringqFlush(lq);
+ return rq_len;
+
+ } else if (c == '\r') {
+ continue;
+ }
+ ringqPutcA(lq, c);
+ }
+ ringqFlush(lq);
+ return -1;
+}
+
+
+int socketInputBuffered(int sid)
+{
+ socket_t *sp;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return -1;
+ }
+ if (socketEof(sid)) {
+ return -1;
+ }
+ return ringqLen(&sp->lineBuf) + ringqLen(&sp->inBuf);
+}
+
+int socketEof(int sid)
+{
+ socket_t *sp;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return -1;
+ }
+ return sp->flags & SOCKET_EOF;
+}
+
+void socketCreateHandler(int sid, int handlerMask, socketHandler_t handler,
+ int data)
+{
+ socket_t *sp;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return;
+ }
+ sp->handler = handler;
+ sp->handler_data = data;
+ socketRegisterInterest(sp, handlerMask);
+}
+
+static int socketDoOutput(socket_t *sp, char *buf, int toWrite, int *errCode)
+{
+ struct sockaddr_in server;
+ int bytes;
+
+ a_assert(sp);
+ a_assert(buf);
+ a_assert(toWrite > 0);
+ a_assert(errCode);
+
+ *errCode = 0;
+
+ if (sp->flags & SOCKET_BROADCAST) {
+ server.sin_family = AF_INET;
+ server.sin_addr.s_addr = INADDR_BROADCAST;
+ server.sin_port = htons((short)(sp->port & 0xFFFF));
+ bytes = sendto(sp->sock, buf, toWrite, 0,(struct sockaddr *) &server, sizeof(server));
+ } else if (sp->flags & SOCKET_DATAGRAM) {
+ server.sin_family = AF_INET;
+ server.sin_addr.s_addr = inet_addr(sp->host);
+ server.sin_port = htons((short)(sp->port & 0xFFFF));
+ bytes = sendto(sp->sock, buf, toWrite, 0,(struct sockaddr *) &server, sizeof(server));
+
+ } else {
+ bytes = send(sp->sock, buf, toWrite, 0);
+ }
+
+ if (bytes < 0) {
+ *errCode = socketGetError();
+ //printf("\n socketDoOutput ERROR: bytes = %d, *errCode = %d! ", bytes, *errCode);
+ return -1;
+
+ } else if (bytes == 0 && bytes != toWrite) {
+ *errCode = EWOULDBLOCK;
+ //printf("\n socketDoOutput ERROR: bytes = %d, *errCode = %d! ", bytes, *errCode);
+ return -1;
+ }
+
+ return bytes;
+}
+
+void socketDeleteHandler(int sid)
+{
+ socket_t *sp;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return;
+ }
+ sp->handler = NULL;
+ socketRegisterInterest(sp, 0);
+}
+
+int socketAlloc(char *host, int port, socketAccept_t accept, int flags)
+{
+ socket_t *sp;
+ int sid;
+
+ if ((sid = hAllocEntry((void***) &socketList, &socketMax,
+ sizeof(socket_t))) < 0) {
+ return -1;
+ }
+ sp = socketList[sid];
+
+ sp->sid = sid;
+ sp->accept = accept;
+ sp->port = port;
+ sp->fileHandle = -1;
+ sp->saveMask = -1;
+
+ if (host) {
+ strncpy(sp->host, host, sizeof(sp->host)-1);
+ }
+
+ a_assert((flags & ~(SOCKET_BROADCAST|SOCKET_DATAGRAM|SOCKET_BLOCK|
+ SOCKET_LISTENING)) == 0);
+ sp->flags = flags & (SOCKET_BROADCAST | SOCKET_DATAGRAM | SOCKET_BLOCK|
+ SOCKET_LISTENING);
+
+
+ ringqOpen(&sp->inBuf, SOCKET_BUFSIZ, SOCKET_BUFSIZ);
+ ringqOpen(&sp->outBuf, SOCKET_BUFSIZ + 1, SOCKET_BUFSIZ + 1);
+ ringqOpen(&sp->lineBuf, SOCKET_BUFSIZ, -1);
+
+ return sid;
+}
+
+void socketFree(int sid)
+{
+ socket_t *sp;
+ char_t buf[256];
+ int i;
+ int recv_len = -1;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return;
+ }
+
+ socketRegisterInterest(sp, 0);
+ if (sp->sock >= 0) {
+ socketSetBlock(sid, 0);
+ if (shutdown(sp->sock, 1) >= 0) {
+ recv_len = recv(sp->sock, buf, sizeof(buf), 0);
+ if(recv_len < 0){
+ ;
+ }else if(recv_len == 0){
+ // ÕâÀï±íʾ¶Ô¶ËµÄsocketÒÑÕý³£¹Ø±Õ?
+ ;
+ }else if(recv_len == sizeof(buf)){
+ ;
+ }else{
+ ;// ÐèÒªÔٴζÁÈ¡
+ }
+ }
+#if (defined (WIN) || defined (CE))
+ closesocket(sp->sock);
+#else
+ close(sp->sock);
+#endif
+ }
+
+ ringqClose(&sp->inBuf);
+ ringqClose(&sp->outBuf);
+ ringqClose(&sp->lineBuf);
+
+ bfree(B_L, sp);
+ socketMax = hFree((void***) &socketList, sid);
+
+ socketHighestFd = -1;
+ for (i = 0; i < socketMax; i++) {
+ if ((sp = socketList[i]) == NULL) {
+ continue;
+ }
+ socketHighestFd = max(socketHighestFd, sp->sock);
+ }
+}
+
+
+int socketGetError()
+{
+#if (defined (WIN) || defined (CE))
+ switch (WSAGetLastError()) {
+ case WSAEWOULDBLOCK:
+ return EWOULDBLOCK;
+ case WSAECONNRESET:
+ return ECONNRESET;
+ case WSAENETDOWN:
+ return ENETDOWN;
+ case WSAEPROCLIM:
+ return EAGAIN;
+ case WSAEINTR:
+ return EINTR;
+ default:
+ return EINVAL;
+ }
+#else
+ return errno;
+#endif
+}
+
+socket_t *socketPtr(int sid)
+{
+ if (sid < 0 || sid >= socketMax || socketList[sid] == NULL) {
+ a_assert(NULL);
+ errno = EBADF;
+ return NULL;
+ }
+
+ a_assert(socketList[sid]);
+ return socketList[sid];
+}
+
+int socketGetHandle(int sid)
+{
+ socket_t *sp;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return -1;
+ }
+ return sp->sock;
+}
+
+int socketGetBlock(int sid)
+{
+ socket_t *sp;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ a_assert(0);
+ return 0;
+ }
+ return (sp->flags & SOCKET_BLOCK);
+}
+
+int socketGetMode(int sid)
+{
+ socket_t *sp;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ a_assert(0);
+ return 0;
+ }
+ return sp->flags;
+}
+
+void socketSetMode(int sid, int mode)
+{
+ socket_t *sp;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ a_assert(0);
+ return;
+ }
+ sp->flags = mode;
+}
+
+int socketGetPort(int sid)
+{
+ socket_t *sp;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return -1;
+ }
+ return sp->port;
+}
+
diff --git a/ap/app/goahead/server/sockGen.c b/ap/app/goahead/server/sockGen.c
new file mode 100755
index 0000000..8e3292c
--- /dev/null
+++ b/ap/app/goahead/server/sockGen.c
@@ -0,0 +1,522 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include "uemf.h"
+#include "softap_log.h"
+
+extern socket_t **socketList;
+extern int socketMax;
+extern int socketHighestFd;
+static int socketOpenCount = 0;
+
+static void socketAccept(socket_t *sp);
+static int socketDoEvent(socket_t *sp);
+static int tryAlternateConnect(int sock, struct sockaddr *sockaddr);
+
+int socketOpen()
+{
+ if (++socketOpenCount > 1) {
+ return 0;
+ }
+ socketList = NULL;
+ socketMax = 0;
+ socketHighestFd = -1;
+
+ return 0;
+}
+
+int socketWaitForEvent(socket_t *sp, int handlerMask, int *errCode)
+{
+ int mask;
+
+ a_assert(sp);
+
+ mask = sp->handlerMask;
+ sp->handlerMask |= handlerMask;
+ while (socketSelect(sp->sid, 1000)) {
+ if (sp->currentEvents & (handlerMask | SOCKET_EXCEPTION)) {
+ break;
+ }
+ }
+ sp->handlerMask = mask;
+ if (sp->currentEvents & SOCKET_EXCEPTION) {
+ return -1;
+ } else if (sp->currentEvents & handlerMask) {
+ return 1;
+ }
+ if (errCode) {
+ *errCode = errno = EWOULDBLOCK;
+ }
+ return 0;
+}
+
+void socketClose()
+{
+ int i;
+
+ if (--socketOpenCount <= 0) {
+ for (i = socketMax; i >= 0; i--) {
+ if (socketList && socketList[i]) {
+ socketCloseConnection(i);
+ }
+ }
+ socketOpenCount = 0;
+ }
+}
+
+int socketOpenConnection6(char *host, int port, socketAccept_t accept, int flags)
+{
+ socket_t *sp;
+ struct sockaddr_in6 sockaddr;
+ int sid, dgram, rc;
+ if (port > SOCKET_PORT_MAX) {
+ return -1;
+ }
+ if ((sid = socketAlloc(NULL, port, accept, flags)) < 0) {
+ return -1;
+ }
+ sp = socketList[sid];
+ a_assert(sp);
+ memset((char *) &sockaddr, '\0', sizeof(struct sockaddr_in6));
+ sockaddr.sin6_family = AF_INET6;
+ sockaddr.sin6_port = htons((short) (port & 0xFFFF));
+ dgram = sp->flags & SOCKET_DATAGRAM;
+ sp->sock = socket(AF_INET6, dgram ? SOCK_DGRAM: SOCK_STREAM, 0);
+ if (sp->sock < 0) {
+ socketFree(sid);
+ return -1;
+ }
+ if(fcntl(sp->sock, F_SETFD, FD_CLOEXEC) < 0)
+ {
+ slog(MISC_PRINT,SLOG_ERR, "fcntl return -1.\n");
+ }
+
+ socketHighestFd = max(socketHighestFd, sp->sock);
+ rc = 1;
+ // cov 3 CHECKED_RETURN
+ if(setsockopt(sp->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&rc, sizeof(rc)) < 0){
+ ;
+ }
+ if (bind(sp->sock, (struct sockaddr *) &sockaddr,
+ sizeof(sockaddr)) < 0) {
+ socketFree(sid);
+ return -1;
+ }
+
+ if (! dgram) {
+ if (listen(sp->sock, SOMAXCONN) < 0) {
+ socketFree(sid);
+ return -1;
+ }
+
+ sp->flags |= SOCKET_LISTENING;
+ }
+ sp->handlerMask |= SOCKET_READABLE;
+
+ if (flags & SOCKET_BLOCK) {
+ socketSetBlock(sid, 1);
+ } else {
+ socketSetBlock(sid, 0);
+ }
+ return sid;
+}
+
+void socketCloseConnection(int sid)
+{
+ socket_t *sp;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return;
+ }
+ socketFree(sid);
+}
+
+static void socketAccept(socket_t *sp)
+{
+ struct sockaddr_in6 addr;
+ //socket_t *nsp;
+ size_t len;
+ char pString[40]={0};
+ int newSock, nid;
+
+ a_assert(sp);
+ len = sizeof(struct sockaddr_in6);
+ if ((newSock = accept(sp->sock, (struct sockaddr *) &addr, (int *) &len)) < 0) {
+ return;
+ }
+ if(fcntl(newSock, F_SETFD, FD_CLOEXEC) < 0)
+ {
+ slog(MISC_PRINT,SLOG_ERR, "fcntl return -1.\n");
+ }
+ socketHighestFd = max(socketHighestFd, newSock);
+
+ nid = socketAlloc(sp->host, sp->port, sp->accept, sp->flags);
+ //nsp = socketList[nid];
+ a_assert(socketList[nid]);
+ if (socketList[nid] == NULL) {
+ close(newSock);
+ return;
+ }
+ socketList[nid]->sock = newSock;
+ socketList[nid]->flags &= ~SOCKET_LISTENING;
+
+ socketSetBlock(nid, (socketList[nid]->flags & SOCKET_BLOCK) ? 1: 0);
+
+ if (sp->accept != NULL) {
+ //pString = inet_ntoa(addr);
+ if(addr.sin6_addr.s6_addr32[0] == 0
+ && addr.sin6_addr.s6_addr32[1] == 0
+ && addr.sin6_addr.s6_addr32[2] == 0xffff0000)
+ inet_ntop(AF_INET,(void*)&addr.sin6_addr.s6_addr32[3],pString,sizeof(pString));
+ else
+ inet_ntop(AF_INET6,(void*)&addr.sin6_addr,pString,sizeof(pString));
+ if ((sp->accept)(nid, pString, ntohs(addr.sin6_port), sp->sid) < 0) {
+ socketFree(nid);
+ }
+ }
+ else
+ socketFree(nid);
+}
+
+int socketGetInput(int sid, char *buf, int toRead, int *errCode)
+{
+ struct sockaddr_in server;
+ socket_t *sp;
+ int len, bytesRead;
+ static int s_ErrorCnt = 0;
+ a_assert(buf);
+ a_assert(errCode);
+
+ *errCode = 0;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return -1;
+ }
+
+ if (sp->flags & SOCKET_EOF) {
+ return 0;
+ }
+ if (sp->flags & SOCKET_DATAGRAM) {
+ len = sizeof(server);
+ bytesRead = recvfrom(sp->sock, buf, toRead, 0,
+ (struct sockaddr *) &server, &len);
+ } else {
+ bytesRead = recv(sp->sock, buf, toRead, 0);
+ }
+
+ if (bytesRead < 0)
+ {
+ *errCode = socketGetError();
+ //printf("\n socketGetInput ERROR: bytesRead = %d, *errCode = %d! ", bytesRead, *errCode);
+ if (*errCode == ECONNRESET || s_ErrorCnt++ > 500)
+ {
+ sp->flags |= SOCKET_CONNRESET;
+ return 0;
+ }
+ return -1;
+ }
+ else
+ {
+ s_ErrorCnt = 0;
+ }
+ return bytesRead;
+}
+
+void socketRegisterInterest(socket_t *sp, int handlerMask)
+{
+ a_assert(sp);
+
+ sp->handlerMask = handlerMask;
+}
+
+int socketReady(int sid)
+{
+ socket_t *sp;
+ int all;
+
+ all = 0;
+ if (sid < 0) {
+ sid = 0;
+ all = 1;
+ }
+
+ for (; sid < socketMax; sid++) {
+ if ((sp = socketList[sid]) == NULL) {
+ if (! all) {
+ break;
+ } else {
+ continue;
+ }
+ }
+ if (sp->flags & SOCKET_CONNRESET) {
+ socketCloseConnection(sid);
+ return 0;
+ }
+ if (sp->currentEvents & sp->handlerMask) {
+ return 1;
+ }
+
+ if (sp->handlerMask & SOCKET_READABLE && socketInputBuffered(sid) > 0) {
+ socketSelect(sid, 0);
+ return 1;
+ }
+ if (! all) {
+ break;
+ }
+ }
+ return 0;
+}
+
+int socketSelect(int sid, int timeout)
+{
+ socket_t *sp;
+ struct timeval tv;
+ fd_mask *readFds, *writeFds, *exceptFds;
+ int all, len, nwords, index, bit, nEvents;
+
+ nwords = (socketHighestFd + NFDBITS) / NFDBITS;
+ len = nwords * sizeof(int);
+
+ readFds = balloc(B_L, len);
+ if(readFds == NULL)
+ return 0;
+ memset(readFds, 0, len);
+ writeFds = balloc(B_L, len);
+ if(writeFds == NULL){
+ bfree(B_L, readFds);
+ return 0;
+ }
+ memset(writeFds, 0, len);
+ exceptFds = balloc(B_L, len);
+ if(exceptFds == NULL){
+ bfree(B_L, readFds);
+ bfree(B_L, writeFds);
+ return 0;
+ }
+ memset(exceptFds, 0, len);
+
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+
+ all = nEvents = 0;
+
+ if (sid < 0) {
+ all++;
+ sid = 0;
+ }
+
+ for (; sid < socketMax; sid++) {
+ if ((sp = socketList[sid]) == NULL) {
+ if (all == 0) {
+ break;
+ } else {
+ continue;
+ }
+ }
+ a_assert(sp);
+
+ index = sp->sock / (NBBY * sizeof(fd_mask));
+ bit = 1 << (sp->sock % (NBBY * sizeof(fd_mask)));
+
+ if (sp->handlerMask & SOCKET_READABLE) {
+ readFds[index] |= bit;
+ nEvents++;
+ if (socketInputBuffered(sid) > 0) {
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ }
+ }
+ if (sp->handlerMask & SOCKET_WRITABLE) {
+ writeFds[index] |= bit;
+ nEvents++;
+ }
+ if (sp->handlerMask & SOCKET_EXCEPTION) {
+ exceptFds[index] |= bit;
+ nEvents++;
+ }
+ if (! all) {
+ break;
+ }
+ }
+
+ nEvents = select(socketHighestFd + 1, (fd_set *) readFds,
+ (fd_set *) writeFds, (fd_set *) exceptFds, &tv);
+
+ if (nEvents > 0) {
+ if (all) {
+ sid = 0;
+ }
+ for (; sid < socketMax; sid++) {
+ if ((sp = socketList[sid]) == NULL) {
+ if (all == 0) {
+ break;
+ } else {
+ continue;
+ }
+ }
+
+ index = sp->sock / (NBBY * sizeof(fd_mask));
+ bit = 1 << (sp->sock % (NBBY * sizeof(fd_mask)));
+
+ if (readFds[index] & bit || socketInputBuffered(sid) > 0) {
+ sp->currentEvents |= SOCKET_READABLE;
+ }
+ if (writeFds[index] & bit) {
+ sp->currentEvents |= SOCKET_WRITABLE;
+ }
+ if (exceptFds[index] & bit) {
+ sp->currentEvents |= SOCKET_EXCEPTION;
+ }
+ if (! all) {
+ break;
+ }
+ }
+ }
+
+ bfree(B_L, readFds);
+ bfree(B_L, writeFds);
+ bfree(B_L, exceptFds);
+
+ return nEvents;
+}
+
+void socketProcess(int sid)
+{
+ socket_t *sp;
+ int all;
+
+ all = 0;
+ if (sid < 0) {
+ all = 1;
+ sid = 0;
+ }
+ for (; sid < socketMax; sid++) {
+ if ((sp = socketList[sid]) == NULL) {
+ if (! all) {
+ break;
+ } else {
+ continue;
+ }
+ }
+ if (socketReady(sid)) {
+ socketDoEvent(sp);
+ }
+ if (! all) {
+ break;
+ }
+ }
+}
+
+static int socketDoEvent(socket_t *sp)
+{
+ ringq_t *rq;
+ int sid;
+
+ a_assert(sp);
+
+ sid = sp->sid;
+ if (sp->currentEvents & SOCKET_READABLE) {
+ if (sp->flags & SOCKET_LISTENING) {
+ socketAccept(sp);
+ sp->currentEvents = 0;
+ return 1;
+ }
+
+ } else {
+
+ if (sp->handlerMask & SOCKET_READABLE && socketInputBuffered(sid) > 0) {
+ sp->currentEvents |= SOCKET_READABLE;
+ }
+ }
+
+ if (sp->currentEvents & SOCKET_WRITABLE) {
+ if (sp->flags & SOCKET_FLUSHING) {
+ rq = &sp->outBuf;
+ if (ringqLen(rq) > 0) {
+ socketFlush(sp->sid);
+ } else {
+ sp->flags &= ~SOCKET_FLUSHING;
+ }
+ }
+ }
+
+ if (sp->handler && (sp->handlerMask & sp->currentEvents)) {
+ (sp->handler)(sid, sp->handlerMask & sp->currentEvents,
+ sp->handler_data);
+
+ if (socketList && sid < socketMax && socketList[sid] == sp) {
+ sp->currentEvents = 0;
+ }
+ }
+ return 1;
+}
+
+int socketSetBlock(int sid, int on)
+{
+ socket_t *sp;
+ unsigned long flag;
+ int iflag;
+ int oldBlock;
+ struct timeval rcv_timeo;
+
+ flag = iflag = !on;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ a_assert(0);
+ return 0;
+ }
+ oldBlock = (sp->flags & SOCKET_BLOCK);
+ sp->flags &= ~(SOCKET_BLOCK);
+ if (on) {
+ sp->flags |= SOCKET_BLOCK;
+ }
+
+
+ if (sp->flags & SOCKET_BLOCK) {
+
+ if(fcntl(sp->sock, F_SETFL, fcntl(sp->sock, F_GETFL) & ~O_NONBLOCK) < 0)
+ {
+ slog(MISC_PRINT,SLOG_ERR, "fcntl return -1.\n");
+ }
+
+ rcv_timeo.tv_sec = 60;
+ rcv_timeo.tv_usec = 0;
+ //printf("[zyl]set 60s send timeout\n");
+ //ÉèÖÃ60Ãë·¢Ëͳ¬Ê±
+ // cov 3 CHECKED_RETURN
+ if(setsockopt(sp->sock, SOL_SOCKET,SO_SNDTIMEO, (void*)&rcv_timeo, sizeof(rcv_timeo)) < 0){
+ ;
+ }
+ rcv_timeo.tv_sec = 1;
+ rcv_timeo.tv_usec = 0;
+
+ //ÉèÖÃ1Ãë½ÓÊÕ³¬Ê±
+ // cov 3 CHECKED_RETURN
+ if(setsockopt(sp->sock, SOL_SOCKET,SO_RCVTIMEO, (void*)&rcv_timeo, sizeof(rcv_timeo)) < 0){
+ ;
+ }
+
+ } else {
+ if(fcntl(sp->sock, F_SETFL, fcntl(sp->sock, F_GETFL) | O_NONBLOCK) < 0)
+ {
+ slog(MISC_PRINT,SLOG_ERR, "fcntl return -1.\n");
+ }
+ }
+ return oldBlock;
+}
+
+int socketSockBuffered(int sock)
+{
+ socket_t *sp;
+ int i;
+
+ for (i = 0; i < socketMax; i++) {
+ if ((sp = socketList[i]) == NULL || sp->sock != sock) {
+ continue;
+ }
+ return socketInputBuffered(i);
+ }
+ return 0;
+}
+
diff --git a/ap/app/goahead/server/sym.c b/ap/app/goahead/server/sym.c
new file mode 100755
index 0000000..036431a
--- /dev/null
+++ b/ap/app/goahead/server/sym.c
@@ -0,0 +1,345 @@
+#ifdef UEMF
+ #include "uemf.h"
+#else
+ #include "basic/basicInternal.h"
+#endif
+
+static int calcPrime(int size);
+
+typedef struct {
+ int inuse;
+ int hash_size;
+ sym_t **hash_table;
+} sym_tabent_t;
+
+static int symMax;
+static int hashIndex(sym_tabent_t *tp, char_t *name);
+static int htIndex;
+static sym_t *hash(sym_tabent_t *tp, char_t *name);
+static sym_t *next;
+static sym_tabent_t **sym;
+
+sym_fd_t symOpen(int hash_size)
+{
+ sym_fd_t sd;
+ sym_tabent_t *tp;
+
+ a_assert(hash_size > 2);
+
+ if ((sd = hAlloc((void***) &sym)) < 0) {
+ return -1;
+ }
+
+ if ((tp = (sym_tabent_t*) balloc(B_L, sizeof(sym_tabent_t))) == NULL) {
+ symMax = hFree((void***) &sym, sd);
+ return -1;
+ }
+ memset(tp, 0, sizeof(sym_tabent_t));
+ if (sd >= symMax) {
+ symMax = sd + 1;
+ }
+ a_assert(0 <= sd && sd < symMax);
+ sym[sd] = tp;
+
+ tp->hash_size = calcPrime(hash_size);
+ tp->hash_table = (sym_t**) balloc(B_L, tp->hash_size * sizeof(sym_t*));
+ a_assert(tp->hash_table);
+ if(tp->hash_table)
+ memset(tp->hash_table, 0, tp->hash_size * sizeof(sym_t*));
+
+ return sd;
+}
+
+void symClose(sym_fd_t sd)
+{
+ sym_tabent_t *tp;
+ sym_t *sp, *forw;
+ int i;
+
+ a_assert(0 <= sd && sd < symMax);
+ tp = sym[sd];
+ a_assert(tp);
+
+ for (i = 0; i < tp->hash_size; i++) {
+ for (sp = tp->hash_table[i]; sp; sp = forw) {
+ forw = sp->forw;
+ valueFree(&sp->name);
+ valueFree(&sp->content);
+ bfree(B_L, (void*) sp);
+ sp = forw;
+ }
+ }
+ bfree(B_L, (void*) tp->hash_table);
+
+ symMax = hFree((void***) &sym, sd);
+ bfree(B_L, (void*) tp);
+}
+
+sym_t* symFirst(sym_fd_t sd)
+{
+ sym_tabent_t *tp;
+ sym_t *sp, *forw;
+ int i;
+
+ a_assert(0 <= sd && sd < symMax);
+ tp = sym[sd];
+ a_assert(tp);
+
+ for (i = 0; i < tp->hash_size; i++) {
+
+#if 0 // KW 3 cov M
+ for (sp = tp->hash_table[i]; sp; sp = forw) {
+ forw = sp->forw;
+
+ if (forw == NULL) {
+ htIndex = i + 1;
+ next = tp->hash_table[htIndex];
+ } else {
+ htIndex = i;
+ next = forw;
+ }
+ return sp;
+ }
+#else
+ sp = tp->hash_table[i];
+ if(NULL != sp){
+ forw = sp->forw;
+
+ if (forw == NULL) {
+ htIndex = i + 1;
+ next = tp->hash_table[htIndex];
+ } else {
+ htIndex = i;
+ next = forw;
+ }
+ return sp;
+ }
+
+#endif
+ }
+ return NULL;
+}
+
+sym_t* symNext(sym_fd_t sd)
+{
+ sym_tabent_t *tp;
+ sym_t *sp, *forw;
+ int i;
+
+ a_assert(0 <= sd && sd < symMax);
+ tp = sym[sd];
+ a_assert(tp);
+
+ for (i = htIndex; i < tp->hash_size; i++) {
+
+#if 0 // kw 3 cov M
+ for (sp = next; sp; sp = forw) {
+ forw = sp->forw;
+
+ if (forw == NULL) {
+ htIndex = i + 1;
+ next = tp->hash_table[htIndex];
+ } else {
+ htIndex = i;
+ next = forw;
+ }
+ return sp;
+ }
+#else
+ sp = next;
+ if(NULL != sp) {
+ forw = sp->forw;
+
+ if (forw == NULL) {
+ htIndex = i + 1;
+ next = tp->hash_table[htIndex];
+ } else {
+ htIndex = i;
+ next = forw;
+ }
+ return sp;
+ }
+
+#endif
+ next = tp->hash_table[i + 1];
+ }
+ return NULL;
+}
+
+
+sym_t *symEnter(sym_fd_t sd, char_t *name, value_t v, int arg)
+{
+ sym_tabent_t *tp;
+ sym_t *sp, *last;
+ char_t *cp;
+ int hindex;
+
+ a_assert(name);
+ a_assert(0 <= sd && sd < symMax);
+ tp = sym[sd];
+ a_assert(tp);
+
+ last = NULL;
+ hindex = hashIndex(tp, name);
+ if ((sp = tp->hash_table[hindex]) != NULL) {
+ for (; sp; sp = sp->forw) {
+ cp = sp->name.value.string;
+ if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
+ break;
+ }
+ last = sp;
+ }
+ if (sp) {
+
+ if (sp->content.valid) {
+ valueFree(&sp->content);
+ }
+ sp->content = v;
+ sp->arg = arg;
+ return sp;
+ }
+
+ sp = (sym_t*) balloc(B_L, sizeof(sym_t));
+ if (sp == NULL) {
+ return NULL;
+ }
+ sp->content = v;
+ sp->forw = (sym_t*) NULL;
+ sp->name = valueString(name, VALUE_ALLOCATE);
+ sp->arg = arg;
+ last->forw = sp;
+
+ } else {
+ sp = (sym_t*) balloc(B_L, sizeof(sym_t));
+ if (sp == NULL) {
+ return NULL;
+ }
+ tp->hash_table[hindex] = sp;
+ tp->hash_table[hashIndex(tp, name)] = sp;
+
+ sp->arg = arg;
+ sp->content = v;
+ sp->name = valueString(name, VALUE_ALLOCATE);
+ sp->forw = (sym_t*) NULL;
+ }
+ return sp;
+}
+
+sym_t *symLookup(sym_fd_t sd, char_t *name)
+{
+ sym_tabent_t *tp;
+ sym_t *sp;
+ char_t *cp;
+
+ a_assert(0 <= sd && sd < symMax);
+ if ((tp = sym[sd]) == NULL) {
+ return NULL;
+ }
+
+ if (name == NULL || *name == '\0') {
+ return NULL;
+ }
+
+
+ for (sp = hash(tp, name); sp; sp = sp->forw) {
+ cp = sp->name.value.string;
+ if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
+ break;
+ }
+ }
+ return sp;
+}
+
+int symDelete(sym_fd_t sd, char_t *name)
+{
+ sym_t *last = NULL;
+ int hindex;
+ char_t *cp;
+ sym_t *sp;
+ sym_tabent_t *tp;
+
+ a_assert(name && *name);
+ a_assert(0 <= sd && sd < symMax);
+ tp = sym[sd];
+ a_assert(tp);
+
+ hindex = hashIndex(tp, name);
+ if ((sp = tp->hash_table[hindex]) != NULL) {
+ for ( ; sp; sp = sp->forw) {
+ cp = sp->name.value.string;
+ if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
+ break;
+ }
+ last = sp;
+ }
+ }
+ if (sp == (sym_t*) NULL) {
+ return -1;
+ }
+
+ if (last) {
+ last->forw = sp->forw;
+ } else {
+ tp->hash_table[hindex] = sp->forw;
+ }
+ valueFree(&sp->name);
+ valueFree(&sp->content);
+ bfree(B_L, (void*) sp);
+
+ return 0;
+}
+
+
+
+static int hashIndex(sym_tabent_t *tp, char_t *name)
+{
+ unsigned int sum;
+ int i;
+
+ a_assert(tp);
+
+ i = 0;
+ sum = 0;
+ while (*name) {
+ sum += (((int) *name++) << i);
+ i = (i + 7) % (BITS(int) - BITSPERBYTE);
+ }
+ return sum % tp->hash_size;
+}
+
+static int isPrime(int n)
+{
+ int i, max;
+
+ a_assert(n > 0);
+
+ max = n / 2;
+ for (i = 2; i <= max; i++) {
+ if (n % i == 0) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static sym_t *hash(sym_tabent_t *tp, char_t *name)
+{
+ a_assert(tp);
+
+ return tp->hash_table[hashIndex(tp, name)];
+}
+
+static int calcPrime(int size)
+{
+ int count;
+
+ a_assert(size > 0);
+
+ for (count = size; count > 0; count--) {
+ if (isPrime(count)) {
+ return count;
+ }
+ }
+ return 1;
+}
+
diff --git a/ap/app/goahead/server/uemf.c b/ap/app/goahead/server/uemf.c
new file mode 100755
index 0000000..8155d8a
--- /dev/null
+++ b/ap/app/goahead/server/uemf.c
@@ -0,0 +1,159 @@
+#include "uemf.h"
+
+
+int emfInst;
+extern void defaultErrorHandler(int etype, char_t *buf);
+extern void defaultTraceHandler(int level, char_t *buf);
+
+static void (*traceHandler)(int level, char_t *buf) = defaultTraceHandler;
+static void (*errorHandler)(int etype, char_t *msg) = defaultErrorHandler;
+
+void error(E_ARGS_DEC, int etype, char_t *fmt, ...)
+{
+ va_list args = {0};
+ char_t *fmtBuf, *buf;
+
+ va_start(args, fmt);
+ fmtValloc(&fmtBuf, E_MAX_ERROR, fmt, args);
+
+ if (etype == E_LOG) {
+ fmtAlloc(&buf, E_MAX_ERROR, T("%s\n"), fmtBuf);
+/*#ifdef DEV*/
+ } else if (etype == E_ASSERT) {
+ fmtAlloc(&buf, E_MAX_ERROR,
+ T("Assertion %s, failed at %s %d\n"), fmtBuf, E_ARGS);
+/*#endif*/
+ } else if (etype == E_USER) {
+ fmtAlloc(&buf, E_MAX_ERROR, T("%s\n"), fmtBuf);
+ }
+
+ else {
+ fmtAlloc(&buf, E_MAX_ERROR, T("Unknown error"));
+ }
+ va_end(args);
+
+ bfree(B_L, fmtBuf);
+
+ printf("%s",buf);
+
+ bfreeSafe(B_L, buf);
+}
+
+void traceRaw(char_t *buf)
+{
+ if(buf)
+ printf("%s",buf);
+}
+
+void trace(int level, char_t *fmt, ...)
+{
+ va_list args = {0};
+ char_t *buf;
+
+ va_start(args, fmt);
+ fmtValloc(&buf, VALUE_MAX_STRING, fmt, args);
+ printf("%s",buf);
+ bfreeSafe(B_L, buf);
+ va_end(args);
+}
+
+char_t *strlower(char_t *string)
+{
+ char_t *s;
+
+ a_assert(string);
+
+ if (string == NULL) {
+ return NULL;
+ }
+
+ s = string;
+ while (*s) {
+ if (gisupper(*s)) {
+ *s = (char_t) gtolower(*s);
+ }
+ s++;
+ }
+ *s = '\0';
+ return string;
+}
+
+char_t *strupper(char_t *string)
+{
+ char_t *s;
+
+ a_assert(string);
+ if (string == NULL) {
+ return NULL;
+ }
+
+ s = string;
+ while (*s) {
+ if (gislower(*s)) {
+ *s = (char_t) gtoupper(*s);
+ }
+ s++;
+ }
+ *s = '\0';
+ return string;
+}
+
+char_t *basicGetProduct()
+{
+ return T("uemf");
+}
+
+char_t *basicGetAddress()
+{
+ return T("localhost");
+}
+
+char_t *stritoa(int n, char_t *string, int width)
+{
+ char_t *cp, *lim, *s;
+ int next, minus;
+ char_t tmp_buf[16];
+
+ a_assert(string && width > 0);
+
+ if (string == NULL) {
+ if (width == 0) {
+ width = 10;
+ }
+ if ((string = balloc(B_L, width + 1)) == NULL) {
+ return NULL;
+ }
+ }
+ if (n < 0) {
+ minus = 1;
+ n = -n;
+ width--;
+ } else {
+ minus = 0;
+ }
+
+ cp = tmp_buf;
+ lim = &tmp_buf[width - 1];
+ while (n > 9 && cp < lim) {
+ next = n;
+ n /= 10;
+ *cp++ = (char_t) (next - n * 10 + '0');
+ }
+ if (cp < lim) {
+ *cp++ = (char_t) (n + '0');
+ }
+
+ s = string;
+ if (minus) {
+ *s++ = '-';
+ }
+
+ while (cp > tmp_buf) {
+ *s++ = *--cp;
+ }
+
+ *s++ = '\0';
+ return string;
+}
+
+
diff --git a/ap/app/goahead/server/uemf.h b/ap/app/goahead/server/uemf.h
new file mode 100755
index 0000000..3010ac0
--- /dev/null
+++ b/ap/app/goahead/server/uemf.h
@@ -0,0 +1,929 @@
+#ifndef _h_UEMF
+#define _h_UEMF 1
+
+#ifdef WIN
+ #include <direct.h>
+ #include <io.h>
+ #include <sys/stat.h>
+ #include <limits.h>
+ #include <tchar.h>
+ #include <windows.h>
+ #include <winnls.h>
+ #include <time.h>
+ #include <sys/types.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <fcntl.h>
+ #include <errno.h>
+#endif /* WIN */
+
+#ifdef CE
+ /*#include <errno.h>*/
+ #include <limits.h>
+ #include <tchar.h>
+ #include <windows.h>
+ #include <winsock.h>
+ #include <winnls.h>
+ #include "CE/wincompat.h"
+ #include <winsock.h>
+#endif /* CE */
+
+#ifdef NW
+ #include <direct.h>
+ #include <io.h>
+ #include <sys/stat.h>
+ #include <time.h>
+ #include <sys/types.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <fcntl.h>
+ #include <errno.h>
+ #include <niterror.h>
+ #define EINTR EINUSE
+ #define WEBS 1
+ #include <limits.h>
+ #include <netdb.h>
+ #include <process.h>
+ #include <tiuser.h>
+ #include <sys/time.h>
+ #include <arpa/inet.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <sys/filio.h>
+ #include <netinet/in.h>
+#endif /* NW */
+
+#ifdef SCOV5
+ #include <sys/types.h>
+ #include <stdio.h>
+ #include "sys/socket.h"
+ #include "sys/select.h"
+ #include "netinet/in.h"
+ #include "arpa/inet.h"
+ #include "netdb.h"
+#endif /* SCOV5 */
+
+#ifdef UNIX
+ #include <stdio.h>
+#endif /* UNIX */
+
+#ifdef LINUX
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/param.h>
+ #include <limits.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <sys/socket.h>
+ #include <sys/select.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <netdb.h>
+ #include <time.h>
+ #include <fcntl.h>
+ #include <errno.h>
+#endif /* LINUX */
+
+#ifdef LYNX
+ #include <limits.h>
+ #include <stdarg.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <netdb.h>
+ #include <time.h>
+ #include <fcntl.h>
+ #include <errno.h>
+#endif /* LYNX */
+
+#ifdef MACOSX
+ #include <sys/stat.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <netdb.h>
+ #include <fcntl.h>
+ #include <errno.h>
+#endif /* MACOSX */
+
+#ifdef UW
+ #include <stdio.h>
+#endif /* UW */
+
+#ifdef VXWORKS
+ #include <vxWorks.h>
+ #include <sockLib.h>
+ #include <selectLib.h>
+ #include <inetLib.h>
+ #include <ioLib.h>
+ #include <stdio.h>
+ #include <stat.h>
+ #include <time.h>
+ #include <usrLib.h>
+ #include <fcntl.h>
+ #include <errno.h>
+#endif /* VXWORKS */
+
+#ifdef sparc
+# define __NO_PACK
+#endif /* sparc */
+
+#ifdef SOLARIS
+ #include <sys/types.h>
+ #include <limits.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <socket.h>
+ #include <sys/select.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <netdb.h>
+ #include <time.h>
+ #include <fcntl.h>
+ #include <errno.h>
+#endif /* SOLARIS */
+
+#ifdef QNX4
+ #include <sys/types.h>
+ #include <stdio.h>
+ #include <sys/socket.h>
+ #include <sys/select.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <netdb.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <sys/uio.h>
+ #include <sys/wait.h>
+#endif /* QNX4 */
+
+#ifdef ECOS
+ #include <limits.h>
+ #include <cyg/infra/cyg_type.h>
+ #include <cyg/kernel/kapi.h>
+ #include <time.h>
+ #include <network.h>
+ #include <errno.h>
+#endif /* ECOS */
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <string.h>
+
+#ifndef WEBS
+#include "messages.h"
+#endif /* ! WEBS */
+
+#ifdef UW
+ #define __NO_PACK 1
+#endif /* UW */
+
+#if (defined (SCOV5) || defined (VXWORKS) || defined (LINUX) || defined (LYNX) || defined (MACOSX))
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif /* O_BINARY */
+#define SOCKET_ERROR -1
+#endif /* SCOV5 || VXWORKS || LINUX || LYNX || MACOSX */
+
+#if (defined (WIN) || defined (CE))
+
+#define __NO_FCNTL 1
+
+#undef R_OK
+#define R_OK 4
+#undef W_OK
+#define W_OK 2
+#undef X_OK
+#define X_OK 1
+#undef F_OK
+#define F_OK 0
+#endif /* WIN || CE */
+
+#if (defined (LINUX) && !defined (_STRUCT_TIMEVAL))
+struct timeval
+{
+ time_t tv_sec;
+ time_t tv_usec;
+};
+#define _STRUCT_TIMEVAL 1
+#endif /* LINUX && ! _STRUCT_TIMEVAL */
+
+#ifdef ECOS
+ #define O_RDONLY 1
+ #define O_BINARY 2
+
+ #define __NO_PACK 1
+ #define __NO_EJ_FILE 1
+ #define __NO_CGI_BIN 1
+ #define __NO_FCNTL 1
+
+ #define LIBKERN_INLINE
+
+#endif /* ECOS */
+
+#ifdef QNX4
+ typedef long fd_mask;
+ #define NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */
+#endif /* QNX4 */
+
+#ifdef NW
+ #define fd_mask fd_set
+ #define INADDR_NONE -1l
+ #define Sleep delay
+
+ #define __NO_FCNTL 1
+
+ #undef R_OK
+ #define R_OK 4
+ #undef W_OK
+ #define W_OK 2
+ #undef X_OK
+ #define X_OK 1
+ #undef F_OK
+ #define F_OK 0
+#endif /* NW */
+
+#define TRACE_MAX (4096 - 48)
+#define VALUE_MAX_STRING (4096 - 48)
+#define SYM_MAX (512)
+#define XML_MAX 4096
+#define BUF_MAX 4096
+#define FMT_STATIC_MAX 256
+
+#if (defined (LITTLEFOOT) || defined (WEBS))
+#define LF_BUF_MAX (510)
+#define LF_PATHSIZE LF_BUF_MAX
+#else
+#define LF_BUF_MAX BUF_MAX
+#define LF_PATHSIZE PATHSIZE
+#define UPPATHSIZE PATHSIZE
+#endif /* LITTLEFOOT || WEBS */
+
+#ifndef CHAR_T_DEFINED
+#define CHAR_T_DEFINED 1
+#ifdef UNICODE
+
+#define T(x) __TXT(x)
+#define __TXT(s) L ## s
+typedef unsigned short char_t;
+typedef unsigned short uchar_t;
+
+#define TSZ(x) (sizeof(x) / sizeof(char_t))
+
+#define TASTRL(x) ((wcslen(x) + 1) * sizeof(char_t))
+
+#else
+#define T(s) s
+typedef char char_t;
+#define TSZ(x) (sizeof(x))
+#define TASTRL(x) (strlen(x) + 1)
+#ifdef WIN
+typedef unsigned char uchar_t;
+#endif /* WIN */
+
+#endif /* UNICODE */
+
+#endif /* ! CHAR_T_DEFINED */
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define GOAHEAD_COPYRIGHT \
+ T("Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.")
+
+#if (defined (LITTLEFOOT) && defined (INMEM))
+ #include "lf/inmem.h"
+#endif /* LITTLEFOOT && INMEM */
+
+#ifdef UNICODE
+
+#define gmain wmain
+
+#define gasctime _wasctime
+#define gsprintf swprintf
+#define gprintf wprintf
+#define gfprintf fwprintf
+#define gsscanf swscanf
+#define gvsprintf vswprintf
+
+#define gstrcpy wcscpy
+#define gstrncpy wcsncpy
+#define gstrncat wcsncat
+#define gstrlen wcslen
+#define gstrcat wcscat
+#define gstrcmp wcscmp
+#define gstrncmp wcsncmp
+#define gstricmp wcsicmp
+#define gstrchr wcschr
+#define gstrrchr wcsrchr
+#define gstrtok wcstok
+#define gstrnset wcsnset
+#define gstrrchr wcsrchr
+#define gstrspn wcsspn
+#define gstrcspn wcscspn
+#define gstrstr wcsstr
+#define gstrtol wcstol
+
+#define gfopen _wfopen
+#define gopen _wopen
+#define gclose close
+#define gcreat _wcreat
+#define gfgets fgetws
+#define gfputs fputws
+#define gfscanf fwscanf
+#define ggets _getws
+#define glseek lseek
+#define gunlink _wunlink
+#define gread read
+#define grename _wrename
+#define gwrite write
+#define gtmpnam _wtmpnam
+#define gtempnam _wtempnam
+#define gfindfirst _wfindfirst
+#define gfinddata_t _wfinddata_t
+#define gfindnext _wfindnext
+#define gfindclose _findclose
+#define gstat _wstat
+#define gaccess _waccess
+#define gchmod _wchmod
+
+typedef struct _stat gstat_t;
+
+#define gmkdir _wmkdir
+#define gchdir _wchdir
+#define grmdir _wrmdir
+#define ggetcwd _wgetcwd
+
+#define gtolower towlower
+#define gtoupper towupper
+#ifdef CE
+#define gisspace isspace
+#define gisdigit isdigit
+#define gisxdigit isxdigit
+#define gisupper isupper
+#define gislower islower
+#define gisprint isprint
+#else
+#define gremove _wremove
+#define gisspace iswspace
+#define gisdigit iswdigit
+#define gisxdigit iswxdigit
+#define gisupper iswupper
+#define gislower iswlower
+#endif /* if CE */
+#define gisalnum iswalnum
+#define gisalpha iswalpha
+#define gatoi(s) wcstol(s, NULL, 10)
+
+#define gctime _wctime
+#define ggetenv _wgetenv
+#define gexecvp _wexecvp
+
+#else /* ! UNICODE */
+
+#ifdef VXWORKS
+#define gchdir vxchdir
+#define gmkdir vxmkdir
+#define grmdir vxrmdir
+#elif (defined (LYNX) || defined (LINUX) || defined (MACOSX) || defined (SOLARIS))
+#define gchdir chdir
+#define gmkdir(s) mkdir(s,0755)
+#define grmdir rmdir
+#else
+#define gchdir chdir
+#define gmkdir mkdir
+#define grmdir rmdir
+#endif /* VXWORKS #elif LYNX || LINUX || MACOSX || SOLARIS*/
+
+#define gclose close
+#define gclosedir closedir
+#define gchmod chmod
+#define ggetcwd getcwd
+#define glseek lseek
+#define gloadModule loadModule
+#define gopen open
+#define gopendir opendir
+#define gread read
+#define greaddir readdir
+#define grename rename
+#define gstat stat
+#define gunlink unlink
+#define gwrite write
+
+#define gasctime asctime
+#define gsprintf sprintf
+#define gprintf printf
+#define gfprintf fprintf
+#define gsscanf sscanf
+#define gvsprintf vsprintf
+
+#define gstrcpy strcpy
+#define gstrncpy strncpy
+#define gstrncat strncat
+#define gstrlen strlen
+#define gstrcat strcat
+#define gstrcmp strcmp
+#define gstrncmp strncmp
+#define gstricmp strcmpci
+#define gstrchr strchr
+#define gstrrchr strrchr
+#define gstrtok strtok
+#define gstrnset strnset
+#define gstrrchr strrchr
+#define gstrspn strspn
+#define gstrcspn strcspn
+#define gstrstr strstr
+#define gstrtol strtol
+
+#define gfopen fopen
+#define gcreat creat
+#define gfgets fgets
+#define gfputs fputs
+#define gfscanf fscanf
+#define ggets gets
+#define gtmpnam tmpnam
+#define gtempnam tempnam
+#define gfindfirst _findfirst
+#define gfinddata_t _finddata_t
+#define gfindnext _findnext
+#define gfindclose _findclose
+#define gaccess access
+
+typedef struct stat gstat_t;
+
+#define gremove remove
+
+#define gtolower tolower
+#define gtoupper toupper
+#define gisspace isspace
+#define gisdigit isdigit
+#define gisxdigit isxdigit
+#define gisalnum isalnum
+#define gisalpha isalpha
+#define gisupper isupper
+#define gislower islower
+#define gatoi atoi
+
+#define gctime ctime
+#define ggetenv getenv
+#define gexecvp execvp
+#ifndef VXWORKS
+#define gmain main
+#endif /* ! VXWORKS */
+#ifdef VXWORKS
+#define fcntl(a, b, c)
+#endif /* VXWORKS */
+#endif /* ! UNICODE */
+
+#ifdef INMEM
+ #include "lf/inmem.h"
+#endif
+
+#ifndef FNAMESIZE
+#define FNAMESIZE 254
+#endif /* FNAMESIZE */
+
+#define E_MAX_ERROR 4096
+#define URL_MAX 4096
+
+#define E_ASSERT 0x1
+#define E_LOG 0x2
+#define E_USER 0x3
+
+#define E_L T(__FILE__), __LINE__
+#define E_ARGS_DEC char_t *file, int line
+#define E_ARGS file, line
+
+#if (defined (ASSERT) || defined (ASSERT_CE))
+ #define a_assert(C) if (C) ; else error(E_L, E_ASSERT, T("%s"), T(#C))
+#else
+ #define a_assert(C) if (1) ; else
+#endif /* ASSERT || ASSERT_CE */
+
+typedef enum {
+ undefined = 0,
+ byteint = 1,
+ shortint = 2,
+ integer = 3,
+ hex = 4,
+ percent = 5,
+ octal = 6,
+ big = 7,
+ flag = 8,
+ floating = 9,
+ string = 10,
+ bytes = 11,
+ symbol = 12,
+ errmsg = 13
+} vtype_t;
+
+#ifndef __NO_PACK
+#pragma pack(2)
+#endif /* _NO_PACK */
+
+typedef struct {
+
+ union {
+ char flag;
+ char byteint;
+ short shortint;
+ char percent;
+ long integer;
+ long hex;
+ long octal;
+ long big[2];
+#ifdef FLOATING_POINT_SUPPORT
+ double floating;
+#endif /* FLOATING_POINT_SUPPORT */
+ char_t *string;
+ char *bytes;
+ char_t *errmsg;
+ void *symbol;
+ } value;
+
+ vtype_t type;
+ unsigned int valid : 8;
+ unsigned int allocated : 8;
+} value_t;
+
+#ifndef __NO_PACK
+#pragma pack()
+#endif /* __NO_PACK */
+
+#define VALUE_ALLOCATE 0x1
+
+#define value_numeric(t) (t >= byteint && t <= big)
+#define value_str(t) (t >= string && t <= bytes)
+#define value_ok(t) (t > undefined && t <= symbol)
+
+#define VALUE_VALID { {0}, integer, 1 }
+#define VALUE_INVALID { {0}, undefined, 0 }
+
+typedef struct {
+ unsigned char *buf;
+ unsigned char *servp;
+ unsigned char *endp;
+ unsigned char *endbuf;
+ int buflen;
+ int maxsize;
+ int increment;
+} ringq_t;
+
+#ifdef B_STATS
+#ifndef B_L
+#define B_L T(__FILE__), __LINE__
+#define B_ARGS_DEC char_t *file, int line
+#define B_ARGS file, line
+#endif /* B_L */
+#endif /* B_STATS */
+
+typedef struct {
+ union {
+ void *next;
+ int size;
+ } u;
+ int flags;
+} bType;
+
+#define B_SHIFT 4
+#define B_ROUND ((1 << (B_SHIFT)) - 1)
+#define B_MAX_CLASS 13
+#define B_MALLOCED 0x80000000
+#define B_DEFAULT_MEM (64 * 1024)
+#define B_MAX_FILES (512)
+#define B_FILL_CHAR (0x77)
+#define B_FILL_WORD (0x77777777)
+#define B_MAX_BLOCKS (64 * 1024)
+
+
+#define B_INTEGRITY 0x8124000
+#define B_INTEGRITY_MASK 0xFFFF000
+#define B_USE_MALLOC 0x1
+#define B_USER_BUF 0x2
+
+
+typedef struct sym_t {
+ struct sym_t *forw;
+ value_t name;
+ value_t content;
+ int arg;
+} sym_t;
+
+typedef int sym_fd_t;
+
+#define EMF_SCRIPT_JSCRIPT 0
+#define EMF_SCRIPT_TCL 1
+#define EMF_SCRIPT_EJSCRIPT 2
+#define EMF_SCRIPT_MAX 3
+
+#define MAXINT INT_MAX
+#define BITSPERBYTE 8
+#define BITS(type) (BITSPERBYTE * (int) sizeof(type))
+#define STRSPACE T("\t \n\r\t")
+
+#ifndef max
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif /* max */
+
+#ifndef min
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif /* min */
+
+typedef struct {
+ char_t *minute;
+ char_t *hour;
+ char_t *day;
+ char_t *month;
+ char_t *dayofweek;
+} cron_t;
+
+extern long cronUntil(cron_t *cp, int period, time_t testTime);
+extern int cronAlloc(cron_t *cp, char_t *str);
+extern int cronFree(cron_t *cp);
+
+
+#if ((defined (WIN) || defined (CE)) && defined (WEBS))
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#define ENETDOWN WSAENETDOWN
+#define ECONNRESET WSAECONNRESET
+#endif /* (WIN || CE) && WEBS) */
+
+#define SOCKET_EOF 0x1
+#define SOCKET_CONNECTING 0x2
+#define SOCKET_BROADCAST 0x4
+#define SOCKET_PENDING 0x8
+#define SOCKET_FLUSHING 0x10
+#define SOCKET_DATAGRAM 0x20
+#define SOCKET_ASYNC 0x40
+#define SOCKET_BLOCK 0x80
+#define SOCKET_LISTENING 0x100
+#define SOCKET_CLOSING 0x200
+#define SOCKET_CONNRESET 0x400
+
+#define SOCKET_PORT_MAX 0xffff
+
+
+#define SOCKET_WOULDBLOCK 1
+#define SOCKET_RESET 2
+#define SOCKET_NETDOWN 3
+#define SOCKET_AGAIN 4
+#define SOCKET_INTR 5
+#define SOCKET_INVAL 6
+
+#define SOCKET_READABLE 0x2
+#define SOCKET_WRITABLE 0x4
+#define SOCKET_EXCEPTION 0x8
+#define EMF_SOCKET_MESSAGE (WM_USER+13)
+
+#ifdef LITTLEFOOT
+#define SOCKET_BUFSIZ 510
+#else
+#define SOCKET_BUFSIZ 1024
+#endif /* LITTLEFOOT */
+
+typedef void (*socketHandler_t)(int sid, int mask, int data);
+typedef int (*socketAccept_t)(int sid, char *ipaddr, int port,
+ int listenSid);
+typedef struct {
+ char host[64];
+ ringq_t inBuf;
+ ringq_t outBuf;
+ ringq_t lineBuf;
+ socketAccept_t accept;
+ socketHandler_t handler;
+ int handler_data;
+ int handlerMask;
+ int sid;
+ int port;
+ int flags;
+ int sock;
+ int fileHandle;
+ int interestEvents;
+ int currentEvents;
+ int selectEvents;
+ int saveMask;
+ int error;
+} socket_t;
+
+
+extern void bclose();
+extern int bopen(void *buf, int bufsize, int flags);
+
+
+#ifdef NO_BALLOC
+#define balloc(B_ARGS, num) malloc(num)
+#define bfree(B_ARGS, p) free(p)
+#define bfreeSafe(B_ARGS, p) \
+ if (p) { free(p); } else
+#define brealloc(B_ARGS, p, num) realloc(p, num)
+extern char_t *bstrdupNoBalloc(char_t *s);
+extern char *bstrdupANoBalloc(char *s);
+#define bstrdup(B_ARGS, s) bstrdupNoBalloc(s)
+#define bstrdupA(B_ARGS, s) bstrdupANoBalloc(s)
+#define gstrdup(B_ARGS, s) bstrdupNoBalloc(s)
+
+#else /* BALLOC */
+
+#ifndef B_STATS
+#define balloc(B_ARGS, num) balloc(num)
+#define bfree(B_ARGS, p) bfree(p)
+#define bfreeSafe(B_ARGS, p) bfreeSafe(p)
+#define brealloc(B_ARGS, p, size) brealloc(p, size)
+#define bstrdup(B_ARGS, p) bstrdup(p)
+
+#ifdef UNICODE
+#define bstrdupA(B_ARGS, p) bstrdupA(p)
+#else /* UNICODE */
+#define bstrdupA bstrdup
+#endif /* UNICODE */
+
+#endif /* B_STATS */
+
+#define gstrdup bstrdup
+extern void *balloc(B_ARGS_DEC, int size);
+extern void bfree(B_ARGS_DEC, void *mp);
+extern void bfreeSafe(B_ARGS_DEC, void *mp);
+extern void *brealloc(B_ARGS_DEC, void *buf, int newsize);
+extern char_t *bstrdup(B_ARGS_DEC, char_t *s);
+
+#ifdef UNICODE
+extern char *bstrdupA(B_ARGS_DEC, char *s);
+#else /* UNICODE */
+#define bstrdupA bstrdup
+#endif /* UNICODE */
+#endif /* BALLOC */
+
+extern void bstats(int handle, void (*writefn)(int handle, char_t *fmt, ...));
+
+#define B_USE_MALLOC 0x1 /* Okay to use malloc if required */
+#define B_USER_BUF 0x2 /* User supplied buffer for mem */
+
+
+#ifndef LINUX
+extern char_t *basename(char_t *name);
+#endif /* !LINUX */
+
+#if (defined (UEMF) && defined (WEBS))
+
+#define emfSchedCallback websSchedCallBack
+#define emfUnschedCallback websUnschedCallBack
+#define emfReschedCallback websReschedCallBack
+#endif /* UEMF && WEBS */
+
+typedef void (emfSchedProc)(void *data, int id);
+extern int emfSchedCallback(int delay, emfSchedProc *proc, void *arg);
+extern void emfUnschedCallback(int id);
+extern void emfReschedCallback(int id, int delay);
+extern void emfSchedProcess();
+extern int emfInstGet();
+extern void emfInstSet(int inst);
+extern void error(E_ARGS_DEC, int flags, char_t *fmt, ...);
+extern void (*errorSetHandler(void (*function)(int etype, char_t *msg))) \
+ (int etype, char_t *msg);
+
+#ifdef B_STATS
+#define hAlloc(x) HALLOC(B_L, x)
+#define hAllocEntry(x, y, z) HALLOCENTRY(B_L, x, y, z)
+extern int HALLOC(B_ARGS_DEC, void ***map);
+extern int HALLOCENTRY(B_ARGS_DEC, void ***list, int *max, int size);
+#else
+extern int hAlloc(void ***map);
+extern int hAllocEntry(void ***list, int *max, int size);
+#endif /* B_STATS */
+
+extern int hFree(void ***map, int handle);
+
+extern int ringqOpen(ringq_t *rq, int increment, int maxsize);
+extern void ringqClose(ringq_t *rq);
+extern int ringqLen(ringq_t *rq);
+
+extern int ringqPutc(ringq_t *rq, char_t c);
+extern int ringqInsertc(ringq_t *rq, char_t c);
+extern int ringqPutStr(ringq_t *rq, char_t *str);
+extern int ringqGetc(ringq_t *rq);
+
+extern int fmtValloc(char_t **s, int n, char_t *fmt, va_list arg);
+extern int fmtAlloc(char_t **s, int n, char_t *fmt, ...);
+extern int fmtStatic(char_t *s, int n, char_t *fmt, ...);
+
+#ifdef UNICODE
+extern int ringqPutcA(ringq_t *rq, char c);
+extern int ringqInsertcA(ringq_t *rq, char c);
+extern int ringqPutStrA(ringq_t *rq, char *str);
+extern int ringqGetcA(ringq_t *rq);
+#else
+#define ringqPutcA ringqPutc
+#define ringqInsertcA ringqInsertc
+#define ringqPutStrA ringqPutStr
+#define ringqGetcA ringqGetc
+#endif /* UNICODE */
+
+extern int ringqPutBlk(ringq_t *rq, unsigned char *buf, int len);
+extern int ringqPutBlkMax(ringq_t *rq);
+extern void ringqPutBlkAdj(ringq_t *rq, int size);
+extern int ringqGetBlk(ringq_t *rq, unsigned char *buf, int len);
+extern int ringqGetBlkMax(ringq_t *rq);
+extern void ringqGetBlkAdj(ringq_t *rq, int size);
+extern void ringqFlush(ringq_t *rq);
+extern void ringqAddNull(ringq_t *rq);
+
+extern int scriptSetVar(int engine, char_t *var, char_t *value);
+extern int scriptEval(int engine, char_t *cmd, char_t **rslt, int chan);
+
+extern void socketClose();
+extern void socketCloseConnection(int sid);
+extern void socketCreateHandler(int sid, int mask, socketHandler_t
+ handler, int arg);
+extern void socketDeleteHandler(int sid);
+extern int socketEof(int sid);
+extern int socketCanWrite(int sid);
+extern void socketSetBufferSize(int sid, int in, int line, int out);
+extern int socketFlush(int sid);
+extern int socketGets(int sid, char_t **buf);
+extern int socketGetPort(int sid);
+extern int socketInputBuffered(int sid);
+extern int socketOpen();
+extern int socketOpenConnection(char *host, int port,
+ socketAccept_t accept, int flags);
+extern void socketProcess(int hid);
+extern int socketRead(int sid, char *buf, int len);
+extern int socketReady(int hid);
+extern int socketWrite(int sid, char *buf, int len);
+extern int socketWriteString(int sid, char_t *buf);
+extern int socketSelect(int hid, int timeout);
+extern int socketGetHandle(int sid);
+extern int socketSetBlock(int sid, int flags);
+extern int socketGetBlock(int sid);
+extern int socketAlloc(char *host, int port, socketAccept_t accept,
+ int flags);
+extern void socketFree(int sid);
+extern int socketGetError();
+extern socket_t *socketPtr(int sid);
+extern int socketWaitForEvent(socket_t *sp, int events, int *errCode);
+extern void socketRegisterInterest(socket_t *sp, int handlerMask);
+extern int socketGetInput(int sid, char *buf, int toRead, int *errCode);
+
+extern char_t *strlower(char_t *string);
+extern char_t *strupper(char_t *string);
+
+extern char_t *stritoa(int n, char_t *string, int width);
+
+extern sym_fd_t symOpen(int hash_size);
+extern void symClose(sym_fd_t sd);
+extern sym_t *symLookup(sym_fd_t sd, char_t *name);
+extern sym_t *symEnter(sym_fd_t sd, char_t *name, value_t v, int arg);
+extern int symDelete(sym_fd_t sd, char_t *name);
+extern void symWalk(sym_fd_t sd, void (*fn)(sym_t *symp));
+extern sym_t *symFirst(sym_fd_t sd);
+extern sym_t *symNext(sym_fd_t sd);
+extern int symSubOpen();
+extern void symSubClose();
+
+extern void trace(int lev, char_t *fmt, ...);
+extern void traceRaw(char_t *buf);
+extern void (*traceSetHandler(void (*function)(int level, char_t *buf)))
+ (int level, char_t *buf);
+
+extern value_t valueInteger(long value);
+extern value_t valueString(char_t *value, int flags);
+extern value_t valueErrmsg(char_t *value);
+extern void valueFree(value_t *v);
+extern int vxchdir(char *dirname);
+
+extern unsigned int hextoi(char_t *hexstring);
+extern unsigned int gstrtoi(char_t *s);
+extern time_t timeMsec();
+
+extern char_t *ascToUni(char_t *ubuf, char *str, int nBytes);
+extern char *uniToAsc(char *buf, char_t *ustr, int nBytes);
+extern char_t *ballocAscToUni(char *cp, int alen);
+extern char *ballocUniToAsc(char_t *unip, int ulen);
+
+extern char_t *basicGetHost();
+extern char_t *basicGetAddress();
+extern char_t *basicGetProduct();
+extern void basicSetHost(char_t *host);
+extern void basicSetAddress(char_t *addr);
+
+extern int harnessOpen(char_t **argv);
+extern void harnessClose(int status);
+extern void harnessTesting(char_t *msg, ...);
+extern void harnessPassed();
+extern void harnessFailed(int line);
+extern int harnessLevel();
+
+#endif /* _h_UEMF */
+
diff --git a/ap/app/goahead/server/unzip.c b/ap/app/goahead/server/unzip.c
new file mode 100644
index 0000000..c51d7ec
--- /dev/null
+++ b/ap/app/goahead/server/unzip.c
@@ -0,0 +1,2208 @@
+/* unzip.c -- IO for uncompress .zip files using zlib
+ Version 1.1, February 14h, 2010
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications of Unzip for Zip64
+ Copyright (C) 2007-2008 Even Rouault
+
+ Modifications for Zip64 support on both zip and unzip
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+
+ ------------------------------------------------------------------------------------
+ Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
+ compatibility with older software. The following is from the original crypt.c.
+ Code woven in by Terry Thorsen 1/2003.
+
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+
+ crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
+
+ The encryption/decryption parts of this source code (as opposed to the
+ non-echoing password parts) were originally written in Europe. The
+ whole source package can be freely distributed, including from the USA.
+ (Prior to January 2000, re-export from the US was a violation of US law.)
+
+ This encryption code is a direct transcription of the algorithm from
+ Roger Schlafly, described by Phil Katz in the file appnote.txt. This
+ file (appnote.txt) is distributed with the PKZIP program (even in the
+ version without encryption capabilities).
+
+ ------------------------------------------------------------------------------------
+
+ Changes in unzip.c
+
+ 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
+ 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*
+ 2007-2008 - Even Rouault - Remove old C style function prototypes
+ 2007-2008 - Even Rouault - Add unzip support for ZIP64
+
+ Copyright (C) 2007-2008 Even Rouault
+
+
+ Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
+ Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
+ should only read the compressed/uncompressed size from the Zip64 format if
+ the size from normal header was 0xFFFFFFFF
+ Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
+ Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
+ Patch created by Daniel Borca
+
+ Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
+
+ Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
+
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef NOUNCRYPT
+ #define NOUNCRYPT
+#endif
+
+#include "zlib.h"
+#include "unzip.h"
+
+#ifdef STDC
+# include <stddef.h>
+# include <string.h>
+# include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+ extern int errno;
+#else
+# include <errno.h>
+#endif
+
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+
+#ifndef CASESENSITIVITYDEFAULT_NO
+# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
+# define CASESENSITIVITYDEFAULT_NO
+# endif
+#endif
+
+
+#ifndef UNZ_BUFSIZE
+#define UNZ_BUFSIZE (16384)
+#endif
+
+#ifndef UNZ_MAXFILENAMEINZIP
+#define UNZ_MAXFILENAMEINZIP (256)
+#endif
+
+//#define WEB_ZIP_MEM_DEBUG
+#ifdef WEB_ZIP_MEM_DEBUG
+static void* web_malloc(unsigned int bytes);
+static void web_free(void* mem);
+
+#define ALLOC(size) (web_malloc(size))
+#define TRYFREE(p) {if (p) web_free(p);}
+#endif
+
+#ifndef ALLOC
+# define ALLOC(size) (malloc(size))
+#endif
+#ifndef TRYFREE
+# define TRYFREE(p) {if (p) free(p);}
+#endif
+
+#define SIZECENTRALDIRITEM (0x2e)
+#define SIZEZIPLOCALHEADER (0x1e)
+
+
+const char unz_copyright[] =
+ " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
+
+/* unz_file_info_interntal contain internal info about a file in zipfile*/
+typedef struct unz_file_info64_internal_s
+{
+ ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
+} unz_file_info64_internal;
+
+
+/* file_in_zip_read_info_s contain internal information about a file in zipfile,
+ when reading and decompress it */
+typedef struct
+{
+ char *read_buffer; /* internal buffer for compressed data */
+ z_stream stream; /* zLib stream structure for inflate */
+
+#ifdef HAVE_BZIP2
+ bz_stream bstream; /* bzLib stream structure for bziped */
+#endif
+
+ ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
+ uLong stream_initialised; /* flag set if stream structure is initialised*/
+
+ ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
+ uInt size_local_extrafield;/* size of the local extra field */
+ ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/
+ ZPOS64_T total_out_64;
+
+ uLong crc32; /* crc32 of all data uncompressed */
+ uLong crc32_wait; /* crc32 we must obtain after decompress all */
+ ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
+ ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
+ zlib_filefunc64_32_def z_filefunc;
+ voidpf filestream; /* io structore of the zipfile */
+ uLong compression_method; /* compression method (0==store) */
+ ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+ int raw;
+} file_in_zip64_read_info_s;
+
+
+/* unz64_s contain internal information about the zipfile
+*/
+typedef struct
+{
+ zlib_filefunc64_32_def z_filefunc;
+ int is64bitOpenFunction;
+ voidpf filestream; /* io structore of the zipfile */
+ unz_global_info64 gi; /* public global information */
+ ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+ ZPOS64_T num_file; /* number of the current file in the zipfile*/
+ ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/
+ ZPOS64_T current_file_ok; /* flag about the usability of the current file*/
+ ZPOS64_T central_pos; /* position of the beginning of the central dir*/
+
+ ZPOS64_T size_central_dir; /* size of the central directory */
+ ZPOS64_T offset_central_dir; /* offset of start of central directory with
+ respect to the starting disk number */
+
+ unz_file_info64 cur_file_info; /* public info about the current file in zip*/
+ unz_file_info64_internal cur_file_info_internal; /* private info about it*/
+ file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
+ file if we are decompressing it */
+ int encrypted;
+
+ int isZip64;
+
+# ifndef NOUNCRYPT
+ unsigned long keys[3]; /* keys defining the pseudo-random sequence */
+ const z_crc_t* pcrc_32_tab;
+# endif
+} unz64_s;
+
+
+#ifndef NOUNCRYPT
+#include "crypt.h"
+#endif
+
+/* ===========================================================================
+ Read a byte from a gz_stream; update next_in and avail_in. Return EOF
+ for end of file.
+ IN assertion: the stream s has been successfully opened for reading.
+*/
+
+
+local int unz64local_getByte OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ int *pi));
+
+local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
+{
+ unsigned char c;
+ int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
+ if (err==1)
+ {
+ *pi = (int)c;
+ return UNZ_OK;
+ }
+ else
+ {
+ if (ZERROR64(*pzlib_filefunc_def,filestream))
+ return UNZ_ERRNO;
+ else
+ return UNZ_EOF;
+ }
+}
+
+
+/* ===========================================================================
+ Reads a long in LSB order from the given gz_stream. Sets
+*/
+local int unz64local_getShort OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ uLong *pX));
+
+local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ uLong *pX)
+{
+ uLong x ;
+ int i = 0;
+ int err;
+
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (uLong)i;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((uLong)i)<<8;
+
+ if (err==UNZ_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+local int unz64local_getLong OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ uLong *pX));
+
+local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ uLong *pX)
+{
+ uLong x ;
+ int i = 0;
+ int err;
+
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (uLong)i;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((uLong)i)<<8;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((uLong)i)<<16;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((uLong)i)<<24;
+
+ if (err==UNZ_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+local int unz64local_getLong64 OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ ZPOS64_T *pX));
+
+
+local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ ZPOS64_T *pX)
+{
+ ZPOS64_T x ;
+ int i = 0;
+ int err;
+
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (ZPOS64_T)i;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<8;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<16;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<24;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<32;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<40;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<48;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<56;
+
+ if (err==UNZ_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+/* My own strcmpi / strcasecmp */
+local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
+{
+ for (;;)
+ {
+ char c1=*(fileName1++);
+ char c2=*(fileName2++);
+ if ((c1>='a') && (c1<='z'))
+ c1 -= 0x20;
+ if ((c2>='a') && (c2<='z'))
+ c2 -= 0x20;
+ if (c1=='\0')
+ return ((c2=='\0') ? 0 : -1);
+ if (c2=='\0')
+ return 1;
+ if (c1<c2)
+ return -1;
+ if (c1>c2)
+ return 1;
+ }
+}
+
+
+#ifdef CASESENSITIVITYDEFAULT_NO
+#define CASESENSITIVITYDEFAULTVALUE 2
+#else
+#define CASESENSITIVITYDEFAULTVALUE 1
+#endif
+
+#ifndef STRCMPCASENOSENTIVEFUNCTION
+#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
+#endif
+
+/*
+ Compare two filename (fileName1,fileName2).
+ If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+ If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+ or strcasecmp)
+ If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+ (like 1 on Unix, 2 on Windows)
+
+*/
+extern int ZEXPORT unzStringFileNameCompare (const char* fileName1,
+ const char* fileName2,
+ int iCaseSensitivity)
+
+{
+ if (iCaseSensitivity==0)
+ iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
+
+ if (iCaseSensitivity==1)
+ return strcmp(fileName1,fileName2);
+
+ return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
+}
+
+#ifndef BUFREADCOMMENT
+#define BUFREADCOMMENT (0x400)
+#endif
+
+/*
+ Locate the Central directory of a zipfile (at the end, just before
+ the global comment)
+*/
+local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
+local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
+{
+ unsigned char* buf;
+ ZPOS64_T uSizeFile;
+ ZPOS64_T uBackRead;
+ ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+ ZPOS64_T uPosFound=0;
+
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+ return 0;
+
+
+ uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+ if (uMaxBack>uSizeFile)
+ uMaxBack = uSizeFile;
+
+ buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+ if (buf==NULL)
+ return 0;
+
+ uBackRead = 4;
+ while (uBackRead<uMaxBack)
+ {
+ uLong uReadSize;
+ ZPOS64_T uReadPos ;
+ int i;
+ if (uBackRead+BUFREADCOMMENT>uMaxBack)
+ uBackRead = uMaxBack;
+ else
+ uBackRead+=BUFREADCOMMENT;
+ uReadPos = uSizeFile-uBackRead ;
+
+ uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+ (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ break;
+
+ if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+ break;
+
+ for (i=(int)uReadSize-3; (i--)>0;)
+ if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+ ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
+ {
+ uPosFound = uReadPos+i;
+ break;
+ }
+
+ if (uPosFound!=0)
+ break;
+ }
+ TRYFREE(buf);
+ return uPosFound;
+}
+
+
+/*
+ Locate the Central directory 64 of a zipfile (at the end, just before
+ the global comment)
+*/
+local ZPOS64_T unz64local_SearchCentralDir64 OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream));
+
+local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream)
+{
+ unsigned char* buf;
+ ZPOS64_T uSizeFile;
+ ZPOS64_T uBackRead;
+ ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+ ZPOS64_T uPosFound=0;
+ uLong uL;
+ ZPOS64_T relativeOffset;
+
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+ return 0;
+
+
+ uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+ if (uMaxBack>uSizeFile)
+ uMaxBack = uSizeFile;
+
+ buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+ if (buf==NULL)
+ return 0;
+
+ uBackRead = 4;
+ while (uBackRead<uMaxBack)
+ {
+ uLong uReadSize;
+ ZPOS64_T uReadPos;
+ int i;
+ if (uBackRead+BUFREADCOMMENT>uMaxBack)
+ uBackRead = uMaxBack;
+ else
+ uBackRead+=BUFREADCOMMENT;
+ uReadPos = uSizeFile-uBackRead ;
+
+ uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+ (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ break;
+
+ if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+ break;
+
+ for (i=(int)uReadSize-3; (i--)>0;)
+ if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+ ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
+ {
+ uPosFound = uReadPos+i;
+ break;
+ }
+
+ if (uPosFound!=0)
+ break;
+ }
+ TRYFREE(buf);
+ if (uPosFound == 0)
+ return 0;
+
+ /* Zip64 end of central directory locator */
+ if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return 0;
+
+ /* the signature, already checked */
+ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+ return 0;
+
+ /* number of the disk with the start of the zip64 end of central directory */
+ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+ return 0;
+ if (uL != 0)
+ return 0;
+
+ /* relative offset of the zip64 end of central directory record */
+ if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
+ return 0;
+
+ /* total number of disks */
+ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+ return 0;
+ if (uL != 1)
+ return 0;
+
+ /* Goto end of central directory record */
+ if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return 0;
+
+ /* the signature */
+ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+ return 0;
+
+ if (uL != 0x06064b50)
+ return 0;
+
+ return relativeOffset;
+}
+
+/*
+ Open a Zip file. path contain the full pathname (by example,
+ on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
+ "zlib/zlib114.zip".
+ If the zipfile cannot be opened (file doesn't exist or in not valid), the
+ return value is NULL.
+ Else, the return value is a unzFile Handle, usable with other function
+ of this unzip package.
+*/
+local unzFile unzOpenInternal (const void *path,
+ zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
+ int is64bitOpenFunction)
+{
+ unz64_s us = {0};
+ unz64_s *s;
+ ZPOS64_T central_pos;
+ uLong uL;
+
+ uLong number_disk; /* number of the current dist, used for
+ spaning ZIP, unsupported, always 0*/
+ uLong number_disk_with_CD; /* number the the disk with central dir, used
+ for spaning ZIP, unsupported, always 0*/
+ ZPOS64_T number_entry_CD; /* total number of entries in
+ the central dir
+ (same than number_entry on nospan) */
+
+ int err=UNZ_OK;
+
+ if (unz_copyright[0]!=' ')
+ return NULL;
+
+ us.z_filefunc.zseek32_file = NULL;
+ us.z_filefunc.ztell32_file = NULL;
+ if (pzlib_filefunc64_32_def==NULL)
+ fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);
+ else
+ us.z_filefunc = *pzlib_filefunc64_32_def;
+ us.is64bitOpenFunction = is64bitOpenFunction;
+
+
+
+ us.filestream = ZOPEN64(us.z_filefunc,
+ path,
+ ZLIB_FILEFUNC_MODE_READ |
+ ZLIB_FILEFUNC_MODE_EXISTING);
+ if (us.filestream==NULL)
+ return NULL;
+
+ central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
+ if (central_pos)
+ {
+ uLong uS;
+ ZPOS64_T uL64;
+
+ us.isZip64 = 1;
+
+ if (ZSEEK64(us.z_filefunc, us.filestream,
+ central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err=UNZ_ERRNO;
+
+ /* the signature, already checked */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* size of zip64 end of central directory record */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* version made by */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* version needed to extract */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* number of this disk */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* number of the disk with the start of the central directory */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* total number of entries in the central directory on this disk */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* total number of entries in the central directory */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if ((number_entry_CD!=us.gi.number_entry) ||
+ (number_disk_with_CD!=0) ||
+ (number_disk!=0))
+ err=UNZ_BADZIPFILE;
+
+ /* size of the central directory */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* offset of start of central directory with respect to the
+ starting disk number */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ us.gi.size_comment = 0;
+ }
+ else
+ {
+ central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
+ if (central_pos==0)
+ err=UNZ_ERRNO;
+
+ us.isZip64 = 0;
+
+ if (ZSEEK64(us.z_filefunc, us.filestream,
+ central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err=UNZ_ERRNO;
+
+ /* the signature, already checked */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* number of this disk */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* number of the disk with the start of the central directory */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* total number of entries in the central dir on this disk */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ us.gi.number_entry = uL;
+
+ /* total number of entries in the central dir */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ number_entry_CD = uL;
+
+ if ((number_entry_CD!=us.gi.number_entry) ||
+ (number_disk_with_CD!=0) ||
+ (number_disk!=0))
+ err=UNZ_BADZIPFILE;
+
+ /* size of the central directory */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ us.size_central_dir = uL;
+
+ /* offset of start of central directory with respect to the
+ starting disk number */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ us.offset_central_dir = uL;
+
+ /* zipfile comment length */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
+ (err==UNZ_OK))
+ err=UNZ_BADZIPFILE;
+
+ if (err!=UNZ_OK)
+ {
+ ZCLOSE64(us.z_filefunc, us.filestream);
+ return NULL;
+ }
+
+ us.byte_before_the_zipfile = central_pos -
+ (us.offset_central_dir+us.size_central_dir);
+ us.central_pos = central_pos;
+ us.pfile_in_zip_read = NULL;
+ us.encrypted = 0;
+
+
+ s=(unz64_s*)ALLOC(sizeof(unz64_s));
+ if( s != NULL)
+ {
+ *s=us;
+ unzGoToFirstFile((unzFile)s);
+ }
+ return (unzFile)s;
+}
+
+
+extern unzFile ZEXPORT unzOpen2 (const char *path,
+ zlib_filefunc_def* pzlib_filefunc32_def)
+{
+ if (pzlib_filefunc32_def != NULL)
+ {
+ zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+ fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
+ return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
+ }
+ else
+ return unzOpenInternal(path, NULL, 0);
+}
+
+extern unzFile ZEXPORT unzOpen2_64 (const void *path,
+ zlib_filefunc64_def* pzlib_filefunc_def)
+{
+ if (pzlib_filefunc_def != NULL)
+ {
+ zlib_filefunc64_32_def zlib_filefunc64_32_def_fill = {0};
+ zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
+ zlib_filefunc64_32_def_fill.ztell32_file = NULL;
+ zlib_filefunc64_32_def_fill.zseek32_file = NULL;
+ return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);
+ }
+ else
+ return unzOpenInternal(path, NULL, 1);
+}
+
+extern unzFile ZEXPORT unzOpen (const char *path)
+{
+ return unzOpenInternal(path, NULL, 0);
+}
+
+extern unzFile ZEXPORT unzOpen64 (const void *path)
+{
+ return unzOpenInternal(path, NULL, 1);
+}
+
+/*
+ Close a ZipFile opened with unzOpen.
+ If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
+ these files MUST be closed with unzCloseCurrentFile before call unzClose.
+ return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzClose (unzFile file)
+{
+ unz64_s* s;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+
+ if (s->pfile_in_zip_read!=NULL)
+ unzCloseCurrentFile(file);
+
+ ZCLOSE64(s->z_filefunc, s->filestream);
+ TRYFREE(s);
+ return UNZ_OK;
+}
+
+
+/*
+ Write info about the ZipFile in the *pglobal_info structure.
+ No preparation of the structure is needed
+ return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
+{
+ unz64_s* s;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ *pglobal_info=s->gi;
+ return UNZ_OK;
+}
+
+extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
+{
+ unz64_s* s;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ /* to do : check if number_entry is not truncated */
+ pglobal_info32->number_entry = (uLong)s->gi.number_entry;
+ pglobal_info32->size_comment = s->gi.size_comment;
+ return UNZ_OK;
+}
+/*
+ Translate date/time from Dos format to tm_unz (readable more easilty)
+*/
+local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
+{
+ ZPOS64_T uDate;
+ uDate = (ZPOS64_T)(ulDosDate>>16);
+ ptm->tm_mday = (uInt)(uDate&0x1f) ;
+ ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
+ ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
+
+ ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
+ ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
+ ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
+}
+
+/*
+ Get Info about the current file in the zipfile, with internal only info
+*/
+local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
+ unz_file_info64 *pfile_info,
+ unz_file_info64_internal
+ *pfile_info_internal,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize));
+
+local int unz64local_GetCurrentFileInfoInternal (unzFile file,
+ unz_file_info64 *pfile_info,
+ unz_file_info64_internal
+ *pfile_info_internal,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize)
+{
+ unz64_s* s;
+ unz_file_info64 file_info;
+ unz_file_info64_internal file_info_internal;
+ int err=UNZ_OK;
+ uLong uMagic;
+ long lSeek=0;
+ uLong uL;
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (ZSEEK64(s->z_filefunc, s->filestream,
+ s->pos_in_central_dir+s->byte_before_the_zipfile,
+ ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err=UNZ_ERRNO;
+
+
+ /* we check the magic */
+ if (err==UNZ_OK)
+ {
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
+ err=UNZ_ERRNO;
+ else if (uMagic!=0x02014b50)
+ err=UNZ_BADZIPFILE;
+ }
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+ err=UNZ_ERRNO;
+ file_info.compressed_size = uL;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+ err=UNZ_ERRNO;
+ file_info.uncompressed_size = uL;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ // relative offset of local header
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+ err=UNZ_ERRNO;
+ file_info_internal.offset_curfile = uL;
+
+ lSeek+=file_info.size_filename;
+ if ((err==UNZ_OK) && (szFileName!=NULL))
+ {
+ uLong uSizeRead ;
+ if (file_info.size_filename<fileNameBufferSize)
+ {
+ *(szFileName+file_info.size_filename)='\0';
+ uSizeRead = file_info.size_filename;
+ }
+ else
+ uSizeRead = fileNameBufferSize;
+
+ if ((file_info.size_filename>0) && (fileNameBufferSize>0))
+ if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
+ err=UNZ_ERRNO;
+ lSeek -= uSizeRead;
+ }
+
+ // Read extrafield
+ if ((err==UNZ_OK) && (extraField!=NULL))
+ {
+ ZPOS64_T uSizeRead ;
+ if (file_info.size_file_extra<extraFieldBufferSize)
+ uSizeRead = file_info.size_file_extra;
+ else
+ uSizeRead = extraFieldBufferSize;
+
+ if (lSeek!=0)
+ {
+ if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+ lSeek=0;
+ else
+ err=UNZ_ERRNO;
+ }
+
+ if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
+ if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
+ err=UNZ_ERRNO;
+
+ lSeek += file_info.size_file_extra - (uLong)uSizeRead;
+ }
+ else
+ lSeek += file_info.size_file_extra;
+
+
+ if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
+ {
+ uLong acc = 0;
+
+ // since lSeek now points to after the extra field we need to move back
+ lSeek -= file_info.size_file_extra;
+
+ if (lSeek!=0)
+ {
+ if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+ lSeek=0;
+ else
+ err=UNZ_ERRNO;
+ }
+
+ while(acc < file_info.size_file_extra)
+ {
+ uLong headerId;
+ uLong dataSize;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* ZIP64 extra fields */
+ if (headerId == 0x0001)
+ {
+ uLong uL;
+
+ if(file_info.uncompressed_size == MAXU32)
+ {
+ if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ if(file_info.compressed_size == MAXU32)
+ {
+ if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ if(file_info_internal.offset_curfile == MAXU32)
+ {
+ /* Relative Header offset */
+ if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ if(file_info.disk_num_start == MAXU32)
+ {
+ /* Disk Start Number */
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ }
+ else
+ {
+ if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
+ err=UNZ_ERRNO;
+ }
+
+ acc += 2 + 2 + dataSize;
+ }
+ }
+
+ if ((err==UNZ_OK) && (szComment!=NULL))
+ {
+ uLong uSizeRead ;
+ if (file_info.size_file_comment<commentBufferSize)
+ {
+ *(szComment+file_info.size_file_comment)='\0';
+ uSizeRead = file_info.size_file_comment;
+ }
+ else
+ uSizeRead = commentBufferSize;
+
+ if (lSeek!=0)
+ {
+ if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+ lSeek=0;
+ else
+ err=UNZ_ERRNO;
+ }
+
+ if ((file_info.size_file_comment>0) && (commentBufferSize>0))
+ if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
+ err=UNZ_ERRNO;
+ lSeek+=file_info.size_file_comment - uSizeRead;
+ }
+ else
+ lSeek+=file_info.size_file_comment;
+
+
+ if ((err==UNZ_OK) && (pfile_info!=NULL))
+ *pfile_info=file_info;
+
+ if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
+ *pfile_info_internal=file_info_internal;
+
+ return err;
+}
+
+
+
+/*
+ Write info about the ZipFile in the *pglobal_info structure.
+ No preparation of the structure is needed
+ return UNZ_OK if there is no problem.
+*/
+extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
+ unz_file_info64 * pfile_info,
+ char * szFileName, uLong fileNameBufferSize,
+ void *extraField, uLong extraFieldBufferSize,
+ char* szComment, uLong commentBufferSize)
+{
+ return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
+ szFileName,fileNameBufferSize,
+ extraField,extraFieldBufferSize,
+ szComment,commentBufferSize);
+}
+
+extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
+ unz_file_info * pfile_info,
+ char * szFileName, uLong fileNameBufferSize,
+ void *extraField, uLong extraFieldBufferSize,
+ char* szComment, uLong commentBufferSize)
+{
+ int err;
+ unz_file_info64 file_info64;
+ err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
+ szFileName,fileNameBufferSize,
+ extraField,extraFieldBufferSize,
+ szComment,commentBufferSize);
+ if ((err==UNZ_OK) && (pfile_info != NULL))
+ {
+ pfile_info->version = file_info64.version;
+ pfile_info->version_needed = file_info64.version_needed;
+ pfile_info->flag = file_info64.flag;
+ pfile_info->compression_method = file_info64.compression_method;
+ pfile_info->dosDate = file_info64.dosDate;
+ pfile_info->crc = file_info64.crc;
+
+ pfile_info->size_filename = file_info64.size_filename;
+ pfile_info->size_file_extra = file_info64.size_file_extra;
+ pfile_info->size_file_comment = file_info64.size_file_comment;
+
+ pfile_info->disk_num_start = file_info64.disk_num_start;
+ pfile_info->internal_fa = file_info64.internal_fa;
+ pfile_info->external_fa = file_info64.external_fa;
+
+ pfile_info->tmu_date = file_info64.tmu_date,
+
+
+ pfile_info->compressed_size = (uLong)file_info64.compressed_size;
+ pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
+
+ }
+ return err;
+}
+/*
+ Set the current file of the zipfile to the first file.
+ return UNZ_OK if there is no problem
+*/
+extern int ZEXPORT unzGoToFirstFile (unzFile file)
+{
+ int err=UNZ_OK;
+ unz64_s* s;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ s->pos_in_central_dir=s->offset_central_dir;
+ s->num_file=0;
+ err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+ &s->cur_file_info_internal,
+ NULL,0,NULL,0,NULL,0);
+ s->current_file_ok = (err == UNZ_OK);
+ return err;
+}
+
+/*
+ Set the current file of the zipfile to the next file.
+ return UNZ_OK if there is no problem
+ return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+extern int ZEXPORT unzGoToNextFile (unzFile file)
+{
+ unz64_s* s;
+ int err;
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return UNZ_END_OF_LIST_OF_FILE;
+ if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
+ if (s->num_file+1==s->gi.number_entry)
+ return UNZ_END_OF_LIST_OF_FILE;
+
+ s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
+ s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
+ s->num_file++;
+ err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+ &s->cur_file_info_internal,
+ NULL,0,NULL,0,NULL,0);
+ s->current_file_ok = (err == UNZ_OK);
+ return err;
+}
+
+
+/*
+ Try locate the file szFileName in the zipfile.
+ For the iCaseSensitivity signification, see unzStringFileNameCompare
+
+ return value :
+ UNZ_OK if the file is found. It becomes the current file.
+ UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
+{
+ unz64_s* s;
+ int err;
+
+ /* We remember the 'current' position in the file so that we can jump
+ * back there if we fail.
+ */
+ unz_file_info64 cur_file_infoSaved;
+ unz_file_info64_internal cur_file_info_internalSaved;
+ ZPOS64_T num_fileSaved;
+ ZPOS64_T pos_in_central_dirSaved;
+
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+
+ if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
+ return UNZ_PARAMERROR;
+
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return UNZ_END_OF_LIST_OF_FILE;
+
+ /* Save the current state */
+ num_fileSaved = s->num_file;
+ pos_in_central_dirSaved = s->pos_in_central_dir;
+ cur_file_infoSaved = s->cur_file_info;
+ cur_file_info_internalSaved = s->cur_file_info_internal;
+
+ err = unzGoToFirstFile(file);
+
+ while (err == UNZ_OK)
+ {
+ char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
+ err = unzGetCurrentFileInfo64(file,NULL,
+ szCurrentFileName,sizeof(szCurrentFileName)-1,
+ NULL,0,NULL,0);
+ if (err == UNZ_OK)
+ {
+ if (unzStringFileNameCompare(szCurrentFileName,
+ szFileName,iCaseSensitivity)==0)
+ return UNZ_OK;
+ err = unzGoToNextFile(file);
+ }
+ }
+
+ /* We failed, so restore the state of the 'current file' to where we
+ * were.
+ */
+ s->num_file = num_fileSaved ;
+ s->pos_in_central_dir = pos_in_central_dirSaved ;
+ s->cur_file_info = cur_file_infoSaved;
+ s->cur_file_info_internal = cur_file_info_internalSaved;
+ return err;
+}
+
+
+/*
+///////////////////////////////////////////
+// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
+// I need random access
+//
+// Further optimization could be realized by adding an ability
+// to cache the directory in memory. The goal being a single
+// comprehensive file read to put the file I need in a memory.
+*/
+
+/*
+typedef struct unz_file_pos_s
+{
+ ZPOS64_T pos_in_zip_directory; // offset in file
+ ZPOS64_T num_of_file; // # of file
+} unz_file_pos;
+*/
+
+extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos)
+{
+ unz64_s* s;
+
+ if (file==NULL || file_pos==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return UNZ_END_OF_LIST_OF_FILE;
+
+ file_pos->pos_in_zip_directory = s->pos_in_central_dir;
+ file_pos->num_of_file = s->num_file;
+
+ return UNZ_OK;
+}
+
+extern int ZEXPORT unzGetFilePos(
+ unzFile file,
+ unz_file_pos* file_pos)
+{
+ unz64_file_pos file_pos64;
+ int err = unzGetFilePos64(file,&file_pos64);
+ if (err==UNZ_OK)
+ {
+ file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
+ file_pos->num_of_file = (uLong)file_pos64.num_of_file;
+ }
+ return err;
+}
+
+extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
+{
+ unz64_s* s;
+ int err;
+
+ if (file==NULL || file_pos==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+
+ /* jump to the right spot */
+ s->pos_in_central_dir = file_pos->pos_in_zip_directory;
+ s->num_file = file_pos->num_of_file;
+
+ /* set the current file */
+ err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+ &s->cur_file_info_internal,
+ NULL,0,NULL,0,NULL,0);
+ /* return results */
+ s->current_file_ok = (err == UNZ_OK);
+ return err;
+}
+
+extern int ZEXPORT unzGoToFilePos(
+ unzFile file,
+ unz_file_pos* file_pos)
+{
+ unz64_file_pos file_pos64;
+ if (file_pos == NULL)
+ return UNZ_PARAMERROR;
+
+ file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
+ file_pos64.num_of_file = file_pos->num_of_file;
+ return unzGoToFilePos64(file,&file_pos64);
+}
+
+/*
+// Unzip Helper Functions - should be here?
+///////////////////////////////////////////
+*/
+
+/*
+ Read the local header of the current zipfile
+ Check the coherency of the local header and info in the end of central
+ directory about this file
+ store in *piSizeVar the size of extra info in local header
+ (filename and size of extra field data)
+*/
+local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
+ ZPOS64_T * poffset_local_extrafield,
+ uInt * psize_local_extrafield)
+{
+ uLong uMagic,uData,uFlags;
+ uLong size_filename;
+ uLong size_extra_field;
+ int err=UNZ_OK;
+
+ *piSizeVar = 0;
+ *poffset_local_extrafield = 0;
+ *psize_local_extrafield = 0;
+
+ if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
+ s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return UNZ_ERRNO;
+
+
+ if (err==UNZ_OK)
+ {
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
+ err=UNZ_ERRNO;
+ else if (uMagic!=0x04034b50)
+ err=UNZ_BADZIPFILE;
+ }
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
+ err=UNZ_ERRNO;
+/*
+ else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
+ err=UNZ_BADZIPFILE;
+*/
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
+ err=UNZ_ERRNO;
+ else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
+ err=UNZ_BADZIPFILE;
+
+ if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
+/* #ifdef HAVE_BZIP2 */
+ (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
+/* #endif */
+ (s->cur_file_info.compression_method!=Z_DEFLATED))
+ err=UNZ_BADZIPFILE;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
+ err=UNZ_ERRNO;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
+ err=UNZ_ERRNO;
+ else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
+ err=UNZ_BADZIPFILE;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
+ err=UNZ_ERRNO;
+ else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
+ err=UNZ_BADZIPFILE;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
+ err=UNZ_ERRNO;
+ else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
+ err=UNZ_BADZIPFILE;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
+ err=UNZ_ERRNO;
+ else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
+ err=UNZ_BADZIPFILE;
+
+ *piSizeVar += (uInt)size_filename;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
+ err=UNZ_ERRNO;
+ *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
+ SIZEZIPLOCALHEADER + size_filename;
+ *psize_local_extrafield = (uInt)size_extra_field;
+
+ *piSizeVar += (uInt)size_extra_field;
+
+ return err;
+}
+
+/*
+ Open for reading data the current file in the zipfile.
+ If there is no error and the file is opened, the return value is UNZ_OK.
+*/
+extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
+ int* level, int raw, const char* password)
+{
+ int err=UNZ_OK;
+ uInt iSizeVar;
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ ZPOS64_T offset_local_extrafield; /* offset of the local extra field */
+ uInt size_local_extrafield; /* size of the local extra field */
+# ifndef NOUNCRYPT
+ char source[12];
+# else
+ if (password != NULL)
+ return UNZ_PARAMERROR;
+# endif
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return UNZ_PARAMERROR;
+
+ if (s->pfile_in_zip_read != NULL)
+ unzCloseCurrentFile(file);
+
+ if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
+ return UNZ_BADZIPFILE;
+
+ pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_INTERNALERROR;
+
+ pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
+ pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
+ pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
+ pfile_in_zip_read_info->pos_local_extrafield=0;
+ pfile_in_zip_read_info->raw=raw;
+
+ if (pfile_in_zip_read_info->read_buffer==NULL)
+ {
+ TRYFREE(pfile_in_zip_read_info);
+ return UNZ_INTERNALERROR;
+ }
+
+ pfile_in_zip_read_info->stream_initialised=0;
+
+ if (method!=NULL)
+ *method = (int)s->cur_file_info.compression_method;
+
+ if (level!=NULL)
+ {
+ *level = 6;
+ switch (s->cur_file_info.flag & 0x06)
+ {
+ case 6 : *level = 1; break;
+ case 4 : *level = 2; break;
+ case 2 : *level = 9; break;
+ }
+ }
+
+ if ((s->cur_file_info.compression_method!=0) &&
+/* #ifdef HAVE_BZIP2 */
+ (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
+/* #endif */
+ (s->cur_file_info.compression_method!=Z_DEFLATED))
+
+ err=UNZ_BADZIPFILE;
+
+ pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
+ pfile_in_zip_read_info->crc32=0;
+ pfile_in_zip_read_info->total_out_64=0;
+ pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
+ pfile_in_zip_read_info->filestream=s->filestream;
+ pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
+ pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
+
+ pfile_in_zip_read_info->stream.total_out = 0;
+
+ if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
+ {
+#ifdef HAVE_BZIP2
+ pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
+ pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
+ pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
+ pfile_in_zip_read_info->bstream.state = (voidpf)0;
+
+ pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
+ pfile_in_zip_read_info->stream.zfree = (free_func)0;
+ pfile_in_zip_read_info->stream.opaque = (voidpf)0;
+ pfile_in_zip_read_info->stream.next_in = (voidpf)0;
+ pfile_in_zip_read_info->stream.avail_in = 0;
+
+ err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
+ if (err == Z_OK)
+ pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
+ else
+ {
+ TRYFREE(pfile_in_zip_read_info);
+ return err;
+ }
+#else
+ pfile_in_zip_read_info->raw=1;
+#endif
+ }
+ else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
+ {
+ pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
+ pfile_in_zip_read_info->stream.zfree = (free_func)0;
+ pfile_in_zip_read_info->stream.opaque = (voidpf)0;
+ pfile_in_zip_read_info->stream.next_in = 0;
+ pfile_in_zip_read_info->stream.avail_in = 0;
+
+ err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
+ if (err == Z_OK)
+ pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
+ else
+ {
+ TRYFREE(pfile_in_zip_read_info->read_buffer);
+ TRYFREE(pfile_in_zip_read_info);
+ return err;
+ }
+ /* windowBits is passed < 0 to tell that there is no zlib header.
+ * Note that in this case inflate *requires* an extra "dummy" byte
+ * after the compressed stream in order to complete decompression and
+ * return Z_STREAM_END.
+ * In unzip, i don't wait absolutely Z_STREAM_END because I known the
+ * size of both compressed and uncompressed data
+ */
+ }
+ pfile_in_zip_read_info->rest_read_compressed =
+ s->cur_file_info.compressed_size ;
+ pfile_in_zip_read_info->rest_read_uncompressed =
+ s->cur_file_info.uncompressed_size ;
+
+
+ pfile_in_zip_read_info->pos_in_zipfile =
+ s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
+ iSizeVar;
+
+ pfile_in_zip_read_info->stream.avail_in = (uInt)0;
+
+ s->pfile_in_zip_read = pfile_in_zip_read_info;
+ s->encrypted = 0;
+
+# ifndef NOUNCRYPT
+ if (password != NULL)
+ {
+ int i;
+ s->pcrc_32_tab = get_crc_table();
+ init_keys(password,s->keys,s->pcrc_32_tab);
+ if (ZSEEK64(s->z_filefunc, s->filestream,
+ s->pfile_in_zip_read->pos_in_zipfile +
+ s->pfile_in_zip_read->byte_before_the_zipfile,
+ SEEK_SET)!=0)
+ return UNZ_INTERNALERROR;
+ if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
+ return UNZ_INTERNALERROR;
+
+ for (i = 0; i<12; i++)
+ zdecode(s->keys,s->pcrc_32_tab,source[i]);
+
+ s->pfile_in_zip_read->pos_in_zipfile+=12;
+ s->encrypted=1;
+ }
+# endif
+
+
+ return UNZ_OK;
+}
+
+extern int ZEXPORT unzOpenCurrentFile (unzFile file)
+{
+ return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
+}
+
+extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password)
+{
+ return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
+}
+
+extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
+{
+ return unzOpenCurrentFile3(file, method, level, raw, NULL);
+}
+
+/** Addition for GDAL : START */
+
+extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
+{
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ s=(unz64_s*)file;
+ if (file==NULL)
+ return 0; //UNZ_PARAMERROR;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+ if (pfile_in_zip_read_info==NULL)
+ return 0; //UNZ_PARAMERROR;
+ return pfile_in_zip_read_info->pos_in_zipfile +
+ pfile_in_zip_read_info->byte_before_the_zipfile;
+}
+
+/** Addition for GDAL : END */
+
+/*
+ Read bytes from the current file.
+ buf contain buffer where data must be copied
+ len the size of buf.
+
+ return the number of byte copied if somes bytes are copied
+ return 0 if the end of file was reached
+ return <0 with error code if there is an error
+ (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
+{
+ int err=UNZ_OK;
+ uInt iRead = 0;
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+
+ if (pfile_in_zip_read_info->read_buffer == NULL)
+ return UNZ_END_OF_LIST_OF_FILE;
+ if (len==0)
+ return 0;
+
+ pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
+
+ pfile_in_zip_read_info->stream.avail_out = (uInt)len;
+
+ if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
+ (!(pfile_in_zip_read_info->raw)))
+ pfile_in_zip_read_info->stream.avail_out =
+ (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
+
+ if ((len>pfile_in_zip_read_info->rest_read_compressed+
+ pfile_in_zip_read_info->stream.avail_in) &&
+ (pfile_in_zip_read_info->raw))
+ pfile_in_zip_read_info->stream.avail_out =
+ (uInt)pfile_in_zip_read_info->rest_read_compressed+
+ pfile_in_zip_read_info->stream.avail_in;
+
+ while (pfile_in_zip_read_info->stream.avail_out>0)
+ {
+ if ((pfile_in_zip_read_info->stream.avail_in==0) &&
+ (pfile_in_zip_read_info->rest_read_compressed>0))
+ {
+ uInt uReadThis = UNZ_BUFSIZE;
+ if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
+ uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
+ if (uReadThis == 0)
+ return UNZ_EOF;
+ if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
+ pfile_in_zip_read_info->filestream,
+ pfile_in_zip_read_info->pos_in_zipfile +
+ pfile_in_zip_read_info->byte_before_the_zipfile,
+ ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return UNZ_ERRNO;
+ if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
+ pfile_in_zip_read_info->filestream,
+ pfile_in_zip_read_info->read_buffer,
+ uReadThis)!=uReadThis)
+ return UNZ_ERRNO;
+
+
+# ifndef NOUNCRYPT
+ if(s->encrypted)
+ {
+ uInt i;
+ for(i=0;i<uReadThis;i++)
+ pfile_in_zip_read_info->read_buffer[i] =
+ zdecode(s->keys,s->pcrc_32_tab,
+ pfile_in_zip_read_info->read_buffer[i]);
+ }
+# endif
+
+
+ pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
+
+ pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
+
+ pfile_in_zip_read_info->stream.next_in =
+ (Bytef*)pfile_in_zip_read_info->read_buffer;
+ pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
+ }
+
+ if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
+ {
+ uInt uDoCopy,i ;
+
+ if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
+ (pfile_in_zip_read_info->rest_read_compressed == 0))
+ return (iRead==0) ? UNZ_EOF : iRead;
+
+ if (pfile_in_zip_read_info->stream.avail_out <
+ pfile_in_zip_read_info->stream.avail_in)
+ uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
+ else
+ uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
+
+ for (i=0;i<uDoCopy;i++)
+ *(pfile_in_zip_read_info->stream.next_out+i) =
+ *(pfile_in_zip_read_info->stream.next_in+i);
+
+ pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
+
+ pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
+ pfile_in_zip_read_info->stream.next_out,
+ uDoCopy);
+ pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
+ pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
+ pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
+ pfile_in_zip_read_info->stream.next_out += uDoCopy;
+ pfile_in_zip_read_info->stream.next_in += uDoCopy;
+ pfile_in_zip_read_info->stream.total_out += uDoCopy;
+ iRead += uDoCopy;
+ }
+ else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
+ {
+#ifdef HAVE_BZIP2
+ uLong uTotalOutBefore,uTotalOutAfter;
+ const Bytef *bufBefore;
+ uLong uOutThis;
+
+ pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in;
+ pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in;
+ pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in;
+ pfile_in_zip_read_info->bstream.total_in_hi32 = 0;
+ pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out;
+ pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out;
+ pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
+ pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
+
+ uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
+ bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
+
+ err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
+
+ uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
+ uOutThis = uTotalOutAfter-uTotalOutBefore;
+
+ pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
+
+ pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
+ pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
+ iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
+
+ pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
+ pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in;
+ pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32;
+ pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
+ pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
+ pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
+
+ if (err==BZ_STREAM_END)
+ return (iRead==0) ? UNZ_EOF : iRead;
+ if (err!=BZ_OK)
+ break;
+#endif
+ } // end Z_BZIP2ED
+ else
+ {
+ ZPOS64_T uTotalOutBefore,uTotalOutAfter;
+ const Bytef *bufBefore;
+ ZPOS64_T uOutThis;
+ int flush=Z_SYNC_FLUSH;
+
+ uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
+ bufBefore = pfile_in_zip_read_info->stream.next_out;
+
+ /*
+ if ((pfile_in_zip_read_info->rest_read_uncompressed ==
+ pfile_in_zip_read_info->stream.avail_out) &&
+ (pfile_in_zip_read_info->rest_read_compressed == 0))
+ flush = Z_FINISH;
+ */
+ err=inflate(&pfile_in_zip_read_info->stream,flush);
+
+ if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
+ err = Z_DATA_ERROR;
+
+ uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
+ uOutThis = uTotalOutAfter-uTotalOutBefore;
+
+ pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
+
+ pfile_in_zip_read_info->crc32 =
+ crc32(pfile_in_zip_read_info->crc32,bufBefore,
+ (uInt)(uOutThis));
+
+ pfile_in_zip_read_info->rest_read_uncompressed -=
+ uOutThis;
+
+ iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
+
+ if (err==Z_STREAM_END)
+ return (iRead==0) ? UNZ_EOF : iRead;
+ if (err!=Z_OK)
+ break;
+ }
+ }
+
+ if (err==Z_OK)
+ return iRead;
+ return err;
+}
+
+
+/*
+ Give the current position in uncompressed data
+*/
+extern z_off_t ZEXPORT unztell (unzFile file)
+{
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+ return (z_off_t)pfile_in_zip_read_info->stream.total_out;
+}
+
+extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
+{
+
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return (ZPOS64_T)-1;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return (ZPOS64_T)-1;
+
+ return pfile_in_zip_read_info->total_out_64;
+}
+
+
+/*
+ return 1 if the end of file was reached, 0 elsewhere
+*/
+extern int ZEXPORT unzeof (unzFile file)
+{
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+ if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
+ return 1;
+ else
+ return 0;
+}
+
+
+
+/*
+Read extra field from the current file (opened by unzOpenCurrentFile)
+This is the local-header version of the extra field (sometimes, there is
+more info in the local-header version than in the central-header)
+
+ if buf==NULL, it return the size of the local extra field that can be read
+
+ if buf!=NULL, len is the size of the buffer, the extra header is copied in
+ buf.
+ the return value is the number of bytes copied in buf, or (if <0)
+ the error code
+*/
+extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
+{
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ uInt read_now;
+ ZPOS64_T size_to_read;
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+ size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
+ pfile_in_zip_read_info->pos_local_extrafield);
+
+ if (buf==NULL)
+ return (int)size_to_read;
+
+ if (len>size_to_read)
+ read_now = (uInt)size_to_read;
+ else
+ read_now = (uInt)len ;
+
+ if (read_now==0)
+ return 0;
+
+ if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
+ pfile_in_zip_read_info->filestream,
+ pfile_in_zip_read_info->offset_local_extrafield +
+ pfile_in_zip_read_info->pos_local_extrafield,
+ ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return UNZ_ERRNO;
+
+ if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
+ pfile_in_zip_read_info->filestream,
+ buf,read_now)!=read_now)
+ return UNZ_ERRNO;
+
+ return (int)read_now;
+}
+
+/*
+ Close the file in zip opened with unzOpenCurrentFile
+ Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+extern int ZEXPORT unzCloseCurrentFile (unzFile file)
+{
+ int err=UNZ_OK;
+
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+
+ if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
+ (!pfile_in_zip_read_info->raw))
+ {
+ if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
+ err=UNZ_CRCERROR;
+ }
+
+
+ TRYFREE(pfile_in_zip_read_info->read_buffer);
+ pfile_in_zip_read_info->read_buffer = NULL;
+ if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
+ inflateEnd(&pfile_in_zip_read_info->stream);
+#ifdef HAVE_BZIP2
+ else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
+ BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
+#endif
+
+
+ pfile_in_zip_read_info->stream_initialised = 0;
+ TRYFREE(pfile_in_zip_read_info);
+
+ s->pfile_in_zip_read=NULL;
+
+ return err;
+}
+
+
+/*
+ Get the global comment string of the ZipFile, in the szComment buffer.
+ uSizeBuf is the size of the szComment buffer.
+ return the number of byte copied or an error code <0
+*/
+extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
+{
+ unz64_s* s;
+ uLong uReadThis ;
+ if (file==NULL)
+ return (int)UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+
+ uReadThis = uSizeBuf;
+ if (uReadThis>s->gi.size_comment)
+ uReadThis = s->gi.size_comment;
+
+ if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return UNZ_ERRNO;
+
+ if (uReadThis>0)
+ {
+ *szComment='\0';
+ if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
+ return UNZ_ERRNO;
+ }
+
+ if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
+ *(szComment+s->gi.size_comment)='\0';
+ return (int)uReadThis;
+}
+
+/* Additions by RX '2004 */
+extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
+{
+ unz64_s* s;
+
+ if (file==NULL)
+ return 0; //UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return 0;
+ if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
+ if (s->num_file==s->gi.number_entry)
+ return 0;
+ return s->pos_in_central_dir;
+}
+
+extern uLong ZEXPORT unzGetOffset (unzFile file)
+{
+ ZPOS64_T offset64;
+
+ if (file==NULL)
+ return 0; //UNZ_PARAMERROR;
+ offset64 = unzGetOffset64(file);
+ return (uLong)offset64;
+}
+
+extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
+{
+ unz64_s* s;
+ int err;
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+
+ s->pos_in_central_dir = pos;
+ s->num_file = s->gi.number_entry; /* hack */
+ err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+ &s->cur_file_info_internal,
+ NULL,0,NULL,0,NULL,0);
+ s->current_file_ok = (err == UNZ_OK);
+ return err;
+}
+
+extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
+{
+ return unzSetOffset64(file,pos);
+}
+
+#ifdef WEB_ZIP_MEM_DEBUG
+
+typedef struct zip_node
+{
+ struct zip_node *next;
+ unsigned int len;
+ void* ptr;
+}t_zip_node;
+
+t_zip_node zip_list ={0};
+
+static void* web_malloc(unsigned int bytes)
+{
+ t_zip_node *node = (t_zip_node *)malloc(sizeof(t_zip_node));
+ if(node == NULL)
+ return NULL;
+ node->ptr = malloc(bytes);
+ if(node->ptr == NULL)
+ {
+ free(node);
+ return NULL;
+ }
+ node->next = NULL;
+ node->len = bytes;
+ t_zip_node *list = &zip_list;
+ while(list->next != NULL)
+ {
+ list = list->next;
+ }
+ list->next = node;
+ return node->ptr;
+}
+
+#ifndef assert
+extern unsigned int sleep (unsigned int __seconds);
+#define assert(cond) {if(!(cond)){while(1){printf("zip assert\n");sleep(1);}}}
+#endif
+
+static void web_free(void* mem)
+{
+ t_zip_node *list = &zip_list;
+ t_zip_node *temp;
+ assert(list->next);
+ while(list->next->ptr != mem)
+ {
+ list = list->next;
+ assert(list->next);
+ }
+ temp = list->next;
+ list->next = list->next->next;
+ free(temp);
+ free(mem);
+}
+
+void print_zip_mem(void)
+{
+ t_zip_node *list = &zip_list;
+ int num = -1;
+ unsigned int len = 0;
+ do
+ {
+ len += list->len;
+ num++;
+ list = list->next;
+ }
+ while(list != NULL);
+ printf("num=%d,total=%d\n",num,len);
+ return;
+}
+
+#endif
+
diff --git a/ap/app/goahead/server/unzip.h b/ap/app/goahead/server/unzip.h
new file mode 100644
index 0000000..2104e39
--- /dev/null
+++ b/ap/app/goahead/server/unzip.h
@@ -0,0 +1,437 @@
+/* unzip.h -- IO for uncompress .zip files using zlib
+ Version 1.1, February 14h, 2010
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications of Unzip for Zip64
+ Copyright (C) 2007-2008 Even Rouault
+
+ Modifications for Zip64 support on both zip and unzip
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+ ---------------------------------------------------------------------------------
+
+ Condition of use and distribution are the same than zlib :
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ ---------------------------------------------------------------------------------
+
+ Changes
+
+ See header of unzip64.c
+
+*/
+
+#ifndef _unz64_H
+#define _unz64_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#ifndef _ZLIBIOAPI_H
+#include "ioapi.h"
+#endif
+
+#ifdef HAVE_BZIP2
+#include "bzlib.h"
+#endif
+
+#define Z_BZIP2ED 12
+
+#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+ from (void*) without cast */
+typedef struct TagunzFile__ { int unused; } unzFile__;
+typedef unzFile__ *unzFile;
+#else
+typedef voidp unzFile;
+#endif
+
+
+#define UNZ_OK (0)
+#define UNZ_END_OF_LIST_OF_FILE (-100)
+#define UNZ_ERRNO (Z_ERRNO)
+#define UNZ_EOF (0)
+#define UNZ_PARAMERROR (-102)
+#define UNZ_BADZIPFILE (-103)
+#define UNZ_INTERNALERROR (-104)
+#define UNZ_CRCERROR (-105)
+
+/* tm_unz contain date/time info */
+typedef struct tm_unz_s
+{
+ uInt tm_sec; /* seconds after the minute - [0,59] */
+ uInt tm_min; /* minutes after the hour - [0,59] */
+ uInt tm_hour; /* hours since midnight - [0,23] */
+ uInt tm_mday; /* day of the month - [1,31] */
+ uInt tm_mon; /* months since January - [0,11] */
+ uInt tm_year; /* years - [1980..2044] */
+} tm_unz;
+
+/* unz_global_info structure contain global data about the ZIPfile
+ These data comes from the end of central dir */
+typedef struct unz_global_info64_s
+{
+ ZPOS64_T number_entry; /* total number of entries in
+ the central dir on this disk */
+ uLong size_comment; /* size of the global comment of the zipfile */
+} unz_global_info64;
+
+typedef struct unz_global_info_s
+{
+ uLong number_entry; /* total number of entries in
+ the central dir on this disk */
+ uLong size_comment; /* size of the global comment of the zipfile */
+} unz_global_info;
+
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_info64_s
+{
+ uLong version; /* version made by 2 bytes */
+ uLong version_needed; /* version needed to extract 2 bytes */
+ uLong flag; /* general purpose bit flag 2 bytes */
+ uLong compression_method; /* compression method 2 bytes */
+ uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
+ uLong crc; /* crc-32 4 bytes */
+ ZPOS64_T compressed_size; /* compressed size 8 bytes */
+ ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */
+ uLong size_filename; /* filename length 2 bytes */
+ uLong size_file_extra; /* extra field length 2 bytes */
+ uLong size_file_comment; /* file comment length 2 bytes */
+
+ uLong disk_num_start; /* disk number start 2 bytes */
+ uLong internal_fa; /* internal file attributes 2 bytes */
+ uLong external_fa; /* external file attributes 4 bytes */
+
+ tm_unz tmu_date;
+} unz_file_info64;
+
+typedef struct unz_file_info_s
+{
+ uLong version; /* version made by 2 bytes */
+ uLong version_needed; /* version needed to extract 2 bytes */
+ uLong flag; /* general purpose bit flag 2 bytes */
+ uLong compression_method; /* compression method 2 bytes */
+ uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
+ uLong crc; /* crc-32 4 bytes */
+ uLong compressed_size; /* compressed size 4 bytes */
+ uLong uncompressed_size; /* uncompressed size 4 bytes */
+ uLong size_filename; /* filename length 2 bytes */
+ uLong size_file_extra; /* extra field length 2 bytes */
+ uLong size_file_comment; /* file comment length 2 bytes */
+
+ uLong disk_num_start; /* disk number start 2 bytes */
+ uLong internal_fa; /* internal file attributes 2 bytes */
+ uLong external_fa; /* external file attributes 4 bytes */
+
+ tm_unz tmu_date;
+} unz_file_info;
+
+extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
+ const char* fileName2,
+ int iCaseSensitivity));
+/*
+ Compare two filename (fileName1,fileName2).
+ If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+ If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+ or strcasecmp)
+ If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+ (like 1 on Unix, 2 on Windows)
+*/
+
+
+extern unzFile ZEXPORT unzOpen OF((const char *path));
+extern unzFile ZEXPORT unzOpen64 OF((const void *path));
+/*
+ Open a Zip file. path contain the full pathname (by example,
+ on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
+ "zlib/zlib113.zip".
+ If the zipfile cannot be opened (file don't exist or in not valid), the
+ return value is NULL.
+ Else, the return value is a unzFile Handle, usable with other function
+ of this unzip package.
+ the "64" function take a const void* pointer, because the path is just the
+ value passed to the open64_file_func callback.
+ Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path
+ is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char*
+ does not describe the reality
+*/
+
+
+extern unzFile ZEXPORT unzOpen2 OF((const char *path,
+ zlib_filefunc_def* pzlib_filefunc_def));
+/*
+ Open a Zip file, like unzOpen, but provide a set of file low level API
+ for read/write the zip file (see ioapi.h)
+*/
+
+extern unzFile ZEXPORT unzOpen2_64 OF((const void *path,
+ zlib_filefunc64_def* pzlib_filefunc_def));
+/*
+ Open a Zip file, like unz64Open, but provide a set of file low level API
+ for read/write the zip file (see ioapi.h)
+*/
+
+extern int ZEXPORT unzClose OF((unzFile file));
+/*
+ Close a ZipFile opened with unzOpen.
+ If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
+ these files MUST be closed with unzCloseCurrentFile before call unzClose.
+ return UNZ_OK if there is no problem. */
+
+extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
+ unz_global_info *pglobal_info));
+
+extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file,
+ unz_global_info64 *pglobal_info));
+/*
+ Write info about the ZipFile in the *pglobal_info structure.
+ No preparation of the structure is needed
+ return UNZ_OK if there is no problem. */
+
+
+extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
+ char *szComment,
+ uLong uSizeBuf));
+/*
+ Get the global comment string of the ZipFile, in the szComment buffer.
+ uSizeBuf is the size of the szComment buffer.
+ return the number of byte copied or an error code <0
+*/
+
+
+/***************************************************************************/
+/* Unzip package allow you browse the directory of the zipfile */
+
+extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
+/*
+ Set the current file of the zipfile to the first file.
+ return UNZ_OK if there is no problem
+*/
+
+extern int ZEXPORT unzGoToNextFile OF((unzFile file));
+/*
+ Set the current file of the zipfile to the next file.
+ return UNZ_OK if there is no problem
+ return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+
+extern int ZEXPORT unzLocateFile OF((unzFile file,
+ const char *szFileName,
+ int iCaseSensitivity));
+/*
+ Try locate the file szFileName in the zipfile.
+ For the iCaseSensitivity signification, see unzStringFileNameCompare
+
+ return value :
+ UNZ_OK if the file is found. It becomes the current file.
+ UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+
+
+/* ****************************************** */
+/* Ryan supplied functions */
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_pos_s
+{
+ uLong pos_in_zip_directory; /* offset in zip file directory */
+ uLong num_of_file; /* # of file */
+} unz_file_pos;
+
+extern int ZEXPORT unzGetFilePos(
+ unzFile file,
+ unz_file_pos* file_pos);
+
+extern int ZEXPORT unzGoToFilePos(
+ unzFile file,
+ unz_file_pos* file_pos);
+
+typedef struct unz64_file_pos_s
+{
+ ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */
+ ZPOS64_T num_of_file; /* # of file */
+} unz64_file_pos;
+
+extern int ZEXPORT unzGetFilePos64(
+ unzFile file,
+ unz64_file_pos* file_pos);
+
+extern int ZEXPORT unzGoToFilePos64(
+ unzFile file,
+ const unz64_file_pos* file_pos);
+
+/* ****************************************** */
+
+extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file,
+ unz_file_info64 *pfile_info,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize));
+
+extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
+ unz_file_info *pfile_info,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize));
+/*
+ Get Info about the current file
+ if pfile_info!=NULL, the *pfile_info structure will contain somes info about
+ the current file
+ if szFileName!=NULL, the filemane string will be copied in szFileName
+ (fileNameBufferSize is the size of the buffer)
+ if extraField!=NULL, the extra field information will be copied in extraField
+ (extraFieldBufferSize is the size of the buffer).
+ This is the Central-header version of the extra field
+ if szComment!=NULL, the comment string of the file will be copied in szComment
+ (commentBufferSize is the size of the buffer)
+*/
+
+
+/** Addition for GDAL : START */
+
+extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));
+
+/** Addition for GDAL : END */
+
+
+/***************************************************************************/
+/* for reading the content of the current zipfile, you can open it, read data
+ from it, and close it (you can close it before reading all the file)
+ */
+
+extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
+/*
+ Open for reading data the current file in the zipfile.
+ If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
+ const char* password));
+/*
+ Open for reading data the current file in the zipfile.
+ password is a crypting password
+ If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
+ int* method,
+ int* level,
+ int raw));
+/*
+ Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
+ if raw==1
+ *method will receive method of compression, *level will receive level of
+ compression
+ note : you can set level parameter as NULL (if you did not want known level,
+ but you CANNOT set method parameter as NULL
+*/
+
+extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
+ int* method,
+ int* level,
+ int raw,
+ const char* password));
+/*
+ Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
+ if raw==1
+ *method will receive method of compression, *level will receive level of
+ compression
+ note : you can set level parameter as NULL (if you did not want known level,
+ but you CANNOT set method parameter as NULL
+*/
+
+
+extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
+/*
+ Close the file in zip opened with unzOpenCurrentFile
+ Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+
+extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
+ voidp buf,
+ unsigned len));
+/*
+ Read bytes from the current file (opened by unzOpenCurrentFile)
+ buf contain buffer where data must be copied
+ len the size of buf.
+
+ return the number of byte copied if somes bytes are copied
+ return 0 if the end of file was reached
+ return <0 with error code if there is an error
+ (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+
+extern z_off_t ZEXPORT unztell OF((unzFile file));
+
+extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file));
+/*
+ Give the current position in uncompressed data
+*/
+
+extern int ZEXPORT unzeof OF((unzFile file));
+/*
+ return 1 if the end of file was reached, 0 elsewhere
+*/
+
+extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
+ voidp buf,
+ unsigned len));
+/*
+ Read extra field from the current file (opened by unzOpenCurrentFile)
+ This is the local-header version of the extra field (sometimes, there is
+ more info in the local-header version than in the central-header)
+
+ if buf==NULL, it return the size of the local extra field
+
+ if buf!=NULL, len is the size of the buffer, the extra header is copied in
+ buf.
+ the return value is the number of bytes copied in buf, or (if <0)
+ the error code
+*/
+
+/***************************************************************************/
+
+/* Get the current file offset */
+extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file);
+extern uLong ZEXPORT unzGetOffset (unzFile file);
+
+/* Set the current file offset */
+extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos);
+extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _unz64_H */
diff --git a/ap/app/goahead/server/value.c b/ap/app/goahead/server/value.c
new file mode 100755
index 0000000..66a2fcf
--- /dev/null
+++ b/ap/app/goahead/server/value.c
@@ -0,0 +1,41 @@
+#include "uemf.h"
+
+value_t valueString(char_t* value, int flags)
+{
+ value_t v;
+
+ memset(&v, 0x0, sizeof(v));
+ v.valid = 1;
+ v.type = string;
+ if (flags & VALUE_ALLOCATE) {
+ v.allocated = 1;
+ v.value.string = gstrdup(B_L, value);
+ } else {
+ v.allocated = 0;
+ v.value.string = value;
+ }
+ return v;
+}
+
+value_t valueInteger(long value)
+{
+ value_t v;
+
+ memset(&v, 0x0, sizeof(v));
+ v.valid = 1;
+ v.type = integer;
+ v.value.integer = value;
+ return v;
+}
+
+void valueFree(value_t* v)
+{
+ if (v->valid && v->allocated && v->type == string &&
+ v->value.string != NULL) {
+ bfree(B_L, v->value.string);
+ }
+ v->type = undefined;
+ v->valid = 0;
+ v->allocated = 0;
+}
+
diff --git a/ap/app/goahead/server/webs.c b/ap/app/goahead/server/webs.c
new file mode 100755
index 0000000..b0238e1
--- /dev/null
+++ b/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 /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("<")
+#define kGt '>'
+#define kGreaterThan T(">")
+
+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/ap/app/goahead/server/webs.h b/ap/app/goahead/server/webs.h
new file mode 100755
index 0000000..9dcb6af
--- /dev/null
+++ b/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("/var/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 */
+
diff --git a/ap/app/goahead/server/websSSL.c b/ap/app/goahead/server/websSSL.c
new file mode 100755
index 0000000..30949b2
--- /dev/null
+++ b/ap/app/goahead/server/websSSL.c
@@ -0,0 +1,759 @@
+#ifndef __ENABLE_MOCANA_SSL_SERVER__
+
+#include "wsIntrn.h"
+#include "webs.h"
+#include "websSSL.h"
+#include "ref_nv_def.h"
+
+
+#define DEFAULT_KEY_FILE "/etc_ro/certs/cakey.pem"
+#define DEFAULT_CA_FILE "/etc_ro/certs/cacert.pem"
+#define DEFAULT_PWD_FILE "/etc_ro/certs/password"
+#define SSL_PORT 443
+
+#define DEFAULT_KEY_MASK 0x60
+typedef struct websSSLKey {
+ char pwd[17];
+ unsigned char procType;
+ unsigned short dekType;
+ unsigned char dekInfo[16];
+ unsigned char privateKey[624];
+ unsigned short certLen;
+} websSSLKey;
+
+
+
+#ifdef SIGPIPE
+#define do_pipe_sig() signal(SIGPIPE,SIG_IGN)
+#else
+#define do_pipe_sig()
+#endif
+
+
+# if defined(MSDOS) || defined(WIN16) || defined(WIN32)
+# ifdef _O_BINARY
+# define apps_startup() \
+ _fmode=_O_BINARY; do_pipe_sig(); CRYPTO_malloc_init(); \
+ SSLC_add_all_algorithms()
+# else
+# define apps_startup() \
+ _fmode=O_BINARY; do_pipe_sig(); CRYPTO_malloc_init(); \
+ SSLC_add_all_algorithms()
+# endif
+# else
+# define apps_startup() do_pipe_sig(); SSLC_add_all_algorithms();
+# endif
+
+
+#ifdef OPENSSL
+#ifndef SSLeay_add_all_algorithms
+#define SSLeay_add_all_algorithms() OpenSSL_add_all_algorithms()
+#endif
+
+#define SSLC_add_all_algorithms() SSLeay_add_all_algorithms()
+#else
+extern void SSLC_add_all_algorithms(void);
+#endif
+
+
+static int websSSLVerifyCallback(int ok, X509_STORE_CTX *ctx);
+static RSA *websSSLTempRSACallback(SSL *s, int is_export, int keylength);
+
+static int websSSLReadEvent (webs_t wp);
+static int websSSLAccept(int sid, char *ipaddr, int port, int listenSid);
+static void websSSLSocketEvent(int sid, int mask, int data);
+static int websSSLSetCertStuff(SSL_CTX *ctx, char *cert_file, char *key_file);
+
+
+static int sslListenSock = -1;
+static SSL_CTX *sslctx = NULL;
+static char *sslpwd = NULL;
+static websSSLKey sslkey = {0};
+static unsigned char *sslcert = NULL;
+
+
+static int getFileSize(char *lpath)
+{
+ gstat_t s;
+
+ if (lpath && stat(lpath, &s) == 0) {
+ return s.st_size;
+ }
+ return 0;
+}
+
+
+int websSSLOpen()
+{
+ SSL_METHOD *meth;
+
+ apps_startup();
+ trace(7, T("SSL: Initializing SSL\n"));
+
+#ifdef SSLC
+ SSL_library_init();
+#endif
+
+ SSL_load_error_strings();
+
+#ifdef OPENSSL
+ SSLeay_add_ssl_algorithms();
+#endif
+
+
+#ifdef WEBINSPECT_FIX
+ meth = TLSv1_2_server_method();
+#else
+ meth = SSLv23_server_method();
+#endif
+ sslctx = SSL_CTX_new(meth);
+
+ a_assert(sslctx);
+
+ if (sslctx == NULL) {
+ trace(2, T("SSL: Unable to create SSL context!\n"));
+ return -1;
+ }
+
+
+ SSL_CTX_set_quiet_shutdown(sslctx, 1);
+ SSL_CTX_set_options(sslctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
+ SSL_CTX_sess_set_cache_size(sslctx, 128);
+
+ EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1);
+ if (ecdh){
+ long eret = SSL_CTX_set_tmp_ecdh (sslctx, ecdh);
+ trace(2, T("SSL: ecdh:%x ret=%d\n"), ecdh, eret);
+ EC_KEY_free(ecdh);
+ ecdh = NULL;
+ }
+
+
+#ifdef WEBINSPECT_FIX
+ if(!SSL_CTX_set_cipher_list(sslctx,"ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:!NULL:!RC4:!RC2:!DES:!3DES:!SHA:!SHA256:!SHA384:!MD5+HIGH:+MEDIUM"))
+ trace(2, T("SSL: Unable to set !DES:!RC4:!SHA1\n"));
+#endif
+
+ unsigned char webkey_flag = 0;
+ int retCode = cpnv_NvItemRead(ZPS_REF_MSINFO_WEBKEY_FLAG_BASE_ADDR, &webkey_flag, sizeof(webkey_flag));
+ if (retCode == CPNV_ERROR)
+ {
+ trace(2, T("SSL: read cpnv keyflag error\n"));
+ websSSLClose();
+ return -1;
+ }
+ trace(2, T("SSL: webkey_flag=%d\n"),webkey_flag);
+ if (webkey_flag != 1)
+ {
+ ssize_t read_len = 0;
+ char *pwdFile = DEFAULT_PWD_FILE;
+ int pwdSize = getFileSize(pwdFile);
+ if(pwdSize > 0)
+ {
+ int fd = open(pwdFile, SOCKET_RDONLY | SOCKET_BINARY, 0666);
+ if(fd >= 0)
+ {
+ sslpwd = balloc(B_L,pwdSize + 1);
+ if(sslpwd != NULL)
+ {
+ memset(sslpwd, 0, pwdSize + 1);
+ read_len = read(fd, sslpwd, pwdSize);
+ if(read_len < 0)
+ {
+ trace(2, T("read len:%d ; errno: %s\n"), read_len, strerror(errno));
+ }
+ trace(2, T("SSL: pwd:%s\n"), sslpwd);
+ SSL_CTX_set_default_passwd_cb_userdata(sslctx, (void *)sslpwd);
+ }
+ close(fd);
+ }
+ }
+
+ //char *certFile = DEFAULT_CA_FILE;
+ //char *keyFile = DEFAULT_KEY_FILE;// kw OVERWRITE_CONST_CHAR
+ if (websSSLSetCertStuff(sslctx, DEFAULT_CA_FILE, DEFAULT_KEY_FILE) != 0) {
+ websSSLClose();
+ return -1;
+ }
+ }
+ else
+ {
+ retCode = cpnv_NvItemRead(ZPS_REF_MSINFO_WEBKEY_DATA_BASE_ADDR, (unsigned char *)&sslkey, sizeof(sslkey));
+ char i = 0;
+ if (retCode == CPNV_ERROR)
+ {
+ trace(2, T("SSL: read cpnv key error\n"));
+ websSSLClose();
+ return -1;
+ }
+ trace(2, T("SSL: key procType=%d dekType=%d certLen=%d\n"),sslkey.procType,sslkey.dekType,sslkey.certLen);
+ sslcert = balloc(B_L, sslkey.certLen);
+ if(sslcert == NULL)
+ {
+ trace(2, T("SSL: alloc cpnv cert fail\n"));
+ websSSLClose();
+ return -1;
+ }
+ retCode = cpnv_NvItemRead(ZPS_REF_MSINFO_WEBKEY_DATA_BASE_ADDR+sizeof(sslkey), sslcert, sslkey.certLen);
+ if (retCode == CPNV_ERROR)
+ {
+ trace(2, T("SSL: read cpnv cert error\n"));
+ websSSLClose();
+ return -1;
+ }
+ for(i=0; i < sizeof(sslkey.pwd); i++)
+ {
+ if(sslkey.pwd[i] != 0)
+ {
+ sslkey.pwd[i] = sslkey.pwd[i] - DEFAULT_KEY_MASK;
+ }
+ else
+ {
+ break;
+ }
+ }
+ SSL_CTX_set_default_passwd_cb_userdata(sslctx, (void *)sslkey.pwd);
+ retCode = websSSLSetCertificate(sslctx, sslcert, sslkey.certLen);
+ if (retCode <= 0)
+ {
+ trace(2, T("SSL: websSSLSetCertificate fail ret=%d\n"),retCode);
+ websSSLClose();
+ return -1;
+ }
+ retCode = websSSLSetPrivateKey(sslctx, &sslkey);
+ if (retCode <= 0)
+ {
+ trace(2, T("SSL: websSSLSetPrivateKey fail ret=%d\n"),retCode);
+ websSSLClose();
+ return -1;
+ }
+ }
+
+ SSL_CTX_set_tmp_rsa_callback(sslctx, websSSLTempRSACallback);
+
+
+ SSL_CTX_set_verify(sslctx, SSL_VERIFY_NONE, websSSLVerifyCallback);
+
+
+ sslListenSock = socketOpenConnection6(NULL, SSL_PORT,
+ websSSLAccept, SOCKET_BLOCK);
+
+ if (sslListenSock < 0) {
+ trace(2, T("SSL: Unable to open SSL socket on port <%d>!\n"),
+ SSL_PORT);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+int websSSLIsOpen()
+{
+ return (sslListenSock != -1);
+}
+
+
+
+int websSSLAccept(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;
+ }
+
+ wp->flags |= WEBS_SECURE;
+
+
+ socketCreateHandler(sid, SOCKET_READABLE, websSSLSocketEvent, (int) wp);
+
+ wp->timeout = emfSchedCallback(WEBS_TIMEOUT, websTimeout, (void *) wp);
+ //trace(8, T("webs: accept request\n"));
+ return 0;
+}
+
+void websSSLClose()
+{
+ trace(7, T("SSL: Closing SSL\n"));
+
+ if (sslctx != NULL) {
+ SSL_CTX_free(sslctx);
+ sslctx = NULL;
+ }
+
+ if (sslListenSock != -1) {
+ socketCloseConnection(sslListenSock);
+ sslListenSock = -1;
+ }
+
+ if(sslpwd != NULL) {
+ bfree(B_L, sslpwd);
+ sslpwd = NULL;
+ }
+
+#ifdef SSLC
+ SSL_library_cleanup();
+#endif
+}
+
+
+static int websSSLReadEvent (webs_t wp)
+{
+ int ret, sock;
+ socket_t *sptr;
+ SSL *ssl;
+ BIO *bio, *bioSSL, *bioSock;
+#ifdef DEV
+ const char *ciphers;
+#endif
+
+ a_assert (wp);
+ a_assert(websValid(wp));
+
+ sptr = socketPtr(wp->sid);
+ a_assert(sptr);
+ if(sptr == NULL)
+ return -1;
+ sock = sptr->sock;
+
+ bio = BIO_new(BIO_f_buffer());
+ a_assert(bio);
+
+ if (!BIO_set_write_buffer_size(bio, 128)) {
+ return -1;
+ }
+
+ ssl = (SSL *) SSL_new(sslctx);
+ a_assert(ssl);
+
+ if (ssl == NULL) {
+ return -1;
+ }
+
+ SSL_set_session(ssl, NULL);
+
+ bioSSL = BIO_new(BIO_f_ssl());
+ a_assert(bioSSL);
+
+ bioSock = BIO_new_socket(sock, BIO_NOCLOSE);
+ a_assert(bioSock);
+
+ SSL_set_bio(ssl, bioSock, bioSock);
+ SSL_set_accept_state(ssl);
+
+ ret = BIO_set_ssl(bioSSL, ssl, BIO_CLOSE);
+ BIO_push(bio, bioSSL);
+
+#ifdef DEV
+ ciphers = SSL_get_cipher_list(ssl, 10);
+#endif
+
+#ifdef WEBS_SSL_SUPPORT
+ websSSLFree(wp->wsp);
+ wp->wsp = balloc(B_L, sizeof(websSSL_t));
+ a_assert (wp->wsp);
+ if(wp->wsp == NULL)
+ return -1;
+ (wp->wsp)->bio = bio;
+ (wp->wsp)->ssl = ssl;
+#endif
+
+ websReadEvent(wp);
+
+ return ret;
+}
+
+static void websSSLSocketEvent(int sid, int mask, int iwp)
+{
+ webs_t wp;
+
+ wp = (webs_t) iwp;
+ a_assert(wp);
+
+ if (! websValid(wp)) {
+ return;
+ }
+
+ if (mask & SOCKET_READABLE) {
+ websSSLReadEvent(wp);
+ }
+ if (mask & SOCKET_WRITABLE) {
+ if (websValid(wp) && wp->writeSocket) {//cov
+ (*wp->writeSocket)(wp);
+ }
+ }
+}
+
+static int sslVerifyDepth = 0;
+static int sslVerifyError = X509_V_OK;
+
+int websSSLVerifyCallback(int ok, X509_STORE_CTX *ctx)
+{
+ char buf[256];
+ X509 *errCert;
+ int err;
+ int depth;
+
+ errCert = X509_STORE_CTX_get_current_cert(ctx);
+ err = X509_STORE_CTX_get_error(ctx);
+ depth = X509_STORE_CTX_get_error_depth(ctx);
+
+ X509_NAME_oneline(X509_get_subject_name(errCert), buf, 256);
+
+ if (!ok) {
+ if (sslVerifyDepth >= depth) {
+ ok = 1;
+ sslVerifyError = X509_V_OK;
+ } else {
+ ok=0;
+ sslVerifyError = X509_V_ERR_CERT_CHAIN_TOO_LONG;
+ }
+ }
+
+ switch (err) {
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+#ifdef OPENSSL
+ //X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
+ X509_NAME_oneline(X509_get_issuer_name(X509_STORE_CTX_get_current_cert(ctx)), buf, 256);
+#endif
+ break;
+
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+ break;
+ }
+
+ return ok;
+}
+
+int websSSLSetCertificate(SSL_CTX *ctx, const unsigned char *data, int len)
+{
+ BIO *in;
+ int ret = 0;
+ X509 *x = NULL;
+
+ in = BIO_new(BIO_s_mem());
+ if (in == NULL) {
+ trace(2, T("SSL: cert BIO_new NULL\n"));
+ goto end;
+ }
+
+ ret = PEM_write_bio(in, PEM_STRING_X509, "", data, len);
+ if (ret <= 0){
+ trace(2, T("SSL: cert PEM_write_bio fail ret=%d\n"),ret);
+ goto end;
+ }
+ x = PEM_read_bio_X509(in, NULL,
+ SSL_CTX_get_default_passwd_cb(ctx),//ctx->default_passwd_callback,
+ SSL_CTX_get_default_passwd_cb_userdata(ctx));//ctx->default_passwd_callback_userdata);
+
+ if (x == NULL) {
+ trace(2, T("SSL: cert PEM_read_bio_X509 NULL\n"));
+ goto end;
+ }
+
+ ret = SSL_CTX_use_certificate(ctx, x);
+ X509_free(x);
+
+ end:
+ if (in != NULL)
+ BIO_free(in);
+ return (ret);
+}
+
+int websSSLSetPrivateKey(SSL_CTX *ctx, websSSLKey *key)
+{
+ int ret = 0;
+ BIO *in;
+ EVP_PKEY *pkey = NULL;
+ const char *objstr = NULL;
+ char buf[PEM_BUFSIZE] = {0};
+
+ in = BIO_new(BIO_s_mem());
+ if (in == NULL) {
+ trace(2, T("SSL: key BIO_new NULL\n"));
+ goto end;
+ }
+
+ objstr = OBJ_nid2sn(key->dekType);
+ if (objstr == NULL) {
+ trace(2, T("SSL: key OBJ_nid2sn NULL type = %d\n"),key->dekType);
+ goto end;
+ }
+ PEM_proc_type(buf, key->procType);
+ PEM_dek_info(buf, objstr, sizeof(key->dekInfo), (char *)key->dekInfo);
+
+ ret = PEM_write_bio(in, PEM_STRING_RSA, buf, key->privateKey, sizeof(key->privateKey));
+ if (ret <= 0){
+ trace(2, T("SSL: key PEM_write_bio fail ret=%d\n"),ret);
+ goto end;
+ }
+ pkey = PEM_read_bio_PrivateKey(in, NULL,
+ SSL_CTX_get_default_passwd_cb(ctx),//ctx->default_passwd_callback,
+ SSL_CTX_get_default_passwd_cb_userdata(ctx));//ctx->default_passwd_callback_userdata);
+ if (pkey == NULL) {
+ trace(2, T("SSL: key PEM_read_bio_PrivateKey NULL\n"));
+ goto end;
+ }
+ ret = SSL_CTX_use_PrivateKey(ctx, pkey);
+ EVP_PKEY_free(pkey);
+
+ end:
+ if (in != NULL)
+ BIO_free(in);
+ return (ret);
+}
+
+
+int websSSLSetCertStuff(SSL_CTX *ctx, char *certFile, char *keyFile)
+{
+ a_assert (ctx);
+ a_assert (certFile);
+
+ if (certFile != NULL) {
+ if (SSL_CTX_use_certificate_file(ctx, certFile,
+ SSL_FILETYPE_PEM) <= 0) {
+ trace(2, T("SSL: Unable to set certificate file <%s>\n"),
+ certFile);
+ return -1;
+ }
+
+ if (keyFile == NULL) {
+ keyFile = certFile;
+ }
+
+ if (SSL_CTX_use_PrivateKey_file(ctx, keyFile, SSL_FILETYPE_PEM) <= 0) {
+ trace(2, T("SSL: Unable to set private key file <%s>\n"),
+ keyFile);
+ return -1;
+ }
+
+
+ if (!SSL_CTX_check_private_key(ctx)) {
+ trace(2, T("SSL: Check of private key file <%s> FAILED!\n"),
+ keyFile);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+int websSSLSetKeyFile(char_t *keyFile)
+{
+ a_assert (sslctx);
+ a_assert (keyFile);
+
+ if (sslctx == NULL) {
+ return -1;
+ }
+
+ if (SSL_CTX_use_PrivateKey_file(sslctx, keyFile, SSL_FILETYPE_PEM) <= 0) {
+ return -1;
+ }
+
+ if (!SSL_CTX_check_private_key(sslctx)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int websSSLSetCertFile(char_t *certFile)
+{
+ a_assert (sslctx);
+ a_assert (certFile);
+
+ if (sslctx == NULL) {
+ return -1;
+ }
+
+ if (SSL_CTX_use_certificate_file(sslctx, certFile,
+ SSL_FILETYPE_PEM) <= 0) {
+ return -1;
+ }
+
+ if (!SSL_CTX_check_private_key(sslctx)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+#ifdef SSLC
+extern RSA *RSA_new(void);
+#endif
+
+int websSSLEof(websSSL_t *wsp)
+{
+ a_assert(wsp);
+
+ if ((wsp == NULL) || (wsp->bio == NULL)) {
+ return -1;
+ }
+
+ return BIO_eof(wsp->bio);
+}
+
+
+int websSSLRead(websSSL_t *wsp, char_t *buf, int len)
+{
+ a_assert(wsp);
+ a_assert(buf);
+
+ if ((wsp == NULL) || (wsp->bio == NULL)) {
+ return -1;
+ }
+
+ return BIO_read(wsp->bio, buf, len);
+}
+
+static RSA *websSSLTempRSACallback(SSL *ssl, int isExport, int keyLength)
+{
+ static RSA *rsaTemp = NULL;
+
+ if (rsaTemp == NULL) {
+
+#ifdef OPENSSL
+ rsaTemp = RSA_generate_key(keyLength, RSA_F4, NULL, NULL);
+#endif
+
+#ifdef SSLC
+ rsaTemp = RSA_new();
+#endif
+
+ }
+
+ return rsaTemp;
+}
+
+
+int websSSLFree(websSSL_t *wsp)
+{
+ if (wsp == NULL) {
+ return -1;
+ }
+
+ if (wsp->ssl != NULL) {
+ SSL_set_shutdown(wsp->ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
+ }
+
+ if (wsp->bio != NULL) {
+ BIO_free_all(wsp->bio);
+ }
+
+ bfree(B_L, wsp);
+
+ return 0;
+}
+
+
+
+
+#define BUF_BLOCK 256
+
+int websSSLGets(websSSL_t *wsp, char_t **buf)
+{
+ int rc, len, lenBuf;
+ char c;
+
+ a_assert(wsp);
+ a_assert(buf);
+
+ lenBuf = 0;
+ len = 0;
+
+ if ((wsp == NULL) || (wsp->bio == NULL)) {
+ return -1;
+ }
+
+ while (len < 1536) {
+
+ if ((rc = BIO_read(wsp->bio, &c, 1)) < 0) {
+ return rc;
+ }
+
+ if (rc == 0) {
+
+ if (len > 0 && BIO_eof(wsp->bio)) {
+ c = '\n';
+ } else {
+ return -1;
+ }
+ }
+
+ if (c == '\n') {
+ if ((len > 0) && (len < lenBuf)) {
+ (*buf)[len] = 0;
+ }
+ return len;
+ } else if (c == '\r') {
+ continue;
+ }
+
+ if (lenBuf == 0 || len >= lenBuf - 1) {
+ lenBuf += BUF_BLOCK;
+ *buf = brealloc(B_L, *buf, lenBuf);
+ }
+
+ a_assert(*buf);
+ if(*buf == NULL)
+ return -1;
+ (*buf)[len] = c;
+ len++;
+ }
+ bfreeSafe(B_L,*buf);
+ *buf = NULL;
+ return -1;
+}
+
+
+int websSSLWrite(websSSL_t *wsp, char_t *buf, int len)
+{
+ a_assert(wsp);
+ a_assert(buf);
+
+ if ((wsp == NULL) || (wsp->bio == NULL)) {
+ return -1;
+ }
+
+ return BIO_write(wsp->bio, buf, len);
+}
+
+
+int websSSLFlush(websSSL_t *wsp)
+{
+ a_assert(wsp);
+
+ if ((wsp == NULL) || (wsp->bio == NULL)) {
+ return -1;
+ }
+
+ return BIO_flush(wsp->bio);
+}
+
+#endif
diff --git a/ap/app/goahead/server/websSSL.h b/ap/app/goahead/server/websSSL.h
new file mode 100755
index 0000000..8f1abfe
--- /dev/null
+++ b/ap/app/goahead/server/websSSL.h
@@ -0,0 +1,45 @@
+#ifndef _h_websSSL
+#define _h_websSSL 1
+
+
+#ifdef OPENSSL
+#define SSLEAY
+#define USE_SOCKETS
+#include <openssl/ssl.h>
+#else
+#include <sslc.h>
+#endif
+
+#ifndef UEMF
+ #include "basic/basic.h"
+ #include "emf/emf.h"
+#else
+ #include "uemf.h"
+#endif
+
+typedef struct {
+ SSL *ssl;
+ BIO *bio;
+} websSSL_t;
+
+
+extern int websSSLIsOpen();
+
+extern int websSSLGets(websSSL_t *wsp, char_t **buf);
+extern int websSSLRead(websSSL_t *wsp, char_t *buf, int nChars);
+extern int websSSLWrite(websSSL_t *wsp, char_t *buf, int nChars);
+
+extern int websSSLOpen();
+extern void websSSLClose();
+
+extern int websSSLEof(websSSL_t *wsp);
+
+extern int websSSLFlush(websSSL_t *wsp);
+extern int websSSLFree(websSSL_t *wsp);
+
+extern int websSSLSetKeyFile(char_t *keyFile);
+extern int websSSLSetCertFile(char_t *certFile);
+
+
+#endif /* _h_websSSL */
+
diff --git a/ap/app/goahead/server/websuemf.c b/ap/app/goahead/server/websuemf.c
new file mode 100755
index 0000000..0ebed71
--- /dev/null
+++ b/ap/app/goahead/server/websuemf.c
@@ -0,0 +1,141 @@
+#include "ejIntrn.h"
+#include "wsIntrn.h"
+
+
+typedef struct {
+ void (*routine)(void *arg, int id);
+ void *arg;
+ time_t at;
+ int schedid;
+} sched_t;
+
+
+static sched_t **sched;
+static int schedMax;
+
+
+void emfUnschedCallback(int schedid)
+{
+ sched_t *s;
+
+ if (sched == NULL || schedid == -1 || schedid >= schedMax ||
+ (s = sched[schedid]) == NULL) {
+ return;
+ }
+ bfree(B_L, s);
+ schedMax = hFree((void***) &sched, schedid);
+}
+
+
+#if 0
+int scriptEval(int engine, char_t *cmd, char_t **result, int chan)
+{
+ int ejid;
+
+ if (engine == EMF_SCRIPT_EJSCRIPT) {
+ ejid = (int) chan;
+
+ if (ejEval(ejid, cmd, result) ) {
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+ return -1;
+}
+#endif
+
+
+int emfSchedCallback(int delay, emfSchedProc *proc, void *arg)
+{
+ sched_t *s;
+ int schedid;
+
+ if ((schedid = hAllocEntry((void***) &sched, &schedMax,
+ sizeof(sched_t))) < 0) {
+ return -1;
+ }
+ s = sched[schedid];
+ s->arg = arg;
+ s->routine = proc;
+ s->at = ((delay + 500) / 1000) + time(0);
+ s->schedid = schedid;
+
+ return schedid;
+}
+
+int strcmpci(char_t *s1, char_t *s2)
+{
+ int rc;
+
+ a_assert(s1 && s2);
+ if (s1 == NULL || s2 == NULL) {
+ return 0;
+ }
+
+ if (s1 == s2) {
+ return 0;
+ }
+
+ do {
+ rc = gtolower(*s1) - gtolower(*s2);
+ if (*s1 == '\0') {
+ break;
+ }
+ s1++;
+ s2++;
+ } while (rc == 0);
+ return rc;
+}
+
+void emfSchedProcess()
+{
+ sched_t *s;
+ int schedid;
+ static int next = 0;
+
+
+ if (schedMax <= 0) {
+ return;
+ }
+
+ if (next >= schedMax) {
+ next = 0;
+ }
+
+ schedid = next;
+ while(1) {
+ if ((s = sched[schedid]) != NULL && (int)s->at <= (int)time(0)) {
+ {
+ sched_t *s;
+
+ a_assert(0 <= schedid && schedid < schedMax);
+ s = sched[schedid];
+ a_assert(s);
+
+ (s->routine)(s->arg, s->schedid);
+ }
+ next = schedid + 1;
+ return;
+ }
+ if (++schedid >= schedMax) {
+ schedid = 0;
+ }
+ if (schedid == next) {
+
+ return;
+ }
+ };
+}
+
+void emfReschedCallback(int schedid, int delay)
+{
+ sched_t *s;
+
+ if (sched == NULL || schedid == -1 || schedid >= schedMax ||
+ (s = sched[schedid]) == NULL) {
+ return;
+ }
+ s->at = ((delay + 500) / 1000) + time(0);
+}
+
diff --git a/ap/app/goahead/server/wsIntrn.h b/ap/app/goahead/server/wsIntrn.h
new file mode 100755
index 0000000..d55148e
--- /dev/null
+++ b/ap/app/goahead/server/wsIntrn.h
@@ -0,0 +1,292 @@
+
+#ifndef _h_WEBS_INTERNAL
+#define _h_WEBS_INTERNAL 1
+
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef NETWARE
+ #include <fcntl.h>
+ #include <sys/stat.h>
+ #include <signal.h>
+ #include <io.h>
+#endif
+
+#ifdef WIN
+ #include <fcntl.h>
+ #include <sys/stat.h>
+ #include <io.h>
+#endif
+
+#ifdef CE
+#ifndef UEMF
+ #include <io.h>
+#endif
+#endif
+
+#ifdef NW
+ #include <fcntl.h>
+ #include <sys/stat.h>
+#endif
+
+#ifdef SCOV5
+ #include <fcntl.h>
+ #include <sys/stat.h>
+ #include <signal.h>
+ #include <unistd.h>
+#endif
+
+#ifdef LYNX
+ #include <fcntl.h>
+ #include <sys/stat.h>
+ #include <signal.h>
+ #include <unistd.h>
+#endif
+
+#ifdef UNIX
+ #include <fcntl.h>
+ #include <sys/stat.h>
+ #include <signal.h>
+ #include <unistd.h>
+#endif
+
+#ifdef QNX4
+ #include <fcntl.h>
+ #include <sys/stat.h>
+ #include <signal.h>
+ #include <unistd.h>
+ #include <unix.h>
+#endif
+
+#ifdef SOLARIS
+ #include <macros.h>
+ #include <fcntl.h>
+ #include <sys/stat.h>
+#endif
+
+#ifdef VXWORKS
+ #include <vxWorks.h>
+ #include <fcntl.h>
+ #include <sys/stat.h>
+#endif
+
+#ifdef UW
+ #include <fcntl.h>
+ #include <sys/stat.h>
+#endif
+
+#ifdef UEMF
+ #include "uemf.h"
+ #include "ejIntrn.h"
+#else
+ #include "emf/emfInternal.h"
+ #include "ej/ejIntrn.h"
+#endif
+
+#include "webs.h"
+
+
+#define WEBS_BEGIN 0x1
+#define WEBS_HEADER 0x2
+#define WEBS_POST 0x4
+#define WEBS_POST_CLEN 0x8
+#define WEBS_PROCESSING 0x10
+#define WEBS_KEEP_TIMEOUT 15000
+#define WEBS_TIMEOUT 60000
+
+#define PAGE_READ_BUFSIZE 512
+#define MAX_PORT_LEN 10
+#define WEBS_SYM_INIT 64
+
+
+typedef struct {
+ int (*handler)(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
+ char_t *url, char_t *path,
+ char_t *query);
+ char_t *webDir;
+ char_t *urlPrefix;
+ int len;
+ int arg;
+ int flags;
+} websUrlHandlerType;
+
+
+typedef struct {
+ long errors;
+ long redirects;
+ long net_requests;
+ long activeNetRequests;
+ long activeBrowserRequests;
+ long timeouts;
+ long access;
+ long localHits;
+ long remoteHits;
+ long formHits;
+ long cgiHits;
+ long handlerHits;
+} websStatsType;
+
+extern websStatsType websStats;
+
+typedef struct {
+ int code;
+ char_t *msg;
+} websErrorType;
+
+
+typedef struct {
+ char_t *type;
+ char_t *ext;
+} websMimeType;
+
+
+typedef struct {
+ unsigned long size;
+ int isDir;
+ time_t mtime;
+} websStatType;
+
+
+typedef struct {
+ char_t *path;
+ unsigned char *page;
+ int size;
+ int pos;
+} websRomPageIndexType;
+
+
+#ifndef CE
+#define SOCKET_RDONLY O_RDONLY
+#define SOCKET_BINARY O_BINARY
+#else /* CE */
+#define SOCKET_RDONLY 0x1
+#define SOCKET_BINARY 0x2
+#endif /* CE */
+
+//#define DOWNLOAD_INTERVAL 1048576 //4194304
+extern int zte_process_cgi_end(webs_t wp);
+extern int zte_check_downloading_file();
+extern int websCgiDownLoadHandler(webs_t wp, char_t *urlPrefix,
+ char_t *webDir, int arg, char_t *url, char_t *path,
+ char_t *query);
+
+#define DOWNLOAD_INTERVAL 1048576 //4194304
+#define UPLOAD_INTERVAL 65536
+
+#ifdef FEATURE_ZTE_WEB_TCARD
+//added by guo shoupeng 10124224 for http share 20111001 start
+#define UPLOAD_INTERVAL 65536
+#define DOWNLOAD_INTERVAL 1048576 //4194304
+#define PATH_SD_CARD "/mmc2"
+#define PATH_SD_MNT "/mnt"
+
+extern int sd_card_isExist();
+extern int sd_card_isClose (webs_t wp);
+extern int zte_process_cgi(webs_t wp);
+extern int zte_process_cgi_end(webs_t wp);
+extern int websGetState(webs_t wp);
+extern int websGetlen(webs_t wp);
+extern char_t * websGetURL(webs_t wp);
+extern int zte_efs_write(webs_t wp);
+
+extern int zte_http_share_process_flagfile_exist(const char *i_filename );
+extern int websCgiDownLoadHandler(webs_t wp, char_t *urlPrefix,
+ char_t *webDir, int arg, char_t *url, char_t *path,
+ char_t *query);
+
+//added by guo shoupeng 10124224 for http share 20111001 end
+#endif
+extern websRomPageIndexType websRomPageIndex[];
+extern websMimeType websMimeList[];
+extern sym_fd_t websMime;
+extern webs_t* webs;
+extern int websMax;
+extern char_t websHost[64];
+extern char_t websIpaddr[64];
+extern char_t *websHostUrl;
+extern char_t *websIpaddrUrl;
+extern int websPort;
+
+extern char_t* websGetDateString(websStatType* sbuf);
+
+extern int strcmpci(char_t* s1, char_t* s2);
+
+extern int websAspOpen();
+extern void websAspClose();
+
+extern int websAspWrite(int ejid, webs_t wp, int argc, char_t **argv);
+
+extern void websFormOpen();
+extern void websFormClose();
+
+extern int websCgiHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
+ int arg, char_t *url, char_t *path, char_t *query);
+extern void websCgiCleanup();
+extern int websCheckCgiProc(int handle, int *status);
+extern char_t *websGetCgiCommName();
+
+extern int websLaunchCgiProc(char_t *cgiPath, char_t **argp,
+ char_t **envp, char_t *stdIn, char_t *stdOut);
+
+extern void websDefaultClose();
+
+extern void websUrlHandlerClose();
+extern int websUrlHandlerOpen();
+
+extern int websDefaultHandler(webs_t wp, char_t *urlPrefix,
+ char_t *webDir, int arg, char_t *url, char_t *path,
+ char_t *query);
+extern int websFormHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
+ int arg, char_t *url, char_t *path, char_t *query);
+
+extern int websOpen(int sid);
+extern void websResponse(webs_t wp, int code, char_t *msg,
+ char_t *redirect);
+extern int websJavaScriptEval(webs_t wp, char_t *script);
+extern int websPageReadData(webs_t wp, char *buf, int nBytes);
+
+extern void websPageSeek(webs_t wp, long offset);
+extern int websPageStat(webs_t wp, char_t *lpath, char_t *path,
+ websStatType *sbuf);
+extern int websPageIsDirectory(char_t *lpath);
+
+extern int websPageOpen(webs_t wp, char_t *lpath, char_t *path, int mode,
+ int perm);
+extern void websPageClose(webs_t wp);
+
+
+extern int websRomPageOpen(webs_t wp, char_t *path, int mode, int perm);
+extern void websRomPageClose(int fd);
+extern int websRomPageReadData(webs_t wp, char *buf, int len);
+extern int websRomPageStat(char_t *path, websStatType *sbuf);
+extern long websRomPageSeek(webs_t wp, long offset, int origin);
+
+extern int websRomOpen();
+extern void websRomClose();
+
+extern void websSetRequestSocketHandler(webs_t wp, int mask,
+ void (*fn)(webs_t wp));
+extern int websSolutionHandler(webs_t wp, char_t *urlPrefix,
+ char_t *webDir, int arg, char_t *url, char_t *path,
+ char_t *query);
+
+extern int websOpenServer(int port, int retries);
+extern void websCloseServer();
+
+#ifdef CE
+extern int writeUniToAsc(int fid, void *buf, unsigned int len);
+extern int readAscToUni(int fid, void **buf, unsigned int len);
+#endif
+
+#ifdef EMF
+extern int websEmfOpen();
+extern void websSetEmfEnvironment(webs_t wp);
+extern void websEmfClose();
+#endif
+
+
+#endif /* _h_WEBS_INTERNAL */
+