From f1959d65e2fc9b7c059f099eee553fbfdfbec3e5 Mon Sep 17 00:00:00 2001 From: Ralf Corsepius Date: Wed, 27 Oct 2004 06:08:56 +0000 Subject: Remove (Moved to cpukit/http). --- c/src/libnetworking/rtems_webserver/.cvsignore | 2 - c/src/libnetworking/rtems_webserver/Makefile.am | 97 - c/src/libnetworking/rtems_webserver/NOTES | 36 - c/src/libnetworking/rtems_webserver/asp.c | 321 --- c/src/libnetworking/rtems_webserver/balloc.c | 967 ------- c/src/libnetworking/rtems_webserver/cgi.c | 331 --- c/src/libnetworking/rtems_webserver/default.c | 431 --- c/src/libnetworking/rtems_webserver/ej.h | 46 - c/src/libnetworking/rtems_webserver/ejIntrn.h | 230 -- c/src/libnetworking/rtems_webserver/ejlex.c | 721 ----- c/src/libnetworking/rtems_webserver/ejparse.c | 1804 ------------ c/src/libnetworking/rtems_webserver/emfdb.c | 1050 ------- c/src/libnetworking/rtems_webserver/emfdb.h | 101 - c/src/libnetworking/rtems_webserver/form.c | 168 -- c/src/libnetworking/rtems_webserver/h.c | 194 -- c/src/libnetworking/rtems_webserver/handler.c | 411 --- c/src/libnetworking/rtems_webserver/license.txt | 282 -- c/src/libnetworking/rtems_webserver/md5.h | 50 - c/src/libnetworking/rtems_webserver/md5c.c | 337 --- c/src/libnetworking/rtems_webserver/mime.c | 116 - c/src/libnetworking/rtems_webserver/misc.c | 675 ----- c/src/libnetworking/rtems_webserver/ringq.c | 584 ---- c/src/libnetworking/rtems_webserver/rom.c | 193 -- .../rtems_webserver/rtems_webserver.h | 6 - c/src/libnetworking/rtems_webserver/security.c | 235 -- c/src/libnetworking/rtems_webserver/sock.c | 791 ------ c/src/libnetworking/rtems_webserver/sockGen.c | 1043 ------- c/src/libnetworking/rtems_webserver/socket.c | 1023 ------- c/src/libnetworking/rtems_webserver/sym.c | 474 ---- c/src/libnetworking/rtems_webserver/uemf.c | 293 -- c/src/libnetworking/rtems_webserver/uemf.h | 1110 -------- c/src/libnetworking/rtems_webserver/um.c | 1435 ---------- c/src/libnetworking/rtems_webserver/um.h | 183 -- c/src/libnetworking/rtems_webserver/umui.c | 641 ----- c/src/libnetworking/rtems_webserver/url.c | 212 -- c/src/libnetworking/rtems_webserver/value.c | 1213 -------- c/src/libnetworking/rtems_webserver/wbase64.c | 149 - c/src/libnetworking/rtems_webserver/webcomp.c | 188 -- c/src/libnetworking/rtems_webserver/webmain.c | 499 ---- c/src/libnetworking/rtems_webserver/webpage.c | 141 - c/src/libnetworking/rtems_webserver/webrom.c | 15 - c/src/libnetworking/rtems_webserver/webs.c | 2961 -------------------- c/src/libnetworking/rtems_webserver/webs.h | 233 -- c/src/libnetworking/rtems_webserver/websSSL.c | 706 ----- c/src/libnetworking/rtems_webserver/websSSL.h | 67 - c/src/libnetworking/rtems_webserver/websda.c | 244 -- c/src/libnetworking/rtems_webserver/websda.h | 41 - c/src/libnetworking/rtems_webserver/websuemf.c | 217 -- c/src/libnetworking/rtems_webserver/wsIntrn.h | 309 -- 49 files changed, 23576 deletions(-) delete mode 100644 c/src/libnetworking/rtems_webserver/.cvsignore delete mode 100644 c/src/libnetworking/rtems_webserver/Makefile.am delete mode 100644 c/src/libnetworking/rtems_webserver/NOTES delete mode 100644 c/src/libnetworking/rtems_webserver/asp.c delete mode 100644 c/src/libnetworking/rtems_webserver/balloc.c delete mode 100644 c/src/libnetworking/rtems_webserver/cgi.c delete mode 100644 c/src/libnetworking/rtems_webserver/default.c delete mode 100644 c/src/libnetworking/rtems_webserver/ej.h delete mode 100644 c/src/libnetworking/rtems_webserver/ejIntrn.h delete mode 100644 c/src/libnetworking/rtems_webserver/ejlex.c delete mode 100644 c/src/libnetworking/rtems_webserver/ejparse.c delete mode 100644 c/src/libnetworking/rtems_webserver/emfdb.c delete mode 100644 c/src/libnetworking/rtems_webserver/emfdb.h delete mode 100644 c/src/libnetworking/rtems_webserver/form.c delete mode 100644 c/src/libnetworking/rtems_webserver/h.c delete mode 100644 c/src/libnetworking/rtems_webserver/handler.c delete mode 100644 c/src/libnetworking/rtems_webserver/license.txt delete mode 100644 c/src/libnetworking/rtems_webserver/md5.h delete mode 100644 c/src/libnetworking/rtems_webserver/md5c.c delete mode 100644 c/src/libnetworking/rtems_webserver/mime.c delete mode 100644 c/src/libnetworking/rtems_webserver/misc.c delete mode 100644 c/src/libnetworking/rtems_webserver/ringq.c delete mode 100644 c/src/libnetworking/rtems_webserver/rom.c delete mode 100644 c/src/libnetworking/rtems_webserver/rtems_webserver.h delete mode 100644 c/src/libnetworking/rtems_webserver/security.c delete mode 100644 c/src/libnetworking/rtems_webserver/sock.c delete mode 100644 c/src/libnetworking/rtems_webserver/sockGen.c delete mode 100644 c/src/libnetworking/rtems_webserver/socket.c delete mode 100644 c/src/libnetworking/rtems_webserver/sym.c delete mode 100644 c/src/libnetworking/rtems_webserver/uemf.c delete mode 100644 c/src/libnetworking/rtems_webserver/uemf.h delete mode 100644 c/src/libnetworking/rtems_webserver/um.c delete mode 100644 c/src/libnetworking/rtems_webserver/um.h delete mode 100644 c/src/libnetworking/rtems_webserver/umui.c delete mode 100644 c/src/libnetworking/rtems_webserver/url.c delete mode 100644 c/src/libnetworking/rtems_webserver/value.c delete mode 100644 c/src/libnetworking/rtems_webserver/wbase64.c delete mode 100644 c/src/libnetworking/rtems_webserver/webcomp.c delete mode 100644 c/src/libnetworking/rtems_webserver/webmain.c delete mode 100644 c/src/libnetworking/rtems_webserver/webpage.c delete mode 100644 c/src/libnetworking/rtems_webserver/webrom.c delete mode 100644 c/src/libnetworking/rtems_webserver/webs.c delete mode 100644 c/src/libnetworking/rtems_webserver/webs.h delete mode 100644 c/src/libnetworking/rtems_webserver/websSSL.c delete mode 100644 c/src/libnetworking/rtems_webserver/websSSL.h delete mode 100644 c/src/libnetworking/rtems_webserver/websda.c delete mode 100644 c/src/libnetworking/rtems_webserver/websda.h delete mode 100644 c/src/libnetworking/rtems_webserver/websuemf.c delete mode 100644 c/src/libnetworking/rtems_webserver/wsIntrn.h (limited to 'c') diff --git a/c/src/libnetworking/rtems_webserver/.cvsignore b/c/src/libnetworking/rtems_webserver/.cvsignore deleted file mode 100644 index 282522db03..0000000000 --- a/c/src/libnetworking/rtems_webserver/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile -Makefile.in diff --git a/c/src/libnetworking/rtems_webserver/Makefile.am b/c/src/libnetworking/rtems_webserver/Makefile.am deleted file mode 100644 index 7c66876683..0000000000 --- a/c/src/libnetworking/rtems_webserver/Makefile.am +++ /dev/null @@ -1,97 +0,0 @@ -## -## $Id$ -## - -include $(top_srcdir)/automake/compile.am - -EXTRA_LIBRARIES = -CLEANFILES = - -AM_CPPFLAGS += -DWEBS -DUEMF -DOS="RTEMS" - -if HAS_NETWORKING -if HAS_POSIX -include_goaheaddir = $(includedir)/goahead - -include_HEADERS = rtems_webserver.h -include_goahead_HEADERS = ej.h ejIntrn.h emfdb.h md5.h uemf.h um.h webs.h \ - wsIntrn.h - -EXTRA_LIBRARIES += libhttpd.a -CLEANFILES += libhttpd.a -libhttpd_a_SOURCES = asp.c balloc.c default.c ejlex.c ejparse.c emfdb.c \ - form.c h.c handler.c md5c.c mime.c misc.c webpage.c ringq.c rom.c \ - security.c sock.c socket.c sym.c uemf.c um.c url.c value.c wbase64.c \ - webrom.c webs.c websuemf.c webmain.c -libhttpd_a_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V) - -EXTRA_LIBRARIES += libhttpd_g.a -CLEANFILES += libhttpd_g.a -libhttpd_g_a_SOURCES = $(libhttpd_a_SOURCES) -libhttpd_g_a_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V) - -noinst_DATA = libhttpd$(LIB_VARIANT).a -endif -endif - -all-local: $(PREINSTALL_FILES) - -EXTRA_DIST = webcomp.c webpage.c - -PREINSTALL_DIRS = -PREINSTALL_FILES = - -$(PROJECT_INCLUDE)/$(dirstamp): - @$(mkdir_p) $(PROJECT_INCLUDE) - @: > $(PROJECT_INCLUDE)/$(dirstamp) -PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp) - -if HAS_NETWORKING -if HAS_POSIX -$(PROJECT_INCLUDE)/goahead/$(dirstamp): - @$(mkdir_p) $(PROJECT_INCLUDE)/goahead - @: > $(PROJECT_INCLUDE)/goahead/$(dirstamp) -PREINSTALL_DIRS += $(PROJECT_INCLUDE)/goahead/$(dirstamp) - -$(PROJECT_INCLUDE)/rtems_webserver.h: rtems_webserver.h $(PROJECT_INCLUDE)/$(dirstamp) - $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems_webserver.h -PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems_webserver.h - -$(PROJECT_INCLUDE)/goahead/ej.h: ej.h $(PROJECT_INCLUDE)/goahead/$(dirstamp) - $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/goahead/ej.h -PREINSTALL_FILES += $(PROJECT_INCLUDE)/goahead/ej.h - -$(PROJECT_INCLUDE)/goahead/ejIntrn.h: ejIntrn.h $(PROJECT_INCLUDE)/goahead/$(dirstamp) - $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/goahead/ejIntrn.h -PREINSTALL_FILES += $(PROJECT_INCLUDE)/goahead/ejIntrn.h - -$(PROJECT_INCLUDE)/goahead/emfdb.h: emfdb.h $(PROJECT_INCLUDE)/goahead/$(dirstamp) - $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/goahead/emfdb.h -PREINSTALL_FILES += $(PROJECT_INCLUDE)/goahead/emfdb.h - -$(PROJECT_INCLUDE)/goahead/md5.h: md5.h $(PROJECT_INCLUDE)/goahead/$(dirstamp) - $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/goahead/md5.h -PREINSTALL_FILES += $(PROJECT_INCLUDE)/goahead/md5.h - -$(PROJECT_INCLUDE)/goahead/uemf.h: uemf.h $(PROJECT_INCLUDE)/goahead/$(dirstamp) - $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/goahead/uemf.h -PREINSTALL_FILES += $(PROJECT_INCLUDE)/goahead/uemf.h - -$(PROJECT_INCLUDE)/goahead/um.h: um.h $(PROJECT_INCLUDE)/goahead/$(dirstamp) - $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/goahead/um.h -PREINSTALL_FILES += $(PROJECT_INCLUDE)/goahead/um.h - -$(PROJECT_INCLUDE)/goahead/webs.h: webs.h $(PROJECT_INCLUDE)/goahead/$(dirstamp) - $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/goahead/webs.h -PREINSTALL_FILES += $(PROJECT_INCLUDE)/goahead/webs.h - -$(PROJECT_INCLUDE)/goahead/wsIntrn.h: wsIntrn.h $(PROJECT_INCLUDE)/goahead/$(dirstamp) - $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/goahead/wsIntrn.h -PREINSTALL_FILES += $(PROJECT_INCLUDE)/goahead/wsIntrn.h -endif -endif - -CLEANFILES += $(PREINSTALL_FILES) -DISTCLEANFILES = $(PREINSTALL_DIRS) - -include $(top_srcdir)/automake/local.am diff --git a/c/src/libnetworking/rtems_webserver/NOTES b/c/src/libnetworking/rtems_webserver/NOTES deleted file mode 100644 index e2ef07eb34..0000000000 --- a/c/src/libnetworking/rtems_webserver/NOTES +++ /dev/null @@ -1,36 +0,0 @@ -# -# $Id$ -# - -Notes on merging GoAhead Webs 2.1.4. Eventually RTEMS should be supported -in their distributions and this directory removed. - -Applied patch from Antti P Miettinen . - -Obtain the original distribution from http://www.goahead.com for -documentation. - -Porting -======= - - added rtems complier flags to uemf.h and misc.c - - following source files are distributed with the web server - but not currently used by RTEMS - [cgi.c, sockGen.c, umui.c, websSSL.c, websda.c] - -Tailoring -========= -socket.c is RTEMS specific - -Renames -======= - -Distributed as This Directory -============== ================ -base64.c wbase64.c -page.c webpage.c - -RTEMS Specific Additions -======================== -webmain.c -rtems_webserver.h - diff --git a/c/src/libnetworking/rtems_webserver/asp.c b/c/src/libnetworking/rtems_webserver/asp.c deleted file mode 100644 index 7d20e683b7..0000000000 --- a/c/src/libnetworking/rtems_webserver/asp.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * asp.c -- Active Server Page Support - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/******************************** Description *********************************/ - -/* - * The ASP module processes ASP pages and executes embedded scripts. It - * support an open scripting architecture with in-built support for - * Ejscript(TM). - */ - -/********************************* Includes ***********************************/ - -#include "wsIntrn.h" - -/********************************** Locals ************************************/ - -static sym_fd_t websAspFunctions = -1; /* Symbol table of functions */ -static int aspOpenCount = 0; /* count of apps using this module */ - -/***************************** Forward Declarations ***************************/ - -static char_t *strtokcmp(char_t *s1, char_t *s2); -static char_t *skipWhite(char_t *s); - -/************************************* Code ***********************************/ -/* - * Create script spaces and commands - */ - -int websAspOpen() -{ - if (++aspOpenCount == 1) { -/* - * Create the table for ASP functions - */ - websAspFunctions = symOpen(WEBS_SYM_INIT * 2); - -/* - * Create standard ASP commands - */ - websAspDefine(T("write"), websAspWrite); - } - return 0; -} - -/************************************* Code ***********************************/ -/* - * Close Asp symbol table. - */ - -void websAspClose() -{ - if (--aspOpenCount <= 0) { - if (websAspFunctions != -1) { - symClose(websAspFunctions); - websAspFunctions = -1; - } - } -} - -/******************************************************************************/ -/* - * Process ASP requests and expand all scripting commands. We read the - * entire ASP page into memory and then process. If you have really big - * documents, it is better to make them plain HTML files rather than ASPs. - */ - -int websAspRequest(webs_t wp, char_t *lpath) -{ - websStatType sbuf; - char *rbuf; - char_t *token, *lang, *result, *path, *ep, *cp, *buf, *nextp; - char_t *last; - int rc, engine, len, ejid; - - a_assert(websValid(wp)); - a_assert(lpath && *lpath); - - rc = -1; - buf = NULL; - rbuf = NULL; - engine = EMF_SCRIPT_EJSCRIPT; - wp->flags |= WEBS_HEADER_DONE; - path = websGetRequestPath(wp); - -/* - * Create Ejscript instance in case it is needed - */ - ejid = ejOpenEngine(wp->cgiVars, websAspFunctions); - if (ejid < 0) { - websError(wp, 200, T("Can't create Ejscript engine")); - goto done; - } - ejSetUserHandle(ejid, (int) wp); - - if (websPageStat(wp, lpath, path, &sbuf) < 0) { - websError(wp, 200, T("Can't stat %s"), lpath); - goto done; - } - -/* - * Create a buffer to hold the ASP file in-memory - */ - len = sbuf.size * sizeof(char); - if ((rbuf = balloc(B_L, len + 1)) == NULL) { - websError(wp, 200, T("Can't get memory")); - goto done; - } - rbuf[len] = '\0'; - - if (websPageReadData(wp, rbuf, len) != len) { - websError(wp, 200, T("Cant read %s"), lpath); - goto done; - } - websPageClose(wp); - -/* - * Convert to UNICODE if necessary. - */ - if ((buf = ballocAscToUni(rbuf, len)) == NULL) { - websError(wp, 200, T("Can't get memory")); - goto done; - } - -/* - * Scan for the next "<%" - */ - last = buf; - rc = 0; - while (rc == 0 && *last && ((nextp = gstrstr(last, T("<%"))) != NULL)) { - websWriteBlock(wp, last, (nextp - last)); - nextp = skipWhite(nextp + 2); - -/* - * Decode the language - */ - token = T("language"); - - if ((lang = strtokcmp(nextp, token)) != NULL) { - if ((cp = strtokcmp(lang, T("=javascript"))) != NULL) { - engine = EMF_SCRIPT_EJSCRIPT; - } else { - cp = nextp; - } - nextp = cp; - } - -/* - * Find tailing bracket and then evaluate the script - */ - if ((ep = gstrstr(nextp, T("%>"))) != NULL) { - - *ep = '\0'; - last = ep + 2; - nextp = skipWhite(nextp); -/* - * Handle backquoted newlines - */ - for (cp = nextp; *cp; ) { - if (*cp == '\\' && (cp[1] == '\r' || cp[1] == '\n')) { - *cp++ = ' '; - while (*cp == '\r' || *cp == '\n') { - *cp++ = ' '; - } - } else { - cp++; - } - } - -/* - * Now call the relevant script engine. Output is done directly - * by the ASP script procedure by calling websWrite() - */ - if (*nextp) { - result = NULL; - if (engine == EMF_SCRIPT_EJSCRIPT) { - rc = scriptEval(engine, nextp, &result, ejid); - } else { - rc = scriptEval(engine, nextp, &result, (int) wp); - } - if (rc < 0) { -/* - * On an error, discard all output accumulated so far - * and store the error in the result buffer. Be careful if the - * user has called websError() already. - */ - if (websValid(wp)) { - if (result) { - websWrite(wp, T("

ASP Error: %s

\n"), - result); - websWrite(wp, T("
%s
"), nextp); - bfree(B_L, result); - } else { - websWrite(wp, T("

ASP Error

\n%s\n"), - nextp); - } - websWrite(wp, T("\n")); - rc = 0; - } - goto done; - } - } - - } else { - websError(wp, 200, T("Unterminated script in %s: \n"), lpath); - rc = -1; - goto done; - } - } -/* - * Output any trailing HTML page text - */ - if (last && *last && rc == 0) { - websWriteBlock(wp, last, gstrlen(last)); - } - rc = 0; - -/* - * Common exit and cleanup - */ -done: - if (websValid(wp)) { - websPageClose(wp); - if (ejid >= 0) { - ejCloseEngine(ejid); - } - } - bfreeSafe(B_L, buf); - bfreeSafe(B_L, rbuf); - return rc; -} - -/******************************************************************************/ -/* - * Define an ASP Ejscript function. Bind an ASP name to a C procedure. - */ - -int websAspDefine(char_t *name, - int (*fn)(int ejid, webs_t wp, int argc, char_t **argv)) -{ - return ejSetGlobalFunctionDirect(websAspFunctions, name, - (int (*)(int, void*, int, char_t**)) fn); -} - -/******************************************************************************/ -/* - * Asp write command. This implemements <% write("text"); %> command - */ - -int websAspWrite(int ejid, webs_t wp, int argc, char_t **argv) -{ - int i; - - a_assert(websValid(wp)); - - for (i = 0; i < argc; ) { - a_assert(argv); - if (websWriteBlock(wp, argv[i], gstrlen(argv[i])) < 0) { - return -1; - } - if (++i < argc) { - if (websWriteBlock(wp, T(" "), 2) < 0) { - return -1; - } - } - } - return 0; -} - -/******************************************************************************/ -/* - * strtokcmp -- Find s2 in s1. We skip leading white space in s1. - * Return a pointer to the location in s1 after s2 ends. - */ - -static char_t *strtokcmp(char_t *s1, char_t *s2) -{ - int len; - - s1 = skipWhite(s1); - len = gstrlen(s2); - for (len = gstrlen(s2); len > 0 && (tolower(*s1) == tolower(*s2)); len--) { - if (*s2 == '\0') { - return s1; - } - s1++; - s2++; - } - if (len == 0) { - return s1; - } - return NULL; -} - -/******************************************************************************/ -/* - * Skip white space - */ - -static char_t *skipWhite(char_t *s) -{ - a_assert(s); - - if (s == NULL) { - return s; - } - while (*s && gisspace(*s)) { - s++; - } - return s; -} - -/******************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/balloc.c b/c/src/libnetworking/rtems_webserver/balloc.c deleted file mode 100644 index f43bc90acb..0000000000 --- a/c/src/libnetworking/rtems_webserver/balloc.c +++ /dev/null @@ -1,967 +0,0 @@ -/* - * balloc.c -- Block allocation module - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/******************************** Description *********************************/ - -/* - * This module implements a very fast block allocation scheme suitable for - * ROMed environments. It maintains block class queues for rapid allocation - * and minimal fragmentation. This module does not coalesce blocks. The - * storage space may be populated statically or via the traditional malloc - * mechanisms. Large blocks greater than the maximum class size may be - * allocated from the O/S or run-time system via malloc. To permit the use - * of malloc, call bopen with flags set to B_USE_MALLOC (this is the default). - * It is recommended that bopen be called first thing in the application. - * If it is not, it will be called with default values on the first call to - * balloc(). Note that this code is not designed for multi-threading purposes - * and it depends on newly declared variables being initialized to zero. - */ - -/********************************* Includes ***********************************/ - -#define IN_BALLOC - -#ifdef UEMF - #include "uemf.h" -#else - #include "basic/basicInternal.h" -#endif - -#include -#include - -#ifndef NO_BALLOC -/********************************* Defines ************************************/ - -/* - * Define B_STATS if you wish to track memory block and stack usage - */ -#ifdef B_STATS -/* - * Optional statistics - */ - -typedef struct { - long alloc; /* Block allocation calls */ - long inuse; /* Blocks in use */ -} bStatsType; - -typedef struct { - char_t file[FNAMESIZE]; - long allocated; /* Bytes currently allocated */ - long count; /* Current block count */ - long times; /* Count of alloc attempts */ - long largest; /* largest allocated here */ - int q; -} bStatsFileType; - -/* - * This one is very expensive but great stats - */ -typedef struct { - void *ptr; /* Pointer to memory */ - bStatsFileType *who; /* Who allocated the memory */ -} bStatsBlkType; - -static bStatsType bStats[B_MAX_CLASS]; /* Per class stats */ -static bStatsFileType bStatsFiles[B_MAX_FILES];/* Per file stats */ -static bStatsBlkType bStatsBlks[B_MAX_BLOCKS];/* Per block stats */ -static int bStatsBlksMax = 0; /* Max block entry */ -static int bStatsFilesMax = 0; /* Max file entry */ -static int bStatsMemInUse = 0; /* Memory currently in use */ -static int bStatsBallocInUse = 0; /* Memory currently balloced */ -static int bStatsMemMax = 0; /* Max memory ever used */ -static int bStatsBallocMax = 0; /* Max memory ever balloced */ -static void *bStackMin = (void*) -1;/* Miniumum stack position */ -static void *bStackStart; /* Starting stack position */ -static int bStatsMemMalloc = 0; /* Malloced memory */ -#endif /* B_STATS */ - -/* - * ROUNDUP4(size) returns the next higher integer value of size that is - * divisible by 4, or the value of size if size is divisible by 4. - * ROUNDUP4() is used in aligning memory allocations on 4-byte boundaries. - * - * Note: ROUNDUP4() is only required on some operating systems (IRIX). - */ - -#define ROUNDUP4(size) ((size) % 4) ? (size) + (4 - ((size) % 4)) : (size) - -/********************************** Locals ************************************/ -/* - * bQhead blocks are created as the original memory allocation is freed up. - * See bfree. - */ -static bType *bQhead[B_MAX_CLASS]; /* Per class block q head */ -static char *bFreeBuf; /* Pointer to free memory */ -static char *bFreeNext; /* Pointer to next free mem */ -static int bFreeSize; /* Size of free memory */ -static int bFreeLeft; /* Size of free left for use */ -static int bFlags = B_USE_MALLOC; /* Default to auto-malloc */ -static int bopenCount = 0; /* Num tasks using balloc */ - -/*************************** Forward Declarations *****************************/ - -#ifdef B_STATS -static void bStatsAlloc(B_ARGS_DEC, void *ptr, int q, int size); -static void bStatsFree(B_ARGS_DEC, void *ptr, int q, int size); -static void bstatsWrite(int handle, char_t *fmt, ...); -static int bStatsFileSort(const void *cp1, const void *cp2); -#endif /* B_STATS */ - -#if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD)) -static void bFillBlock(void *buf, int bufsize); -#endif - -#ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD -static void verifyUsedBlock(bType *bp, int q); -static void verifyFreeBlock(bType *bp, int q); -void verifyBallocSpace(); -#endif - -static int ballocGetSize(int size, int *q); - -/********************************** Code **************************************/ -/* - * Initialize the balloc module. bopen should be called the very first thing - * after the application starts and bclose should be called the last thing - * before exiting. If bopen is not called, it will be called on the first - * allocation with default values. "buf" points to memory to use of size - * "bufsize". If buf is NULL, memory is allocated using malloc. flags may - * be set to B_USE_MALLOC if using malloc is okay. This routine will allocate - * an initial buffer of size bufsize for use by the application. - */ - -int bopen(void *buf, int bufsize, int flags) -{ - bFlags = flags; - -#ifdef BASTARD_TESTING - srand(time(0L)); -#endif /* BASTARD_TESTING */ - -/* - * If bopen already called by a shared process, just increment the count - * and return; - */ - if (++bopenCount > 1) { - return 0; - } - - if (buf == NULL) { - if (bufsize == 0) { - bufsize = B_DEFAULT_MEM; - } -#ifdef IRIX - bufsize = ROUNDUP4(bufsize); -#endif - if ((buf = malloc(bufsize)) == NULL) { - return -1; - } -#ifdef B_STATS - bStatsMemMalloc += bufsize; -#endif - } else { - bFlags |= B_USER_BUF; - } - - bFreeSize = bFreeLeft = bufsize; - bFreeBuf = bFreeNext = buf; - memset(bQhead, 0, sizeof(bQhead)); -#if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD)) - bFillBlock(buf, bufsize); -#endif -#ifdef B_STATS - bStackStart = &buf; -#endif -#ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD - verifyFreeBlock(buf, bufsize); -#endif - return 0; -} - -/******************************************************************************/ -/* - * Close down the balloc module and free all malloced memory. - */ - -void bclose() -{ -#ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD - verifyBallocSpace(); -#endif - if (--bopenCount <= 0 && !(bFlags & B_USER_BUF)) { - free(bFreeBuf); - bopenCount = 0; - } -} - -/******************************************************************************/ -/* - * Allocate a block of the requested size. First check the block - * queues for a suitable one. - */ - -void *balloc(B_ARGS_DEC, int size) -{ - bType *bp; - int q, memSize; - -/* - * Call bopen with default values if the application has not yet done so - */ - if (bFreeBuf == NULL) { - if (bopen(NULL, B_DEFAULT_MEM, 0) < 0) { - return NULL; - } - } -#ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD - verifyBallocSpace(); -#endif - if (size < 0) { - return NULL; - } - -#ifdef BASTARD_TESTING - if (rand() == 0x7fff) { - return NULL; - } -#endif /* BASTARD_TESTING */ - - - memSize = ballocGetSize(size, &q); - - if (q >= B_MAX_CLASS) { -/* - * Size if bigger than the maximum class. Malloc if use has been okayed - */ - if (bFlags & B_USE_MALLOC) { -#ifdef B_STATS - bstats(0, NULL); -#endif -#ifdef IRIX - memSize = ROUNDUP4(memSize); -#endif - bp = (bType*) malloc(memSize); - if (bp == NULL) { - traceRaw(T("B: malloc failed\n")); - return NULL; - } -#ifdef B_STATS - bStatsMemMalloc += memSize; -#endif -#if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD)) - bFillBlock(bp, memSize); -#endif - - } else { - traceRaw(T("B: malloc failed\n")); - return NULL; - } - -/* - * the u.size is the actual size allocated for data - */ - bp->u.size = memSize - sizeof(bType); - bp->flags = B_MALLOCED; - - } else if ((bp = bQhead[q]) != NULL) { -/* - * Take first block off the relevant q if non-empty - */ - bQhead[q] = bp->u.next; -#ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD - verifyFreeBlock(bp, q); -#endif -#if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD)) - bFillBlock(bp, memSize); -#endif - bp->u.size = memSize - sizeof(bType); - bp->flags = 0; - - } else { - if (bFreeLeft > memSize) { -/* - * The q was empty, and the free list has spare memory so - * create a new block out of the primary free block - */ - bp = (bType*) bFreeNext; -#ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD - verifyFreeBlock(bp, q); -#endif - bFreeNext += memSize; - bFreeLeft -= memSize; -#if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD)) - bFillBlock(bp, memSize); -#endif - bp->u.size = memSize - sizeof(bType); - bp->flags = 0; - - } else if (bFlags & B_USE_MALLOC) { -#ifdef B_STATS - static int once = 0; - if (once++ == 0) { - bstats(0, NULL); - } -#endif -/* - * Nothing left on the primary free list, so malloc a new block - */ -#ifdef IRIX - memSize = ROUNDUP4(memSize); -#endif - if ((bp = (bType*) malloc(memSize)) == NULL) { - traceRaw(T("B: malloc failed\n")); - return NULL; - } -#ifdef B_STATS - bStatsMemMalloc += memSize; -#endif -#if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD)) - bFillBlock(bp, memSize); -#endif - bp->u.size = memSize - sizeof(bType); - bp->flags = B_MALLOCED; - - } else { - traceRaw(T("B: malloc failed\n")); - return NULL; - } - } - -#ifdef B_STATS - bStatsAlloc(B_ARGS, bp, q, memSize); -#endif - bp->flags |= B_INTEGRITY; - -/* - * The following is a good place to put a breakpoint when trying to reduce - * determine and reduce maximum memory use. - */ -#if 0 -#ifdef B_STATS - if (bStatsBallocInUse == bStatsBallocMax) { - bstats(0, NULL); - } -#endif -#endif - return (void*) ((char*) bp + sizeof(bType)); -} - -/******************************************************************************/ -/* - * Free a block back to the relevant free q. We don't free back to the O/S - * or run time system unless the block is greater than the maximum class size. - * We also do not coalesce blocks. - */ - -void bfree(B_ARGS_DEC, void *mp) -{ - bType *bp; - int q, memSize; - -#ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD - verifyBallocSpace(); -#endif - 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); - -#ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD - verifyUsedBlock(bp,q); -#endif -#ifdef B_STATS - bStatsFree(B_ARGS, bp, q, bp->u.size+sizeof(bType)); -#endif - if (bp->flags & B_MALLOCED) { - free(bp); - return; - } - -#ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD - bFillBlock(bp, memSize); -#endif - -/* - * Simply link onto the head of the relevant q - */ - bp->u.next = bQhead[q]; - bQhead[q] = bp; - - bp->flags = B_FILL_WORD; -} - -/******************************************************************************/ -/* - * Safe free - */ - -void bfreeSafe(B_ARGS_DEC, void *mp) -{ - if (mp) { - bfree(B_ARGS, mp); - } -} - -/******************************************************************************/ -#ifdef UNICODE -/* - * Duplicate a string, allow NULL pointers and then dup an empty string. - */ - -char *bstrdupA(B_ARGS_DEC, char *s) -{ - char *cp; - int len; - - if (s == NULL) { - s = ""; - } - len = strlen(s) + 1; - if (cp = balloc(B_ARGS, len)) { - strcpy(cp, s); - } - return cp; -} - -#endif /* UNICODE */ -/******************************************************************************/ -/* - * Duplicate an ascii string, allow NULL pointers and then dup an empty string. - * If UNICODE, bstrdup above works with wide chars, so we need this routine - * for ascii strings. - */ - -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; -} - -/******************************************************************************/ -/* - * Reallocate a block. Allow NULL pointers and just do a malloc. - * Note: if the realloc fails, we return NULL and the previous buffer is - * preserved. - */ - -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 the allocated memory already has enough room just return the previously - * allocated address. - */ - 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; -} - -/******************************************************************************/ -/* - * Find the size of the block to be balloc'ed. It takes in a size, finds the - * smallest binary block it fits into, adds an overhead amount and returns. - * q is the binary size used to keep track of block sizes in use. Called - * from both balloc and bfree. - */ - -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)); -} - -/******************************************************************************/ -#if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD)) -/* - * Fill the block (useful during development to catch zero fill assumptions) - */ - -static void bFillBlock(void *buf, int bufsize) -{ - memset(buf, B_FILL_CHAR, bufsize); -} -#endif - -/******************************************************************************/ -#ifdef B_STATS -/* - * Statistics. Do output via calling the writefn callback function with - * "handle" as the output file handle. - */ - -void bstats(int handle, void (*writefn)(int handle, char_t *fmt, ...)) -{ - bStatsFileType *fp, *files; - bStatsBlkType *blkp; - bType *bp; - char_t *cp; - int q, count, mem, total, len; - static int recurseProtect = 0; - - if (recurseProtect++ > 0) { - recurseProtect--; - return; - } - - if (writefn == NULL) { - writefn = bstatsWrite; - } - -/* - * Print stats for each memory block - */ - (*writefn)(handle, T("\nMemory Stats\n")); - -/* - * The following tabular format is now used for the output. - * Q Size Free Bytes Inuse Bytes Allocs - * dd ddddd ddd ddddd dddd ddddd dddd - */ - (*writefn)(handle, " Q Size Free Bytes Inuse Bytes Allocs\n"); - - total = 0; - for (q = 0; q < B_MAX_CLASS; q++) { - count = 0; - for (bp = bQhead[q]; bp; bp = bp->u.next) { - count++; - } - mem = count * (1 << (q + B_SHIFT)); - total += mem; - (*writefn)(handle, - T("%2d %5d %4d %6d %4d %5d %4d\n"), - q, 1 << (q + B_SHIFT), count, mem, bStats[q].inuse, - bStats[q].inuse * (1 << (q + B_SHIFT)), bStats[q].alloc); - } - - (*writefn)(handle, T("\n")); - -/* - * Print summary stats - * - * bFreeSize Initial memory reserved with bopen call - * bStatsMemMalloc memory from calls to system MALLOC - * bStatsMemMax - * bStatsBallocMax largest amount of memory from balloc calls - * bStatsMemInUse - * bStatsBallocInUse present balloced memory being used - * bStatsBlksMax); - * bStackStart - * bStackMin); - * total); - * bFreeLeft); - * - */ - (*writefn)(handle, T("Initial free list size %7d\n"), bFreeSize); - (*writefn)(handle, T("Max memory malloced %7d\n"), bStatsMemMalloc); - (*writefn)(handle, T("Max memory ever used %7d\n"), bStatsMemMax); - (*writefn)(handle, T("Max memory ever balloced %7d\n"), bStatsBallocMax); - (*writefn)(handle, T("Memory currently in use %7d\n"), bStatsMemInUse); - (*writefn)(handle, T("Memory currently balloced %7d\n"), bStatsBallocInUse); - (*writefn)(handle, T("Max blocks allocated %7d\n"), bStatsBlksMax); - (*writefn)(handle, T("Maximum stack used %7d\n"), - (int) bStackStart - (int) bStackMin); - - (*writefn)(handle, T("Free memory on all queues %7d\n"), total); - (*writefn)(handle, T("Free list buffer left %7d\n"), bFreeLeft); - (*writefn)(handle, T("Total free memory %7d\n"), bFreeLeft + total); - -/* - * Print per file allocation stats. Sort the copied table. - */ - len = sizeof(bStatsFileType) * B_MAX_FILES; - files = malloc(len); - if (files == NULL) { - (*writefn)(handle, T("Can't allocate stats memory\n")); - recurseProtect--; - return; - } - memcpy(files, bStatsFiles, len); - qsort(files, bStatsFilesMax, sizeof(bStatsFileType), bStatsFileSort); - - (*writefn)(handle, T("\nMemory Currently Allocated\n")); - total = 0; - (*writefn)(handle, - T(" bytes, blocks in use, total times,") - T("largest, q\n")); - - for (fp = files; fp < &files[bStatsFilesMax]; fp++) { - if (fp->file[0]) { - (*writefn)(handle, T("%18s, %7d, %5d, %6d, %7d,%4d\n"), - fp->file, fp->allocated, fp->count, fp->times, fp->largest, - fp->q); - total += fp->allocated; - } - } - (*writefn)(handle, T("\nTotal allocated %7d\n\n"), total); - -/* - * Dump the actual strings - */ - (*writefn)(handle, T("\nStrings\n")); - for (blkp = &bStatsBlks[bStatsBlksMax - 1]; blkp >= bStatsBlks; blkp--) { - if (blkp->ptr) { - cp = (char_t*) ((char*) blkp->ptr + sizeof(bType)); - fp = blkp->who; - if (gisalnum(*cp)) { - (*writefn)(handle, T("%-50s allocated by %s\n"), cp, - fp->file); - } - } - } - free(files); - recurseProtect--; -} - -/******************************************************************************/ -/* - * File sort function. Used to sort per file stats - */ - -static int bStatsFileSort(const void *cp1, const void *cp2) -{ - bStatsFileType *s1, *s2; - - s1 = (bStatsFileType*) cp1; - s2 = (bStatsFileType*) cp2; - - if (s1->allocated < s2->allocated) - return -1; - else if (s1->allocated == s2->allocated) - return 0; - return 1; -} - -/******************************************************************************/ -/* - * Accumulate allocation statistics - */ - -static void bStatsAlloc(B_ARGS_DEC, void *ptr, int q, int size) -{ - int memSize; - bStatsFileType *fp; - bStatsBlkType *bp; - char_t name[FNAMESIZE + 10]; - - gsprintf(name, T("%s:%d"), B_ARGS); - - bStats[q].alloc++; - bStats[q].inuse++; - bStatsMemInUse += size; - if (bStatsMemInUse > bStatsMemMax) { - bStatsMemMax = bStatsMemInUse; - } - memSize = (1 << (B_SHIFT + q)) + sizeof(bType); - bStatsBallocInUse += memSize; - if (bStatsBallocInUse > bStatsBallocMax) { - bStatsBallocMax = bStatsBallocInUse; - } - -/* - * Track maximum stack usage. Assumes a stack growth down. Approximate as - * we only measure this on block allocation. - */ - if ((void*) &file < bStackMin) { - bStackMin = (void*) &file; - } - -/* - * Find the file and adjust the stats for this file - */ - for (fp = bStatsFiles; fp < &bStatsFiles[bStatsFilesMax]; fp++) { - if (fp->file[0] == file[0] && gstrcmp(fp->file, name) == 0) { - fp->allocated += size; - fp->count++; - fp->times++; - if (fp->largest < size) { - fp->largest = size; - fp->q = q; - } - break; - } - } - -/* - * New entry: find the first free slot and create a new entry - */ - if (fp >= &bStatsFiles[bStatsFilesMax]) { - for (fp = bStatsFiles; fp < &bStatsFiles[B_MAX_FILES]; fp++) { - if (fp->file[0] == '\0') { - gstrncpy(fp->file, name, TSZ(fp->file)); - fp->allocated += size; - fp->count++; - fp->times++; - fp->largest = size; - fp->q = q; - if ((fp - bStatsFiles) >= bStatsFilesMax) { - bStatsFilesMax = (fp - bStatsFiles) + 1; - } - break; - } - } - } - -/* - * Update the per block stats. Allocate a new slot. - */ - for (bp = bStatsBlks; bp < &bStatsBlks[B_MAX_BLOCKS]; bp++) { - if (bp->ptr == NULL) { - bp->ptr = ptr; - bp->who = fp; - if ((bp - bStatsBlks) >= bStatsBlksMax) { - bStatsBlksMax = (bp - bStatsBlks) + 1; - } - break; - } - } -} - -/******************************************************************************/ -/* - * Free statistics - */ - -static void bStatsFree(B_ARGS_DEC, void *ptr, int q, int size) -{ - int memSize; - bStatsFileType *fp; - bStatsBlkType *bp; - - memSize = (1 << (B_SHIFT + q)) + sizeof(bType); - bStatsMemInUse -= size; - bStatsBallocInUse -= memSize; - bStats[q].inuse--; - -/* - * Update the per block stats. Try from the end first - */ - for (bp = &bStatsBlks[bStatsBlksMax - 1]; bp >= bStatsBlks; bp--) { - if (bp->ptr == ptr) { - bp->ptr = NULL; - fp = bp->who; - bp->who = NULL; - fp->allocated -= size; - fp->count--; - return; - } - } -} - -/******************************************************************************/ -/* - * Default output function. Just send to trace channel. - */ - -#undef sprintf -static void bstatsWrite(int handle, char_t *fmt, ...) -{ - va_list args; - char_t buf[BUF_MAX]; - - va_start(args, fmt); - vsprintf(buf, fmt, args); - va_end(args); - traceRaw(buf); -} - - -#else /* not B_STATS */ -/******************************************************************************/ -/* - * Dummy bstats for external calls that aren't protected by #if B_STATS. - */ - -void bstats(int handle, void (*writefn)(int handle, char_t *fmt, ...)) -{ -} -#endif /* B_STATS */ - -/******************************************************************************/ -#ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD -/* - * The following routines verify the integrity of the balloc memory space. - * These functions use the B_FILL feature. Corruption is defined - * as bad integrity flags in allocated blocks or data other than B_FILL_CHAR - * being found anywhere in the space which is unallocated and that is not a - * next pointer in the free queues. a_assert is called if any corruption is - * found. CAUTION: These functions add severe processing overhead and should - * only be used when searching for a tough corruption problem. - */ - -/******************************************************************************/ -/* - * verifyUsedBlock verifies that a block which was previously allocated is - * still uncorrupted. - */ - -static void verifyUsedBlock(bType *bp, int q) -{ - int memSize, size; - char *p; - - memSize = (1 << (B_SHIFT + q)) + sizeof(bType); - a_assert((bp->flags & ~B_MALLOCED) == B_INTEGRITY); - size = bp->u.size; - for (p = ((char *)bp)+sizeof(bType)+size; p < ((char*)bp)+memSize; p++) { - a_assert(*p == B_FILL_CHAR); - } -} - -/******************************************************************************/ -/* - * verifyFreeBlock verifies that a previously free'd block in one of the queues - * is still uncorrupted. - */ - -static void verifyFreeBlock(bType *bp, int q) -{ - int memSize; - char *p; - - memSize = (1 << (B_SHIFT + q)) + sizeof(bType); - for (p = ((char *)bp)+sizeof(void*); p < ((char*)bp)+memSize; p++) { - a_assert(*p == B_FILL_CHAR); - } - bp = (bType *)p; - a_assert((bp->flags & ~B_MALLOCED) == B_INTEGRITY || - bp->flags == B_FILL_WORD); -} - -/******************************************************************************/ -/* - * verifyBallocSpace reads through the entire balloc memory space and - * verifies that all allocated blocks are uncorrupted and that, with the - * exception of free list next pointers, all other unallocated space is - * filled with B_FILL_CHAR. - */ - -void verifyBallocSpace() -{ - int q; - char *p; - bType *bp; - -/* - * First verify all the free blocks. - */ - for (q = 0; q < B_MAX_CLASS; q++) { - for (bp = bQhead[q]; bp != NULL; bp = bp->u.next) { - verifyFreeBlock(bp, q); - } - } - -/* - * Now verify other space - */ - p = bFreeBuf; - while (p < (bFreeBuf + bFreeSize)) { - bp = (bType *)p; - if (bp->u.size > 0xFFFFF) { - p += sizeof(bp->u); - while (p < (bFreeBuf + bFreeSize) && *p == B_FILL_CHAR) { - p++; - } - } else { - a_assert(((bp->flags & ~B_MALLOCED) == B_INTEGRITY) || - bp->flags == B_FILL_WORD); - p += (sizeof(bType) + bp->u.size); - while (p < (bFreeBuf + bFreeSize) && *p == B_FILL_CHAR) { - p++; - } - } - } -} -#endif /* B_VERIFY_CAUSES_SEVERE_OVERHEAD */ - -/******************************************************************************/ - -#else /* NO_BALLOC */ -int bopen(void *buf, int bufsize, int flags) -{ - return 0; -} - -/******************************************************************************/ - -void bclose() -{ -} - -/******************************************************************************/ - -void bstats(int handle, void (*writefn)(int handle, char_t *fmt, ...)) -{ -} - -/******************************************************************************/ - -char_t *bstrdupNoBalloc(char_t *s) -{ -#ifdef UNICODE - if (s) { - return wcsdup(s); - } else { - return wcsdup(T("")); - } -#else - return bstrdupANoBalloc(s); -#endif -} - -/******************************************************************************/ - -char *bstrdupANoBalloc(char *s) -{ - char* buf; - - if (s == NULL) { - s = ""; - } - buf = malloc(strlen(s)+1); - strcpy(buf, s); - return buf; -} - -#endif /* NO_BALLOC */ -/******************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/cgi.c b/c/src/libnetworking/rtems_webserver/cgi.c deleted file mode 100644 index c2328eab6e..0000000000 --- a/c/src/libnetworking/rtems_webserver/cgi.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * cgi.c -- CGI processing (for the GoAhead Web server - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/********************************** Description *******************************/ -/* - * This module implements the /cgi-bin handler. CGI processing differs from - * goforms processing in that each CGI request is executed as a separate - * process, rather than within the webserver process. For each CGI request the - * environment of the new process must be set to include all the CGI variables - * and its standard input and output must be directed to the socket. This - * is done using temporary files. - */ - -/*********************************** Includes *********************************/ -#include "wsIntrn.h" -#ifdef UEMF - #include "uemf.h" -#else - #include "basic/basicInternal.h" -#endif - -/************************************ Locals **********************************/ -typedef struct { /* Struct for CGI tasks which have completed */ - webs_t wp; /* pointer to session websRec */ - char_t *stdIn; /* file desc. for task's temp input fd */ - char_t *stdOut; /* file desc. for task's temp output fd */ - char_t *cgiPath; /* path to executable process file */ - char_t **argp; /* pointer to buf containing argv tokens */ - char_t **envp; /* pointer to array of environment strings */ - int handle; /* process handle of the task */ - long fplacemark; /* seek location for CGI output file */ -} cgiRec; -static cgiRec **cgiList; /* hAlloc chain list of wp's to be closed */ -static int cgiMax; /* Size of hAlloc list */ - -/************************************* Code ***********************************/ - -/* - * Process a form request. Returns 1 always to indicate it handled the URL - */ -int websCgiHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, - char_t *url, char_t *path, char_t* query) -{ - cgiRec *cgip; - sym_t *s; - char_t cgiBuf[FNAMESIZE], *stdIn, *stdOut, cwd[FNAMESIZE]; - char_t *cp, *cgiName, *cgiPath, **argp, **envp, **ep; - int n, envpsize, argpsize, pHandle, cid; - a_assert(websValid(wp)); - a_assert(url && *url); - a_assert(path && *path == '/'); - websStats.cgiHits++; -/* - * Extract the form name and then build the full path name. The form - * name will follow the first '/' in path. - */ - gstrncpy(cgiBuf, path, TSZ(cgiBuf)); - if ((cgiName = gstrchr(&cgiBuf[1], '/')) == NULL) { - websError(wp, 200, T("Missing CGI name")); - return 1; - } - cgiName++; - if ((cp = gstrchr(cgiName, '/')) != NULL) { - *cp = '\0'; - } - fmtAlloc(&cgiPath, FNAMESIZE, T("%s/%s/%s"), websGetDefaultDir(), - CGI_BIN, cgiName); -#ifndef VXWORKS -/* - * See if the file exists and is executable. If not error out. - * Don't do this step for VxWorks, since the module may already - * be part of the OS image, rather than in the file system. - */ - { - 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 (defined (WIN) || defined (CE)) - if (gstrstr(cgiPath, T(".exe")) == NULL && - gstrstr(cgiPath, T(".bat")) == NULL) { -#elif (defined (NW)) - if (gstrstr(cgiPath, T(".nlm")) == NULL) { -#else - if (gaccess(cgiPath, X_OK) != 0) { -#endif /* WIN || CE */ - websError(wp, 200, T("CGI process file is not executable")); - bfree(B_L, cgiPath); - return 1; - } - } -#endif /* ! VXWORKS */ - - -/* - * Get the CWD for resetting after launching the child process CGI - */ - ggetcwd(cwd, FNAMESIZE); -/* - * Retrieve the directory of the child process CGI - */ - if ((cp = gstrrchr(cgiPath, '/')) != NULL) { - *cp = '\0'; - gchdir(cgiPath); - *cp = '/'; - } -/* - * Build command line arguments. Only used if there is no non-encoded - * = character. This is indicative of a ISINDEX query. POST separators - * are & and others are +. argp will point to a balloc'd array of - * pointers. Each pointer will point to substring within the - * query string. This array of string pointers is how the spawn or - * exec routines expect command line arguments to be passed. Since - * we don't know ahead of time how many individual items there are in - * the query string, the for loop includes logic to grow the array - * size via brealloc. - */ - argpsize = 10; - argp = balloc(B_L, argpsize * sizeof(char_t *)); - *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 *)); - } - cp = gstrtok(NULL, T(" ")); - } - } - *(argp+n) = NULL; -/* - * Add all CGI variables to the environment strings to be passed - * to the spawned CGI process. This includes a few we don't - * already have in the symbol table, plus all those that are in - * the cgiVars symbol table. envp will point to a balloc'd array of - * pointers. Each pointer will point to a balloc'd string containing - * the keyword value pair in the form keyword=value. Since we don't - * know ahead of time how many environment strings there will be the - * for loop includes logic to grow the array size via brealloc. - */ - envpsize = WEBS_SYM_INIT; - envp = balloc(B_L, envpsize * sizeof(char_t *)); - 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 *)); - } - } - } - *(envp+n) = NULL; -/* - * Create temporary file name(s) for the child's stdin and stdout. - * For POST data the stdin temp file (and name) should already exist. - */ - if (wp->cgiStdin == NULL) { - wp->cgiStdin = websGetCgiCommName(); - } - stdIn = wp->cgiStdin; - stdOut = websGetCgiCommName(); -/* - * Now launch the process. If not successful, do the cleanup of resources. - * If successful, the cleanup will be done after the process completes. - */ - 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 { -/* - * If the spawn was successful, put this wp on a queue to be - * checked for completion. - */ - cid = hAllocEntry((void***) &cgiList, &cgiMax, sizeof(cgiRec)); - 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); - } -/* - * Restore the current working directory after spawning child CGI - */ - gchdir(cwd); - return 1; -} - - - -/******************************************************************************/ -/* - * Any entry in the cgiList need to be checked to see if it has - */ -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 ); -/* - * Check to see if any data is available in the - * output file and send its contents to the socket. - */ - if (fdout >= 0) { - webs_t wp = cgip->wp; - int nRead; -/* - * Write the HTTP header on our first pass - */ - if (cgip->fplacemark == 0) { - websWrite(wp, T("HTTP/1.0 200 OK\r\n")); - } - glseek(fdout, cgip->fplacemark, SEEK_SET); - while ((nRead = gread(fdout, cgiBuf, FNAMESIZE)) > 0) { - websWriteBlock(wp, cgiBuf, nRead); - cgip->fplacemark += nRead; - } - gclose(fdout); - } - } -} - - - -/******************************************************************************/ -/* - * Any entry in the cgiList need to be checked to see if it has - * completed, and if so, process its output and clean up. - */ -void websCgiCleanup() -{ - cgiRec *cgip; - webs_t wp; - char_t **ep; - int cid, nTries; - for (cid = 0; cid < cgiMax; cid++) { - if ((cgip = cgiList[cid]) != NULL) { - wp = cgip->wp; - websCgiGatherOutput (cgip); - if (websCheckCgiProc(cgip->handle) == 0) { -/* - * We get here if the CGI process has terminated. Clean up. - */ - nTries = 0; -/* - * Make sure we didn't miss something during a task switch. - * Maximum wait is 100 times 10 msecs (1 second). - */ - while ((cgip->fplacemark == 0) && (nTries < 100)) { - websCgiGatherOutput(cgip); -/* - * There are some cases when we detect app exit - * before the file is ready. - */ - if (cgip->fplacemark == 0) { -#ifdef WIN - Sleep(10); -#endif /* WIN*/ - } - nTries++; - } - if (cgip->fplacemark == 0) { - websError(wp, 200, T("CGI generated no output")); - } else { - websDone(wp, 200); - } -/* - * Remove the temporary re-direction files - */ - gunlink(cgip->stdIn); - gunlink(cgip->stdOut); -/* - * Free all the memory buffers pointed to by cgip. - * The stdin file name (wp->cgiStdin) gets freed as - * part of websFree(). - */ - 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); - } - } - } -} -/******************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/default.c b/c/src/libnetworking/rtems_webserver/default.c deleted file mode 100644 index 2dfb2f70b2..0000000000 --- a/c/src/libnetworking/rtems_webserver/default.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * default.c -- Default URL handler. Includes support for ASP. - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/******************************** Description *********************************/ - -/* - * This module provides default URL handling and Active Server Page support. - * - * In many cases we don't check the return code of calls to websWrite as - * it is easier, smaller and non-fatal to continue even when the requesting - * browser has gone away. - */ - -/********************************* Includes ***********************************/ - -#include "wsIntrn.h" - -/*********************************** Locals ***********************************/ - -static char_t *websDefaultPage; /* Default page name */ -static char_t *websDefaultDir; /* Default Web page directory */ - -/**************************** Forward Declarations ****************************/ - -static void websDefaultWriteEvent(webs_t wp); - -/*********************************** Code *************************************/ -/* - * Process a default URL request. This will validate the URL and handle "../" - * and will provide support for Active Server Pages. As the handler is the - * last handler to run, it always indicates that it has handled the URL - * by returning 1. - */ - -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; - - a_assert(websValid(wp)); - a_assert(url && *url); - a_assert(path); - a_assert(query); - -/* - * Validate the URL and ensure that ".."s don't give access to unwanted files - */ - flags = websGetRequestFlags(wp); - - if (websValidateUrl(wp, path) < 0) { - websError(wp, 500, T("Invalid URL %s"), url); - return 1; - } - lpath = websGetRequestLpath(wp); - nchars = gstrlen(lpath) - 1; - if (lpath[nchars] == '/' || lpath[nchars] == '\\') { - lpath[nchars] = '\0'; - } - -/* - * If the file is a directory, redirect using the nominated default page - */ - 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; - } - -/* - * Open the document. Stat for later use. - */ - if (websPageOpen(wp, lpath, path, SOCKET_RDONLY | SOCKET_BINARY, - 0666) < 0) { - websError(wp, 400, T("Cannot open URL %s"), url); - return 1; - } - - if (websPageStat(wp, lpath, path, &sbuf) < 0) { - websError(wp, 400, T("Cannot stat page for URL %s"), url); - return 1; - } - -/* - * If the page has not been modified since the user last received it and it - * is not dynamically generated each time (ASP), then optimize request by - * sending a 304 Use local copy response - */ - 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")); - -/* - * by license terms the following line of code must - * not be modified. - */ - 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 - -/* - * Output the normal HTTP response header - */ - if ((date = websGetDateString(NULL)) != NULL) { - websWrite(wp, T("HTTP/1.0 200 OK\r\nDate: %s\r\n"), date); - -/* - * By license terms the following line of code must not be modified. - */ - websWrite(wp, T("Server: %s\r\n"), WEBS_NAME); - bfree(B_L, date); - } - flags |= WEBS_HEADER_DONE; - -/* - * If this is an ASP request, ensure the remote browser doesn't cache it. - * Send back both HTTP/1.0 and HTTP/1.1 cache control directives - */ - if (flags & WEBS_ASP) { - bytes = 0; - websWrite(wp, T("Pragma: no-cache\r\nCache-Control: no-cache\r\n")); - - } else { - if ((date = websGetDateString(&sbuf)) != NULL) { - websWrite(wp, T("Last-modified: %s\r\n"), date); - bfree(B_L, date); - } - bytes = sbuf.size; - } - - if (bytes) { - 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")); - -/* - * All done if the browser did a HEAD request - */ - if (flags & WEBS_HEAD_REQUEST) { - websDone(wp, 200); - return 1; - } - -/* - * Evaluate ASP requests - */ - if (flags & WEBS_ASP) { - if (websAspRequest(wp, lpath) < 0) { - return 1; - } - websDone(wp, 200); - return 1; - } - -#ifdef WEBS_SSL_SUPPORT - if (wp->flags & WEBS_SECURE) { - websDefaultWriteEvent(wp); - } else { - websSetRequestSocketHandler(wp, SOCKET_WRITABLE, websDefaultWriteEvent); - } -#else -/* - * For normal web documents, return the data via background write - */ - websSetRequestSocketHandler(wp, SOCKET_WRITABLE, websDefaultWriteEvent); -#endif - return 1; -} - -/******************************************************************************/ -/* - * Validate the URL path and process ".." path segments. Return -1 if the URL - * is bad. - */ - -int websValidateUrl(webs_t wp, char_t *path) -{ - char_t *parts[64]; /* 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') { - return -1; - } - -/* - * Copy the string so we don't destroy the original - */ - path = bstrdup(B_L, path); - websDecodeUrl(path, path, gstrlen(path)); - - len = npart = 0; - parts[0] = NULL; - - /* - * 22 Jul 02 -- there were reports that a directory traversal exploit was - * possible in the WebServer running under Windows if directory paths - * outside the server's specified root web were given by URL-encoding the - * backslash character, like: - * - * GoAhead is vulnerable to a directory traversal bug. A request such as - * - * GoAhead-server/../../../../../../../ results in an error message - * 'Cannot open URL'. - - * However, by encoding the '/' character, it is possible to break out of - * the - * web root and read arbitrary files from the server. - * Hence a request like: - * - * GoAhead-server/..%5C..%5C..%5C..%5C..%5C..%5C/winnt/win.ini returns the - * contents of the win.ini file. - * (Note that the description uses forward slashes (0x2F), but the example - * uses backslashes (0x5C). In my tests, forward slashes are correctly - * trapped, but backslashes are not. The code below substitutes forward - * slashes for backslashes before attempting to validate that there are no - * unauthorized paths being accessed. - */ - token = gstrchr(path, '\\'); - while (token != NULL) - { - *token = '/'; - token = gstrchr(token, '\\'); - } - - token = gstrtok(path, T("/")); - -/* - * Look at each directory segment and process "." and ".." segments - * Don't allow the browser to pop outside the root web. - */ - 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("/")); - } - -/* - * Create local path for document. Need extra space all "/" and null. - */ - if (npart || (gstrcmp(path, T("/")) == 0) || (path[0] == '\0')) { - lpath = balloc(B_L, (gstrlen(dir) + 1 + len + 1) * sizeof(char_t)); - 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; -} - -/******************************************************************************/ -/* - * Do output back to the browser in the background. This is a socket - * write handler. - */ - -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); - -/* - * We only do this for non-ASP documents - */ - if ( !(flags & WEBS_ASP)) { - bytes = websGetRequestBytes(wp); -/* - * Note: websWriteDataNonBlock may return less than we wanted. It will - * return -1 on a socket error - */ - if ((buf = balloc(B_L, PAGE_READ_BUFSIZE)) == NULL) { - websError(wp, 200, T("Can't get memory")); - } else { - while ((len = websPageReadData(wp, buf, PAGE_READ_BUFSIZE)) > 0) { - if ((wrote = websWriteDataNonBlock(wp, buf, len)) < 0) { - break; - } - written += wrote; - if (wrote != len) { - websPageSeek(wp, - (len - wrote)); - break; - } - } -/* - * Safety. If we are at EOF, we must be done - */ - if (len == 0) { - a_assert(written >= bytes); - written = bytes; - } - bfree(B_L, buf); - } - } - -/* - * We're done if an error, or all bytes output - */ - websSetRequestWritten(wp, written); - if (wrote < 0 || written >= bytes) { - websDone(wp, 200); - } -} - -/******************************************************************************/ -/* - * Closing down. Free resources. - */ - -void websDefaultClose() -{ - if (websDefaultPage) { - bfree(B_L, websDefaultPage); - websDefaultPage = NULL; - } - if (websDefaultDir) { - bfree(B_L, websDefaultDir); - websDefaultDir = NULL; - } -} - -/******************************************************************************/ -/* - * Get the default page for URL requests ending in "/" - */ - -char_t *websGetDefaultPage() -{ - return websDefaultPage; -} - -/******************************************************************************/ -/* - * Get the default web directory - */ - -char_t *websGetDefaultDir() -{ - return websDefaultDir; -} - -/******************************************************************************/ -/* - * Set the default page for URL requests ending in "/" - */ - -void websSetDefaultPage(char_t *page) -{ - a_assert(page && *page); - - if (websDefaultPage) { - bfree(B_L, websDefaultPage); - } - websDefaultPage = bstrdup(B_L, page); -} - -/******************************************************************************/ -/* - * Set the default web directory - */ - -void websSetDefaultDir(char_t *dir) -{ - a_assert(dir && *dir); - if (websDefaultDir) { - bfree(B_L, websDefaultDir); - } - websDefaultDir = bstrdup(B_L, dir); -} - -/******************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/ej.h b/c/src/libnetworking/rtems_webserver/ej.h deleted file mode 100644 index 879dae91a7..0000000000 --- a/c/src/libnetworking/rtems_webserver/ej.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * ej.h -- Ejscript(TM) header - * - * Copyright (c) GoAhead Software Inc., 1992-2000. All Rights Reserved. - * - * See the file "license.txt" for information on usage and redistribution - * - * $Id$ - */ - -#ifndef _h_EJ -#define _h_EJ 1 - -/******************************** Description *********************************/ - -/* - * GoAhead Ejscript(TM) header. This defines the Ejscript API and internal - * structures. - */ - -/********************************* Includes ***********************************/ - -#ifndef UEMF - #include "basic/basic.h" - #include "emf/emf.h" -#else - #include "uemf.h" -#endif - -/********************************** Defines ***********************************/ - -/******************************** Prototypes **********************************/ - -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)); -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); - -#endif /* _h_EJ */ - -/*****************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/ejIntrn.h b/c/src/libnetworking/rtems_webserver/ejIntrn.h deleted file mode 100644 index 401da17891..0000000000 --- a/c/src/libnetworking/rtems_webserver/ejIntrn.h +++ /dev/null @@ -1,230 +0,0 @@ -/* - * ejIntrn.h -- Ejscript(TM) header - * - * Copyright (c) GoAhead Software, Inc., 1992-2000 - * - * See the file "license.txt" for information on usage and redistribution - * - * $Id$ - */ - -#ifndef _h_EJINTERNAL -#define _h_EJINTERNAL 1 - -/******************************** Description *********************************/ - -/* - * GoAhead Ejscript(TM) header. This defines the Ejscript API and internal - * structures. - */ - -/********************************* Includes ***********************************/ - -#include -#include -#include - -#ifdef CE -#ifndef UEMF - #include -#endif -#endif - -#ifdef LYNX - #include -#endif - -#ifdef QNX4 - #include -#endif - -#ifdef UEMF - #include "uemf.h" -#else - #include - #include - #include "basic/basicInternal.h" - #include "emf/emfInternal.h" -#endif - -#include "ej.h" - -/********************************** Defines ***********************************/ -/* - * Constants - */ -#define EJ_INC 110 /* Growth for tags/tokens */ -#define EJ_SCRIPT_INC 1023 /* Growth for ej scripts */ -#define EJ_OFFSET 1 /* hAlloc doesn't like 0 entries */ -#define EJ_MAX_RECURSE 100 /* Sanity for maximum recursion */ - -/* - * Ejscript Lexical analyser tokens - */ -#define TOK_ERR -1 /* Any error */ -#define TOK_LPAREN 1 /* ( */ -#define TOK_RPAREN 2 /* ) */ -#define TOK_IF 3 /* if */ -#define TOK_ELSE 4 /* else */ -#define TOK_LBRACE 5 /* { */ -#define TOK_RBRACE 6 /* } */ -#define TOK_LOGICAL 7 /* ||, &&, ! */ -#define TOK_EXPR 8 /* +, -, /, % */ -#define TOK_SEMI 9 /* ; */ -#define TOK_LITERAL 10 /* literal string */ -#define TOK_FUNCTION 11 /* function name */ -#define TOK_NEWLINE 12 /* newline white space */ -#define TOK_ID 13 /* function name */ -#define TOK_EOF 14 /* End of script */ -#define TOK_COMMA 15 /* Comma */ -#define TOK_VAR 16 /* var */ -#define TOK_ASSIGNMENT 17 /* = */ -#define TOK_FOR 18 /* for */ -#define TOK_INC_DEC 19 /* ++, -- */ -#define TOK_RETURN 20 /* return */ - -/* - * Expression operators - */ -#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 /* ! */ -/* - * Conditional operators - */ -#define COND_AND 1 /* && */ -#define COND_OR 2 /* || */ -#define COND_NOT 3 /* ! */ - -/* - * States - */ -#define STATE_ERR -1 /* Error state */ -#define STATE_EOF 1 /* End of file */ -#define STATE_COND 2 /* Parsing a "(conditional)" stmt */ -#define STATE_COND_DONE 3 -#define STATE_RELEXP 4 /* Parsing a relational expr */ -#define STATE_RELEXP_DONE 5 -#define STATE_EXPR 6 /* Parsing an expression */ -#define STATE_EXPR_DONE 7 -#define STATE_STMT 8 /* Parsing General statement */ -#define STATE_STMT_DONE 9 -#define STATE_STMT_BLOCK_DONE 10 /* End of block "}" */ -#define STATE_ARG_LIST 11 /* Function arg list */ -#define STATE_ARG_LIST_DONE 12 -#define STATE_DEC_LIST 16 /* Declaration list */ -#define STATE_DEC_LIST_DONE 17 -#define STATE_DEC 18 -#define STATE_DEC_DONE 19 - -#define STATE_RET 20 /* Return statement */ - -#define STATE_BEGIN STATE_STMT - -/* - * Flags. Used in ej_t and as parameter to parse() - */ -#define FLAGS_EXE 0x1 /* Execute statements */ -#define FLAGS_VARIABLES 0x2 /* Allocated variables store */ -#define FLAGS_FUNCTIONS 0x4 /* Allocated function store */ - -/* - * Function call structure - */ -typedef struct { - char_t *fname; /* Function name */ - char_t **args; /* Args for function (halloc) */ - int nArgs; /* Number of args */ -} ejfunc_t; - -/* - * EJ evaluation block structure - */ -typedef struct ejEval { - ringq_t tokbuf; /* Current token */ - ringq_t script; /* Input script for parsing */ - char_t *putBackToken; /* Putback token string */ - int putBackTokenId; /* Putback token ID */ - char_t *line; /* Current line */ - int lineLength; /* Current line length */ - int lineNumber; /* Parse line number */ - int lineColumn; /* Column in line */ -} ejinput_t; - -/* - * Per Ejscript session structure - */ -typedef struct ej { - ejinput_t *input; /* Input evaluation block */ - sym_fd_t functions; /* Symbol table for functions */ - sym_fd_t *variables; /* hAlloc list of variables */ - int variableMax; /* Number of entries */ - ejfunc_t *func; /* Current function */ - char_t *result; /* Current expression result */ - char_t *error; /* Error message */ - char_t *token; /* Pointer to token string */ - int tid; /* Current token id */ - int eid; /* Halloc handle */ - int flags; /* Flags */ - int userHandle; /* User defined handle */ -} ej_t; - -/******************************** Prototypes **********************************/ - -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 sym_fd_t ejGetVariableTable(int eid); -extern sym_fd_t ejGetFunctionTable(int eid); - -extern int ejEmfOpen(int eid); -extern void ejEmfClose(int eid); - -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); - -#endif /* _h_EJINTERNAL */ diff --git a/c/src/libnetworking/rtems_webserver/ejlex.c b/c/src/libnetworking/rtems_webserver/ejlex.c deleted file mode 100644 index 45181d9d83..0000000000 --- a/c/src/libnetworking/rtems_webserver/ejlex.c +++ /dev/null @@ -1,721 +0,0 @@ -/* - * ejlex.c -- Ejscript(TM) Lexical Analyser - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/******************************** Description *********************************/ - -/* - * Ejscript lexical analyser. This implementes a lexical analyser for a - * a subset of the JavaScript language. - */ - -/********************************** Includes **********************************/ - -#include "ejIntrn.h" - -#ifdef UEMF - #include "uemf.h" -#else - #include "basic/basicInternal.h" -#endif - -/********************************** Defines ***********************************/ -#define OCTAL 8 -#define HEX 16 -/****************************** Forward Declarations **************************/ - -static int getLexicalToken(ej_t* ep, int state); -static int tokenAddChar(ej_t *ep, int c); -static int inputGetc(ej_t* ep); -static void inputPutback(ej_t* ep, int c); -static int charConvert(ej_t* ep, int base, int maxDig); - -/************************************* Code ***********************************/ -/* - * Setup the lexical analyser - */ - -int ejLexOpen(ej_t* ep) -{ - return 0; -} - -/******************************************************************************/ -/* - * Close the lexicial analyser - */ - -void ejLexClose(ej_t* ep) -{ -} - -/******************************************************************************/ -/* - * Open a new input script - */ - -int ejLexOpenScript(ej_t* ep, char_t *script) -{ - ejinput_t *ip; - - a_assert(ep); - a_assert(script); - - if ((ep->input = balloc(B_L, sizeof(ejinput_t))) == NULL) { - return -1; - } - ip = ep->input; - memset(ip, 0, sizeof(*ip)); - - a_assert(ip); - a_assert(ip->putBackToken == NULL); - a_assert(ip->putBackTokenId == 0); - -/* - * Create the parse token buffer and script buffer - */ - if (ringqOpen(&ip->tokbuf, EJ_INC, -1) < 0) { - return -1; - } - if (ringqOpen(&ip->script, EJ_SCRIPT_INC, -1) < 0) { - return -1; - } -/* - * Put the Ejscript into a ring queue for easy parsing - */ - ringqPutStr(&ip->script, script); - - ip->lineNumber = 1; - ip->lineLength = 0; - ip->lineColumn = 0; - ip->line = NULL; - - return 0; -} - -/******************************************************************************/ -/* - * Close the input script - */ - -void ejLexCloseScript(ej_t* ep) -{ - ejinput_t *ip; - - a_assert(ep); - - ip = ep->input; - a_assert(ip); - - if (ip->putBackToken) { - bfree(B_L, ip->putBackToken); - ip->putBackToken = NULL; - } - ip->putBackTokenId = 0; - - if (ip->line) { - bfree(B_L, ip->line); - ip->line = NULL; - } - - ringqClose(&ip->tokbuf); - ringqClose(&ip->script); - - bfree(B_L, ip); -} - -/******************************************************************************/ -/* - * Save the input state - */ - -void ejLexSaveInputState(ej_t* ep, ejinput_t* state) -{ - ejinput_t *ip; - - a_assert(ep); - - ip = ep->input; - a_assert(ip); - - *state = *ip; - if (ip->putBackToken) { - state->putBackToken = bstrdup(B_L, ip->putBackToken); - } -} - -/******************************************************************************/ -/* - * Restore the input state - */ - -void ejLexRestoreInputState(ej_t* ep, ejinput_t* state) -{ - ejinput_t *ip; - - a_assert(ep); - - ip = ep->input; - a_assert(ip); - - ip->tokbuf = state->tokbuf; - ip->script = state->script; - ip->putBackTokenId = state->putBackTokenId; - if (ip->putBackToken) { - bfree(B_L, ip->putBackToken); - } - if (state->putBackToken) { - ip->putBackToken = bstrdup(B_L, state->putBackToken); - } -} - -/******************************************************************************/ -/* - * Free a saved input state - */ - -void ejLexFreeInputState(ej_t* ep, ejinput_t* state) -{ - if (state->putBackToken) { - bfree(B_L, state->putBackToken); - state->putBackToken = NULL; - } -} - -/******************************************************************************/ -/* - * Get the next Ejscript token - */ - -int ejLexGetToken(ej_t* ep, int state) -{ - ep->tid = getLexicalToken(ep, state); - /* - * commented out 04 Apr 02 Bg Porter -- we found a case where very long - * arguments to write() were being corrupted downstream in the trace call - * (the ep->token pointer was being overwritten with the trace message. - * restore this if it's useful for your debugging. - trace(9, T("ejGetToken: %d, \"%s\"\n"), ep->tid, ep->token); - */ - return ep->tid; -} - -/******************************************************************************/ -/* - * Get the next Ejscript token - */ - -static int getLexicalToken(ej_t* ep, int state) -{ - ringq_t *inq, *tokq; - ejinput_t* ip; - int done, tid, c, quote, style; - - a_assert(ep); - ip = ep->input; - a_assert(ip); - - inq = &ip->script; - tokq = &ip->tokbuf; - - ep->tid = -1; - tid = -1; - ep->token = T(""); - - ringqFlush(tokq); - - if (ip->putBackTokenId > 0) { - ringqPutStr(tokq, ip->putBackToken); - tid = ip->putBackTokenId; - ip->putBackTokenId = 0; - ep->token = (char_t*) tokq->servp; - return tid; - } - - if ((c = inputGetc(ep)) < 0) { - return TOK_EOF; - } - - for (done = 0; !done; ) { - switch (c) { - case -1: - return TOK_EOF; - - case ' ': - case '\t': - case '\r': - do { - if ((c = inputGetc(ep)) < 0) - break; - } while (c == ' ' || c == '\t' || c == '\r'); - break; - - case '\n': - return TOK_NEWLINE; - - case '(': - tokenAddChar(ep, c); - return TOK_LPAREN; - - case ')': - tokenAddChar(ep, c); - return TOK_RPAREN; - - case '{': - tokenAddChar(ep, c); - return TOK_LBRACE; - - case '}': - tokenAddChar(ep, c); - return TOK_RBRACE; - - case '+': - if ((c = inputGetc(ep)) < 0) { - ejError(ep, T("Syntax Error")); - return TOK_ERR; - } - if (c != '+' ) { - inputPutback(ep, c); - tokenAddChar(ep, EXPR_PLUS); - return TOK_EXPR; - } - tokenAddChar(ep, EXPR_INC); - return TOK_INC_DEC; - - case '-': - if ((c = inputGetc(ep)) < 0) { - ejError(ep, T("Syntax Error")); - return TOK_ERR; - } - if (c != '-' ) { - inputPutback(ep, c); - tokenAddChar(ep, EXPR_MINUS); - return TOK_EXPR; - } - tokenAddChar(ep, EXPR_DEC); - return TOK_INC_DEC; - - case '*': - tokenAddChar(ep, EXPR_MUL); - return TOK_EXPR; - - case '%': - tokenAddChar(ep, EXPR_MOD); - return TOK_EXPR; - - case '/': -/* - * Handle the division operator and comments - */ - if ((c = inputGetc(ep)) < 0) { - ejError(ep, T("Syntax Error")); - return TOK_ERR; - } - if (c != '*' && c != '/') { - inputPutback(ep, c); - tokenAddChar(ep, EXPR_DIV); - return TOK_EXPR; - } - style = c; -/* - * Eat comments. Both C and C++ comment styles are supported. - */ - while (1) { - if ((c = inputGetc(ep)) < 0) { - ejError(ep, T("Syntax Error")); - return TOK_ERR; - } - if (c == '\n' && style == '/') { - break; - } else if (c == '*') { - c = inputGetc(ep); - if (style == '/') { - if (c == '\n') { - break; - } - } else { - if (c == '/') { - break; - } - } - } - } -/* - * Continue looking for a token, so get the next character - */ - if ((c = inputGetc(ep)) < 0) { - return TOK_EOF; - } - break; - - case '<': /* < and <= */ - if ((c = inputGetc(ep)) < 0) { - ejError(ep, T("Syntax Error")); - return TOK_ERR; - } - if (c == '<') { - tokenAddChar(ep, EXPR_LSHIFT); - return TOK_EXPR; - } else if (c == '=') { - tokenAddChar(ep, EXPR_LESSEQ); - return TOK_EXPR; - } - tokenAddChar(ep, EXPR_LESS); - inputPutback(ep, c); - return TOK_EXPR; - - case '>': /* > and >= */ - if ((c = inputGetc(ep)) < 0) { - ejError(ep, T("Syntax Error")); - return TOK_ERR; - } - if (c == '>') { - tokenAddChar(ep, EXPR_RSHIFT); - return TOK_EXPR; - } else if (c == '=') { - tokenAddChar(ep, EXPR_GREATEREQ); - return TOK_EXPR; - } - tokenAddChar(ep, EXPR_GREATER); - inputPutback(ep, c); - return TOK_EXPR; - - case '=': /* "==" */ - if ((c = inputGetc(ep)) < 0) { - ejError(ep, T("Syntax Error")); - return TOK_ERR; - } - if (c == '=') { - tokenAddChar(ep, EXPR_EQ); - return TOK_EXPR; - } - inputPutback(ep, c); - return TOK_ASSIGNMENT; - - case '!': /* "!=" or "!"*/ - if ((c = inputGetc(ep)) < 0) { - ejError(ep, T("Syntax Error")); - return TOK_ERR; - } - if (c == '=') { - tokenAddChar(ep, EXPR_NOTEQ); - return TOK_EXPR; - } - inputPutback(ep, c); - tokenAddChar(ep, EXPR_BOOL_COMP); - return TOK_EXPR; - - case ';': - tokenAddChar(ep, c); - return TOK_SEMI; - - case ',': - tokenAddChar(ep, c); - return TOK_COMMA; - - case '|': /* "||" */ - if ((c = inputGetc(ep)) < 0 || c != '|') { - ejError(ep, T("Syntax Error")); - return TOK_ERR; - } - tokenAddChar(ep, COND_OR); - return TOK_LOGICAL; - - case '&': /* "&&" */ - if ((c = inputGetc(ep)) < 0 || c != '&') { - ejError(ep, T("Syntax Error")); - return TOK_ERR; - } - tokenAddChar(ep, COND_AND); - return TOK_LOGICAL; - - case '\"': /* String quote */ - case '\'': - quote = c; - if ((c = inputGetc(ep)) < 0) { - ejError(ep, T("Syntax Error")); - return TOK_ERR; - } - - while (c != quote) { -/* - * check for escape sequence characters - */ - if (c == '\\') { - c = inputGetc(ep); - - if (gisdigit(c)) { -/* - * octal support, \101 maps to 65 = 'A'. put first char - * back so converter will work properly. - */ - inputPutback(ep, c); - c = charConvert(ep, OCTAL, 3); - - } else { - switch (c) { - case 'n': - c = '\n'; break; - case 'b': - c = '\b'; break; - case 'f': - c = '\f'; break; - case 'r': - c = '\r'; break; - case 't': - c = '\t'; break; - case 'x': -/* - * hex support, \x41 maps to 65 = 'A' - */ - c = charConvert(ep, HEX, 2); - break; - case 'u': -/* - * unicode support, \x0401 maps to 65 = 'A' - */ - c = charConvert(ep, HEX, 2); - c = c*16 + charConvert(ep, HEX, 2); - - break; - case '\'': - case '\"': - case '\\': - break; - default: - ejError(ep, T("Invalid Escape Sequence")); - return TOK_ERR; - } - } - if (tokenAddChar(ep, c) < 0) { - return TOK_ERR; - } - } else { - if (tokenAddChar(ep, c) < 0) { - return TOK_ERR; - } - } - if ((c = inputGetc(ep)) < 0) { - ejError(ep, T("Unmatched Quote")); - return TOK_ERR; - } - } - return TOK_LITERAL; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - do { - if (tokenAddChar(ep, c) < 0) { - return TOK_ERR; - } - if ((c = inputGetc(ep)) < 0) - break; - } while (gisdigit(c)); - inputPutback(ep, c); - return TOK_LITERAL; - - default: -/* - * Identifiers or a function names - */ - while (1) { - if (c == '\\') { -/* - * just ignore any \ characters. - */ - } else if (tokenAddChar(ep, c) < 0) { - break; - } - if ((c = inputGetc(ep)) < 0) { - break; - } - if (!gisalnum(c) && c != '$' && c != '_' && - c != '\\') { - break; - } - } - if (! gisalpha(*tokq->servp) && *tokq->servp != '$' && - *tokq->servp != '_') { - ejError(ep, T("Invalid identifier %s"), tokq->servp); - return TOK_ERR; - } -/* - * Check for reserved words (only "if", "else", "var", "for" - * and "return" at the moment) - */ - if (state == STATE_STMT) { - if (gstrcmp(ep->token, T("if")) == 0) { - return TOK_IF; - } else if (gstrcmp(ep->token, T("else")) == 0) { - return TOK_ELSE; - } else if (gstrcmp(ep->token, T("var")) == 0) { - return TOK_VAR; - } else if (gstrcmp(ep->token, T("for")) == 0) { - return TOK_FOR; - } else if (gstrcmp(ep->token, T("return")) == 0) { - if ((c == ';') || (c == '(')) { - inputPutback(ep, c); - } - return TOK_RETURN; - } - } - -/* - * Skip white space after token to find out whether this is - * a function or not. - */ - while (c == ' ' || c == '\t' || c == '\r' || c == '\n') { - if ((c = inputGetc(ep)) < 0) - break; - } - - tid = (c == '(') ? TOK_FUNCTION : TOK_ID; - done++; - } - } - -/* - * Putback the last extra character for next time - */ - inputPutback(ep, c); - return tid; -} - -/******************************************************************************/ -/* - * Putback the last token read - */ - -void ejLexPutbackToken(ej_t* ep, int tid, char_t *string) -{ - ejinput_t* ip; - - a_assert(ep); - ip = ep->input; - a_assert(ip); - - if (ip->putBackToken) { - bfree(B_L, ip->putBackToken); - } - ip->putBackTokenId = tid; - ip->putBackToken = bstrdup(B_L, string); -} - -/******************************************************************************/ -/* - * Add a character to the token ringq buffer - */ - -static int tokenAddChar(ej_t *ep, int c) -{ - ejinput_t* ip; - - a_assert(ep); - ip = ep->input; - a_assert(ip); - - if (ringqPutc(&ip->tokbuf, (char_t) c) < 0) { - ejError(ep, T("Token too big")); - return -1; - } - * ((char_t*) ip->tokbuf.endp) = '\0'; - ep->token = (char_t*) ip->tokbuf.servp; - - return 0; -} - -/******************************************************************************/ -/* - * Get another input character - */ - -static int inputGetc(ej_t* ep) -{ - ejinput_t *ip; - int c, len; - - a_assert(ep); - ip = ep->input; - - if ((len = ringqLen(&ip->script)) == 0) { - return -1; - } - - c = ringqGetc(&ip->script); - - if (c == '\n') { - ip->lineNumber++; - ip->lineColumn = 0; - } else { - if ((ip->lineColumn + 2) >= ip->lineLength) { - ip->lineLength += EJ_INC; - ip->line = brealloc(B_L, ip->line, ip->lineLength * sizeof(char_t)); - } - ip->line[ip->lineColumn++] = c; - ip->line[ip->lineColumn] = '\0'; - } - return c; -} - -/******************************************************************************/ -/* - * Putback a character onto the input queue - */ - -static void inputPutback(ej_t* ep, int c) -{ - ejinput_t *ip; - - a_assert(ep); - - ip = ep->input; - ringqInsertc(&ip->script, (char_t) c); - ip->lineColumn--; - ip->line[ip->lineColumn] = '\0'; -} - -/******************************************************************************/ -/* - * Convert a hex or octal character back to binary, return original char if - * not a hex digit - */ - -static int charConvert(ej_t* ep, int base, int maxDig) -{ - int i, c, lval, convChar; - - lval = 0; - for (i = 0; i < maxDig; i++) { - if ((c = inputGetc(ep)) < 0) { - break; - } -/* - * Initialize to out of range value - */ - convChar = base; - if (gisdigit(c)) { - convChar = c - '0'; - } else if (c >= 'a' && c <= 'f') { - convChar = c - 'a' + 10; - } else if (c >= 'A' && c <= 'F') { - convChar = c - 'A' + 10; - } -/* - * if unexpected character then return it to buffer. - */ - if (convChar >= base) { - inputPutback(ep, c); - break; - } - lval = (lval * base) + convChar; - } - return lval; -} - -/******************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/ejparse.c b/c/src/libnetworking/rtems_webserver/ejparse.c deleted file mode 100644 index fdbb9c1d8a..0000000000 --- a/c/src/libnetworking/rtems_webserver/ejparse.c +++ /dev/null @@ -1,1804 +0,0 @@ -/* - * ejparse.c -- Ejscript(TM) Parser - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/******************************** Description *********************************/ - -/* - * Ejscript parser. This implementes a subset of the JavaScript language. - * Multiple Ejscript parsers can be opened at a time. - */ - -/********************************** Includes **********************************/ - -#include "ejIntrn.h" - -#ifdef CE - #include "CE/wincompat.h" -#endif - -/********************************** Local Data ********************************/ - -ej_t **ejHandles; /* List of ej handles */ -int ejMax = -1; /* Maximum size of */ - -/****************************** Forward Declarations **************************/ - -#ifndef B_STATS -#define setString(a,b,c) setstring(b,c) -#endif - -static ej_t *ejPtr(int eid); -static void clearString(char_t **ptr); -static void setString(B_ARGS_DEC, char_t **ptr, char_t *s); -static void appendString(char_t **ptr, char_t *s); -static int parse(ej_t *ep, int state, int flags); -static int parseStmt(ej_t *ep, int state, int flags); -static int parseDeclaration(ej_t *ep, int state, int flags); -static int parseArgs(ej_t *ep, int state, int flags); -static int parseCond(ej_t *ep, int state, int flags); -static int parseExpr(ej_t *ep, int state, int flags); -static int evalExpr(ej_t *ep, char_t *lhs, int rel, char_t *rhs); -static int evalCond(ej_t *ep, char_t *lhs, int rel, char_t *rhs); -static int evalFunction(ej_t *ep); -static void freeFunc(ejfunc_t *func); -static void ejRemoveNewlines(ej_t *ep, int state); - -/************************************* Code ***********************************/ -/* - * Initialize a Ejscript engine - */ - -int ejOpenEngine(sym_fd_t variables, sym_fd_t functions) -{ - ej_t *ep; - int eid, vid; - - if ((eid = hAllocEntry((void*) &ejHandles, &ejMax, sizeof(ej_t))) < 0) { - return -1; - } - ep = ejHandles[eid]; - ep->eid = eid; - -/* - * Create a top level symbol table if one is not provided for variables and - * functions. Variables may create other symbol tables for block level - * declarations so we use hAlloc to manage a list of variable tables. - */ - if ((vid = hAlloc((void***) &ep->variables)) < 0) { - ejMax = hFree((void*) &ejHandles, ep->eid); - return -1; - } - if (vid >= ep->variableMax) { - ep->variableMax = vid + 1; - } - - if (variables == -1) { - ep->variables[vid] = symOpen(64) + EJ_OFFSET; - ep->flags |= FLAGS_VARIABLES; - } else { - ep->variables[vid] = variables + EJ_OFFSET; - } - - if (functions == -1) { - ep->functions = symOpen(64); - ep->flags |= FLAGS_FUNCTIONS; - } else { - ep->functions = functions; - } - - ejLexOpen(ep); - -/* - * Define standard constants - */ - ejSetGlobalVar(ep->eid, T("null"), NULL); - -#ifdef EMF - ejEmfOpen(ep->eid); -#endif - return ep->eid; -} - -/******************************************************************************/ -/* - * Close - */ - -void ejCloseEngine(int eid) -{ - ej_t *ep; - int i; - - if ((ep = ejPtr(eid)) == NULL) { - return; - } - -#ifdef EMF - ejEmfClose(eid); -#endif - - bfreeSafe(B_L, ep->error); - ep->error = NULL; - bfreeSafe(B_L, ep->result); - ep->result = NULL; - - ejLexClose(ep); - - for (i = ep->variableMax - 1; i >= 0; i--) { - if (ep->flags & FLAGS_VARIABLES) { - symClose(ep->variables[i] - EJ_OFFSET); - } - ep->variableMax = hFree((void***) &ep->variables, i); - } - - if (ep->flags & FLAGS_FUNCTIONS) { - symClose(ep->functions); - } - - ejMax = hFree((void*) &ejHandles, ep->eid); - bfree(B_L, ep); -} - -#ifndef __NO_EJ_FILE -/******************************************************************************/ -/* - * Evaluate a Ejscript file - */ - -char_t *ejEvalFile(int eid, char_t *path, char_t **emsg) -{ - gstat_t sbuf; - ej_t *ep; - char_t *script, *rs; - char *fileBuf; - int fd; - - a_assert(path && *path); - - if (emsg) { - *emsg = NULL; - } - - if ((ep = ejPtr(eid)) == NULL) { - return NULL; - } - - if ((fd = gopen(path, O_RDONLY | O_BINARY, 0666)) < 0) { - ejError(ep, T("Bad handle %d"), eid); - return NULL; - } - - if (gstat(path, &sbuf) < 0) { - gclose(fd); - ejError(ep, T("Cant stat %s"), path); - return NULL; - } - - if ((fileBuf = balloc(B_L, sbuf.st_size + 1)) == NULL) { - gclose(fd); - ejError(ep, T("Cant malloc %d"), sbuf.st_size); - return NULL; - } - - if (gread(fd, fileBuf, sbuf.st_size) != (int)sbuf.st_size) { - gclose(fd); - bfree(B_L, fileBuf); - ejError(ep, T("Error reading %s"), path); - return NULL; - } - - fileBuf[sbuf.st_size] = '\0'; - gclose(fd); - - if ((script = ballocAscToUni(fileBuf, sbuf.st_size)) == NULL) { - bfree(B_L, fileBuf); - ejError(ep, T("Cant malloc %d"), sbuf.st_size + 1); - return NULL; - } - bfree(B_L, fileBuf); - - rs = ejEvalBlock(eid, script, emsg); - - bfree(B_L, script); - return rs; -} -#endif /* __NO_EJ_FILE */ - -/******************************************************************************/ -/* - * Create a new variable scope block so that consecutive ejEval calls may - * be made with the same varible scope. This space MUST be closed with - * ejCloseBlock when the evaluations are complete. - */ - -int ejOpenBlock(int eid) -{ - ej_t *ep; - int vid; - - if((ep = ejPtr(eid)) == NULL) { - return -1; - } - - if ((vid = hAlloc((void***) &ep->variables)) < 0) { - return -1; - } - - if (vid >= ep->variableMax) { - ep->variableMax = vid + 1; - } - ep->variables[vid] = symOpen(64) + EJ_OFFSET; - return vid; - -} - -/******************************************************************************/ -/* - * Close a variable scope block. The vid parameter is the return value from - * the call to ejOpenBlock - */ - -int ejCloseBlock(int eid, int vid) -{ - ej_t *ep; - - if((ep = ejPtr(eid)) == NULL) { - return -1; - } - symClose(ep->variables[vid] - EJ_OFFSET); - ep->variableMax = hFree((void***) &ep->variables, vid); - return 0; - -} - -/******************************************************************************/ -/* - * Create a new variable scope block and evaluate a script. All variables - * created during this context will be automatically deleted when complete. - */ - -char_t *ejEvalBlock(int eid, char_t *script, char_t **emsg) -{ - char_t* returnVal; - int vid; - - a_assert(script); - - vid = ejOpenBlock(eid); - returnVal = ejEval(eid, script, emsg); - ejCloseBlock(eid, vid); - - return returnVal; -} - -/******************************************************************************/ -/* - * Parse and evaluate a Ejscript. The caller may provide a symbol table to - * use for variables and function definitions. Return char_t pointer on - * success otherwise NULL pointer is returned. - */ - -char_t *ejEval(int eid, char_t *script, char_t **emsg) -{ - ej_t *ep; - ejinput_t *oldBlock; - int state; - void *endlessLoopTest; - int loopCounter; - - - a_assert(script); - - if (emsg) { - *emsg = NULL; - } - - if ((ep = ejPtr(eid)) == NULL) { - return NULL; - } - - setString(B_L, &ep->result, T("")); - -/* - * Allocate a new evaluation block, and save the old one - */ - oldBlock = ep->input; - ejLexOpenScript(ep, script); - -/* - * Do the actual parsing and evaluation - */ - loopCounter = 0; - endlessLoopTest = NULL; - - do { - state = parse(ep, STATE_BEGIN, FLAGS_EXE); - - if (state == STATE_RET) { - state = STATE_EOF; - } -/* - * prevent parser from going into infinite loop. If parsing the same - * line 10 times then fail and report Syntax error. Most normal error - * are caught in the parser itself. - */ - if (endlessLoopTest == ep->input->script.servp) { - if (loopCounter++ > 10) { - state = STATE_ERR; - ejError(ep, T("Syntax error")); - } - } else { - endlessLoopTest = ep->input->script.servp; - loopCounter = 0; - } - } while (state != STATE_EOF && state != STATE_ERR); - - ejLexCloseScript(ep); - -/* - * Return any error string to the user - */ - if (state == STATE_ERR && emsg) { - *emsg = bstrdup(B_L, ep->error); - } - -/* - * Restore the old evaluation block - */ - ep->input = oldBlock; - - if (state == STATE_EOF) { - return ep->result; - } - - if (state == STATE_ERR) { - return NULL; - } - - return ep->result; -} - -/******************************************************************************/ -/* - * Recursive descent parser for Ejscript - */ - -static int parse(ej_t *ep, int state, int flags) -{ - a_assert(ep); - - switch (state) { -/* - * Any statement, function arguments or conditional expressions - */ - case STATE_STMT: - if ((state = parseStmt(ep, state, flags)) != STATE_STMT_DONE && - state != STATE_EOF && state != STATE_STMT_BLOCK_DONE && - state != STATE_RET) { - state = STATE_ERR; - } - break; - - case STATE_DEC: - if ((state = parseStmt(ep, state, flags)) != STATE_DEC_DONE && - state != STATE_EOF) { - state = STATE_ERR; - } - break; - - case STATE_EXPR: - if ((state = parseStmt(ep, state, flags)) != STATE_EXPR_DONE && - state != STATE_EOF) { - state = STATE_ERR; - } - break; - -/* - * Variable declaration list - */ - case STATE_DEC_LIST: - state = parseDeclaration(ep, state, flags); - break; - -/* - * Function argument string - */ - case STATE_ARG_LIST: - state = parseArgs(ep, state, flags); - break; - -/* - * Logical condition list (relational operations separated by &&, ||) - */ - case STATE_COND: - state = parseCond(ep, state, flags); - break; - -/* - * Expression list - */ - case STATE_RELEXP: - state = parseExpr(ep, state, flags); - break; - } - - if (state == STATE_ERR && ep->error == NULL) { - ejError(ep, T("Syntax error")); - } - return state; -} - -/******************************************************************************/ -/* - * Parse any statement including functions and simple relational operations - */ - -static int parseStmt(ej_t *ep, int state, int flags) -{ - ejfunc_t func; - ejfunc_t *saveFunc; - ejinput_t condScript, endScript, bodyScript, incrScript; - char_t *value, *identifier; - int done, expectSemi, thenFlags, elseFlags, tid, cond, forFlags; - int ejVarType; - - a_assert(ep); - -/* - * Set these to NULL, else we try to free them if an error occurs. - */ - endScript.putBackToken = NULL; - bodyScript.putBackToken = NULL; - incrScript.putBackToken = NULL; - condScript.putBackToken = NULL; - - expectSemi = 0; - saveFunc = NULL; - - for (done = 0; !done; ) { - tid = ejLexGetToken(ep, state); - - switch (tid) { - default: - ejLexPutbackToken(ep, TOK_EXPR, ep->token); - done++; - break; - - case TOK_ERR: - state = STATE_ERR; - done++; - break; - - case TOK_EOF: - state = STATE_EOF; - done++; - break; - - case TOK_NEWLINE: - break; - - case TOK_SEMI: -/* - * This case is when we discover no statement and just a lone ';' - */ - if (state != STATE_STMT) { - ejLexPutbackToken(ep, tid, ep->token); - } - done++; - break; - - case TOK_ID: -/* - * This could either be a reference to a variable or an assignment - */ - identifier = NULL; - setString(B_L, &identifier, ep->token); -/* - * Peek ahead to see if this is an assignment - */ - tid = ejLexGetToken(ep, state); - if (tid == TOK_ASSIGNMENT) { - if (parse(ep, STATE_RELEXP, flags) != STATE_RELEXP_DONE) { - clearString(&identifier); - goto error; - } - if (flags & FLAGS_EXE) { - if ( state == STATE_DEC ) { - ejSetLocalVar(ep->eid, identifier, ep->result); - } else { - ejVarType = ejGetVar(ep->eid, identifier, &value); - if (ejVarType > 0) { - ejSetLocalVar(ep->eid, identifier, ep->result); - } else { - ejSetGlobalVar(ep->eid, identifier, ep->result); - } - } - } - - } else if (tid == TOK_INC_DEC ) { - value = NULL; - if (flags & FLAGS_EXE) { - ejVarType = ejGetVar(ep->eid, identifier, &value); - if (ejVarType < 0) { - ejError(ep, T("Undefined variable %s\n"), identifier); - goto error; - } - setString(B_L, &ep->result, value); - if (evalExpr(ep, value, (int) *ep->token, T("1")) < 0) { - state = STATE_ERR; - break; - } - - if (ejVarType > 0) { - ejSetLocalVar(ep->eid, identifier, ep->result); - } else { - ejSetGlobalVar(ep->eid, identifier, ep->result); - } - } - - } else { -/* - * If we are processing a declaration, allow undefined vars - */ - value = NULL; - if (state == STATE_DEC) { - if (ejGetVar(ep->eid, identifier, &value) > 0) { - ejError(ep, T("Variable already declared"), - identifier); - clearString(&identifier); - goto error; - } - ejSetLocalVar(ep->eid, identifier, NULL); - } else { - if ( flags & FLAGS_EXE ) { - if (ejGetVar(ep->eid, identifier, &value) < 0) { - ejError(ep, T("Undefined variable %s\n"), - identifier); - clearString(&identifier); - goto error; - } - } - } - setString(B_L, &ep->result, value); - ejLexPutbackToken(ep, tid, ep->token); - } - clearString(&identifier); - - if (state == STATE_STMT) { - expectSemi++; - } - done++; - break; - - case TOK_LITERAL: -/* - * Set the result to the literal (number or string constant) - */ - setString(B_L, &ep->result, ep->token); - if (state == STATE_STMT) { - expectSemi++; - } - done++; - break; - - case TOK_FUNCTION: -/* - * We must save any current ep->func value for the current stack frame - */ - if (ep->func) { - saveFunc = ep->func; - } - memset(&func, 0, sizeof(ejfunc_t)); - setString(B_L, &func.fname, ep->token); - ep->func = &func; - - setString(B_L, &ep->result, T("")); - if (ejLexGetToken(ep, state) != TOK_LPAREN) { - freeFunc(&func); - goto error; - } - - if (parse(ep, STATE_ARG_LIST, flags) != STATE_ARG_LIST_DONE) { - freeFunc(&func); - ep->func = saveFunc; - goto error; - } -/* - * Evaluate the function if required - */ - if (flags & FLAGS_EXE && evalFunction(ep) < 0) { - freeFunc(&func); - ep->func = saveFunc; - goto error; - } - - freeFunc(&func); - ep->func = saveFunc; - - if (ejLexGetToken(ep, state) != TOK_RPAREN) { - goto error; - } - if (state == STATE_STMT) { - expectSemi++; - } - done++; - break; - - case TOK_IF: - if (state != STATE_STMT) { - goto error; - } - if (ejLexGetToken(ep, state) != TOK_LPAREN) { - goto error; - } -/* - * Evaluate the entire condition list "(condition)" - */ - if (parse(ep, STATE_COND, flags) != STATE_COND_DONE) { - goto error; - } - if (ejLexGetToken(ep, state) != TOK_RPAREN) { - goto error; - } -/* - * This is the "then" case. We need to always parse both cases and - * execute only the relevant case. - */ - if (*ep->result == '1') { - thenFlags = flags; - elseFlags = flags & ~FLAGS_EXE; - } else { - thenFlags = flags & ~FLAGS_EXE; - elseFlags = flags; - } -/* - * Process the "then" case. Allow for RETURN statement - */ - switch (parse(ep, STATE_STMT, thenFlags)) { - case STATE_RET: - return STATE_RET; - case STATE_STMT_DONE: - break; - default: - goto error; - } -/* - * check to see if there is an "else" case - */ - ejRemoveNewlines(ep, state); - tid = ejLexGetToken(ep, state); - if (tid != TOK_ELSE) { - ejLexPutbackToken(ep, tid, ep->token); - done++; - break; - } -/* - * Process the "else" case. Allow for return. - */ - switch (parse(ep, STATE_STMT, elseFlags)) { - case STATE_RET: - return STATE_RET; - case STATE_STMT_DONE: - break; - default: - goto error; - } - done++; - break; - - case TOK_FOR: -/* - * Format for the expression is: - * - * for (initial; condition; incr) { - * body; - * } - */ - if (state != STATE_STMT) { - goto error; - } - if (ejLexGetToken(ep, state) != TOK_LPAREN) { - goto error; - } - -/* - * Evaluate the for loop initialization statement - */ - if (parse(ep, STATE_EXPR, flags) != STATE_EXPR_DONE) { - goto error; - } - if (ejLexGetToken(ep, state) != TOK_SEMI) { - goto error; - } - -/* - * The first time through, we save the current input context just - * to each step: prior to the conditional, the loop increment and the - * loop body. - */ - ejLexSaveInputState(ep, &condScript); - if (parse(ep, STATE_COND, flags) != STATE_COND_DONE) { - goto error; - } - cond = (*ep->result != '0'); - - if (ejLexGetToken(ep, state) != TOK_SEMI) { - goto error; - } - -/* - * Don't execute the loop increment statement or the body first time - */ - forFlags = flags & ~FLAGS_EXE; - ejLexSaveInputState(ep, &incrScript); - if (parse(ep, STATE_EXPR, forFlags) != STATE_EXPR_DONE) { - goto error; - } - if (ejLexGetToken(ep, state) != TOK_RPAREN) { - goto error; - } - -/* - * Parse the body and remember the end of the body script - */ - ejLexSaveInputState(ep, &bodyScript); - if (parse(ep, STATE_STMT, forFlags) != STATE_STMT_DONE) { - goto error; - } - ejLexSaveInputState(ep, &endScript); - -/* - * Now actually do the for loop. Note loop has been rotated - */ - while (cond && (flags & FLAGS_EXE) ) { -/* - * Evaluate the body - */ - ejLexRestoreInputState(ep, &bodyScript); - - switch (parse(ep, STATE_STMT, flags)) { - case STATE_RET: - return STATE_RET; - case STATE_STMT_DONE: - break; - default: - goto error; - } -/* - * Evaluate the increment script - */ - ejLexRestoreInputState(ep, &incrScript); - if (parse(ep, STATE_EXPR, flags) != STATE_EXPR_DONE) { - goto error; - } -/* - * Evaluate the condition - */ - ejLexRestoreInputState(ep, &condScript); - if (parse(ep, STATE_COND, flags) != STATE_COND_DONE) { - goto error; - } - cond = (*ep->result != '0'); - } - ejLexRestoreInputState(ep, &endScript); - done++; - break; - - case TOK_VAR: - if (parse(ep, STATE_DEC_LIST, flags) != STATE_DEC_LIST_DONE) { - goto error; - } - done++; - break; - - case TOK_COMMA: - ejLexPutbackToken(ep, TOK_EXPR, ep->token); - done++; - break; - - case TOK_LPAREN: - if (state == STATE_EXPR) { - if (parse(ep, STATE_RELEXP, flags) != STATE_RELEXP_DONE) { - goto error; - } - if (ejLexGetToken(ep, state) != TOK_RPAREN) { - goto error; - } - return STATE_EXPR_DONE; - } - done++; - break; - - case TOK_RPAREN: - ejLexPutbackToken(ep, tid, ep->token); - return STATE_EXPR_DONE; - - case TOK_LBRACE: -/* - * This handles any code in braces except "if () {} else {}" - */ - if (state != STATE_STMT) { - goto error; - } - -/* - * Parse will return STATE_STMT_BLOCK_DONE when the RBRACE is seen - */ - do { - state = parse(ep, STATE_STMT, flags); - } while (state == STATE_STMT_DONE); - -/* - * Allow return statement. - */ - if (state == STATE_RET) { - return state; - } - - if (ejLexGetToken(ep, state) != TOK_RBRACE) { - goto error; - } - return STATE_STMT_DONE; - - case TOK_RBRACE: - if (state == STATE_STMT) { - ejLexPutbackToken(ep, tid, ep->token); - return STATE_STMT_BLOCK_DONE; - } - goto error; - - case TOK_RETURN: - if (parse(ep, STATE_RELEXP, flags) != STATE_RELEXP_DONE) { - goto error; - } - if (flags & FLAGS_EXE) { - while ( ejLexGetToken(ep, state) != TOK_EOF ); - done++; - return STATE_RET; - } - break; - } - } - - if (expectSemi) { - tid = ejLexGetToken(ep, state); - if (tid != TOK_SEMI && tid != TOK_NEWLINE) { - goto error; - } - -/* - * Skip newline after semi-colon - */ - ejRemoveNewlines(ep, state); - } - -/* - * Free resources and return the correct status - */ -doneParse: - if (tid == TOK_FOR) { - ejLexFreeInputState(ep, &condScript); - ejLexFreeInputState(ep, &incrScript); - ejLexFreeInputState(ep, &endScript); - ejLexFreeInputState(ep, &bodyScript); - } - - if (state == STATE_STMT) { - return STATE_STMT_DONE; - } else if (state == STATE_DEC) { - return STATE_DEC_DONE; - } else if (state == STATE_EXPR) { - return STATE_EXPR_DONE; - } else if (state == STATE_EOF) { - return state; - } else { - return STATE_ERR; - } - -/* - * Common error exit - */ -error: - state = STATE_ERR; - goto doneParse; -} - -/******************************************************************************/ -/* - * Parse variable declaration list - */ - -static int parseDeclaration(ej_t *ep, int state, int flags) -{ - int tid; - - a_assert(ep); - -/* - * Declarations can be of the following forms: - * var x; - * var x, y, z; - * var x = 1 + 2 / 3, y = 2 + 4; - * - * We set the variable to NULL if there is no associated assignment. - */ - - do { - if ((tid = ejLexGetToken(ep, state)) != TOK_ID) { - return STATE_ERR; - } - ejLexPutbackToken(ep, tid, ep->token); - -/* - * Parse the entire assignment or simple identifier declaration - */ - if (parse(ep, STATE_DEC, flags) != STATE_DEC_DONE) { - return STATE_ERR; - } - -/* - * Peek at the next token, continue if comma seen - */ - tid = ejLexGetToken(ep, state); - if (tid == TOK_SEMI) { - return STATE_DEC_LIST_DONE; - } else if (tid != TOK_COMMA) { - return STATE_ERR; - } - } while (tid == TOK_COMMA); - - if (tid != TOK_SEMI) { - return STATE_ERR; - } - return STATE_DEC_LIST_DONE; -} - -/******************************************************************************/ -/* - * Parse function arguments - */ - -static int parseArgs(ej_t *ep, int state, int flags) -{ - int tid, aid; - - a_assert(ep); - - do { - state = parse(ep, STATE_RELEXP, flags); - if (state == STATE_EOF || state == STATE_ERR) { - return state; - } - if (state == STATE_RELEXP_DONE) { - aid = hAlloc((void***) &ep->func->args); - ep->func->args[aid] = bstrdup(B_L, ep->result); - ep->func->nArgs++; - } -/* - * Peek at the next token, continue if more args (ie. comma seen) - */ - tid = ejLexGetToken(ep, state); - if (tid != TOK_COMMA) { - ejLexPutbackToken(ep, tid, ep->token); - } - } while (tid == TOK_COMMA); - - if (tid != TOK_RPAREN && state != STATE_RELEXP_DONE) { - return STATE_ERR; - } - return STATE_ARG_LIST_DONE; -} - -/******************************************************************************/ -/* - * Parse conditional expression (relational ops separated by ||, &&) - */ - -static int parseCond(ej_t *ep, int state, int flags) -{ - char_t *lhs, *rhs; - int tid, operator; - - a_assert(ep); - - setString(B_L, &ep->result, T("")); - rhs = lhs = NULL; - operator = 0; - - do { -/* - * Recurse to handle one side of a conditional. Accumulate the - * left hand side and the final result in ep->result. - */ - state = parse(ep, STATE_RELEXP, flags); - if (state != STATE_RELEXP_DONE) { - state = STATE_ERR; - break; - } - - if (operator > 0) { - setString(B_L, &rhs, ep->result); - if (evalCond(ep, lhs, operator, rhs) < 0) { - state = STATE_ERR; - break; - } - } - setString(B_L, &lhs, ep->result); - - tid = ejLexGetToken(ep, state); - if (tid == TOK_LOGICAL) { - operator = (int) *ep->token; - - } else if (tid == TOK_RPAREN || tid == TOK_SEMI) { - ejLexPutbackToken(ep, tid, ep->token); - state = STATE_COND_DONE; - break; - - } else { - ejLexPutbackToken(ep, tid, ep->token); - } - - } while (state == STATE_RELEXP_DONE); - - if (lhs) { - bfree(B_L, lhs); - } - - if (rhs) { - bfree(B_L, rhs); - } - return state; -} - -/******************************************************************************/ -/* - * Parse expression (leftHandSide operator rightHandSide) - */ - -static int parseExpr(ej_t *ep, int state, int flags) -{ - char_t *lhs, *rhs; - int rel, tid; - - a_assert(ep); - - setString(B_L, &ep->result, T("")); - rhs = lhs = NULL; - rel = 0; - tid = 0; - - do { -/* - * This loop will handle an entire expression list. We call parse - * to evalutate each term which returns the result in ep->result. - */ - if (tid == TOK_LOGICAL) { - if ((state = parse(ep, STATE_RELEXP, flags)) != STATE_RELEXP_DONE) { - state = STATE_ERR; - break; - } - } else { - if ((state = parse(ep, STATE_EXPR, flags)) != STATE_EXPR_DONE) { - state = STATE_ERR; - break; - } - } - - if (rel > 0) { - setString(B_L, &rhs, ep->result); - if (tid == TOK_LOGICAL) { - if (evalCond(ep, lhs, rel, rhs) < 0) { - state = STATE_ERR; - break; - } - } else { - if (evalExpr(ep, lhs, rel, rhs) < 0) { - state = STATE_ERR; - break; - } - } - } - setString(B_L, &lhs, ep->result); - - if ((tid = ejLexGetToken(ep, state)) == TOK_EXPR || - tid == TOK_INC_DEC || tid == TOK_LOGICAL) { - rel = (int) *ep->token; - - } else { - ejLexPutbackToken(ep, tid, ep->token); - state = STATE_RELEXP_DONE; - } - - } while (state == STATE_EXPR_DONE); - - if (rhs) { - bfree(B_L, rhs); - } - - if (lhs) { - bfree(B_L, lhs); - } - - return state; -} - -/******************************************************************************/ -/* - * Evaluate a condition. Implements &&, ||, ! - */ - -static int evalCond(ej_t *ep, char_t *lhs, int rel, char_t *rhs) -{ - char_t buf[16]; - int l, r, lval; - - a_assert(lhs); - a_assert(rhs); - a_assert(rel > 0); - - lval = 0; - if (gisdigit((int)*lhs) && gisdigit((int)*rhs)) { - l = gatoi(lhs); - r = gatoi(rhs); - switch (rel) { - case COND_AND: - lval = l && r; - break; - case COND_OR: - lval = l || r; - break; - default: - ejError(ep, T("Bad operator %d"), rel); - return -1; - } - } else { - if (!gisdigit((int)*lhs)) { - ejError(ep, T("Conditional must be numeric"), lhs); - } else { - ejError(ep, T("Conditional must be numeric"), rhs); - } - } - - stritoa(lval, buf, sizeof(buf)); - setString(B_L, &ep->result, buf); - return 0; -} - -/******************************************************************************/ -/* - * Evaluate an operation - */ - -static int evalExpr(ej_t *ep, char_t *lhs, int rel, char_t *rhs) -{ - char_t *cp, buf[16]; - int numeric, l, r, lval; - - a_assert(lhs); - a_assert(rhs); - a_assert(rel > 0); - -/* - * All of the characters in the lhs and rhs must be numeric - */ - numeric = 1; - for (cp = lhs; *cp; cp++) { - if (!gisdigit((int)*cp)) { - numeric = 0; - break; - } - } - - if (numeric) { - for (cp = rhs; *cp; cp++) { - if (!gisdigit((int)*cp)) { - numeric = 0; - break; - } - } - } - - if (numeric) { - l = gatoi(lhs); - r = gatoi(rhs); - switch (rel) { - case EXPR_PLUS: - lval = l + r; - break; - case EXPR_INC: - lval = l + 1; - break; - case EXPR_MINUS: - lval = l - r; - break; - case EXPR_DEC: - lval = l - 1; - break; - case EXPR_MUL: - lval = l * r; - break; - case EXPR_DIV: - if (r != 0) { - lval = l / r; - } else { - lval = 0; - } - break; - case EXPR_MOD: - if (r != 0) { - lval = l % r; - } else { - lval = 0; - } - break; - case EXPR_LSHIFT: - lval = l << r; - break; - case EXPR_RSHIFT: - lval = l >> r; - break; - case EXPR_EQ: - lval = l == r; - break; - case EXPR_NOTEQ: - lval = l != r; - break; - case EXPR_LESS: - lval = (l < r) ? 1 : 0; - break; - case EXPR_LESSEQ: - lval = (l <= r) ? 1 : 0; - break; - case EXPR_GREATER: - lval = (l > r) ? 1 : 0; - break; - case EXPR_GREATEREQ: - lval = (l >= r) ? 1 : 0; - break; - case EXPR_BOOL_COMP: - lval = (r == 0) ? 1 : 0; - break; - default: - ejError(ep, T("Bad operator %d"), rel); - return -1; - } - - } else { - switch (rel) { - case EXPR_PLUS: - clearString(&ep->result); - appendString(&ep->result, lhs); - appendString(&ep->result, rhs); - return 0; - case EXPR_LESS: - lval = gstrcmp(lhs, rhs) < 0; - break; - case EXPR_LESSEQ: - lval = gstrcmp(lhs, rhs) <= 0; - break; - case EXPR_GREATER: - lval = gstrcmp(lhs, rhs) > 0; - break; - case EXPR_GREATEREQ: - lval = gstrcmp(lhs, rhs) >= 0; - break; - case EXPR_EQ: - lval = gstrcmp(lhs, rhs) == 0; - break; - case EXPR_NOTEQ: - lval = gstrcmp(lhs, rhs) != 0; - break; - case EXPR_INC: - case EXPR_DEC: - case EXPR_MINUS: - case EXPR_DIV: - case EXPR_MOD: - case EXPR_LSHIFT: - case EXPR_RSHIFT: - default: - ejError(ep, T("Bad operator")); - return -1; - } - } - - stritoa(lval, buf, sizeof(buf)); - setString(B_L, &ep->result, buf); - return 0; -} - -/******************************************************************************/ -/* - * Evaluate a function - */ - -static int evalFunction(ej_t *ep) -{ - sym_t *sp; - int (*fn)(int eid, void *handle, int argc, char_t **argv); - - if ((sp = symLookup(ep->functions, ep->func->fname)) == NULL) { - ejError(ep, T("Undefined procedure %s"), ep->func->fname); - return -1; - } - - fn = (int (*)(int, void*, int, char_t**)) sp->content.value.integer; - if (fn == NULL) { - ejError(ep, T("Undefined procedure %s"), ep->func->fname); - return -1; - } - - return (*fn)(ep->eid, (void*) ep->userHandle, ep->func->nArgs, - ep->func->args); -} - -/******************************************************************************/ -/* - * Output a parse ej_error message - */ - -void ejError(ej_t* ep, char_t* fmt, ...) -{ - va_list args; - ejinput_t *ip; - char_t *errbuf, *msgbuf; - - a_assert(ep); - a_assert(fmt); - ip = ep->input; - - va_start(args, fmt); - msgbuf = NULL; - fmtValloc(&msgbuf, E_MAX_ERROR, fmt, args); - va_end(args); - - if (ep && ip) { - fmtAlloc(&errbuf, E_MAX_ERROR, T("%s\n At line %d, line => \n\n%s\n"), - msgbuf, ip->lineNumber, ip->line); - bfreeSafe(B_L, ep->error); - ep->error = errbuf; - } - bfreeSafe(B_L, msgbuf); -} - -/******************************************************************************/ -/* - * Clear a string value - */ - -static void clearString(char_t **ptr) -{ - a_assert(ptr); - - if (*ptr) { - bfree(B_L, *ptr); - } - *ptr = NULL; -} - -/******************************************************************************/ -/* - * Set a string value - */ - -static void setString(B_ARGS_DEC, char_t **ptr, char_t *s) -{ - a_assert(ptr); - - if (*ptr) { - bfree(B_ARGS, *ptr); - } - *ptr = bstrdup(B_ARGS, s); -} - -/******************************************************************************/ -/* - * Append to the pointer value - */ - -static void appendString(char_t **ptr, char_t *s) -{ - int len, oldlen; - - a_assert(ptr); - - if (*ptr) { - len = gstrlen(s); - oldlen = gstrlen(*ptr); - *ptr = brealloc(B_L, *ptr, (len + oldlen + 1) * sizeof(char_t)); - gstrcpy(&(*ptr)[oldlen], s); - } else { - *ptr = bstrdup(B_L, s); - } -} - -/******************************************************************************/ -/* - * Define a function - */ - -int ejSetGlobalFunction(int eid, char_t *name, - int (*fn)(int eid, void *handle, int argc, char_t **argv)) -{ - ej_t *ep; - - if ((ep = ejPtr(eid)) == NULL) { - return -1; - } - return ejSetGlobalFunctionDirect(ep->functions, name, fn); -} - -/******************************************************************************/ -/* - * Define a function directly into the function symbol table. - */ - -int ejSetGlobalFunctionDirect(sym_fd_t functions, char_t *name, - int (*fn)(int eid, void *handle, int argc, char_t **argv)) -{ - if (symEnter(functions, name, valueInteger((long) fn), 0) == NULL) { - return -1; - } - return 0; -} - -/******************************************************************************/ -/* - * Remove ("undefine") a function - */ - -int ejRemoveGlobalFunction(int eid, char_t *name) -{ - ej_t *ep; - - if ((ep = ejPtr(eid)) == NULL) { - return -1; - } - return symDelete(ep->functions, name); -} - -/******************************************************************************/ -/* - * Get a function definition - */ - -void *ejGetGlobalFunction(int eid, char_t *name) -{ - ej_t *ep; - sym_t *sp; - int (*fn)(int eid, void *handle, int argc, char_t **argv); - - if ((ep = ejPtr(eid)) == NULL) { - return NULL; - } - - if ((sp = symLookup(ep->functions, name)) != NULL) { - fn = (int (*)(int, void*, int, char_t**)) sp->content.value.integer; - return (void*) fn; - } - return NULL; -} - -/******************************************************************************/ -/* - * Utility routine to crack Ejscript arguments. Return the number of args - * seen. This routine only supports %s and %d type args. - * - * Typical usage: - * - * if (ejArgs(argc, argv, "%s %d", &name, &age) < 2) { - * error("Insufficient args\n"); - * return -1; - * } - */ - -int ejArgs(int argc, char_t **argv, char_t *fmt, ...) -{ - va_list vargs; - char_t *cp, **sp; - int *ip; - int argn; - - va_start(vargs, fmt); - - if (argv == NULL) { - return 0; - } - - for (argn = 0, cp = fmt; cp && *cp && argv[argn]; ) { - if (*cp++ != '%') { - continue; - } - - switch (*cp) { - case 'd': - ip = va_arg(vargs, int*); - *ip = gatoi(argv[argn]); - break; - - case 's': - sp = va_arg(vargs, char_t**); - *sp = argv[argn]; - break; - - default: -/* - * Unsupported - */ - a_assert(0); - } - argn++; - } - - va_end(vargs); - return argn; -} - -/******************************************************************************/ -/* - * Define the user handle - */ - -void ejSetUserHandle(int eid, int handle) -{ - ej_t *ep; - - if ((ep = ejPtr(eid)) == NULL) { - return; - } - ep->userHandle = handle; -} - -/******************************************************************************/ -/* - * Get the user handle - */ - -int ejGetUserHandle(int eid) -{ - ej_t *ep; - - if ((ep = ejPtr(eid)) == NULL) { - return -1; - } - return ep->userHandle; -} - -/******************************************************************************/ -/* - * Get the current line number - */ - -int ejGetLineNumber(int eid) -{ - ej_t *ep; - - if ((ep = ejPtr(eid)) == NULL) { - return -1; - } - return ep->input->lineNumber; -} - -/******************************************************************************/ -/* - * Set the result - */ - -void ejSetResult(int eid, char_t *s) -{ - ej_t *ep; - - if ((ep = ejPtr(eid)) == NULL) { - return; - } - setString(B_L, &ep->result, s); -} - -/******************************************************************************/ -/* - * Get the result - */ - -char_t *ejGetResult(int eid) -{ - ej_t *ep; - - if ((ep = ejPtr(eid)) == NULL) { - return NULL; - } - return ep->result; -} - -/******************************************************************************/ -/* - * Set a variable. Note: a variable with a value of NULL means declared but - * undefined. The value is defined in the top-most variable frame. - */ - -void ejSetVar(int eid, char_t *var, char_t *value) -{ - ej_t *ep; - value_t v; - - a_assert(var && *var); - - if ((ep = ejPtr(eid)) == NULL) { - return; - } - - if (value == NULL) { - v = valueString(value, 0); - } else { - v = valueString(value, VALUE_ALLOCATE); - } - symEnter(ep->variables[ep->variableMax - 1] - EJ_OFFSET, var, v, 0); -} - -/******************************************************************************/ -/* - * Set a local variable. Note: a variable with a value of NULL means - * declared but undefined. The value is defined in the top-most variable frame. - */ - -void ejSetLocalVar(int eid, char_t *var, char_t *value) -{ - ej_t *ep; - value_t v; - - a_assert(var && *var); - - if ((ep = ejPtr(eid)) == NULL) { - return; - } - - if (value == NULL) { - v = valueString(value, 0); - } else { - v = valueString(value, VALUE_ALLOCATE); - } - symEnter(ep->variables[ep->variableMax - 1] - EJ_OFFSET, var, v, 0); -} - -/******************************************************************************/ -/* - * Set a global variable. Note: a variable with a value of NULL means - * declared but undefined. The value is defined in the global variable frame. - */ - -void ejSetGlobalVar(int eid, char_t *var, char_t *value) -{ - ej_t *ep; - value_t v; - - a_assert(var && *var); - - if ((ep = ejPtr(eid)) == NULL) { - return; - } - - if (value == NULL) { - v = valueString(value, 0); - } else { - v = valueString(value, VALUE_ALLOCATE); - } - symEnter(ep->variables[0] - EJ_OFFSET, var, v, 0); -} - -/******************************************************************************/ -/* - * Get a variable - */ - -int ejGetVar(int eid, char_t *var, char_t **value) -{ - ej_t *ep; - sym_t *sp; - int i; - - a_assert(var && *var); - a_assert(value); - - if ((ep = ejPtr(eid)) == NULL) { - return -1; - } - - i = ep->variableMax - 1; - if ((sp = symLookup(ep->variables[i] - EJ_OFFSET, var)) == NULL) { - i = 0; - if ((sp = symLookup(ep->variables[0] - EJ_OFFSET, var)) == NULL) { - return -1; - } - } - a_assert(sp->content.type == string); - *value = sp->content.value.string; - return i; -} - -/******************************************************************************/ -/* - * Get the variable symbol table - */ - -sym_fd_t ejGetVariableTable(int eid) -{ - ej_t *ep; - - if ((ep = ejPtr(eid)) == NULL) { - return -1; - } - return *ep->variables; -} - -/******************************************************************************/ -/* - * Get the functions symbol table - */ - -sym_fd_t ejGetFunctionTable(int eid) -{ - ej_t *ep; - - if ((ep = ejPtr(eid)) == NULL) { - return -1; - } - return ep->functions; -} - -/******************************************************************************/ -/* - * Free an argument list - */ - -static void freeFunc(ejfunc_t *func) -{ - int i; - - for (i = func->nArgs - 1; i >= 0; i--) { - bfree(B_L, func->args[i]); - func->nArgs = hFree((void***) &func->args, i); - } - - if (func->fname) { - bfree(B_L, func->fname); - func->fname = NULL; - } -} - -/******************************************************************************/ -/* - * Get Ejscript pointer - */ - -static ej_t *ejPtr(int eid) -{ - a_assert(0 <= eid && eid < ejMax); - - if (eid < 0 || eid >= ejMax || ejHandles[eid] == NULL) { - ejError(NULL, T("Bad handle %d"), eid); - return NULL; - } - return ejHandles[eid]; -} - -/******************************************************************************/ -/* - * This function removes any new lines. Used for else cases, etc. - */ -static void ejRemoveNewlines(ej_t *ep, int state) -{ - int tid; - - do { - tid = ejLexGetToken(ep, state); - } while (tid == TOK_NEWLINE); - - ejLexPutbackToken(ep, tid, ep->token); -} - -/******************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/emfdb.c b/c/src/libnetworking/rtems_webserver/emfdb.c deleted file mode 100644 index 708b51106b..0000000000 --- a/c/src/libnetworking/rtems_webserver/emfdb.c +++ /dev/null @@ -1,1050 +0,0 @@ -/* - * emfdb.c -- EMF database compatability functions for GoAhead WebServer. - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/******************************** Description *********************************/ -/* - * Textfile-based database support for WebServer 2.1. - */ - -/********************************* Includes ***********************************/ - -#include "emfdb.h" -#include "wsIntrn.h" - -/********************************* Defines ************************************/ - -#define KEYWORD_TABLE T("TABLE") -#define KEYWORD_ROW T("ROW") - -/*********************************** Locals ***********************************/ - -/* - * Variable to support the basicSet and basicGet functions. - */ - -static char_t *basicProdDir = NULL; -static char_t *basicDefaultDir = T("."); /* Default set to current */ - -/* - * hAlloc chain list of table schemas to be closed - */ - -static int dbMaxTables = 0; -static dbTable_t **dbListTables = NULL; - -/****************************** Forward Declarations **************************/ - -static int crack(char_t *buf, char_t **key, char_t **val); -static char_t *trim(char_t *str); -static int GetColumnIndex(int tid, char_t *colName); - -/******************************************************************************/ -/* - * Add a schema to the module-internal schema database - */ - -int dbRegisterDBSchema(dbTable_t *pTableRegister) -{ - dbTable_t *pTable; - int tid; - - a_assert(pTableRegister); - - trace(4, T("DB: Registering database table <%s>\n"), - pTableRegister->name); - -/* - * Bump up the size of the table array - */ - tid = hAllocEntry((void*) &dbListTables, - &dbMaxTables, sizeof(dbTable_t)); - -/* - * Copy the table schema to the last spot in schema array - */ - a_assert(dbListTables); - pTable = dbListTables[tid]; - a_assert(pTable); - -/* - * Copy the name of the table - */ - pTable->name = bstrdup(B_L, pTableRegister->name); - -/* - * Copy the number of columns - */ - pTable->nColumns = pTableRegister->nColumns; - -/* - * Copy the column definitions - */ - if (pTable->nColumns > 0) { - int i; - pTable->columnNames = balloc(B_L, sizeof(char_t *) * pTable->nColumns); - pTable->columnTypes = balloc(B_L, sizeof(int *) * pTable->nColumns); - - for (i = 0; (i < pTableRegister->nColumns); i++) { - pTable->columnNames[i] = - bstrdup(B_L, pTableRegister->columnNames[i]); - pTable->columnTypes[i] = pTableRegister->columnTypes[i]; - } - - } else { - pTable->columnNames = NULL; - pTable->columnTypes = NULL; - } - -/* - * Zero out the table's data (very important!) - */ - pTable->nRows = 0; - pTable->rows = NULL; - - return 0; -} - -/******************************************************************************/ -/* - * This is provided for compatibility with EMF. Tables are "registered" - * with staticly defined schemas. There is only one did in this package: 0. - */ - -int dbOpen(char_t *tablename, char_t *filename, - int (*gettime)(int did), int flags) -{ - basicProdDir = NULL; - basicDefaultDir = T("."); - dbMaxTables = 0; - dbListTables = NULL; - return 0; -} - -/******************************************************************************/ -/* - * Delete all the rows of the tables, and all of the tables - */ - -void dbClose(int did) -{ - int table, column; - dbTable_t *pTable; - -/* - * Before doing anything, delete all the contents of the database - */ - dbZero(did); - -/* - * Now delete the tables - */ - for (table = 0; table < dbMaxTables; table++) { - pTable = dbListTables[table]; - - if (pTable != NULL) { -/* - * Delete the table schema - */ - if (pTable->nColumns) { - for (column = 0; column < pTable->nColumns; column++) { - bfreeSafe(B_L, pTable->columnNames[column]); - } - bfreeSafe(B_L, pTable->columnNames); - bfreeSafe(B_L, pTable->columnTypes); - } -/* - * Delete the table name - */ - bfreeSafe(B_L, pTable->name); -/* - * Free the table - */ - bfreeSafe(B_L, pTable); - hFree((void *) &dbListTables, table); - } - } - - if (dbListTables) { - bfree(B_L, dbListTables); - } - -/* - * Set the global table list to a safe value - */ - dbListTables = NULL; - dbMaxTables = 0; -} - - -/******************************************************************************/ -/* - * Delete all the data records in all tables - */ - -void dbZero(int did) -{ - int table, row, column, nRows, nColumns; - int *pRow; - dbTable_t *pTable; - -/* - * Delete all data from all tables - */ - for (table = 0; table < dbMaxTables; table++) { - pTable = dbListTables[table]; -/* - * Delete the row data contained within the schema - */ - if (pTable) { - nColumns = pTable->nColumns; - nRows = pTable->nRows; - for (row = 0; row < nRows; row++) { - pRow = pTable->rows[row]; - if (pRow) { -/* - * Only delete the contents of rows not previously deleted! - */ - for (column = 0; column < nColumns; column++) { - if (pTable->columnTypes[column] == T_STRING) { - bfreeSafe(B_L, (char_t *)(pRow[column])); - pRow[column] = (int)NULL; - } - } - - bfreeSafe(B_L, pRow); - hFree((void ***) &pTable->rows, row); - } - } - - pTable->rows = NULL; - pTable->nRows = 0; - } - } -} - -/******************************************************************************/ -/* - * Find the a row in the table with the given string in the given column - */ - -int dbSearchStr(int did, char_t *tablename, - char_t *colName, char_t *value, int flags) -{ - int tid, nRows, nColumns, column; - dbTable_t *pTable; - - a_assert(tablename); - a_assert(colName); - a_assert(value); - - tid = dbGetTableId(0, tablename); - a_assert(tid >= 0); - - if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) { - pTable = dbListTables[tid]; - } else { - return DB_ERR_TABLE_NOT_FOUND; - } - - nColumns = pTable->nColumns; - nRows = pTable->nRows; - column = GetColumnIndex(tid, colName); - a_assert (column >= 0); - - if (column >= 0) { - char_t *compareVal; - int row, *pRow; -/* - * Scan through rows until we find a match. - * Note that some of these rows may be deleted! - */ - row = 0; - while (row < nRows) { - pRow = pTable->rows[row]; - if (pRow) { - compareVal = (char_t *)(pRow[column]); - if (compareVal && (gstrcmp(compareVal, value) == 0)) { - return row; - } - } - row++; - } - } else { -/* - * Return -2 if search column was not found - */ - trace(3, T("DB: Unable to find column <%s> in table <%s>\n"), - colName, tablename); - return DB_ERR_COL_NOT_FOUND; - } - - return -1; -} - -/******************************************************************************/ -/* - * Add a new row to the given table. Return the new row ID. - */ - -int dbAddRow(int did, char_t *tablename) -{ - int tid, size; - dbTable_t *pTable; - - a_assert(tablename); - - tid = dbGetTableId(0, tablename); - a_assert(tid >= 0); - - if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) { - pTable = dbListTables[tid]; - } else { - return DB_ERR_TABLE_NOT_FOUND; - } - - a_assert(pTable); - - if (pTable) { - trace(5, T("DB: Adding a row to table <%s>\n"), tablename); - - size = pTable->nColumns * max(sizeof(int), sizeof(char_t *)); - return hAllocEntry((void***) &(pTable->rows), &(pTable->nRows), size); - } - - return -1; -} - -/******************************************************************************/ -/* - * Delete a row in the table. - */ - -int dbDeleteRow(int did, char_t *tablename, int row) -{ - int tid, nColumns, nRows; - dbTable_t *pTable; - - a_assert(tablename); - tid = dbGetTableId(0, tablename); - a_assert(tid >= 0); - - if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) { - pTable = dbListTables[tid]; - } else { - return DB_ERR_TABLE_NOT_FOUND; - } - - nColumns = pTable->nColumns; - nRows = pTable->nRows; - - if ((row >= 0) && (row < nRows)) { - int *pRow = pTable->rows[row]; - - if (pRow) { - int column = 0; -/* - * Free up any allocated strings - */ - while (column < nColumns) { - if (pRow[column] && - (pTable->columnTypes[column] == T_STRING)) { - bfree(B_L, (char_t *)pRow[column]); - } - - column++; - } -/* - * Zero out the row for safety - */ - memset(pRow, 0, nColumns * max(sizeof(int), sizeof(char_t *))); - - bfreeSafe(B_L, pRow); - pTable->nRows = hFree((void ***)&pTable->rows, row); - trace(5, T("DB: Deleted row <%d> from table <%s>\n"), - row, tablename); - } - return 0; - } else { - trace(3, T("DB: Unable to delete row <%d> from table <%s>\n"), - row, tablename); - } - - return -1; -} - -/*****************************************************************************/ -/* - * Grow the rows in the table to the nominated size. - */ - -int dbSetTableNrow(int did, char_t *tablename, int nNewRows) -{ - int nRet, tid, nRows, nColumns; - dbTable_t *pTable; - - a_assert(tablename); - tid = dbGetTableId(0, tablename); - a_assert(tid >= 0) ; - - if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) { - pTable = dbListTables[tid]; - } else { - return DB_ERR_TABLE_NOT_FOUND; - } - - nRet = -1; - - a_assert(pTable); - if (pTable) { - nColumns = pTable->nColumns; - nRows = pTable->nRows; - nRet = 0; - - if (nRows >= nNewRows) { -/* - * If number of rows already allocated exceeds requested number, do nothing - */ - trace(4, T("DB: Ignoring row set to <%d> in table <%s>\n"), - nNewRows, tablename); - } else { - trace(4, T("DB: Setting rows to <%d> in table <%s>\n"), - nNewRows, tablename); - while (pTable->nRows < nNewRows) { - if (dbAddRow(did, tablename) < 0) { - return -1; - } - } - } - } - - return nRet; -} - -/******************************************************************************/ -/* - * Return the number of rows in the given table - */ - -int dbGetTableNrow(int did, char_t *tablename) -{ - int tid; - - a_assert(tablename); - tid = dbGetTableId(did, tablename); - - if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) { - return (dbListTables[tid])->nRows; - } else { - return -1; - } -} - -/******************************************************************************/ -/* - * Do table driven read of the database - */ - -int dbReadInt(int did, char_t *table, char_t *column, int row, int *returnValue) -{ - int colIndex, *pRow, tid; - dbTable_t *pTable; - - a_assert(table); - a_assert(column); - a_assert(returnValue); - - tid = dbGetTableId(0, table); - a_assert(tid >= 0); - -/* - * Return -6 if table is not found - */ - if (tid < 0) { - return DB_ERR_TABLE_NOT_FOUND; - } - -/* - * Return -7 if table id has been deleted - */ - pTable = dbListTables[tid]; - if (pTable == NULL) { - return DB_ERR_TABLE_DELETED; - } - - a_assert(row >= 0); - - if ((row >= 0) && (row < pTable->nRows)) { - colIndex = GetColumnIndex(tid, column); - a_assert(colIndex >= 0); - - if (colIndex >= 0) { - pRow = pTable->rows[row]; - if (pRow) { - *returnValue = pRow[colIndex]; - return 0; - } - return DB_ERR_ROW_DELETED; - } - return DB_ERR_COL_NOT_FOUND; - } - - return DB_ERR_ROW_NOT_FOUND; -} - -/******************************************************************************/ -/* - * dbReadStr calls dbReadInt to do table driven read of database - */ - -int dbReadStr(int did, char_t *table, char_t *column, int row, - char_t **returnValue) -{ - return dbReadInt(did, table, column, row, (int *)returnValue); -} - -/******************************************************************************/ -/* - * The dbWriteInt function writes a value into a table at a given row and - * column. The existence of the row and column is verified before the - * write. 0 is returned on succes, -1 is returned on error. - */ - -int dbWriteInt(int did, char_t *table, char_t *column, int row, int iData) -{ - int tid, colIndex, *pRow; - dbTable_t *pTable; - - a_assert(table); - a_assert(column); - -/* - * Make sure that this table exists - */ - tid = dbGetTableId(0, table); - a_assert(tid >= 0); - - if (tid < 0) { - return DB_ERR_TABLE_NOT_FOUND; - } - - pTable = dbListTables[tid]; - - if (pTable) { -/* - * Make sure that the column exists - */ - colIndex = GetColumnIndex(tid, column); - a_assert(colIndex >= 0); - if (colIndex >= 0) { -/* - * Make sure that the row exists - */ - a_assert((row >= 0) && (row < pTable->nRows)); - if ((row >= 0) && (row < pTable->nRows)) { - pRow = pTable->rows[row]; - if (pRow) { - pRow[colIndex] = iData; - return 0; - } - return DB_ERR_ROW_DELETED; - } - return DB_ERR_ROW_NOT_FOUND; - } - return DB_ERR_COL_NOT_FOUND; - } - - return DB_ERR_TABLE_DELETED; -} - -/******************************************************************************/ -/* - * The dbWriteStr function writes a string value into a table at a given row - * and column. The existence of the row and column is verified before the - * write. The column is also checked to confirm it is a string field. - * 0 is returned on succes, -1 is returned on error. - */ - -int dbWriteStr(int did, char_t *table, char_t *column, int row, char_t *s) -{ - int tid, colIndex; - int *pRow; - char_t *ptr; - dbTable_t *pTable; - - a_assert(table); - a_assert(column); - - tid = dbGetTableId(0, table); - a_assert(tid >= 0); - - if (tid < 0) { - return DB_ERR_TABLE_NOT_FOUND; - } - -/* - * Make sure that this table exists - */ - pTable = dbListTables[tid]; - a_assert(pTable); - if (!pTable) { - return DB_ERR_TABLE_DELETED; - } - -/* - * Make sure that this column exists - */ - colIndex = GetColumnIndex(tid, column); - if (colIndex < 0) { - return DB_ERR_COL_NOT_FOUND; - } - -/* - * Make sure that this column is a string column - */ - if (pTable->columnTypes[colIndex] != T_STRING) { - return DB_ERR_BAD_FORMAT; - } - -/* - * Make sure that the row exists - */ - a_assert((row >= 0) && (row < pTable->nRows)); - if ((row >= 0) && (row < pTable->nRows)) { - pRow = pTable->rows[row]; - } else { - return DB_ERR_ROW_NOT_FOUND; - } - - if (!pRow) { - return DB_ERR_ROW_DELETED; - } - -/* - * If the column already has a value, be sure to delete it to prevent - * memory leaks. - */ - if (pRow[colIndex]) { - bfree(B_L, (char_t *) pRow[colIndex]); - } - -/* - * Make sure we make a copy of the string to write into the column. - * This allocated string will be deleted when the row is deleted. - */ - ptr = bstrdup(B_L, s); - pRow[colIndex] = (int)ptr; - - return 0; -} - -/******************************************************************************/ -/* - * Print a key-value pair to a file - */ - -static int dbWriteKeyValue(int fd, char_t *key, char_t *value) -{ - int rc; - int len; - char_t *pLineOut; - - a_assert(key && *key); - a_assert(value); - - fmtAlloc(&pLineOut, BUF_MAX, T("%s=%s\n"), key, value); - - if (pLineOut) { - len = gstrlen(pLineOut); -#ifdef CE - rc = writeUniToAsc(fd, pLineOut, len); -#else - rc = gwrite(fd, pLineOut, len); -#endif - bfree(B_L, pLineOut); - } else { - rc = -1; - } - - return rc; -} - -/******************************************************************************/ -/* - * Persist a database to a file - */ - -int dbSave(int did, char_t *filename, int flags) -{ - int row, column, nColumns, nRows, fd, rc; - int *colTypes, *pRow, nRet, tid; - char_t *path, *tmpFile, *tmpNum; - char_t **colNames; - dbTable_t *pTable; - - trace(5, T("DB: About to save database to file\n")); - - a_assert(dbMaxTables > 0); - -/* - * First write to a temporary file, then switch around later. - */ - fmtAlloc(&tmpFile, FNAMESIZE, T("%s/data.tmp"), basicGetProductDir()); - if ((fd = gopen(tmpFile, - O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0666)) < 0) { - trace(1, T("WARNING: Failed to open file %s\n"), tmpFile); - bfree(B_L, tmpFile); - return -1; - } - - nRet = 0; - - for (tid = 0; (tid < dbMaxTables) && (nRet != -1); tid++) { - pTable = dbListTables[tid]; - - if (pTable) { -/* - * Print the TABLE=tableName directive to the file - */ - rc = dbWriteKeyValue(fd, KEYWORD_TABLE, pTable->name); - - nColumns = pTable->nColumns; - nRows = pTable->nRows; - - for (row = 0; (row < nRows) && (nRet == 0); row++) { - pRow = pTable->rows[row]; -/* - * if row is NULL, the row has been deleted, so don't - * write it out. - */ - if ((pRow == NULL) || (pRow[0] == '\0') || - (*(char_t *)(pRow[0]) == '\0')) { - continue; - } -/* - * Print the ROW=rowNumber directive to the file - */ - fmtAlloc(&tmpNum, 20, T("%d"), row); - rc = dbWriteKeyValue(fd, KEYWORD_ROW, tmpNum); - bfreeSafe(B_L, tmpNum); - - colNames = pTable->columnNames; - colTypes = pTable->columnTypes; -/* - * Print the key-value pairs (COLUMN=value) for data cells - */ - for (column = 0; (column < nColumns) && (rc >= 0); - column++, colNames++, colTypes++) { - if (*colTypes == T_STRING) { - rc = dbWriteKeyValue(fd, *colNames, - (char_t *)(pRow[column])); - } else { - fmtAlloc(&tmpNum, 20, T("%d"), pRow[column]); - rc = dbWriteKeyValue(fd, *colNames, tmpNum); - bfreeSafe(B_L, tmpNum); - } - } - - if (rc < 0) { - trace(1, T("WARNING: Failed to write to file %s\n"), - tmpFile); - nRet = -1; - } - } - } - } - - gclose(fd); - -/* - * Replace the existing file with the temporary file, if no errors - */ - if (nRet == 0) { - fmtAlloc(&path, FNAMESIZE, T("%s/%s"), basicGetProductDir(), filename); - - gunlink(path); - if (grename(tmpFile, path) != 0) { - trace(1, T("WARNING: Failed to rename %s to %s\n"), tmpFile, path); - nRet = -1; - } - - bfree(B_L, path); - } - - bfree(B_L, tmpFile); - - return nRet; -} - -/******************************************************************************/ -/* - * Crack a keyword=value string into keyword and value. We can change buf. - */ - -static int crack(char_t *buf, char_t **key, char_t **val) -{ - char_t *ptr; - - if ((ptr = gstrrchr(buf, '\n')) != NULL || - (ptr = gstrrchr(buf, '\r')) != NULL) { - *ptr = '\0'; - } - -/* - * Find the = sign. It must exist. - */ - if ((ptr = gstrstr(buf, T("="))) == NULL) { - return -1; - } - - *ptr++ = '\0'; - *key = trim(buf); - *val = trim(ptr); - - return 0; -} - -/******************************************************************************/ -/* - * Parse the file. These files consist of key-value pairs, separated by the - * "=" sign. Parsing of tables starts with the "TABLE=value" pair, and rows - * are parsed starting with the "ROW=value" pair. - */ - -int dbLoad(int did, char_t *filename, int flags) -{ - gstat_t sbuf; - char_t *buf, *keyword, *value, *path, *ptr; - char_t *tablename; - int fd, tid, row; - dbTable_t *pTable; - - a_assert(did >= 0); - - fmtAlloc(&path, FNAMESIZE, T("%s/%s"), basicGetProductDir(), filename); - trace(4, T("DB: About to read data file <%s>\n"), path); - - if (gstat(path, &sbuf) < 0) { - trace(3, T("DB: Failed to stat persistent data file.\n")); - bfree(B_L, path); - return -1; - } - - fd = gopen(path, O_RDONLY | O_BINARY, 0666); - bfree(B_L, path); - - if (fd < 0) { - trace(3, T("DB: No persistent data file present.\n")); - return -1; - } - - if (sbuf.st_size <= 0) { - trace(3, T("DB: Persistent data file is empty.\n")); - gclose(fd); - return -1; - } -/* - * Read entire file into temporary buffer - */ - buf = balloc(B_L, sbuf.st_size + 1); -#ifdef CE - if (readAscToUni(fd, &buf, sbuf.st_size) != (int)sbuf.st_size) { -#else - if (gread(fd, buf, sbuf.st_size) != (int)sbuf.st_size) { -#endif - trace(3, T("DB: Persistent data read failed.\n")); - bfree(B_L, buf); - gclose(fd); - return -1; - } - - gclose(fd); - *(buf + sbuf.st_size) = '\0'; - - row = -1; - tid = -1; - pTable = NULL; - ptr = gstrtok(buf, T("\n")); - tablename = NULL; - - do { - if (crack(ptr, &keyword, &value) < 0) { - trace(5, T("DB: Failed to crack line %s\n"), ptr); - continue; - } - - a_assert(keyword && *keyword); - - if (gstrcmp(keyword, KEYWORD_TABLE) == 0) { -/* - * Table name found, check to see if it's registered - */ - if (tablename) { - bfree(B_L, tablename); - } - - tablename = bstrdup(B_L, value); - tid = dbGetTableId(did, tablename); - - if (tid >= 0) { - pTable = dbListTables[tid]; - } else { - pTable = NULL; - } - - } else if (gstrcmp(keyword, KEYWORD_ROW) == 0) { -/* - * Row/Record indicator found, add a new row to table - */ - if (tid >= 0) { - int nRows = dbGetTableNrow(did, tablename); - - if (dbSetTableNrow(did, tablename, nRows + 1) == 0) { - row = nRows; - } - } - - } else if (row != -1) { -/* - * some other data found, assume it's a COLUMN=value - */ - int nColumn = GetColumnIndex(tid, keyword); - - if ((nColumn >= 0) && (pTable != NULL)) { - int nColumnType = pTable->columnTypes[nColumn]; - if (nColumnType == T_STRING) { - dbWriteStr(did, tablename, keyword, row, value); - } else { - dbWriteInt(did, tablename, keyword, row, gstrtoi(value)); - } - } - } - } while ((ptr = gstrtok(NULL, T("\n"))) != NULL); - - if (tablename) { - bfree(B_L, tablename); - } - - bfree(B_L, buf); - - return 0; -} - -/******************************************************************************/ -/* - * Return a table id given the table name - */ - -int dbGetTableId(int did, char_t *tablename) -{ - int tid; - dbTable_t *pTable; - - a_assert(tablename); - - for (tid = 0; (tid < dbMaxTables); tid++) { - if ((pTable = dbListTables[tid]) != NULL) { - if (gstrcmp(tablename, pTable->name) == 0) { - return tid; - } - } - } - - return -1; -} - -/******************************************************************************/ -/* - * Return a pointer to the table name, given its ID - */ - -char_t *dbGetTableName(int did, int tid) -{ - if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) { - return (dbListTables[tid])->name; - } - - return NULL; -} - -/******************************************************************************/ -/* - * Trim leading white space. - */ - -static char_t *trim(char_t *str) -{ - while (isspace((int)*str)) { - str++; - } - return str; -} - -/******************************************************************************/ -/* - * Return a column index given the column name - */ - -static int GetColumnIndex(int tid, char_t *colName) -{ - int column; - dbTable_t *pTable; - - a_assert(colName); - - if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) { - pTable = dbListTables[tid]; - - for (column = 0; (column < pTable->nColumns); column++) { - if (gstrcmp(colName, pTable->columnNames[column]) == 0) - return column; - } - } - - return -1; -} - -/******************************************************************************/ -/* - * Set the prefix-directory - */ - -void basicSetProductDir(char_t *proddir) -{ - int len; - - if (basicProdDir != NULL) { - bfree(B_L, basicProdDir); - } - - basicProdDir = bstrdup(B_L, proddir); -/* - * Make sure that prefix-directory doesn't end with a '/' - */ - len = gstrlen(basicProdDir); - if ((len > 0) && *(basicProdDir + len - 1) == '/') { - *(basicProdDir+len-1) = '\0'; - } -} - -/******************************************************************************/ -/* - * Return the prefix-directory - */ - -char_t *basicGetProductDir() -{ - if (basicProdDir) { - return basicProdDir; - } else { - return basicDefaultDir; - } -} - -/******************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/emfdb.h b/c/src/libnetworking/rtems_webserver/emfdb.h deleted file mode 100644 index 882c1c80d2..0000000000 --- a/c/src/libnetworking/rtems_webserver/emfdb.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * emfdb.h -- EMF database compatability functions for GoAhead WebServer. - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/******************************** Description *********************************/ -/* - * Emf-like textfile database support for WebServer 2.1. - */ - -/********************************* Includes ***********************************/ - -#ifndef _h_EMFDB -#define _h_EMFDB 1 - -#ifndef UEMF - #include "basic/basic.h" - #include "emf/emf.h" -#else - #include "uemf.h" -#endif - - -/********************************* Defines ************************************/ - -#define T_INT 0 -#define T_STRING 1 - -#define DB_OK 0 -#define DB_ERR_GENERAL -1 -#define DB_ERR_COL_NOT_FOUND -2 -#define DB_ERR_COL_DELETED -3 -#define DB_ERR_ROW_NOT_FOUND -4 -#define DB_ERR_ROW_DELETED -5 -#define DB_ERR_TABLE_NOT_FOUND -6 -#define DB_ERR_TABLE_DELETED -7 -#define DB_ERR_BAD_FORMAT -8 - -typedef struct dbTable_s { - char_t *name; - int nColumns; - char_t **columnNames; - int *columnTypes; - int nRows; - int **rows; -} dbTable_t; - -/********************************** Prototypes ********************************/ - -/* - * Add a schema to the module-internal schema database - */ -extern int dbRegisterDBSchema(dbTable_t *sTable); - -extern int dbOpen(char_t *databasename, char_t *filename, - int (*gettime)(int did), int flags); -extern void dbClose(int did); -extern int dbGetTableId(int did, char_t *tname); -extern char_t *dbGetTableName(int did, int tid); -extern int dbReadInt(int did, char_t *table, char_t *column, int row, - int *returnValue); -extern int dbReadStr(int did, char_t *table, char_t *column, int row, - char_t **returnValue); -extern int dbWriteInt(int did, char_t *table, char_t *column, int row, - int idata); -extern int dbWriteStr(int did, char_t *table, char_t *column, int row, - char_t *s); -extern int dbAddRow(int did, char_t *table); -extern int dbDeleteRow(int did, char_t *table, int rid); -extern int dbSetTableNrow(int did, char_t *table, int nNewRows); -extern int dbGetTableNrow(int did, char_t *table); - -/* - * Dump the contents of a database to file - */ -extern int dbSave(int did, char_t *filename, int flags); - -/* - * Load the contents of a database to file - */ -extern int dbLoad(int did, char_t *filename, int flags); - -/* - * Search for a data in a given column - */ -extern int dbSearchStr(int did, char_t *table, char_t *column, - char_t *value, int flags); - -extern void dbZero(int did); - -extern char_t *basicGetProductDir(); -extern void basicSetProductDir(char_t *proddir); - -#endif /* _h_EMFDB */ - -/******************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/form.c b/c/src/libnetworking/rtems_webserver/form.c deleted file mode 100644 index 501cea72e2..0000000000 --- a/c/src/libnetworking/rtems_webserver/form.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * form.c -- Form processing (in-memory CGI) for the GoAhead Web server - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/********************************** Description *******************************/ - -/* - * This module implements the /goform handler. It emulates CGI processing - * but performs this in-process and not as an external process. This enables - * a very high performance implementation with easy parsing and decoding - * of query strings and posted data. - */ - -/*********************************** Includes *********************************/ - -#include "wsIntrn.h" - -/************************************ Locals **********************************/ - -static sym_fd_t formSymtab = -1; /* Symbol table for form handlers */ - -/************************************* Code ***********************************/ -/* - * Process a form request. Returns 1 always to indicate it handled the URL - */ - -int websFormHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, - char_t *url, char_t *path, char_t *query) -{ - sym_t *sp; - char_t formBuf[FNAMESIZE]; - char_t *cp, *formName; - int (*fn)(void *sock, char_t *path, char_t *args); - - a_assert(websValid(wp)); - a_assert(url && *url); - a_assert(path && *path == '/'); - - websStats.formHits++; - -/* - * Extract the form name - */ - gstrncpy(formBuf, path, TSZ(formBuf)); - if ((formName = gstrchr(&formBuf[1], '/')) == NULL) { - websError(wp, 200, T("Missing form name")); - return 1; - } - formName++; - if ((cp = gstrchr(formName, '/')) != NULL) { - *cp = '\0'; - } - -/* - * Lookup the C form function first and then try tcl (no javascript support - * yet). - */ - sp = symLookup(formSymtab, formName); - if (sp == NULL) { - websError(wp, 200, T("Form %s is not defined"), formName); - } else { - fn = (int (*)(void *, char_t *, char_t *)) sp->content.value.integer; - a_assert(fn); - if (fn) { -/* - * For good practice, forms must call websDone() - */ - (*fn)((void*) wp, formName, query); - -/* - * Remove the test to force websDone, since this prevents - * the server "push" from a form> - */ -#if 0 /* push */ - if (websValid(wp)) { - websError(wp, 200, T("Form didn't call websDone")); - } -#endif /* push */ - } - } - return 1; -} - -/******************************************************************************/ -/* - * Define a form function in the "form" map space. - */ - -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; -} - -/******************************************************************************/ -/* - * Open the symbol table for forms. - */ - -void websFormOpen() -{ - formSymtab = symOpen(WEBS_SYM_INIT); -} - -/******************************************************************************/ -/* - * Close the symbol table for forms. - */ - -void websFormClose() -{ - if (formSymtab != -1) { - symClose(formSymtab); - formSymtab = -1; - } -} - -/******************************************************************************/ -/* - * Write a webs header. This is a convenience routine to write a common - * header for a form back to the browser. - */ - -void websHeader(webs_t wp) -{ - a_assert(websValid(wp)); - - websWrite(wp, T("HTTP/1.0 200 OK\n")); - -/* - * By license terms the following line of code must not be modified - */ - websWrite(wp, T("Server: %s\r\n"), WEBS_NAME); - - 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("\n")); -} - -/******************************************************************************/ -/* - * Write a webs footer - */ - -void websFooter(webs_t wp) -{ - a_assert(websValid(wp)); - - websWrite(wp, T("\n")); -} - -/******************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/h.c b/c/src/libnetworking/rtems_webserver/h.c deleted file mode 100644 index 35b0bbbae6..0000000000 --- a/c/src/libnetworking/rtems_webserver/h.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * h.c -- Handle allocation module - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/******************************** Description *********************************/ - -/* - * This module provides a simple API to allocate and free handles - * It maintains a dynamic array of pointers. These usually point to - * per-handle structures. - */ - -/********************************* Includes ***********************************/ - -#ifdef UEMF - #include "uemf.h" -#else - #include "basic/basicInternal.h" -#endif - -/********************************** Defines ***********************************/ -/* - * The handle list stores the length of the list and the number of used - * handles in the first two words. These are hidden from the caller by - * returning a pointer to the third word to the caller - */ - -#define H_LEN 0 /* First entry holds length of list */ -#define H_USED 1 /* Second entry holds number of used */ -#define H_OFFSET 2 /* Offset to real start of list */ - -#define H_INCR 16 /* Grow handle list in chunks this size */ - -/*********************************** Code *************************************/ -/* - * Allocate a new file handle. On the first call, the caller must set the - * handle map to be a pointer to a null pointer. *map points to the second - * element in the handle array. - */ - -#ifdef B_STATS -int HALLOC(B_ARGS_DEC, void ***map) -#else -int hAlloc(void ***map) -#endif -{ - int *mp; - int handle, len, memsize, incr; - - 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]; - -/* - * Find the first null handle - */ - 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; - } - -/* - * No free handle so grow the handle list. Grow list in chunks of H_INCR. - */ - 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; -} - -/******************************************************************************/ -/* - * Free a handle. This function returns the value of the largest - * handle in use plus 1, to be saved as a max value. - */ - -int hFree(void ***map, int handle) -{ - int *mp; - int len; - - 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; - } - -/* - * Find the greatest handle number in use. - */ - 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; -} - -/******************************************************************************/ -/* - * Allocate an entry in the halloc array. - */ - -#ifdef B_STATS -int HALLOCENTRY(B_ARGS_DEC, void ***list, int *max, int size) -#else -int hAllocEntry(void ***list, int *max, int size) -#endif -{ - char_t *cp; - int id; - - 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/c/src/libnetworking/rtems_webserver/handler.c b/c/src/libnetworking/rtems_webserver/handler.c deleted file mode 100644 index dbbe4148d5..0000000000 --- a/c/src/libnetworking/rtems_webserver/handler.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * handler.c -- URL handler support - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/******************************** Description *********************************/ - -/* - * This module implements a URL handler interface and API to permit - * the addition of user definable URL processors. - */ - -/********************************* Includes ***********************************/ - -#include "wsIntrn.h" - -/*********************************** Locals ***********************************/ - -static websUrlHandlerType *websUrlHandler; /* URL handler list */ -static int websUrlHandlerMax; /* Number of entries */ -static int urlHandlerOpenCount = 0; /* count of apps */ - -/**************************** Forward Declarations ****************************/ - -static int websUrlHandlerSort(const void *p1, const void *p2); -static int websPublishHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, - int sid, char_t *url, char_t *path, char_t *query); -static char_t *websCondenseMultipleChars(char_t *strToCondense, char_t cCondense); - -/*********************************** Code *************************************/ -/* - * Initialize the URL handler module - */ - -int websUrlHandlerOpen() -{ - if (++urlHandlerOpenCount == 1) { - websAspOpen(); - websUrlHandler = NULL; - websUrlHandlerMax = 0; - } - return 0; -} - -/******************************************************************************/ -/* - * Close the URL handler module - */ - -void websUrlHandlerClose() -{ - websUrlHandlerType *sp; - - if (--urlHandlerOpenCount <= 0) { - websAspClose(); - 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; - } -} - -/******************************************************************************/ -/* - * Define a new URL handler. urlPrefix is the URL prefix to match. webDir is - * an optional root directory path for a web directory. arg is an optional - * arg to pass to the URL handler. flags defines the matching order. Valid - * flags include WEBS_HANDLER_LAST, WEBS_HANDLER_FIRST. If multiple users - * specify last or first, their order is defined alphabetically by the - * urlPrefix. - */ - -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); - -/* - * Grow the URL handler array to create a new slot - */ - 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); - 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; - -/* - * Sort in decreasing URL length order observing the flags for first and last - */ - qsort(websUrlHandler, websUrlHandlerMax, sizeof(websUrlHandlerType), - websUrlHandlerSort); - return 0; -} - -/******************************************************************************/ -/* - * Delete an existing URL handler. We don't reclaim the space of the old - * handler, just NULL the entry. Return -1 if handler is not found. - */ - -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 i; - - for (i = 0; i < websUrlHandlerMax; i++) { - sp = &websUrlHandler[i]; - if (sp->handler == handler) { - sp->handler = NULL; - return 0; - } - } - return -1; -} - -/******************************************************************************/ -/* - * Sort in decreasing URL length order observing the flags for first and last - */ - -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; -} - -/******************************************************************************/ -/* - * Publish a new web directory (Use the default URL handler) - */ - -int websPublish(char_t *urlPrefix, char_t *path) -{ - return websUrlHandlerDefine(urlPrefix, path, 0, websPublishHandler, 0); -} - -/******************************************************************************/ -/* - * Return the directory for a given prefix. Ignore empty prefixes - */ - -char_t *websGetPublishDir(char_t *path, char_t **urlPrefix) -{ - websUrlHandlerType *sp; - int i; - - for (i = 0; i < websUrlHandlerMax; i++) { - sp = &websUrlHandler[i]; - 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; -} - -/******************************************************************************/ -/* - * Publish URL handler. We just patch the web page Directory and let the - * default handler do the rest. - */ - -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); - -/* - * Trim the urlPrefix off the path and set the webdirectory. Add one to step - * over the trailing '/' - */ - len = gstrlen(urlPrefix) + 1; - websSetRequestPath(wp, webDir, &path[len]); - return 0; -} - -/******************************************************************************/ -/* - * See if any valid handlers are defined for this request. If so, call them - * and continue calling valid handlers until one accepts the request. - * Return true if a handler was invoked, else return FALSE. - */ - -int websUrlHandlerRequest(webs_t wp) -{ - websUrlHandlerType *sp; - int i, first; - - a_assert(websValid(wp)); - -/* - * Delete the socket handler as we don't want to start reading any - * data on the connection as it may be for the next pipelined HTTP/1.1 - * request if using Keep Alive - */ - socketDeleteHandler(wp->sid); - wp->state = WEBS_PROCESSING; - websStats.handlerHits++; - - websSetRequestPath(wp, websGetDefaultDir(), NULL); - -/* - * Eliminate security hole - */ - websCondenseMultipleChars(wp->path, '/'); - websCondenseMultipleChars(wp->url, '/'); - -/* - * We loop over each handler in order till one accepts the request. - * The security handler will handle the request if access is NOT allowed. - */ - 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 ((*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 no handler processed the request, then return an error. Note: It is - * the handlers responsibility to call websDone - */ - if (i >= websUrlHandlerMax) { - websError(wp, 200, T("No handler for this URL %s"), wp->url); - } - return 0; -} - -#ifdef OBSOLETE_CODE - -/******************************************************************************/ -/* - * Tidy up the URL path. Return -1 if the URL is bad. - * Used to eliminate repeated directory delimiters ('/'). - */ - -static int websTidyUrl(webs_t wp) -{ - char_t *parts[64]; /* Array of ptr's to URL parts */ - char_t *token, *url, *tidyurl; - int i, len, npart; - - a_assert(websValid(wp)); - -/* - * Copy the string so we don't destroy the original (yet) - */ - url = bstrdup(B_L, wp->url); - websDecodeUrl(url, url, gstrlen(url)); - - len = npart = 0; - parts[0] = NULL; - token = gstrtok(url, T("/")); - -/* - * Look at each directory segment and process "." and ".." segments - * Don't allow the browser to pop outside the root web. - */ - 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("/")); - } - -/* - * Re-construct URL. Need extra space all "/" and null. - */ - 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 - -/******************************************************************************/ -/* - * Convert multiple adjacent occurrences of a given character to a single - * instance. - */ - -static char_t *websCondenseMultipleChars(char_t *strToCondense, char_t cCondense) -{ - if (strToCondense != NULL) { - char_t *pStr, *pScan; - - pStr = pScan = strToCondense; - - while (*pScan && *pStr) { -/* - * Advance scan pointer over multiple occurences of condense character - */ - while ((*pScan == cCondense) && (*(pScan + 1) == cCondense)) { - pScan++; - } -/* - * Copy character if an advance of the scan pointer has occurred - */ - if (pStr != pScan) { - *pStr = *pScan; - } - - pScan++; - pStr++; - } -/* - * Zero terminate string if multiple adjacent characters were found and condensed - */ - if (pStr != pScan) { - *pStr = 0; - } - } - - return strToCondense; -} - -/******************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/license.txt b/c/src/libnetworking/rtems_webserver/license.txt deleted file mode 100644 index 1fa9e67e79..0000000000 --- a/c/src/libnetworking/rtems_webserver/license.txt +++ /dev/null @@ -1,282 +0,0 @@ -License Agreement - -THIS LICENSE ALLOWS ONLY THE LIMITED USE OF GO AHEAD SOFTWARE, -INC. PROPRIETARY CODE. PLEASE CAREFULLY READ THIS AGREEMENT AS IT -PERTAINS TO THIS LICENSE, YOU CERTIFY THAT YOU WILL USE THE SOFTWARE -ONLY IN THE MANNER PERMITTED HEREIN. - -1. Definitions. - -1.1 "Documentation" means any documentation GoAhead includes with the -Original Code. - -1.2 "GoAhead" means Go Ahead Software, Inc. - -1.3 "Intellectual Property Rights" means all rights, whether now existing -or hereinafter acquired, in and to trade secrets, patents, copyrights, -trademarks, know-how, as well as moral rights and similar rights of any -type under the laws of any governmental authority, domestic or foreign, -including rights in and to all applications and registrations relating -to any of the foregoing. - -1.4 "License" or "Agreement" means this document. - -1.5 "Modifications" means any addition to or deletion from the substance -or structure of either the Original Code or any previous Modifications. - -1.6 "Original Code" means the Source Code to GoAhead’s proprietary -computer software entitled GoAhead WebServer. - -1.7 "Response Header" means the first portion of the response message -output by the GoAhead WebServer, containing but not limited to, header -fields for date, content-type, server identification and cache control. - -1.8 "Server Identification Field" means the field in the Response Header -which contains the text "Server: GoAhead-Webs". - -1.9 "You" means an individual or a legal entity exercising rights under, -and complying with all of the terms of, this license or a future version -of this license. For legal entities, "You" includes any entity which -controls, is controlled by, or is under common control with You. For -purposes of this definition, "control" means (a) the power, direct or -indirect, to cause the direction or management of such entity, whether -by contract or otherwise, or (b) ownership of fifty percent (50%) or -more of the outstanding shares or beneficial ownership of such entity. - -2. Source Code License. - -2.1 Limited Source Code Grant. - -GoAhead hereby grants You a world-wide, royalty-free, non-exclusive -license, subject to third party intellectual property claims, to use, -reproduce, modify, copy and distribute the Original Code. - -2.2 Binary Code. - -GoAhead hereby grants You a world-wide, royalty-free, non-exclusive -license to copy and distribute the binary code versions of the Original -Code together with Your Modifications. - -2.3 License Back to GoAhead. - -You hereby grant in both source code and binary code to GoAhead a -world-wide, royalty-free, non-exclusive license to copy, modify, display, -use and sublicense any Modifications You make that are distributed or -planned for distribution. Within 30 days of either such event, You -agree to ship to GoAhead a file containing the Modifications (in a media -to be determined by the parties), including any programmers’ notes and -other programmers’ materials. Additionally, You will provide to GoAhead -a complete description of the product, the product code or model number, -the date on which the product is initially shipped, and a contact name, -phone number and e-mail address for future correspondence. GoAhead will -keep confidential all data specifically marked as such. - -2.4 Restrictions on Use. - -You may sublicense Modifications to third parties such as subcontractors -or OEM's provided that You enter into license agreements with such third -parties that bind such third parties to all the obligations under this -Agreement applicable to you and that are otherwise substantially similar -in scope and application to this Agreement. - -3. Term. - -This Agreement and license are effective from the time You accept the -terms of this Agreement until this Agreement is terminated. You may -terminate this Agreement at any time by uninstalling or destroying -all copies of the Original Code including any and all binary versions -and removing any Modifications to the Original Code existing in any -products. This Agreement will terminate immediately and without further -notice if You fail to comply with any provision of this Agreement. All -restrictions on use, and all other provisions that may reasonably -be interpreted to survive termination of this Agreement, will survive -termination of this Agreement for any reason. Upon termination, You agree -to uninstall or destroy all copies of the Original Code, Modifications, -and Documentation. - -4. Trademarks and Brand. - -4.1 License and Use. - -GoAhead hereby grants to You a limited world-wide, royalty-free, -non-exclusive license to use the GoAhead trade names, trademarks, logos, -service marks and product designations posted in Exhibit A (collectively, -the "GoAhead Marks") in connection with the activities by You under this -Agreement. Additionally, GoAhead grants You a license under the terms -above to such GoAhead trademarks as shall be identified at a URL (the -"URL") provided by GoAhead. The use by You of GoAhead Marks shall be in -accordance with GoAhead’s trademark policies regarding trademark usage -as established at the web site designated by the URL, or as otherwise -communicated to You by GoAhead at its sole discretion. You understand and -agree that any use of GoAhead Marks in connection with this Agreement -shall not create any right, title or interest in or to such GoAhead -Marks and that all such use and goodwill associated with GoAhead Marks -will inure to the benefit of GoAhead. - -4.2 Promotion by You of GoAhead WebServer Mark. - -In consideration for the licenses granted by GoAhead to You herein, You -agree to notify GoAhead when You incorporate the GoAhead WebServer in -Your product and to inform GoAhead when such product begins to ship. You -agree to promote the Original Code by prominently and visibly displaying -a graphic of the GoAhead WebServer mark on the initial web page of Your -product that is displayed each time a user connects to it. You also agree -that GoAhead may identify your company as a user of the GoAhead WebServer -in conjunction with its own marketing efforts. You may further promote -the Original Code by displaying the GoAhead WebServer mark in marketing -and promotional materials such as the home page of your web site or web -pages promoting the product. - -4.3 Placement of Copyright Notice by You. - -You agree to include copies of the following notice (the "Notice") -regarding proprietary rights in all copies of the products that You -distribute, as follows: (i) embedded in the object code; and (ii) on -the title pages of all documentation. Furthermore, You agree to use -commercially reasonable efforts to cause any licensees of your products -to embed the Notice in object code and on the title pages or relevant -documentation. The Notice is as follows: Copyright (c) 20xx GoAhead -Software, Inc. All Rights Reserved. Unless GoAhead otherwise instructs, -the year 20xx is to be replaced with the year during which the release of -the Original Code containing the notice is issued by GoAhead. If this year -is not supplied with Documentation, GoAhead will supply it upon request. - -4.4 No Modifications to Server Identification Field. - -You agree not to remove or modify the Server identification Field -contained in the Response Header as defined in Section 1.6 and 1.7. - -5. Warranty Disclaimers. - -THE ORIGINAL CODE, THE DOCUMENTATION AND THE MEDIA UPON WHICH THE ORIGINAL -CODE IS RECORDED (IF ANY) ARE PROVIDED "AS IS" AND WITHOUT WARRANTIES OF -ANY KIND, EXPRESS, STATUTORY OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. - -The entire risk as to the quality and performance of the Original Code -(including any Modifications You make) and the Documentation is with -You. Should the Original Code or the Documentation prove defective, -You (and not GoAhead or its distributors, licensors or dealers) assume -the entire cost of all necessary servicing or repair. GoAhead does not -warrant that the functions contained in the Original Code will meet your -requirements or operate in the combination that You may select for use, -that the operation of the Original Code will be uninterrupted or error -free, or that defects in the Original Code will be corrected. No oral -or written statement by GoAhead or by a representative of GoAhead shall -create a warranty or increase the scope of this warranty. - -GOAHEAD DOES NOT WARRANT THE ORIGINAL CODE AGAINST INFRINGEMENT OR THE -LIKE WITH RESPECT TO ANY COPYRIGHT, PATENT, TRADE SECRET, TRADEMARK -OR OTHER PROPRIETARY RIGHT OF ANY THIRD PARTY AND DOES NOT WARRANT -THAT THE ORIGINAL CODE DOES NOT INCLUDE ANY VIRUS, SOFTWARE ROUTINE -OR OTHER SOFTWARE DESIGNED TO PERMIT UNAUTHORIZED ACCESS, TO DISABLE, -ERASE OR OTHERWISE HARM SOFTWARE, HARDWARE OR DATA, OR TO PERFORM ANY -OTHER SUCH ACTIONS. - -Any warranties that by law survive the foregoing disclaimers shall -terminate ninety (90) days from the date You received the Original Code. - -6. Limitation of Liability. - -YOUR SOLE REMEDIES AND GOAHEAD'S ENTIRE LIABILITY ARE SET FORTH ABOVE. IN -NO EVENT WILL GOAHEAD OR ITS DISTRIBUTORS OR DEALERS BE LIABLE FOR -DIRECT, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES RESULTING FROM -THE USE OF THE ORIGINAL CODE, THE INABILITY TO USE THE ORIGINAL CODE, -OR ANY DEFECT IN THE ORIGINAL CODE, INCLUDING ANY LOST PROFITS, EVEN IF -THEY HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -You agree that GoAhead and its distributors and dealers will not be -LIABLE for defense or indemnity with respect to any claim against You -by any third party arising from your possession or use of the Original -Code or the Documentation. - -In no event will GoAhead’s total liability to You for all damages, losses, -and causes of action (whether in contract, tort, including negligence, -or otherwise) exceed the amount You paid for this product. - -SOME STATES DO NOT ALLOW LIMITATIONS ON HOW LONG AN IMPLIED WARRANTY -LASTS, AND SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION -OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE ABOVE LIMITATIONS OR -EXCLUSIONS MAY NOT APPLY TO YOU. THIS WARRANTY GIVES YOU SPECIFIC LEGAL -RIGHTS AND YOU MAY ALSO HAVE OTHER RIGHTS WHICH VARY FROM STATE TO STATE. - -7. Indemnification by You. - -You agree to indemnify and hold GoAhead harmless against any and all -claims, losses, damages and costs (including legal expenses and reasonable -counsel fees) arising out of any claim of a third party with respect to -the contents of the Your products, and any intellectual property rights -or other rights or interests related thereto. - -8. High Risk Activities. - -The Original Code is not fault-tolerant and is not designed , manufactured -or intended for use or resale as online control equipment in hazardous -environments requiring fail-safe performance, such as in the operation -of nuclear facilities, aircraft navigation or communication systems, -air traffic control, direct life support machines or weapons systems, -in which the failure of the Original Code could lead directly to death, -personal injury, or severe physical or environmental damage. GoAhead and -its suppliers specifically disclaim any express or implied warranty of -fitness for any high risk uses listed above. - -9. Government Restricted Rights. - -For units of the Department of Defense, use, duplication, or disclosure -by the Government is subject to restrictions as set forth in subparagraph -(c)(1)(ii) of the Rights in Technical Data and Computer Software clause -at DFARS 252.227-7013. Contractor/manufacturer is GoAhead Software, -Inc., 10900 N.E. 8th Street, Suite 750, Bellevue, Washington 98004. - -If the Commercial Computer Software Restricted rights clause at FAR -52.227-19 or its successors apply, the Software and Documentation -constitute restricted computer software as defined in that clause and -the Government shall not have the license for published software set -forth in subparagraph (c)(3) of that clause. - -The Original Code (i) was developed at private expense, and no part of it -was developed with governmental funds; (ii) is a trade secret of GoAhead -(or its licensor(s)) for all purposes of the Freedom of Information Act; -(iii) is "restricted computer software" subject to limited utilization as -provided in the contract between the vendor and the governmental entity; -and (iv) in all respects is proprietary data belonging solely to GoAhead -(or its licensor(s)). - -10. Governing Law and Interpretation. - -This Agreement shall be interpreted under and governed by the laws of the -State of Washington, without regard to its rules governing the conflict of -laws. If any provision of this Agreement is held illegal or unenforceable -by a court or tribunal of competent jurisdiction, the remaining provisions -of this Agreement shall remain in effect and the invalid provision deemed -modified to the least degree necessary to remedy such invalidity. - -11. Entire Agreement. - -This Agreement is the complete agreement between GoAhead and You and -supersedes all prior agreements, oral or written, with respect to the -subject matter hereof. - -If You have any questions concerning this Agreement, You may write to -GoAhead Software, Inc., 10900 N.E. 8th Street, Suite 750, Bellevue, -Washington 98004 or send e-mail to info@goahead.com. - -BY CLICKING ON THE "Register" BUTTON ON THE REGISTRATION FORM, YOU -ACCEPT AND AGREE TO BE BOUND BY ALL OF THE TERMS AND CONDITIONS SET -FORTH IN THIS AGREEMENT. IF YOU DO NOT WISH TO ACCEPT THIS LICENSE OR -YOU DO NOT QUALIFY FOR A LICENSE BASED ON THE TERMS SET FORTH ABOVE, -YOU MUST NOT CLICK THE "Register" BUTTON. - -Exhibit A - -GoAhead Trademarks, Logos, and Product Designation Information - - - - -01/28/00 - - - - diff --git a/c/src/libnetworking/rtems_webserver/md5.h b/c/src/libnetworking/rtems_webserver/md5.h deleted file mode 100644 index 99df4eb735..0000000000 --- a/c/src/libnetworking/rtems_webserver/md5.h +++ /dev/null @@ -1,50 +0,0 @@ -/* MD5.H - header file for MD5C.C - * - * $Id$ - */ - -/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -rights reserved. - -License to copy and use this software is granted provided that it -is identified as the "RSA Data Security, Inc. MD5 Message-Digest -Algorithm" in all material mentioning or referencing this software -or this function. - -License is also granted to make and use derivative works provided -that such works are identified as "derived from the RSA Data -Security, Inc. MD5 Message-Digest Algorithm" in all material -mentioning or referencing the derived work. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. - -These notices must be retained in any copies of any part of this -documentation and/or software. - */ - -#ifndef _h_MD5 -#define _h_MD5 1 - -#ifndef UINT4 -#define UINT4 unsigned long -#endif - -#ifndef POINTER -#define POINTER unsigned char * -#endif - -/* MD5 context. */ -typedef struct { - UINT4 state[4]; /* state (ABCD) */ - UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ - unsigned char buffer[64]; /* input buffer */ -} MD5_CONTEXT; - -extern void MD5Init (MD5_CONTEXT *); -extern void MD5Update (MD5_CONTEXT *, unsigned char *, unsigned int); -extern void MD5Final (unsigned char [16], MD5_CONTEXT *); - -#endif /* _h_MD5 */ diff --git a/c/src/libnetworking/rtems_webserver/md5c.c b/c/src/libnetworking/rtems_webserver/md5c.c deleted file mode 100644 index 1e5a3442fa..0000000000 --- a/c/src/libnetworking/rtems_webserver/md5c.c +++ /dev/null @@ -1,337 +0,0 @@ -/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm - * - * $Id$ - */ - -/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -rights reserved. - -License to copy and use this software is granted provided that it -is identified as the "RSA Data Security, Inc. MD5 Message-Digest -Algorithm" in all material mentioning or referencing this software -or this function. - -License is also granted to make and use derivative works provided -that such works are identified as "derived from the RSA Data -Security, Inc. MD5 Message-Digest Algorithm" in all material -mentioning or referencing the derived work. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. - -These notices must be retained in any copies of any part of this -documentation and/or software. - */ - -#include "md5.h" - -/* Constants for MD5Transform routine. - */ -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - -static void MD5Transform (UINT4 [4], unsigned char [64]); -static void Encode (unsigned char *, UINT4 *, unsigned int); -static void Decode (UINT4 *, unsigned char *, unsigned int); -static void MD5_memcpy (POINTER, POINTER, unsigned int); -static void MD5_memset (POINTER, int, unsigned int); - -static unsigned char PADDING[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * Note: The following MD5 macros can be implemented as functions - * for code compactness, (at the expense of execution speed). - */ - -/* F, G, H and I are basic MD5 functions. - */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | (~z))) - -/* ROTATE_LEFT rotates x left n bits. - */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. -Rotation is separate from addition to prevent recomputation. - */ -#define FF(a, b, c, d, x, s, ac) { \ - (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define GG(a, b, c, d, x, s, ac) { \ - (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define HH(a, b, c, d, x, s, ac) { \ - (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define II(a, b, c, d, x, s, ac) { \ - (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - -/* MD5 initialization. Begins an MD5 operation, writing a new context. - */ -void MD5Init (context) -MD5_CONTEXT *context; /* context */ -{ - context->count[0] = context->count[1] = 0; - /* Load magic initialization constants. -*/ - context->state[0] = 0x67452301; - context->state[1] = 0xefcdab89; - context->state[2] = 0x98badcfe; - context->state[3] = 0x10325476; -} - -/* MD5 block update operation. Continues an MD5 message-digest - operation, processing another message block, and updating the - context. - */ -void MD5Update (context, input, inputLen) -MD5_CONTEXT *context; /* context */ -unsigned char *input; /* input block */ -unsigned int inputLen; /* length of input block */ -{ - unsigned int i, index, partLen; - - /* Compute number of bytes mod 64 */ - index = (unsigned int)((context->count[0] >> 3) & 0x3F); - - /* Update number of bits */ - if ((context->count[0] += ((UINT4)inputLen << 3)) - < ((UINT4)inputLen << 3)) - context->count[1]++; - context->count[1] += ((UINT4)inputLen >> 29); - - partLen = 64 - index; - - /* Transform as many times as possible. -*/ - if (inputLen >= partLen) { - MD5_memcpy - ((POINTER)&context->buffer[index], (POINTER)input, partLen); - MD5Transform (context->state, context->buffer); - - for (i = partLen; i + 63 < inputLen; i += 64) - MD5Transform (context->state, &input[i]); - - index = 0; - } - else - i = 0; - - /* Buffer remaining input */ - MD5_memcpy - ((POINTER)&context->buffer[index], (POINTER)&input[i], - inputLen-i); -} - -/* MD5 finalization. Ends an MD5 message-digest operation, writing the - the message digest and zeroizing the context. - */ -void MD5Final (digest, context) -unsigned char digest[16]; /* message digest */ -MD5_CONTEXT *context; /* context */ -{ - unsigned char bits[8]; - unsigned int index, padLen; - - /* Save number of bits */ - Encode (bits, context->count, 8); - - /* Pad out to 56 mod 64. -*/ - index = (unsigned int)((context->count[0] >> 3) & 0x3f); - padLen = (index < 56) ? (56 - index) : (120 - index); - MD5Update (context, PADDING, padLen); - - /* Append length (before padding) */ - MD5Update (context, bits, 8); - /* Store state in digest */ - Encode (digest, context->state, 16); - - /* Zeroize sensitive information. -*/ - MD5_memset ((POINTER)context, 0, sizeof (*context)); -} - -/* MD5 basic transformation. Transforms state based on block. - */ -static void MD5Transform (state, block) -UINT4 state[4]; -unsigned char block[64]; -{ - UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - - Decode (x, block, 64); - - /* Round 1 */ - FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ - FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ - FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ - FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ - FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ - FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ - FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ - FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ - FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ - FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ - FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ - FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ - FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ - FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ - FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ - FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ - - /* Round 2 */ - GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ - GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ - GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ - GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ - GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ - GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ - GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ - GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ - GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ - GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ - GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ - GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ - GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ - GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ - GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ - GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ - - /* Round 3 */ - HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ - HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ - HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ - HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ - HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ - HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ - HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ - HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ - HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ - HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ - HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ - HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ - HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ - HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ - HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ - HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ - - /* Round 4 */ - II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ - II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ - II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ - II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ - II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ - II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ - II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ - II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ - II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ - II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ - II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ - II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ - II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ - II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ - II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ - II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - - /* Zeroize sensitive information. -*/ - MD5_memset ((POINTER)x, 0, sizeof (x)); -} - -/* Encodes input (UINT4) into output (unsigned char). Assumes len is - a multiple of 4. - */ -static void Encode (output, input, len) -unsigned char *output; -UINT4 *input; -unsigned int len; -{ - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) { - output[j] = (unsigned char)(input[i] & 0xff); - output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); - output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); - output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); - } -} - -/* Decodes input (unsigned char) into output (UINT4). Assumes len is - a multiple of 4. - */ -static void Decode (output, input, len) -UINT4 *output; -unsigned char *input; -unsigned int len; -{ - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) - output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | - (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); -} - -/* Note: Replace "for loop" with standard memcpy if possible. - */ - -static void MD5_memcpy (output, input, len) -POINTER output; -POINTER input; -unsigned int len; -{ - unsigned int i; - - for (i = 0; i < len; i++) - output[i] = input[i]; -} - -/* Note: Replace "for loop" with standard memset if possible. - */ -static void MD5_memset (output, value, len) -POINTER output; -int value; -unsigned int len; -{ - unsigned int i; - - for (i = 0; i < len; i++) - ((char *)output)[i] = (char)value; -} diff --git a/c/src/libnetworking/rtems_webserver/mime.c b/c/src/libnetworking/rtems_webserver/mime.c deleted file mode 100644 index 689360ea68..0000000000 --- a/c/src/libnetworking/rtems_webserver/mime.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * mime.c -- Web server mime types - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/******************************** Description *********************************/ - -/* - * Mime types and file extensions. This module maps URL extensions to - * content types. - */ - -/********************************* Includes ***********************************/ - -#include "wsIntrn.h" - -/******************************** Global Data *********************************/ -/* - * Addd entries to the MimeList as required for your content - */ - - -websMimeType websMimeList[] = { - { T("application/java"), T(".class") }, - { T("application/java"), T(".jar") }, - { T("text/html"), T(".asp") }, - { T("text/html"), T(".htm") }, - { T("text/html"), T(".html") }, - { T("image/gif"), T(".gif") }, - { T("image/jpeg"), T(".jpg") }, - { T("text/css"), T(".css") }, - { T("text/plain"), T(".txt") }, - { T("application/x-javascript"), T(".js") }, - -#ifdef MORE_MIME_TYPES - { T("application/binary"), T(".exe") }, - { T("application/compress"), T(".z") }, - { T("application/gzip"), T(".gz") }, - { T("application/octet-stream"), T(".bin") }, - { T("application/oda"), T(".oda") }, - { T("application/pdf"), T(".pdf") }, - { T("application/postscript"), T(".ai") }, - { T("application/postscript"), T(".eps") }, - { T("application/postscript"), T(".ps") }, - { T("application/rtf"), T(".rtf") }, - { T("application/x-bcpio"), T(".bcpio") }, - { T("application/x-cpio"), T(".cpio") }, - { T("application/x-csh"), T(".csh") }, - { T("application/x-dvi"), T(".dvi") }, - { T("application/x-gtar"), T(".gtar") }, - { T("application/x-hdf"), T(".hdf") }, - { T("application/x-latex"), T(".latex") }, - { T("application/x-mif"), T(".mif") }, - { T("application/x-netcdf"), T(".nc") }, - { T("application/x-netcdf"), T(".cdf") }, - { T("application/x-ns-proxy-autoconfig"), T(".pac") }, - { T("application/x-patch"), T(".patch") }, - { T("application/x-sh"), T(".sh") }, - { T("application/x-shar"), T(".shar") }, - { 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("application/x-texinfo"), T(".texinfo") }, - { T("application/x-texinfo"), T(".texi") }, - { T("application/x-troff"), T(".t") }, - { T("application/x-troff"), T(".tr") }, - { T("application/x-troff"), T(".roff") }, - { T("application/x-troff-man"), T(".man") }, - { T("application/x-troff-me"), T(".me") }, - { T("application/x-troff-ms"), T(".ms") }, - { T("application/x-ustar"), T(".ustar") }, - { T("application/x-wais-source"), T(".src") }, - { T("application/zip"), T(".zip") }, - { 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("audio/x-wav"), T(".wav") }, - { T("audio/x-wav"), T(".ram") }, - { T("image/ief"), T(".ief") }, - { T("image/jpeg"), T(".jpeg") }, - { T("image/jpeg"), T(".jpe") }, - { T("image/tiff"), T(".tiff") }, - { T("image/tiff"), T(".tif") }, - { T("image/x-cmu-raster"), T(".ras") }, - { 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("image/x-rgb"), T(".rgb") }, - { T("image/x-xbitmap"), T(".xbm") }, - { T("image/x-xpixmap"), T(".xpm") }, - { T("image/x-xwindowdump"), T(".xwd") }, - { T("text/html"), T(".cfm") }, - { T("text/html"), T(".shtm") }, - { T("text/html"), T(".shtml") }, - { T("text/richtext"), T(".rtx") }, - { T("text/tab-separated-values"), T(".tsv") }, - { T("text/x-setext"), T(".etx") }, - { T("video/mpeg"), T(".mpeg mpg mpe") }, - { T("video/quicktime"), T(".qt") }, - { T("video/quicktime"), T(".mov") }, - { T("video/x-msvideo"), T(".avi") }, - { T("video/x-sgi-movie"), T(".movie") }, -#endif - { NULL, NULL}, -}; - -/*****************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/misc.c b/c/src/libnetworking/rtems_webserver/misc.c deleted file mode 100644 index e08b7c76b4..0000000000 --- a/c/src/libnetworking/rtems_webserver/misc.c +++ /dev/null @@ -1,675 +0,0 @@ -/* - * misc.c -- Miscellaneous routines. - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/********************************* Includes ***********************************/ - -#ifdef UEMF - #include "uemf.h" -#else - #include "basic/basicInternal.h" -#endif - -/********************************* Defines ************************************/ -/* - * Sprintf buffer structure. Make the increment 64 so that - * a balloc can use a 64 byte block. - */ - -#define STR_REALLOC 0x1 /* Reallocate the buffer as required */ -#define STR_INC 64 /* Growth increment */ - -typedef struct { - char_t *s; /* Pointer to buffer */ - int size; /* Current buffer size */ - int max; /* Maximum buffer size */ - int count; /* Buffer count */ - int flags; /* Allocation flags */ -} strbuf_t; - -/* - * Sprintf formatting flags - */ -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 -}; - -/************************** Forward Declarations ******************************/ - -static int dsnprintf(char_t **s, int size, char_t *fmt, va_list arg, - int msize); -#if !defined(__rtems__) -static int strnlen(char_t *s, unsigned int n); -#endif -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_ulong(strbuf_t *buf, unsigned long int value, int base, - int upper, char_t *prefix, int width, int prec, enum flag f); - -/************************************ Code ************************************/ -/* - * "basename" returns a pointer to the last component of a pathname - * LINUX, LynxOS and Mac OS X have their own basename function - */ - -#if (!defined (LINUX) && !defined (LYNX) && !defined (MACOSX)) -char_t *basename(char_t *name) -{ - char_t *cp; - -#if (defined (NW) || defined (WIN)) - if (((cp = gstrrchr(name, '\\')) == NULL) && - ((cp = gstrrchr(name, '/')) == NULL)) { - return name; -#else - if ((cp = gstrrchr(name, '/')) == NULL) { - return name; -#endif - } else if (*(cp + 1) == '\0' && cp == name) { - return name; - } else if (*(cp + 1) == '\0' && cp != name) { - return T(""); - } else { - return ++cp; - } -} -#endif /* ! LINUX & ! LYNX & ! MACOSX */ - -/******************************************************************************/ -/* - * Returns a pointer to the directory component of a pathname. bufsize is - * the size of the buffer in BYTES! - */ - -char_t *dirname(char_t *buf, char_t *name, int bufsize) -{ - char_t *cp; - int len; - - a_assert(name); - a_assert(buf); - a_assert(bufsize > 0); - -#if (defined (WIN) || defined (NW)) - if ((cp = gstrrchr(name, '/')) == NULL && - (cp = gstrrchr(name, '\\')) == NULL) -#else - if ((cp = gstrrchr(name, '/')) == NULL) -#endif - { - gstrcpy(buf, T(".")); - return buf; - } - - if ((*(cp + 1) == '\0' && cp == name)) { - gstrncpy(buf, T("."), TSZ(bufsize)); - gstrcpy(buf, T(".")); - return buf; - } - - len = cp - name; - - if (len < bufsize) { - gstrncpy(buf, name, len); - buf[len] = '\0'; - } else { - gstrncpy(buf, name, TSZ(bufsize)); - buf[bufsize - 1] = '\0'; - } - - return buf; -} - - -/******************************************************************************/ -/* - * sprintf and vsprintf are bad, ok. You can easily clobber memory. Use - * fmtAlloc and fmtValloc instead! These functions do _not_ support floating - * point, like %e, %f, %g... - */ - -int fmtAlloc(char_t **s, int n, char_t *fmt, ...) -{ - va_list ap; - 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; -} - -/******************************************************************************/ -/* - * Support a static buffer version for small buffers only! - */ - -int fmtStatic(char_t *s, int n, char_t *fmt, ...) -{ - va_list ap; - int result; - - a_assert(s); - a_assert(fmt); - a_assert(n <= 256); - - if (n <= 0) { - return -1; - } - va_start(ap, fmt); - result = dsnprintf(&s, n, fmt, ap, 0); - va_end(ap); - return result; -} - -/******************************************************************************/ -/* - * This function appends the formatted string to the supplied string, - * reallocing if required. - */ - -int fmtRealloc(char_t **s, int n, int msize, char_t *fmt, ...) -{ - va_list ap; - 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; -} - -/******************************************************************************/ -/* - * A vsprintf replacement. - */ - -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); -} - -/******************************************************************************/ -/* - * Dynamic sprintf implementation. Supports dynamic buffer allocation. - * This function can be called multiple times to grow an existing allocated - * buffer. In this case, msize is set to the size of the previously allocated - * buffer. The buffer will be realloced, as required. If msize is set, we - * return the size of the allocated buffer for use with the next call. For - * the first call, msize can be set to -1. - */ - -static int dsnprintf(char_t **s, int size, char_t *fmt, va_list arg, int msize) -{ - strbuf_t buf; - char_t c; - - a_assert(s); - a_assert(fmt); - - memset(&buf, 0, sizeof(buf)); - buf.s = *s; - - if (*s == NULL || msize != 0) { - buf.max = size; - buf.flags |= STR_REALLOC; - if (msize != 0) { - buf.size = max(msize, 0); - } - if (*s != NULL && msize != 0) { - buf.count = gstrlen(*s); - } - } else { - buf.size = size; - } - - while ((c = *fmt++) != '\0') { - if (c != '%' || (c = *fmt++) == '%') { - put_char(&buf, c); - } else { - enum flag f = flag_none; - int width = 0; - int prec = -1; - for ( ; c != '\0'; c = *fmt++) { - if (c == '-') { - f |= flag_minus; - } else if (c == '+') { - f |= flag_plus; - } else if (c == ' ') { - f |= flag_space; - } else if (c == '#') { - f |= flag_hash; - } else if (c == '0') { - f |= flag_zero; - } else { - break; - } - } - if (c == '*') { - width = va_arg(arg, int); - if (width < 0) { - f |= flag_minus; - width = -width; - } - c = *fmt++; - } else { - for ( ; gisdigit((int)c); c = *fmt++) { - width = width * 10 + (c - '0'); - } - } - if (c == '.') { - f &= ~flag_zero; - c = *fmt++; - if (c == '*') { - prec = va_arg(arg, int); - c = *fmt++; - } else { - for (prec = 0; gisdigit((int)c); c = *fmt++) { - prec = prec * 10 + (c - '0'); - } - } - } - if (c == 'h' || c == 'l') { - f |= (c == 'h' ? flag_short : flag_long); - c = *fmt++; - } - if (c == 'd' || 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(&buf, value, 10, 0, T("+"), width, prec, f); - } else if (f & flag_space) { - put_ulong(&buf, value, 10, 0, T(" "), width, prec, f); - } else { - put_ulong(&buf, value, 10, 0, NULL, width, prec, f); - } - } else { - put_ulong(&buf, -value, 10, 0, T("-"), width, prec, f); - } - } else if (c == 'o' || c == 'u' || c == 'x' || 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 (c == 'o') { - if (f & flag_hash && value != 0) { - put_ulong(&buf, value, 8, 0, T("0"), width, prec, f); - } else { - put_ulong(&buf, value, 8, 0, NULL, width, prec, f); - } - } else if (c == 'u') { - put_ulong(&buf, value, 10, 0, NULL, width, prec, f); - } else { - if (f & flag_hash && value != 0) { - if (c == 'x') { - put_ulong(&buf, value, 16, 0, T("0x"), width, - prec, f); - } else { - put_ulong(&buf, value, 16, 1, T("0X"), width, - prec, f); - } - } else { - /* 04 Apr 02 BgP -- changed so that %X correctly outputs - * uppercase hex digits when requested. - put_ulong(&buf, value, 16, 0, NULL, width, prec, f); - */ - put_ulong(&buf, value, 16, ('X' == c) , NULL, width, prec, f); - } - } - - } else if (c == 'c') { - char_t value = va_arg(arg, int); - put_char(&buf, value); - - } else if (c == 's' || c == 'S') { - char_t *value = va_arg(arg, char_t *); - if (value == NULL) { - put_string(&buf, T("(null)"), -1, width, prec, f); - } else if (f & flag_hash) { - put_string(&buf, - value + 1, (char_t) *value, width, prec, f); - } else { - put_string(&buf, value, -1, width, prec, f); - } - } else if (c == 'p') { - void *value = va_arg(arg, void *); - put_ulong(&buf, - (unsigned long int) value, 16, 0, T("0x"), width, prec, f); - } else if (c == 'n') { - if (f & flag_short) { - short int *value = va_arg(arg, short int *); - *value = buf.count; - } else if (f & flag_long) { - long int *value = va_arg(arg, long int *); - *value = buf.count; - } else { - int *value = va_arg(arg, int *); - *value = buf.count; - } - } else { - put_char(&buf, c); - } - } - } - if (buf.s == NULL) { - put_char(&buf, '\0'); - } - -/* - * If the user requested a dynamic buffer (*s == NULL), ensure it is returned. - */ - if (*s == NULL || msize != 0) { - *s = buf.s; - } - - if (*s != NULL && size > 0) { - if (buf.count < size) { - (*s)[buf.count] = '\0'; - } else { - (*s)[buf.size - 1] = '\0'; - } - } - - if (msize != 0) { - return buf.size; - } - return buf.count; -} - -/******************************************************************************/ -/* - * Return the length of a string limited by a given length - */ - -#if !defined(__rtems__) -static int strnlen(char_t *s, unsigned int n) -{ - unsigned int len; - - len = gstrlen(s); - return min(len, n); -} -#endif - -/******************************************************************************/ -/* - * Add a character to a string buffer - */ - -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) { -/* - * Caller should increase the size of the calling buffer - */ - 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)); - } - } - buf->s[buf->count] = c; - if (c != '\0') { - ++buf->count; - } -} - -/******************************************************************************/ -/* - * Add a string to a string buffer - */ - -static void put_string(strbuf_t *buf, char_t *s, int len, int width, - int prec, enum flag f) -{ - int i; - - 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 (i = len; i < width; ++i) { - put_char(buf, ' '); - } - } - for (i = 0; i < len; ++i) { - put_char(buf, s[i]); - } - if (width > len && f & flag_minus) { - for (i = len; i < width; ++i) { - put_char(buf, ' '); - } - } -} - -/******************************************************************************/ -/* - * Add a long to a string buffer - */ - -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, i; - - 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 (i = 0; i < width; ++i) { - put_char(buf, '0'); - } - } else { - for (i = 0; i < width; ++i) { - put_char(buf, ' '); - } - } - } - if (prefix != NULL) { - put_string(buf, prefix, -1, 0, -1, flag_none); - } - for (i = 0; i < zeros; ++i) { - 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 (i = 0; i < width; ++i) { - put_char(buf, ' '); - } - } -} - -/******************************************************************************/ -/* - * Convert an ansi string to a unicode string. On an error, we return the - * original ansi string which is better than returning NULL. nBytes is the - * size of the destination buffer (ubuf) in _bytes_. - */ - -char_t *ascToUni(char_t *ubuf, char *str, int nBytes) -{ -#ifdef UNICODE - if (MultiByteToWideChar(CP_ACP, 0, str, nBytes / sizeof(char_t), ubuf, - nBytes / sizeof(char_t)) < 0) { - return (char_t*) str; - } -#else - strncpy(ubuf, str, nBytes); -#endif - return ubuf; -} - -/******************************************************************************/ -/* - * Convert a unicode string to an ansi string. On an error, return the - * original unicode string which is better than returning NULL. - * N.B. nBytes is the number of _bytes_ in the destination buffer, buf. - */ - -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 - strncpy(buf, ustr, nBytes); -#endif - return (char*) buf; -} - -/******************************************************************************/ -/* - * allocate (balloc) a buffer and do ascii to unicode conversion into it. - * cp points to the ascii buffer. alen is the length of the buffer to be - * converted not including a terminating NULL. Return a pointer to the - * unicode buffer which must be bfree'd later. Return NULL on failure to - * get buffer. The buffer returned is NULL terminated. - */ - -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; -} - -/******************************************************************************/ -/* - * allocate (balloc) a buffer and do unicode to ascii conversion into it. - * unip points to the unicoded string. ulen is the number of characters - * in the unicode string not including a teminating null. Return a pointer - * to the ascii buffer which must be bfree'd later. Return NULL on failure - * to get buffer. The buffer returned is NULL terminated. - */ - -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; -} - -/******************************************************************************/ -/* - * convert a hex string to an integer. The end of the string or a non-hex - * character will indicate the end of the hex specification. - */ - -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; -} - -/******************************************************************************/ -/* - * convert a string to an integer. If the string starts with "0x" or "0X" - * a hexidecimal conversion is done. - */ - -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/c/src/libnetworking/rtems_webserver/ringq.c b/c/src/libnetworking/rtems_webserver/ringq.c deleted file mode 100644 index efb9c45a70..0000000000 --- a/c/src/libnetworking/rtems_webserver/ringq.c +++ /dev/null @@ -1,584 +0,0 @@ -/* - * ringq.c -- Ring queue buffering module - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/******************************** Description *********************************/ - -/* - * A ring queue allows maximum utilization of memory for data storage and is - * ideal for input/output buffering. This module provides a highly efficient - * implementation and a vehicle for dynamic strings. - * - * WARNING: This is a public implementation and callers have full access to - * the queue structure and pointers. Change this module very carefully. - * - * This module follows the open/close model. - * - * Operation of a ringq where rq is a pointer to a ringq : - * - * rq->buflen contains the size of the buffer. - * rq->buf will point to the start of the buffer. - * rq->servp will point to the first (un-consumed) data byte. - * rq->endp will point to the next free location to which new data is added - * rq->endbuf will point to one past the end of the buffer. - * - * Eg. If the ringq contains the data "abcdef", it might look like : - * - * +-------------------------------------------------------------------+ - * | | | | | | | | a | b | c | d | e | f | | | | | - * +-------------------------------------------------------------------+ - * ^ ^ ^ ^ - * | | | | - * rq->buf rq->servp rq->endp rq->enduf - * - * The queue is empty when servp == endp. This means that the queue will hold - * at most rq->buflen -1 bytes. It is the filler's responsibility to ensure - * the ringq is never filled such that servp == endp. - * - * It is the filler's responsibility to "wrap" the endp back to point to - * rq->buf when the pointer steps past the end. Correspondingly it is the - * consumers responsibility to "wrap" the servp when it steps to rq->endbuf. - * The ringqPutc and ringqGetc routines will do this automatically. - */ - -/********************************* Includes ***********************************/ - -#ifdef UEMF - #include "uemf.h" -#else - #include "basic/basicInternal.h" -#endif - -/*********************************** Defines **********************************/ -/* - * Faster than a function call - */ - -#define RINGQ_LEN(rq) \ - ((rq->servp > rq->endp) ? \ - (rq->buflen + (rq->endp - rq->servp)) : \ - (rq->endp - rq->servp)) - -/***************************** Forward Declarations ***************************/ - -static int ringqGrow(ringq_t *rq); -static int getBinBlockSize(int size); - -int ringqGrowCalls = 0; - -/*********************************** Code *************************************/ -/* - * Create a new ringq. "increment" is the amount to increase the size of the - * ringq should it need to grow to accomodate data being added. "maxsize" is - * an upper limit (sanity level) beyond which the q must not grow. Set maxsize - * to -1 to imply no upper limit. The buffer for the ringq is always - * dynamically allocated. Set maxsize - */ - -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; -} - -/******************************************************************************/ -/* - * Delete a ringq and free the ringq buffer. - */ - -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; -} - -/******************************************************************************/ -/* - * Return the length of the data in the ringq. Users must fill the queue to - * a high water mark of at most one less than the queue size. - */ - -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; - } -} - -/******************************************************************************/ -/* - * Get a byte from the queue - */ - -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 c; -} - -/******************************************************************************/ -/* - * Add a char to the queue. Note if being used to store wide strings - * this does not add a trailing '\0'. Grow the q as required. - */ - -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; -} - -/******************************************************************************/ -/* - * Insert a wide character at the front of the queue - */ - -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; -} - -/******************************************************************************/ -/* - * Add a string to the queue. Add a trailing null (maybe two nulls) - */ - -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; -} - -/******************************************************************************/ -/* - * Add a null terminator. This does NOT increase the size of the queue - */ - -void ringqAddNull(ringq_t *rq) -{ - a_assert(rq); - a_assert(rq->buflen == (rq->endbuf - rq->buf)); - - *((char_t*) rq->endp) = (char_t) '\0'; -} - -/******************************************************************************/ -#ifdef UNICODE -/* - * Get a byte from the queue - */ - -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; -} - -/******************************************************************************/ -/* - * Add a byte to the queue. Note if being used to store strings this does not - * add a trailing '\0'. Grow the q as required. - */ - -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; -} - -/******************************************************************************/ -/* - * Insert a byte at the front of the queue - */ - -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; -} - -/******************************************************************************/ -/* - * Add a string to the queue. Add a trailing null (not really in the q). - * ie. beyond the last valid byte. - */ - -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; -} - -#endif /* UNICODE */ -/******************************************************************************/ -/* - * Add a block of data to the ringq. Return the number of bytes added. - * Grow the q as required. - */ - -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); - -/* - * Loop adding the maximum bytes we can add in a single straight line copy - */ - 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; -} - -/******************************************************************************/ -/* - * Get a block of data from the ringq. Return the number of bytes returned. - */ - -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); - -/* - * Loop getting the maximum bytes we can get in a single straight line copy - */ - 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; -} - -/******************************************************************************/ -/* - * Return the maximum number of bytes the ring q can accept via a single - * block copy. Useful if the user is doing their own data insertion. - */ - -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); -} - -/******************************************************************************/ -/* - * Return the maximum number of bytes the ring q can provide via a single - * block copy. Useful if the user is doing their own data retrieval. - */ - -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); -} - -/******************************************************************************/ -/* - * Adjust the endp pointer after the user has copied data into the queue. - */ - -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; - } -/* - * Flush the queue if the endp pointer is corrupted via a bad size - */ - if (rq->endp >= rq->endbuf) { - error(E_L, E_LOG, T("Bad end pointer")); - ringqFlush(rq); - } -} - -/******************************************************************************/ -/* - * Adjust the servp pointer after the user has copied data from the queue. - */ - -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; - } -/* - * Flush the queue if the servp pointer is corrupted via a bad size - */ - if (rq->servp >= rq->endbuf) { - error(E_L, E_LOG, T("Bad serv pointer")); - ringqFlush(rq); - } -} - -/******************************************************************************/ -/* - * Flush all data in a ring q. Reset the pointers. - */ - -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'; - } -} - -/******************************************************************************/ -/* - * Grow the buffer. Return true if the buffer can be grown. Grow using - * the increment size specified when opening the ringq. Don't grow beyond - * the maximum possible size. - */ - -static int ringqGrow(ringq_t *rq) -{ - unsigned char *newbuf; - int len; - - a_assert(rq); - - if (rq->maxsize >= 0 && rq->buflen >= rq->maxsize) { - return 0; - } - - len = ringqLen(rq); - - if ((newbuf = balloc(B_L, rq->buflen + rq->increment)) == NULL) { - return 0; - } - ringqGetBlk(rq, newbuf, ringqLen(rq)); - bfree(B_L, (char*) rq->buf); - -#ifdef OLD - rq->endp = &newbuf[endp]; - rq->servp = &newbuf[servp]; - rq->endbuf = &newbuf[rq->buflen]; - rq->buf = newbuf; -#endif - - rq->buflen += rq->increment; - rq->endp = newbuf; - rq->servp = newbuf; - rq->buf = newbuf; - rq->endbuf = &rq->buf[rq->buflen]; - - ringqPutBlk(rq, newbuf, len); - -/* - * Double the increment so the next grow will line up with balloc'ed memory - */ - rq->increment = getBinBlockSize(2 * rq->increment); - - return 1; -} - -/******************************************************************************/ -/* - * Find the smallest binary memory size that "size" will fit into. This - * makes the ringq and ringqGrow routines much more efficient. The balloc - * routine likes powers of 2 minus 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/c/src/libnetworking/rtems_webserver/rom.c b/c/src/libnetworking/rtems_webserver/rom.c deleted file mode 100644 index f9ff5312ac..0000000000 --- a/c/src/libnetworking/rtems_webserver/rom.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * rom.c -- Support for ROMed page retrieval. - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/******************************** Description *********************************/ - -/* - * This module provides web page retrieval from compiled web pages. Use the - * webcomp program to compile web pages and link into the GoAhead WebServer. - * This module uses a hashed symbol table for fast page lookup. - * - * Usage: webcomp -f webPageFileList -p Prefix >webrom.c - */ - -/********************************* Includes ***********************************/ - -#include - -#include "wsIntrn.h" - -/******************************** Local Data **********************************/ - -#ifdef WEBS_PAGE_ROM - -sym_fd_t romTab; /* Symbol table for web pages */ - -/*********************************** Code *************************************/ -/* - * Open the ROM module - */ - -int websRomOpen() -{ - websRomPageIndexType *wip; - int nchars; - char_t name[SYM_MAX]; - - romTab = symOpen(WEBS_SYM_INIT); - - for (wip = websRomPageIndex; wip->path; wip++) { - gstrncpy(name, wip->path, SYM_MAX); - nchars = gstrlen(name) - 1; - if (nchars > 0 && - (name[nchars] == '/' || name[nchars] == '\\')) { - name[nchars] = '\0'; - } - symEnter(romTab, name, valueInteger((int) wip), 0); - } - return 0; -} - -/******************************************************************************/ -/* - * Close the ROM module - */ - -void websRomClose() -{ - symClose(romTab); -} - -/******************************************************************************/ -/* - * Open a web page - */ - -int websRomPageOpen(webs_t wp, char_t *path, int mode, int perm) -{ - websRomPageIndexType *wip; - sym_t *sp; - - a_assert(websValid(wp)); - a_assert(path && *path); - - if ((sp = symLookup(romTab, path)) == NULL) { - return -1; - } - wip = (websRomPageIndexType*) sp->content.value.integer; - wip->pos = 0; - return (wp->docfd = wip - websRomPageIndex); -} - -/******************************************************************************/ -/* - * Close a web page - */ - -void websRomPageClose(int fd) -{ -} - -/******************************************************************************/ -/* - * Stat a web page - */ - -int websRomPageStat(char_t *path, websStatType *sbuf) -{ - websRomPageIndexType *wip; - sym_t *sp; - - a_assert(path && *path); - - if ((sp = symLookup(romTab, path)) == NULL) { - return -1; - } - wip = (websRomPageIndexType*) sp->content.value.integer; - - memset(sbuf, 0, sizeof(websStatType)); - sbuf->size = wip->size; - if (wip->page == NULL) { - sbuf->isDir = 1; - } - return 0; -} - -/******************************************************************************/ -/* - * Read a web page - */ - -int websRomPageReadData(webs_t wp, char *buf, int nBytes) -{ - websRomPageIndexType *wip; - int len; - - a_assert(websValid(wp)); - a_assert(buf); - a_assert(wp->docfd >= 0); - - wip = &websRomPageIndex[wp->docfd]; - - len = min(wip->size - wip->pos, nBytes); - memcpy(buf, &wip->page[wip->pos], len); - wip->pos += len; - return len; -} - -/******************************************************************************/ -/* - * Position a web page - */ - -long websRomPageSeek(webs_t wp, long offset, int origin) -{ - websRomPageIndexType *wip; - long pos; - - a_assert(websValid(wp)); - a_assert(origin == SEEK_SET || origin == SEEK_CUR || origin == SEEK_END); - a_assert(wp->docfd >= 0); - - wip = &websRomPageIndex[wp->docfd]; - - if (origin != SEEK_SET && origin != SEEK_CUR && origin != SEEK_END) { - errno = EINVAL; - return -1; - } - - if (wp->docfd < 0) { - errno = EBADF; - return -1; - } - - pos = offset; - switch (origin) { - case SEEK_CUR: - pos = wip->pos + offset; - break; - case SEEK_END: - pos = wip->size + offset; - break; - default: - break; - } - - if (pos < 0) { - errno = EBADF; - return -1; - } - - return (wip->pos = pos); -} - -#endif /* WEBS_PAGE_ROM */ - -/******************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/rtems_webserver.h b/c/src/libnetworking/rtems_webserver/rtems_webserver.h deleted file mode 100644 index f62790b601..0000000000 --- a/c/src/libnetworking/rtems_webserver/rtems_webserver.h +++ /dev/null @@ -1,6 +0,0 @@ -/* - * rtems_webserver.h -- - * - */ - -int rtems_initialize_webserver(); diff --git a/c/src/libnetworking/rtems_webserver/security.c b/c/src/libnetworking/rtems_webserver/security.c deleted file mode 100644 index 9064b5d56f..0000000000 --- a/c/src/libnetworking/rtems_webserver/security.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * security.c -- Security handler - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/******************************** Description *********************************/ - -/* - * This module provides a basic security policy. - */ - -/********************************* Includes ***********************************/ - -#include "wsIntrn.h" -#include "um.h" -#ifdef DIGEST_ACCESS_SUPPORT -#include "websda.h" -#endif - -/********************************** Defines ***********************************/ -/* - * The following #defines change the behaviour of security in the absence - * of User Management. - * Note that use of User management functions require prior calling of - * umInit() to behave correctly - */ - -#ifndef USER_MANAGEMENT_SUPPORT -#define umGetAccessMethodForURL(url) AM_FULL -#define umUserExists(userid) 0 -#define umUserCanAccessURL(userid, url) 1 -#define umGetUserPassword(userid) websGetPassword() -#define umGetAccessLimitSecure(accessLimit) 0 -#define umGetAccessLimit(url) NULL -#endif - -/******************************** Local Data **********************************/ - -static char_t websPassword[WEBS_MAX_PASS]; /* Access password (decoded) */ -#ifdef _DEBUG -static int debugSecurity = 1; -#else -static int debugSecurity = 0; -#endif - -/*********************************** Code *************************************/ -/* - * Determine if this request should be honored - */ - -int websSecurityHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, - char_t *url, char_t *path, char_t *query) -{ - char_t *type, *userid, *password, *accessLimit; - int flags, nRet; - accessMeth_t am; - - a_assert(websValid(wp)); - a_assert(url && *url); - a_assert(path && *path); -/* - * Get the critical request details - */ - type = websGetRequestType(wp); - password = websGetRequestPassword(wp); - userid = websGetRequestUserName(wp); - flags = websGetRequestFlags(wp); -/* - * Get the access limit for the URL. Exit if none found. - */ - accessLimit = umGetAccessLimit(path); - if (accessLimit == NULL) { - return 0; - } - -/* - * Check to see if URL must be encrypted - */ -#ifdef WEBS_SSL_SUPPORT - nRet = umGetAccessLimitSecure(accessLimit); - if (nRet && ((flags & WEBS_SECURE) == 0)) { - websStats.access++; - websError(wp, 405, T("Access Denied\nSecure access is required.")); - trace(3, T("SEC: Non-secure access attempted on <%s>\n"), path); - /* bugfix 5/24/02 -- we were leaking the memory pointed to by - * 'accessLimit'. Thanks to Simon Byholm. - */ - bfree(B_L, accessLimit); - return 1; - } -#endif - -/* - * Get the access limit for the URL - */ - am = umGetAccessMethodForURL(accessLimit); - - nRet = 0; - if ((flags & WEBS_LOCAL_REQUEST) && (debugSecurity == 0)) { -/* - * Local access is always allowed (defeat when debugging) - */ - } else if (am == AM_NONE) { -/* - * URL is supposed to be hidden! Make like it wasn't found. - */ - websStats.access++; - websError(wp, 400, T("Page Not Found")); - nRet = 1; - } else if (userid && *userid) { - if (!umUserExists(userid)) { - websStats.access++; - websError(wp, 401, T("Access Denied\nUnknown User")); - trace(3, T("SEC: Unknown user <%s> attempted to access <%s>\n"), - userid, path); - nRet = 1; - } else if (!umUserCanAccessURL(userid, accessLimit)) { - websStats.access++; - websError(wp, 403, T("Access Denied\nProhibited User")); - nRet = 1; - } else if (password && * password) { - char_t * userpass = umGetUserPassword(userid); - if (userpass) { - if (gstrcmp(password, userpass) != 0) { - websStats.access++; - websError(wp, 401, T("Access Denied\nWrong Password")); - trace(3, T("SEC: Password fail for user <%s>") - T("attempt to access <%s>\n"), userid, path); - nRet = 1; - } else { -/* - * User and password check out. - */ - } - - bfree (B_L, userpass); - } -#ifdef DIGEST_ACCESS_SUPPORT - } else if (flags & WEBS_AUTH_DIGEST) { - - char_t *digestCalc; - -/* - * Check digest for equivalence - */ - wp->password = umGetUserPassword(userid); - - a_assert(wp->digest); - a_assert(wp->nonce); - a_assert(wp->password); - - digestCalc = websCalcDigest(wp); - a_assert(digestCalc); - - if (gstrcmp(wp->digest, digestCalc) != 0) { - websStats.access++; - websError(wp, 405, T("Access Denied\nWrong Password")); - nRet = 1; - } - - bfree (B_L, digestCalc); -#endif - } else { -/* - * No password has been specified - */ -#ifdef DIGEST_ACCESS_SUPPORT - if (am == AM_DIGEST) { - wp->flags |= WEBS_AUTH_DIGEST; - } -#endif - websStats.errors++; - websError(wp, 401, - T("Access to this document requires a password")); - nRet = 1; - } - } else if (am != AM_FULL) { -/* - * This will cause the browser to display a password / username - * dialog - */ -#ifdef DIGEST_ACCESS_SUPPORT - if (am == AM_DIGEST) { - wp->flags |= WEBS_AUTH_DIGEST; - } -#endif - websStats.errors++; - websError(wp, 401, T("Access to this document requires a User ID")); - nRet = 1; - } - - bfree(B_L, accessLimit); - - return nRet; -} - -/******************************************************************************/ -/* - * Delete the default security handler - */ - -void websSecurityDelete() -{ - websUrlHandlerDelete(websSecurityHandler); -} - -/******************************************************************************/ -/* - * Store the new password, expect a decoded password. Store in websPassword in - * the decoded form. - */ - -void websSetPassword(char_t *password) -{ - a_assert(password); - - gstrncpy(websPassword, password, TSZ(websPassword)); -} - -/******************************************************************************/ -/* - * Get password, return the decoded form - */ - -char_t *websGetPassword() -{ - return bstrdup(B_L, websPassword); -} - -/******************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/sock.c b/c/src/libnetworking/rtems_webserver/sock.c deleted file mode 100644 index fce0b692cb..0000000000 --- a/c/src/libnetworking/rtems_webserver/sock.c +++ /dev/null @@ -1,791 +0,0 @@ -/* - * sock.c -- Posix Socket upper layer support module for general posix use - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * $Id$ - */ - -/******************************** Description *********************************/ - -/* - * Posix Socket Module. This supports blocking and non-blocking buffered - * socket I/O. - */ - -/********************************** Includes **********************************/ - -#include -#include - -#ifdef UEMF - #include "uemf.h" -#else - #include - #include - #include - #include "emfInternal.h" -#endif - -/************************************ Locals **********************************/ - -socket_t **socketList; /* List of open sockets */ -int socketMax; /* Maximum size of socket */ -int socketHighestFd = -1; /* Highest socket fd opened */ - -/***************************** Forward Declarations ***************************/ - -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); - -/*********************************** Code *************************************/ -/* - * Write to a socket. Absorb as much data as the socket can buffer. Block if - * the socket is in blocking mode. Returns -1 on error, otherwise the number - * of bytes written. - */ - -int socketWrite(int sid, char *buf, int bufsize) -{ - socket_t *sp; - ringq_t *rq; - int len, bytesWritten, room; - - a_assert(buf); - a_assert(bufsize >= 0); - - if ((sp = socketPtr(sid)) == NULL) { - return -1; - } - -/* - * Loop adding as much data to the output ringq as we can absorb. Initiate a - * flush when the ringq is too full and continue. Block in socketFlush if the - * socket is in blocking mode. - */ - 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; - } - len = min(room, bufsize); - ringqPutBlk(rq, (unsigned char *) buf, len); - bytesWritten += len; - bufsize -= len; - buf += len; - } - return bytesWritten; -} - -/******************************************************************************/ -/* - * Write a string to a socket - */ - -int socketWriteString(int sid, char_t *buf) -{ - #ifdef UNICODE - char *byteBuf; - int r, len; - - len = gstrlen(buf); - byteBuf = ballocUniToAsc(buf, len); - r = socketWrite(sid, byteBuf, len); - bfreeSafe(B_L, byteBuf); - return r; - #else - return socketWrite(sid, buf, strlen(buf)); - #endif /* UNICODE */ -} - -/******************************************************************************/ -/* - * Read from a socket. Return the number of bytes read if successful. This - * may be less than the requested "bufsize" and may be zero. Return -1 for - * errors. Return 0 for EOF. Otherwise return the number of bytes read. - * If this routine returns zero it indicates an EOF condition. - * which can be verified with socketEof() - - * Note: this ignores the line buffer, so a previous socketGets - * which read a partial line may cause a subsequent socketRead to miss some - * data. This routine may block if the socket is in blocking mode. - * - */ - -int socketRead(int sid, char *buf, int bufsize) -{ - socket_t *sp; - ringq_t *rq; - int 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; ) { - len = min(ringqLen(rq), bufsize); - if (len <= 0) { -/* - * if blocking mode and already have data, exit now or it may block - * forever. - */ - if ((sp->flags & SOCKET_BLOCK) && - (bytesRead > 0)) { - break; - } -/* - * This flush is critical for readers of datagram packets. If the - * buffer is not big enough to read the whole datagram in one hit, - * the recvfrom call will fail. - */ - ringqFlush(rq); - room = ringqPutBlkMax(rq); - len = socketGetInput(sid, (char *) rq->endp, room, &errCode); - if (len < 0) { - if (errCode == EWOULDBLOCK) { - if ((sp->flags & SOCKET_BLOCK) && - (bytesRead == 0)) { - continue; - } - if (bytesRead >= 0) { - return bytesRead; - } - } - return -1; - - } else if (len == 0) { -/* - * If bytesRead is 0, this is EOF since socketRead should never - * be called unless there is data yet to be read. Set the flag. - * Then pass back the number of bytes read. - */ - if (bytesRead == 0) { - sp->flags |= SOCKET_EOF; - } - return bytesRead; - } - ringqPutBlkAdj(rq, len); - len = min(len, bufsize); - } - memcpy(&buf[bytesRead], rq->servp, len); - ringqGetBlkAdj(rq, len); - bufsize -= len; - bytesRead += len; - } - return bytesRead; -} - -/******************************************************************************/ -/* - * Get a string from a socket. This returns data in *buf in a malloced string - * after trimming the '\n'. If there is zero bytes returned, *buf will be set - * to NULL. If doing non-blocking I/O, it returns -1 for error, EOF or when - * no complete line yet read. If doing blocking I/O, it will block until an - * entire line is read. If a partial line is read socketInputBuffered or - * socketEof can be used to distinguish between EOF and partial line still - * buffered. This routine eats and ignores carriage returns. - */ - -int socketGets(int sid, char_t **buf) -{ - socket_t *sp; - ringq_t *lq; - char c; - int rc, len; - - a_assert(buf); - *buf = NULL; - - if ((sp = socketPtr(sid)) == NULL) { - return -1; - } - lq = &sp->lineBuf; - - while (1) { - - if ((rc = socketRead(sid, &c, 1)) < 0) { - return rc; - } - - if (rc == 0) { -/* - * If there is a partial line and we are at EOF, pretend we saw a '\n' - */ - if (ringqLen(lq) > 0 && (sp->flags & SOCKET_EOF)) { - c = '\n'; - } else { - return -1; - } - } -/* - * If a newline is seen, return the data excluding the new line to the - * caller. If carriage return is seen, just eat it. - */ - if (c == '\n') { - len = ringqLen(lq); - if (len > 0) { - *buf = ballocAscToUni((char *)lq->servp, len); - } else { - *buf = NULL; - } - ringqFlush(lq); - return len; - - } else if (c == '\r') { - continue; - } - ringqPutcA(lq, c); - } - return 0; -} - -/******************************************************************************/ -/* - * Flush the socket. Block if the socket is in blocking mode. - * This will return -1 on errors and 0 if successful. - */ - -int socketFlush(int sid) -{ - socket_t *sp; - ringq_t *rq; - int len, bytesWritten, errCode; - - if ((sp = socketPtr(sid)) == NULL) { - return -1; - } - rq = &sp->outBuf; - -/* - * Set the background flushing flag which socketEventProc will check to - * continue the flush. - */ - if (! (sp->flags & SOCKET_BLOCK)) { - sp->flags |= SOCKET_FLUSHING; - } - -/* - * Break from loop if not blocking after initiating output. If we are blocking - * we wait for a write event. - */ - while (ringqLen(rq) > 0) { - len = ringqGetBlkMax(&sp->outBuf); - bytesWritten = socketDoOutput(sp, (char*) rq->servp, len, &errCode); - if (bytesWritten < 0) { - if (errCode == EINTR) { - continue; - } else if (errCode == EWOULDBLOCK || errCode == EAGAIN) { -#if (defined (WIN) || defined (CE)) - if (sp->flags & SOCKET_BLOCK) { - int errCode; - if (! socketWaitForEvent(sp, FD_WRITE | SOCKET_WRITABLE, - &errCode)) { - return -1; - } - continue; - } -#endif -/* - * Ensure we get a FD_WRITE message when the socket can absorb - * more data (non-blocking only.) Store the user's mask if we - * haven't done it already. - */ - if (sp->saveMask < 0 ) { - sp->saveMask = sp->handlerMask; - socketRegisterInterest(sp, - sp->handlerMask | SOCKET_WRITABLE); - } - return 0; - } - return -1; - } - ringqGetBlkAdj(rq, bytesWritten); - } -/* - * If the buffer is empty, reset the ringq pointers to point to the start - * of the buffer. This is essential to ensure that datagrams get written - * in one single I/O operation. - */ - if (ringqLen(rq) == 0) { - ringqFlush(rq); - } -/* - * Restore the users mask if it was saved by the non-blocking code above. - * Note: saveMask = -1 if empty. socketRegisterInterest will set handlerMask - */ - if (sp->saveMask >= 0) { - socketRegisterInterest(sp, sp->saveMask); - sp->saveMask = -1; - } - sp->flags &= ~SOCKET_FLUSHING; - return 0; -} - -/******************************************************************************/ -/* - * Return the count of input characters buffered. We look at both the line - * buffer and the input (raw) buffer. Return -1 on error or EOF. - */ - -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); -} - -/******************************************************************************/ -/* - * Return true if EOF - */ - -int socketEof(int sid) -{ - socket_t *sp; - - if ((sp = socketPtr(sid)) == NULL) { - return -1; - } - return sp->flags & SOCKET_EOF; -} - -/******************************************************************************/ -/* - * Return the number of bytes the socket can absorb without blocking - */ - -int socketCanWrite(int sid) -{ - socket_t *sp; - - if ((sp = socketPtr(sid)) == NULL) { - return -1; - } - return sp->outBuf.buflen - ringqLen(&sp->outBuf) - 1; -} - -/******************************************************************************/ -/* - * Add one to allow the user to write exactly SOCKET_BUFSIZ - */ - -void socketSetBufferSize(int sid, int in, int line, int out) -{ - socket_t *sp; - - if ((sp = socketPtr(sid)) == NULL) { - return; - } - - if (in >= 0) { - ringqClose(&sp->inBuf); - in++; - ringqOpen(&sp->inBuf, in, in); - } - - if (line >= 0) { - ringqClose(&sp->lineBuf); - line++; - ringqOpen(&sp->lineBuf, line, line); - } - - if (out >= 0) { - ringqClose(&sp->outBuf); - out++; - ringqOpen(&sp->outBuf, out, out); - } -} - -/******************************************************************************/ -/* - * Create a user handler for this socket. The handler called whenever there - * is an event of interest as defined by handlerMask (SOCKET_READABLE, ...) - */ - -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); -} - -/******************************************************************************/ -/* - * Delete a handler - */ - -void socketDeleteHandler(int sid) -{ - socket_t *sp; - - if ((sp = socketPtr(sid)) == NULL) { - return; - } - sp->handler = NULL; - socketRegisterInterest(sp, 0); -} - -/******************************************************************************/ -/* - * Socket output procedure. Return -1 on errors otherwise return the number - * of bytes written. - */ - -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 (defined (WIN) || defined (CE)) - if ((sp->flags & SOCKET_ASYNC) - && ! socketWaitForEvent(sp, FD_CONNECT, errCode)) { - return -1; - } -#endif - -/* - * Write the data - */ - if (sp->flags & SOCKET_BROADCAST) { - server.sin_family = AF_INET; -#if (defined (UEMF) || defined (LITTLEFOOT)) - server.sin_addr.s_addr = INADDR_BROADCAST; -#else - server.sin_addr.s_addr = inet_addr(basicGetBroadcastAddress()); -#endif - server.sin_port = htons((short)(sp->port & 0xFFFF)); - if ((bytes = sendto(sp->sock, buf, toWrite, 0, - (struct sockaddr *) &server, sizeof(server))) < 0) { - bytes = tryAlternateSendTo(sp->sock, buf, toWrite, 0, - (struct sockaddr *) &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(); -#if (defined (WIN) || defined (CE)) - sp->currentEvents &= ~FD_WRITE; -#endif - - return -1; - - } else if (bytes == 0 && bytes != toWrite) { - *errCode = EWOULDBLOCK; -#if (defined (WIN) || defined (CE)) - sp->currentEvents &= ~FD_WRITE; -#endif - return -1; - } - -/* - * Ensure we get to write some more data real soon if the socket can absorb - * more data - */ -#ifndef UEMF -#ifdef WIN - if (sp->interestEvents & FD_WRITE) { - emfTime_t blockTime = { 0, 0 }; - emfSetMaxBlockTime(&blockTime); - } -#endif /* WIN */ -#endif - return bytes; -} - -/******************************************************************************/ -/* - * If the sendto failed, swap the first two bytes in the - * sockaddr structure. This is a kludge due to a change in - * VxWorks between versions 5.3 and 5.4, but we want the - * product to run on either. - */ -static int tryAlternateSendTo(int sock, char *buf, int toWrite, int i, - struct sockaddr *server) -{ -#ifdef VXWORKS - char *ptr; - - ptr = (char *)server; - *ptr = *(ptr+1); - *(ptr+1) = 0; - return sendto(sock, buf, toWrite, i, server, sizeof(struct sockaddr)); -#else - return -1; -#endif /* VXWORKS */ -} - -/******************************************************************************/ -/* - * Allocate a new socket structure - */ - -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)); - } - -/* - * Preserve only specified flags from the callers open - */ - a_assert((flags & ~(SOCKET_BROADCAST|SOCKET_DATAGRAM|SOCKET_BLOCK| - SOCKET_LISTENING)) == 0); - sp->flags = flags & (SOCKET_BROADCAST | SOCKET_DATAGRAM | SOCKET_BLOCK| - SOCKET_LISTENING); - -/* - * Add one to allow the user to write exactly SOCKET_BUFSIZ - */ - ringqOpen(&sp->inBuf, SOCKET_BUFSIZ, SOCKET_BUFSIZ); - ringqOpen(&sp->outBuf, SOCKET_BUFSIZ + 1, SOCKET_BUFSIZ + 1); - ringqOpen(&sp->lineBuf, SOCKET_BUFSIZ, -1); - - return sid; -} - -/******************************************************************************/ -/* - * Free a socket structure - */ - -void socketFree(int sid) -{ - socket_t *sp; - char_t buf[256]; - int i; - - if ((sp = socketPtr(sid)) == NULL) { - return; - } - -/* - * To close a socket, remove any registered interests, set it to - * non-blocking so that the recv which follows won't block, do a - * shutdown on it so peers on the other end will receive a FIN, - * then read any data not yet retrieved from the receive buffer, - * and finally close it. If these steps are not all performed - * RESETs may be sent to the other end causing problems. - */ - socketRegisterInterest(sp, 0); - if (sp->sock >= 0) { - socketSetBlock(sid, 0); - if (shutdown(sp->sock, 1) >= 0) { - recv(sp->sock, buf, sizeof(buf), 0); - } -#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); - -/* - * Calculate the new highest socket number - */ - socketHighestFd = -1; - for (i = 0; i < socketMax; i++) { - if ((sp = socketList[i]) == NULL) { - continue; - } - socketHighestFd = max(socketHighestFd, sp->sock); - } -} - -/******************************************************************************/ -/* - * Validate a socket handle - */ - -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]; -} - -/******************************************************************************/ -/* - * Get the operating system error code - */ - -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 -} - -/******************************************************************************/ -/* - * Return the underlying socket handle - */ - -int socketGetHandle(int sid) -{ - socket_t *sp; - - if ((sp = socketPtr(sid)) == NULL) { - return -1; - } - return sp->sock; -} - -/******************************************************************************/ -/* - * Get blocking mode - */ - -int socketGetBlock(int sid) -{ - socket_t *sp; - - if ((sp = socketPtr(sid)) == NULL) { - a_assert(0); - return 0; - } - return (sp->flags & SOCKET_BLOCK); -} - -/******************************************************************************/ -/* - * Get mode - */ - -int socketGetMode(int sid) -{ - socket_t *sp; - - if ((sp = socketPtr(sid)) == NULL) { - a_assert(0); - return 0; - } - return sp->flags; -} - -/******************************************************************************/ -/* - * Set mode - */ - -void socketSetMode(int sid, int mode) -{ - socket_t *sp; - - if ((sp = socketPtr(sid)) == NULL) { - a_assert(0); - return; - } - sp->flags = mode; -} - -/******************************************************************************/ -/* - * Get port. - */ - -int socketGetPort(int sid) -{ - socket_t *sp; - - if ((sp = socketPtr(sid)) == NULL) { - return -1; - } - return sp->port; -} - -/******************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/sockGen.c b/c/src/libnetworking/rtems_webserver/sockGen.c deleted file mode 100644 index 822aea6407..0000000000 --- a/c/src/libnetworking/rtems_webserver/sockGen.c +++ /dev/null @@ -1,1043 +0,0 @@ - -/* - * sockGen.c -- Posix Socket support module for general posix use - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * $Id$ - */ - -/******************************** Description *********************************/ - -/* - * Posix Socket Module. This supports blocking and non-blocking buffered - * socket I/O. - */ - -#if (!defined (WIN) || defined (LITTLEFOOT) || defined (WEBS)) - -/********************************** Includes **********************************/ - -#include -#include -#include -#include - -#ifdef UEMF - #include "uemf.h" -#else - #include - #include - #include - #include "emfInternal.h" -#endif - -#ifdef VXWORKS - #include -#endif - -/************************************ Locals **********************************/ - -extern socket_t **socketList; /* List of open sockets */ -extern int socketMax; /* Maximum size of socket */ -extern int socketHighestFd; /* Highest socket fd opened */ -static int socketOpenCount = 0; /* Number of task using sockets */ - -/***************************** Forward Declarations ***************************/ - -static void socketAccept(socket_t *sp); -static int socketDoEvent(socket_t *sp); -static int tryAlternateConnect(int sock, struct sockaddr *sockaddr); - -/*********************************** Code *************************************/ -/* - * Open socket module - */ - -int socketOpen() -{ -#if (defined (CE) || defined (WIN)) - WSADATA wsaData; -#endif - - if (++socketOpenCount > 1) { - return 0; - } - -#if (defined (CE) || defined (WIN)) - if (WSAStartup(MAKEWORD(1,1), &wsaData) != 0) { - return -1; - } - if (wsaData.wVersion != MAKEWORD(1,1)) { - WSACleanup(); - return -1; - } -#endif - - socketList = NULL; - socketMax = 0; - socketHighestFd = -1; - - return 0; -} - -/******************************************************************************/ -/* - * Close the socket module, by closing all open connections - */ - -void socketClose() -{ - int i; - - if (--socketOpenCount <= 0) { - for (i = socketMax; i >= 0; i--) { - if (socketList && socketList[i]) { - socketCloseConnection(i); - } - } - socketOpenCount = 0; - } -} - -/******************************************************************************/ -/* - * Open a client or server socket. Host is NULL if we want server capability. - */ - -int socketOpenConnection(char *host, int port, socketAccept_t accept, int flags) -{ -#if (!defined (NO_GETHOSTBYNAME) && !defined (VXWORKS)) - struct hostent *hostent; /* Host database entry */ -#endif /* ! (NO_GETHOSTBYNAME || VXWORKS) */ - socket_t *sp; - struct sockaddr_in sockaddr; - int sid, bcast, dgram, rc; - - if (port > SOCKET_PORT_MAX) { - return -1; - } -/* - * Allocate a socket structure - */ - if ((sid = socketAlloc(host, port, accept, flags)) < 0) { - return -1; - } - sp = socketList[sid]; - a_assert(sp); - -/* - * Create the socket address structure - */ - memset((char *) &sockaddr, '\0', sizeof(struct sockaddr_in)); - sockaddr.sin_family = AF_INET; - sockaddr.sin_port = htons((short) (port & 0xFFFF)); - - if (host == NULL) { - sockaddr.sin_addr.s_addr = INADDR_ANY; - } else { - sockaddr.sin_addr.s_addr = inet_addr(host); - if (sockaddr.sin_addr.s_addr == INADDR_NONE) { -/* - * If the OS does not support gethostbyname functionality, the macro: - * NO_GETHOSTBYNAME should be defined to skip the use of gethostbyname. - * Unfortunatly there is no easy way to recover, the following code - * simply uses the basicGetHost IP for the sockaddr. - */ - -#ifdef NO_GETHOSTBYNAME - if (strcmp(host, basicGetHost()) == 0) { - sockaddr.sin_addr.s_addr = inet_addr(basicGetAddress()); - } - if (sockaddr.sin_addr.s_addr == INADDR_NONE) { - socketFree(sid); - return -1; - } -#elif (defined (VXWORKS)) - sockaddr.sin_addr.s_addr = (unsigned long) hostGetByName(host); - if (sockaddr.sin_addr.s_addr == NULL) { - errno = ENXIO; - socketFree(sid); - return -1; - } -#else - hostent = gethostbyname(host); - if (hostent != NULL) { - memcpy((char *) &sockaddr.sin_addr, - (char *) hostent->h_addr_list[0], - (size_t) hostent->h_length); - } else { - char *asciiAddress; - char_t *address; - - address = basicGetAddress(); - asciiAddress = ballocUniToAsc(address, gstrlen(address)); - sockaddr.sin_addr.s_addr = inet_addr(asciiAddress); - bfree(B_L, asciiAddress); - if (sockaddr.sin_addr.s_addr == INADDR_NONE) { - errno = ENXIO; - socketFree(sid); - return -1; - } - } -#endif /* (NO_GETHOSTBYNAME || VXWORKS) */ - } - } - - bcast = sp->flags & SOCKET_BROADCAST; - if (bcast) { - sp->flags |= SOCKET_DATAGRAM; - } - dgram = sp->flags & SOCKET_DATAGRAM; - -/* - * Create the socket. Support for datagram sockets. Set the close on - * exec flag so children don't inherit the socket. - */ - sp->sock = socket(AF_INET, dgram ? SOCK_DGRAM: SOCK_STREAM, 0); - if (sp->sock < 0) { - socketFree(sid); - return -1; - } -#ifndef __NO_FCNTL - fcntl(sp->sock, F_SETFD, FD_CLOEXEC); -#endif - socketHighestFd = max(socketHighestFd, sp->sock); - -/* - * If broadcast, we need to turn on broadcast capability. - */ - if (bcast) { - int broadcastFlag = 1; - if (setsockopt(sp->sock, SOL_SOCKET, SO_BROADCAST, - (char *) &broadcastFlag, sizeof(broadcastFlag)) < 0) { - socketFree(sid); - return -1; - } - } - -/* - * Host is set if we are the client - */ - if (host) { -/* - * Connect to the remote server in blocking mode, then go into - * non-blocking mode if desired. - */ - if (!dgram) { - if (! (sp->flags & SOCKET_BLOCK)) { -/* - * sockGen.c is only used for Windows products when blocking - * connects are expected. This applies to FieldUpgrader - * agents and open source webserver connectws. Therefore the - * asynchronous connect code here is not compiled. - */ -#if (defined (WIN) || defined (CE)) && (!defined (LITTLEFOOT) && !defined (WEBS)) - int flag; - - sp->flags |= SOCKET_ASYNC; -/* - * Set to non-blocking for an async connect - */ - flag = 1; - if (ioctlsocket(sp->sock, FIONBIO, &flag) == SOCKET_ERROR) { - socketFree(sid); - return -1; - } -#else - socketSetBlock(sid, 1); -#endif /* #if (WIN || CE) && !(LITTLEFOOT || WEBS) */ - - } - if ((rc = connect(sp->sock, (struct sockaddr *) &sockaddr, - sizeof(sockaddr))) < 0 && - (rc = tryAlternateConnect(sp->sock, - (struct sockaddr *) &sockaddr)) < 0) { -#if (defined (WIN) || defined (CE)) - if (socketGetError() != EWOULDBLOCK) { - socketFree(sid); - return -1; - } -#else - socketFree(sid); - return -1; - -#endif /* WIN || CE */ - - } - } - } else { -/* - * Bind to the socket endpoint and the call listen() to start listening - */ - rc = 1; - setsockopt(sp->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&rc, sizeof(rc)); - 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; - } -#ifndef UEMF - sp->fileHandle = emfCreateFileHandler(sp->sock, SOCKET_READABLE, - (emfFileProc *) socketAccept, (void *) sp); -#else - sp->flags |= SOCKET_LISTENING; -#endif - } - sp->handlerMask |= SOCKET_READABLE; - } - -/* - * Set the blocking mode - */ - - if (flags & SOCKET_BLOCK) { - socketSetBlock(sid, 1); - } else { - socketSetBlock(sid, 0); - } - return sid; -} - - -/******************************************************************************/ -/* - * If the connection failed, swap the first two bytes in the - * sockaddr structure. This is a kludge due to a change in - * VxWorks between versions 5.3 and 5.4, but we want the - * product to run on either. - */ - -static int tryAlternateConnect(int sock, struct sockaddr *sockaddr) -{ -#ifdef VXWORKS - char *ptr; - - ptr = (char *)sockaddr; - *ptr = *(ptr+1); - *(ptr+1) = 0; - return connect(sock, sockaddr, sizeof(struct sockaddr)); -#else - return -1; -#endif /* VXWORKS */ -} - -/******************************************************************************/ -/* - * Close a socket - */ - -void socketCloseConnection(int sid) -{ - socket_t *sp; - - if ((sp = socketPtr(sid)) == NULL) { - return; - } - socketFree(sid); -} - -/******************************************************************************/ -/* - * Accept a connection. Called as a callback on incoming connection. - */ - -static void socketAccept(socket_t *sp) -{ - struct sockaddr_in addr; - socket_t *nsp; - size_t len; - char *pString; - int newSock, nid; - - -#ifdef NW - NETINET_DEFINE_CONTEXT; -#endif - - a_assert(sp); - -/* - * Accept the connection and prevent inheriting by children (F_SETFD) - */ - len = sizeof(struct sockaddr_in); - if ((newSock = accept(sp->sock, (struct sockaddr *) &addr, (int *) &len)) < 0) { - return; - } -#ifndef __NO_FCNTL - fcntl(newSock, F_SETFD, FD_CLOEXEC); -#endif - socketHighestFd = max(socketHighestFd, newSock); - -/* - * Create a socket structure and insert into the socket list - */ - nid = socketAlloc(sp->host, sp->port, sp->accept, sp->flags); - nsp = socketList[nid]; - a_assert(nsp); - nsp->sock = newSock; - nsp->flags &= ~SOCKET_LISTENING; - - if (nsp == NULL) { - return; - } -/* - * Set the blocking mode before calling the accept callback. - */ - - socketSetBlock(nid, (nsp->flags & SOCKET_BLOCK) ? 1: 0); -/* - * Call the user accept callback. The user must call socketCreateHandler - * to register for further events of interest. - */ - if (sp->accept != NULL) { - pString = inet_ntoa(addr.sin_addr); - if ((sp->accept)(nid, pString, ntohs(addr.sin_port), sp->sid) < 0) { - socketFree(nid); - } -#ifdef VXWORKS - free(pString); -#endif - } -} - -/******************************************************************************/ -/* - * Get more input from the socket and return in buf. - * Returns 0 for EOF, -1 for errors and otherwise the number of bytes read. - */ - -int socketGetInput(int sid, char *buf, int toRead, int *errCode) -{ - struct sockaddr_in server; - socket_t *sp; - int len, bytesRead; - - a_assert(buf); - a_assert(errCode); - - *errCode = 0; - - if ((sp = socketPtr(sid)) == NULL) { - return -1; - } - -/* - * If we have previously seen an EOF condition, then just return - */ - if (sp->flags & SOCKET_EOF) { - return 0; - } -#if ((defined (WIN) || defined (CE)) && (!defined (LITTLEFOOT) && !defined (WEBS))) - if ( !(sp->flags & SOCKET_BLOCK) - && ! socketWaitForEvent(sp, FD_CONNECT, errCode)) { - return -1; - } -#endif - -/* - * Read the data - */ - 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); - } - - /* - * BUG 01865 -- CPU utilization hangs on Windows. The original code used - * the 'errno' global variable, which is not set by the winsock functions - * as it is under *nix platforms. We use the platform independent - * socketGetError() function instead, which does handle Windows correctly. - * Other, *nix compatible platforms should work as well, since on those - * platforms, socketGetError() just returns the value of errno. - * Thanks to Jonathan Burgoyne for the fix. - */ - if (bytesRead < 0) - { - *errCode = socketGetError(); - if (*errCode == ECONNRESET) - { - sp->flags |= SOCKET_CONNRESET; - return 0; - } - return -1; - } - return bytesRead; -} - -/******************************************************************************/ -/* - * Process an event on the event queue - */ - -#ifndef UEMF - -static int socketEventProc(void *data, int mask) -{ - socket_t *sp; - ringq_t *rq; - int sid; - - sid = (int) data; - - a_assert(sid >= 0 && sid < socketMax); - a_assert(socketList[sid]); - - if ((sp = socketPtr(sid)) == NULL) { - return 1; - } - -/* - * If now writable and flushing in the background, continue flushing - */ - if (mask & SOCKET_WRITABLE) { - if (sp->flags & SOCKET_FLUSHING) { - rq = &sp->outBuf; - if (ringqLen(rq) > 0) { - socketFlush(sp->sid); - } else { - sp->flags &= ~SOCKET_FLUSHING; - } - } - } - -/* - * Now invoke the users socket handler. NOTE: the handler may delete the - * socket, so we must be very careful after calling the handler. - */ - if (sp->handler && (sp->handlerMask & mask)) { - (sp->handler)(sid, mask & sp->handlerMask, sp->handler_data); - } - if (socketList && sid < socketMax && socketList[sid] == sp) { - socketRegisterInterest(sp, sp->handlerMask); - } - return 1; -} -#endif /* ! UEMF */ - -/******************************************************************************/ -/* - * Define the events of interest - */ - -void socketRegisterInterest(socket_t *sp, int handlerMask) -{ - a_assert(sp); - - sp->handlerMask = handlerMask; -#ifndef UEMF - if (handlerMask) { - sp->fileHandle = emfCreateFileHandler(sp->sock, handlerMask, - (emfFileProc *) socketEventProc, (void *) sp->sid); - } else { - emfDeleteFileHandler(sp->fileHandle); - sp->fileHandle = -1; - } -#endif /* ! UEMF */ -} - -/******************************************************************************/ -/* - * Wait until an event occurs on a socket. Return 1 on success, 0 on failure. - * or -1 on exception (UEMF only) - */ - -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; -} - -/******************************************************************************/ -/* - * Return TRUE if there is a socket with an event ready to process, - */ - -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 there is input data, also call select to test for new events - */ - if (sp->handlerMask & SOCKET_READABLE && socketInputBuffered(sid) > 0) { - socketSelect(sid, 0); - return 1; - } - if (! all) { - break; - } - } - return 0; -} - -/******************************************************************************/ -/* - * Wait for a handle to become readable or writable and return a number of - * noticed events. Timeout is in milliseconds. - */ - -#if (defined (WIN) || defined (CE) || defined (NW)) - -int socketSelect(int sid, int timeout) -{ - struct timeval tv; - socket_t *sp; - fd_set readFds, writeFds, exceptFds; - int nEvents; - int all, socketHighestFd; /* Highest socket fd opened */ - - FD_ZERO(&readFds); - FD_ZERO(&writeFds); - FD_ZERO(&exceptFds); - socketHighestFd = -1; - - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - -/* - * Set the select event masks for events to watch - */ - all = nEvents = 0; - - if (sid < 0) { - all++; - sid = 0; - } - - for (; sid < socketMax; sid++) { - if ((sp = socketList[sid]) == NULL) { - continue; - } - a_assert(sp); -/* - * Set the appropriate bit in the ready masks for the sp->sock. - */ - if (sp->handlerMask & SOCKET_READABLE) { - FD_SET(sp->sock, &readFds); - nEvents++; - if (socketInputBuffered(sid) > 0) { - tv.tv_sec = 0; - tv.tv_usec = 0; - } - } - if (sp->handlerMask & SOCKET_WRITABLE) { - FD_SET(sp->sock, &writeFds); - nEvents++; - } - if (sp->handlerMask & SOCKET_EXCEPTION) { - FD_SET(sp->sock, &exceptFds); - nEvents++; - } - if (! all) { - break; - } - } - -/* - * Windows select() fails if no descriptors are set, instead of just sleeping - * like other, nice select() calls. So, if WIN, sleep. - */ - if (nEvents == 0) { - Sleep(timeout); - return 0; - } - -/* - * Wait for the event or a timeout. - */ - nEvents = select(socketHighestFd+1, &readFds, &writeFds, &exceptFds, &tv); - - if (all) { - sid = 0; - } - for (; sid < socketMax; sid++) { - if ((sp = socketList[sid]) == NULL) { - continue; - } - - if (FD_ISSET(sp->sock, &readFds) || socketInputBuffered(sid) > 0) { - sp->currentEvents |= SOCKET_READABLE; - } - if (FD_ISSET(sp->sock, &writeFds)) { - sp->currentEvents |= SOCKET_WRITABLE; - } - if (FD_ISSET(sp->sock, &exceptFds)) { - sp->currentEvents |= SOCKET_EXCEPTION; - } - if (! all) { - break; - } - } - - return nEvents; -} - -#else /* not WIN || CE || NW */ - -int socketSelect(int sid, int timeout) -{ - socket_t *sp; - struct timeval tv; - fd_mask *readFds, *writeFds, *exceptFds; - int all, len, nwords, index, bit, nEvents; - -/* - * Allocate and zero the select masks - */ - nwords = (socketHighestFd + NFDBITS) / NFDBITS; - len = nwords * sizeof(int); - - readFds = balloc(B_L, len); - memset(readFds, 0, len); - writeFds = balloc(B_L, len); - memset(writeFds, 0, len); - exceptFds = balloc(B_L, len); - memset(exceptFds, 0, len); - - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - -/* - * Set the select event masks for events to watch - */ - 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); - -/* - * Initialize the ready masks and compute the mask offsets. - */ - index = sp->sock / (NBBY * sizeof(fd_mask)); - bit = 1 << (sp->sock % (NBBY * sizeof(fd_mask))); - -/* - * Set the appropriate bit in the ready masks for the sp->sock. - */ - 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; - } - } - -/* - * Wait for the event or a timeout. Reset nEvents to be the number of actual - * events now. - */ - 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; -} -#endif /* WIN || CE */ - -/******************************************************************************/ -/* - * Process socket events - */ - -void socketProcess(int sid) -{ - socket_t *sp; - int all; - - all = 0; - if (sid < 0) { - all = 1; - sid = 0; - } -/* - * Process each socket - */ - for (; sid < socketMax; sid++) { - if ((sp = socketList[sid]) == NULL) { - if (! all) { - break; - } else { - continue; - } - } - if (socketReady(sid)) { - socketDoEvent(sp); - } - if (! all) { - break; - } - } -} - -/******************************************************************************/ -/* - * Process an event on the event queue - */ - -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 there is still read data in the buffers, trigger the read handler - * NOTE: this may busy spin if the read handler doesn't read the data - */ - if (sp->handlerMask & SOCKET_READABLE && socketInputBuffered(sid) > 0) { - sp->currentEvents |= SOCKET_READABLE; - } - } - - -/* - * If now writable and flushing in the background, continue flushing - */ - 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; - } - } - } - -/* - * Now invoke the users socket handler. NOTE: the handler may delete the - * socket, so we must be very careful after calling the handler. - */ - if (sp->handler && (sp->handlerMask & sp->currentEvents)) { - (sp->handler)(sid, sp->handlerMask & sp->currentEvents, - sp->handler_data); -/* - * Make sure socket pointer is still valid, then reset the currentEvents. - */ - if (socketList && sid < socketMax && socketList[sid] == sp) { - sp->currentEvents = 0; - } - } - return 1; -} - -/******************************************************************************/ -/* - * Set the socket blocking mode - */ - -int socketSetBlock(int sid, int on) -{ - socket_t *sp; - unsigned long flag; - int iflag; - int oldBlock; - - 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; - } - -/* - * Put the socket into block / non-blocking mode - */ - if (sp->flags & SOCKET_BLOCK) { -#if (defined (CE) || defined (WIN)) - ioctlsocket(sp->sock, FIONBIO, &flag); -#elif (defined (ECOS)) - int off; - off = 0; - ioctl(sp->sock, FIONBIO, &off); -#elif (defined (VXWORKS) || defined (NW)) - ioctl(sp->sock, FIONBIO, (int)&iflag); -#else - fcntl(sp->sock, F_SETFL, fcntl(sp->sock, F_GETFL) & ~O_NONBLOCK); -#endif - - } else { -#if (defined (CE) || defined (WIN)) - ioctlsocket(sp->sock, FIONBIO, &flag); -#elif (defined (ECOS)) - int on; - on = 1; - ioctl(sp->sock, FIONBIO, &on); -#elif (defined (VXWORKS) || defined (NW)) - ioctl(sp->sock, FIONBIO, (int)&iflag); -#else - fcntl(sp->sock, F_SETFL, fcntl(sp->sock, F_GETFL) | O_NONBLOCK); -#endif - } - return oldBlock; -} - -/******************************************************************************/ -/* - * Return true if a readable socket has buffered data. - not public - */ - -int socketDontBlock() -{ - socket_t *sp; - int i; - - for (i = 0; i < socketMax; i++) { - if ((sp = socketList[i]) == NULL || - (sp->handlerMask & SOCKET_READABLE) == 0) { - continue; - } - if (socketInputBuffered(i) > 0) { - return 1; - } - } - return 0; -} - -/******************************************************************************/ -/* - * Return true if a particular socket buffered data. - not public - */ - -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; -} - -#endif /* (!WIN) | LITTLEFOOT | WEBS */ - -/******************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/socket.c b/c/src/libnetworking/rtems_webserver/socket.c deleted file mode 100644 index bca64741d5..0000000000 --- a/c/src/libnetworking/rtems_webserver/socket.c +++ /dev/null @@ -1,1023 +0,0 @@ - -/* - * sockGen.c -- Posix Socket support module for general posix use - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - */ - -/******************************** Description *********************************/ - -/* - * Posix Socket Module. This supports blocking and non-blocking buffered - * socket I/O. - */ - -#if (!WIN) || LITTLEFOOT || WEBS - -/********************************** Includes **********************************/ - -#include -#include - -#if UEMF - #include "uemf.h" -#else - #include - #include - #include - #include "emfInternal.h" -#endif - -#if VXWORKS - #include -#endif - -#if __rtems__ - #include -#endif - -/************************************ Locals **********************************/ - -extern socket_t **socketList; /* List of open sockets */ -extern int socketMax; /* Maximum size of socket */ -extern int socketHighestFd; /* Highest socket fd opened */ -static int socketOpenCount = 0; /* Number of task using sockets */ - -/***************************** Forward Declarations ***************************/ - -static void socketAccept(socket_t *sp); -static int socketDoEvent(socket_t *sp); -static int tryAlternateConnect(int sock, struct sockaddr *sockaddr); - -/*********************************** Code *************************************/ -/* - * Open socket module - */ - -int socketOpen() -{ -#if CE || WIN - WSADATA wsaData; -#endif - - if (++socketOpenCount > 1) { - return 0; - } - -#if CE || WIN - if (WSAStartup(MAKEWORD(1,1), &wsaData) != 0) { - return -1; - } - if (wsaData.wVersion != MAKEWORD(1,1)) { - WSACleanup(); - return -1; - } -#endif - socketList = NULL; - socketMax = 0; - socketHighestFd = -1; - - return 0; -} - -/******************************************************************************/ -/* - * Close the socket module, by closing all open connections - */ - -void socketClose() -{ - int i; - - if (--socketOpenCount <= 0) { - for (i = socketMax; i >= 0; i--) { - if (socketList && socketList[i]) { - socketCloseConnection(i); - } - } - socketOpenCount = 0; - } -} - -/******************************************************************************/ -/* - * Open a client or server socket. Host is NULL if we want server capability. - */ - -int socketOpenConnection(char *host, int port, socketAccept_t accept, int flags) -{ -#if ! (NO_GETHOSTBYNAME || VXWORKS) - struct hostent *hostent; /* Host database entry */ -#endif /* ! (NO_GETHOSTBYNAME || VXWORKS) */ - socket_t *sp; - struct sockaddr_in sockaddr; - int sid, bcast, dgram, rc; - - if (port > SOCKET_PORT_MAX) { - return -1; - } -/* - * Allocate a socket structure - */ - if ((sid = socketAlloc(host, port, accept, flags)) < 0) { - return -1; - } - sp = socketList[sid]; - a_assert(sp); - -/* - * Create the socket address structure - */ - memset((char *) &sockaddr, '\0', sizeof(struct sockaddr_in)); - sockaddr.sin_family = AF_INET; - sockaddr.sin_port = htons((short) (port & 0xFFFF)); - - if (host == NULL) { - sockaddr.sin_addr.s_addr = INADDR_ANY; - } else { - sockaddr.sin_addr.s_addr = inet_addr(host); - if (sockaddr.sin_addr.s_addr == INADDR_NONE) { -/* - * If the OS does not support gethostbyname functionality, the macro: - * NO_GETHOSTBYNAME should be defined to skip the use of gethostbyname. - * Unfortunatly there is no easy way to recover, the following code - * simply uses the basicGetHost IP for the sockaddr. - */ - -#if NO_GETHOSTBYNAME - if (strcmp(host, basicGetHost()) == 0) { - sockaddr.sin_addr.s_addr = inet_addr(basicGetAddress()); - } - if (sockaddr.sin_addr.s_addr == INADDR_NONE) { - socketFree(sid); - return -1; - } -#elif VXWORKS - sockaddr.sin_addr.s_addr = (unsigned long) hostGetByName(host); - if (sockaddr.sin_addr.s_addr == NULL) { - errno = ENXIO; - socketFree(sid); - return -1; - } -#else - hostent = gethostbyname(host); - if (hostent != NULL) { - memcpy((char *) &sockaddr.sin_addr, - (char *) hostent->h_addr_list[0], - (size_t) hostent->h_length); - } else { - char *asciiAddress; - char_t *address; - - address = basicGetAddress(); - asciiAddress = ballocUniToAsc(address, gstrlen(address)); - sockaddr.sin_addr.s_addr = inet_addr(asciiAddress); - bfree(B_L, asciiAddress); - if (sockaddr.sin_addr.s_addr == INADDR_NONE) { - errno = ENXIO; - socketFree(sid); - return -1; - } - } -#endif /* (NO_GETHOSTBYNAME || VXWORKS) */ - } - } - - bcast = sp->flags & SOCKET_BROADCAST; - if (bcast) { - sp->flags |= SOCKET_DATAGRAM; - } - dgram = sp->flags & SOCKET_DATAGRAM; - -/* - * Create the socket. Support for datagram sockets. Set the close on - * exec flag so children don't inherit the socket. - */ - sp->sock = socket(AF_INET, dgram ? SOCK_DGRAM: SOCK_STREAM, 0); - if (sp->sock < 0) { - socketFree(sid); - return -1; - } -#ifndef __NO_FCNTL - fcntl(sp->sock, F_SETFD, FD_CLOEXEC); -#endif - socketHighestFd = max(socketHighestFd, sp->sock); - -/* - * If broadcast, we need to turn on broadcast capability. - */ - if (bcast) { - int broadcastFlag = 1; - if (setsockopt(sp->sock, SOL_SOCKET, SO_BROADCAST, - (char *) &broadcastFlag, sizeof(broadcastFlag)) < 0) { - socketFree(sid); - return -1; - } - } - -/* - * Host is set if we are the client - */ - if (host) { -/* - * Connect to the remote server in blocking mode, then go into - * non-blocking mode if desired. - */ - if (!dgram) { - if (! (sp->flags & SOCKET_BLOCK)) { -/* - * sockGen.c is only used for Windows products when blocking - * connects are expected. This applies to FieldUpgrader - * agents and open source webserver connectws. Therefore the - * asynchronous connect code here is not compiled. - */ -#if (WIN || CE) && !(LITTLEFOOT || WEBS) - int flag; - - sp->flags |= SOCKET_ASYNC; -/* - * Set to non-blocking for an async connect - */ - flag = 1; - if (ioctlsocket(sp->sock, FIONBIO, &flag) == SOCKET_ERROR) { - socketFree(sid); - return -1; - } -#else - socketSetBlock(sid, 1); -#endif /* #if (WIN || CE) && !(LITTLEFOOT || WEBS) */ - - } - if ((rc = connect(sp->sock, (struct sockaddr *) &sockaddr, - sizeof(sockaddr))) < 0 && - (rc = tryAlternateConnect(sp->sock, - (struct sockaddr *) &sockaddr)) < 0) { -#if WIN || CE - if (socketGetError() != EWOULDBLOCK) { - socketFree(sid); - return -1; - } -#else - socketFree(sid); - return -1; - -#endif /* WIN || CE */ - - } - } - } else { -/* - * Bind to the socket endpoint and the call listen() to start listening - */ - rc = 1; - setsockopt(sp->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&rc, sizeof(rc)); - 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; - } -#if !UEMF - sp->fileHandle = emfCreateFileHandler(sp->sock, SOCKET_READABLE, - (emfFileProc *) socketAccept, (void *) sp); -#else - sp->flags |= SOCKET_LISTENING; -#endif - } - sp->handlerMask |= SOCKET_READABLE; - } - -/* - * Set the blocking mode - */ - - if (flags & SOCKET_BLOCK) { - socketSetBlock(sid, 1); - } else { - socketSetBlock(sid, 0); - } - return sid; -} - -/******************************************************************************/ -/* - * If the connection failed, swap the first two bytes in the - * sockaddr structure. This is a kludge due to a change in - * VxWorks between versions 5.3 and 5.4, but we want the - * product to run on either. - */ - -static int tryAlternateConnect(int sock, struct sockaddr *sockaddr) -{ -#if VXWORKS - char *ptr; - - ptr = (char *)sockaddr; - *ptr = *(ptr+1); - *(ptr+1) = 0; - return connect(sock, sockaddr, sizeof(struct sockaddr)); -#else - return -1; -#endif /* VXWORKS */ -} - -/******************************************************************************/ -/* - * Close a socket - */ - -void socketCloseConnection(int sid) -{ - socket_t *sp; - - if ((sp = socketPtr(sid)) == NULL) { - return; - } - socketFree(sid); -} - -/******************************************************************************/ -/* - * Accept a connection. Called as a callback on incoming connection. - */ - -static void socketAccept(socket_t *sp) -{ - union { - struct sockaddr addr; - struct sockaddr_in addr_in; - } overlay; - struct sockaddr_in *addr; - socket_t *nsp; - int len; - char *pString; - int newSock, nid; - - a_assert(sp); - addr = &overlay.addr_in; - -/* - * Accept the connection and prevent inheriting by children (F_SETFD) - */ - len = sizeof(struct sockaddr_in); - if ((newSock = accept(sp->sock, &overlay.addr, &len)) < 0) { - return; - } -#ifndef __NO_FCNTL - fcntl(newSock, F_SETFD, FD_CLOEXEC); -#endif - socketHighestFd = max(socketHighestFd, newSock); - -/* - * Create a socket structure and insert into the socket list - */ - nid = socketAlloc(sp->host, sp->port, sp->accept, sp->flags); - nsp = socketList[nid]; - a_assert(nsp); - nsp->sock = newSock; - nsp->flags &= ~SOCKET_LISTENING; - - if (nsp == NULL) { - return; - } -/* - * Set the blocking mode before calling the accept callback. - */ - - socketSetBlock(nid, (nsp->flags & SOCKET_BLOCK) ? 1: 0); -/* - * Call the user accept callback. The user must call socketCreateHandler - * to register for further events of interest. - */ - if (sp->accept != NULL) { - pString = inet_ntoa(addr->sin_addr); - if ((sp->accept)(nid, pString, ntohs(addr->sin_port), sp->sid) < 0) { - socketFree(nid); - } -#if VXWORKS - free(pString); -#endif - } -} - -/******************************************************************************/ -/* - * Get more input from the socket and return in buf. - * Returns 0 for EOF, -1 for errors and otherwise the number of bytes read. - */ - -int socketGetInput(int sid, char *buf, int toRead, int *errCode) -{ - struct sockaddr_in server; - socket_t *sp; - int len, bytesRead; - - a_assert(buf); - a_assert(errCode); - - *errCode = 0; - - if ((sp = socketPtr(sid)) == NULL) { - return -1; - } - -/* - * If we have previously seen an EOF condition, then just return - */ - if (sp->flags & SOCKET_EOF) { - return 0; - } -#if (WIN || CE) && !(LITTLEFOOT || WEBS) - if ( !(sp->flags & SOCKET_BLOCK) - && ! socketWaitForEvent(sp, FD_CONNECT, errCode)) { - return -1; - } -#endif - -/* - * Read the data - */ - 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) { - if (errno == ECONNRESET) { - return 0; - } - *errCode = socketGetError(); - return -1; - } - return bytesRead; -} - -/******************************************************************************/ -/* - * Process an event on the event queue - */ - -#ifndef UEMF - -static int socketEventProc(void *data, int mask) -{ - socket_t *sp; - ringq_t *rq; - int sid; - - sid = (int) data; - - a_assert(sid >= 0 && sid < socketMax); - a_assert(socketList[sid]); - - if ((sp = socketPtr(sid)) == NULL) { - return 1; - } - -/* - * If now writable and flushing in the background, continue flushing - */ - if (mask & SOCKET_WRITABLE) { - if (sp->flags & SOCKET_FLUSHING) { - rq = &sp->outBuf; - if (ringqLen(rq) > 0) { - socketFlush(sp->sid); - } else { - sp->flags &= ~SOCKET_FLUSHING; - } - } - } - -/* - * Now invoke the users socket handler. NOTE: the handler may delete the - * socket, so we must be very careful after calling the handler. - */ - if (sp->handler && (sp->handlerMask & mask)) { - (sp->handler)(sid, mask & sp->handlerMask, sp->handler_data); - } - if (socketList && sid < socketMax && socketList[sid] == sp) { - socketRegisterInterest(sp, sp->handlerMask); - } - return 1; -} -#endif /* ! UEMF */ - -/******************************************************************************/ -/* - * Define the events of interest - */ - -void socketRegisterInterest(socket_t *sp, int handlerMask) -{ - a_assert(sp); - - sp->handlerMask = handlerMask; -#if !UEMF - if (handlerMask) { - sp->fileHandle = emfCreateFileHandler(sp->sock, handlerMask, - (emfFileProc *) socketEventProc, (void *) sp->sid); - } else { - emfDeleteFileHandler(sp->fileHandle); - } -#endif /* ! UEMF */ -} - -/******************************************************************************/ -/* - * Wait until an event occurs on a socket. Return 1 on success, 0 on failure. - * or -1 on exception (UEMF only) - */ - -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; -} - -/******************************************************************************/ -/* - * Return TRUE if there is a socket with an event ready to process, - */ - -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->currentEvents & sp->handlerMask) { - return 1; - } -/* - * If there is input data, also call select to test for new events - */ - if (sp->handlerMask & SOCKET_READABLE && socketInputBuffered(sid)) { - socketSelect(sid, 0); - return 1; - } - if (! all) { - break; - } - } - return 0; -} - -/******************************************************************************/ -/* - * Wait for a handle to become readable or writable and return a number of - * noticed events. Timeout is in milliseconds. - */ - -#if WIN || CE - -int socketSelect(int sid, int timeout) -{ - struct timeval tv; - socket_t *sp; - fd_set readFds, writeFds, exceptFds; - int nEvents; - int all, socketHighestFd; /* Highest socket fd opened */ - - FD_ZERO(&readFds); - FD_ZERO(&writeFds); - FD_ZERO(&exceptFds); - socketHighestFd = -1; - - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - -/* - * Set the select event masks for events to watch - */ - all = nEvents = 0; - - if (sid < 0) { - all++; - sid = 0; - } - - for (; sid < socketMax; sid++) { - if ((sp = socketList[sid]) == NULL) { - continue; - } - a_assert(sp); -/* - * Set the appropriate bit in the ready masks for the sp->sock. - */ - if (sp->handlerMask & SOCKET_READABLE) { - FD_SET(sp->sock, &readFds); - nEvents++; - if (socketInputBuffered(sid) > 0) { - tv.tv_sec = 0; - tv.tv_usec = 0; - } - } - if (sp->handlerMask & SOCKET_WRITABLE) { - FD_SET(sp->sock, &writeFds); - nEvents++; - } - if (sp->handlerMask & SOCKET_EXCEPTION) { - FD_SET(sp->sock, &exceptFds); - nEvents++; - } - if (! all) { - break; - } - } - -/* - * Windows select() fails if no descriptors are set, instead of just sleeping - * like other, nice select() calls. So, if WIN, sleep. - */ - if (nEvents == 0) { - Sleep(timeout); - return 0; - } - -/* - * Wait for the event or a timeout. - */ - nEvents = select(socketHighestFd+1, &readFds, &writeFds, &exceptFds, &tv); - - if (all) { - sid = 0; - } - for (; sid < socketMax; sid++) { - if ((sp = socketList[sid]) == NULL) { - continue; - } - - if (FD_ISSET(sp->sock, &readFds) || socketInputBuffered(sid) > 0) { - sp->currentEvents |= SOCKET_READABLE; - } - if (FD_ISSET(sp->sock, &writeFds)) { - sp->currentEvents |= SOCKET_WRITABLE; - } - if (FD_ISSET(sp->sock, &exceptFds)) { - sp->currentEvents |= SOCKET_EXCEPTION; - } - if (! all) { - break; - } - } - - return nEvents; -} - -#else /* not WIN || CE */ - -int socketSelect(int sid, int timeout) -{ - socket_t *sp; - struct timeval tv; - fd_mask *readFds, *writeFds, *exceptFds; - int all, len, nwords, index, bit, nEvents; - -/* - * Allocate and zero the select masks - */ - nwords = (socketHighestFd + NFDBITS) / NFDBITS; - len = nwords * sizeof(int); - - readFds = balloc(B_L, len); - memset(readFds, 0, len); - writeFds = balloc(B_L, len); - memset(writeFds, 0, len); - exceptFds = balloc(B_L, len); - memset(exceptFds, 0, len); - - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - -/* - * Set the select event masks for events to watch - */ - 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); - -/* - * Initialize the ready masks and compute the mask offsets. - */ - index = sp->sock / (NBBY * sizeof(fd_mask)); - bit = 1 << (sp->sock % (NBBY * sizeof(fd_mask))); - -/* - * Set the appropriate bit in the ready masks for the sp->sock. - */ - 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; - } - } - -/* - * Wait for the event or a timeout. Reset nEvents to be the number of actual - * events now. - */ - 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; -} -#endif /* WIN || CE */ - -/******************************************************************************/ -/* - * Process socket events - */ - -void socketProcess(int sid) -{ - socket_t *sp; - int all; - - all = 0; - if (sid < 0) { - all = 1; - sid = 0; - } -/* - * Process each socket - */ - for (; sid < socketMax; sid++) { - if ((sp = socketList[sid]) == NULL) { - if (! all) { - break; - } else { - continue; - } - } - if (socketReady(sid)) { - socketDoEvent(sp); - } - if (! all) { - break; - } - } -} - -/******************************************************************************/ -/* - * Process an event on the event queue - */ - -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 there is still read data in the buffers, trigger the read handler - * NOTE: this may busy spin if the read handler doesn't read the data - */ - if (sp->handlerMask & SOCKET_READABLE && socketInputBuffered(sid)) { - sp->currentEvents |= SOCKET_READABLE; - } - } - - -/* - * If now writable and flushing in the background, continue flushing - */ - 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; - } - } - } - -/* - * Now invoke the users socket handler. NOTE: the handler may delete the - * socket, so we must be very careful after calling the handler. - */ - if (sp->handler && (sp->handlerMask & sp->currentEvents)) { - (sp->handler)(sid, sp->handlerMask & sp->currentEvents, - sp->handler_data); -/* - * Make sure socket pointer is still valid, then reset the currentEvents. - */ - if (socketList && sid < socketMax && socketList[sid] == sp) { - sp->currentEvents = 0; - } - } - return 1; -} - -/******************************************************************************/ -/* - * Set the socket blocking mode - */ - -int socketSetBlock(int sid, int on) -{ - socket_t *sp; - unsigned long flag; - int iflag; - int oldBlock; - - 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; - } - -/* - * Put the socket into block / non-blocking mode - */ - if (sp->flags & SOCKET_BLOCK) { -#if CE || WIN - ioctlsocket(sp->sock, FIONBIO, &flag); -#elif ECOS - int off; - off = 0; - ioctl(sp->sock, FIONBIO, &off); -#elif VXWORKS - ioctl(sp->sock, FIONBIO, (int)&iflag); -#else - fcntl(sp->sock, F_SETFL, fcntl(sp->sock, F_GETFL) & ~O_NONBLOCK); -#endif - - } else { -#if CE || WIN - ioctlsocket(sp->sock, FIONBIO, &flag); -#elif ECOS - int on; - on = 1; - ioctl(sp->sock, FIONBIO, &on); -#elif VXWORKS - ioctl(sp->sock, FIONBIO, (int)&iflag); -#else - fcntl(sp->sock, F_SETFL, fcntl(sp->sock, F_GETFL) | O_NONBLOCK); -#endif - } - return oldBlock; -} - -/******************************************************************************/ -/* - * Return true if a readable socket has buffered data. - not public - */ - -int socketDontBlock() -{ - socket_t *sp; - int i; - - for (i = 0; i < socketMax; i++) { - if ((sp = socketList[i]) == NULL || - (sp->handlerMask & SOCKET_READABLE) == 0) { - continue; - } - if (socketInputBuffered(i) > 0) { - return 1; - } - } - return 0; -} - -/******************************************************************************/ -/* - * Return true if a particular socket buffered data. - not public - */ - -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; -} - -#endif /* (!WIN) | LITTLEFOOT | WEBS */ - -/******************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/sym.c b/c/src/libnetworking/rtems_webserver/sym.c deleted file mode 100644 index 3df45e86d7..0000000000 --- a/c/src/libnetworking/rtems_webserver/sym.c +++ /dev/null @@ -1,474 +0,0 @@ -/* - * sym.c -- Symbol Table module - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/******************************** Description *********************************/ -/* - * This module implements a highly efficient generic symbol table with - * update and access routines. Symbols are simple character strings and - * the values they take can be flexible types as defined by value_t. - * This modules allows multiple symbol tables to be created. - */ - -/********************************* Includes ***********************************/ - -#ifdef UEMF - #include "uemf.h" -#else - #include "basic/basicInternal.h" -#endif - -/********************************* Defines ************************************/ - -typedef struct { /* Symbol table descriptor */ - int inuse; /* Is this entry in use */ - int hash_size; /* Size of the table below */ - sym_t **hash_table; /* Allocated at run time */ -} sym_tabent_t; - -/********************************* Globals ************************************/ - -static sym_tabent_t **sym; /* List of symbol tables */ -static int symMax; /* One past the max symbol table */ -static int symOpenCount = 0; /* Count of apps using sym */ - -static int htIndex; /* Current location in table */ -static sym_t* next; /* Next symbol in iteration */ - -/**************************** Forward Declarations ****************************/ - -static int hashIndex(sym_tabent_t *tp, char_t *name); -static sym_t *hash(sym_tabent_t *tp, char_t *name); -static int calcPrime(int size); - -/*********************************** Code *************************************/ -/* - * Open the symbol table subSystem. - */ - -int symSubOpen() -{ - if (++symOpenCount == 1) { - symMax = 0; - sym = NULL; - } - return 0; -} - -/******************************************************************************/ -/* - * Close the symbol table subSystem. - */ - -void symSubClose() -{ - if (--symOpenCount <= 0) { - symOpenCount = 0; - } -} - -/******************************************************************************/ -/* - * Create a symbol table. - */ - -sym_fd_t symOpen(int hash_size) -{ - sym_fd_t sd; - sym_tabent_t *tp; - - a_assert(hash_size > 2); - -/* - * Create a new handle for this symbol table - */ - if ((sd = hAlloc((void*) &sym)) < 0) { - return -1; - } - -/* - * Create a new symbol table structure and zero - */ - 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; - -/* - * Now create the hash table for fast indexing. - */ - 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); - memset(tp->hash_table, 0, tp->hash_size * sizeof(sym_t*)); - - return sd; -} - -/******************************************************************************/ -/* - * Close this symbol table. Call a cleanup function to allow the caller - * to free resources associated with each symbol table entry. - */ - -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); - -/* - * Free all symbols in the hash table, then the hash table itself. - */ - 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); -} - -/******************************************************************************/ -/* - * Return the first symbol in the hashtable if there is one. This call is used - * as the first step in traversing the table. A call to symFirst should be - * followed by calls to symNext to get all the rest of the entries. - */ - -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); - -/* - * Find the first symbol in the hashtable and return a pointer to it. - */ - for (i = 0; i < tp->hash_size; i++) { - 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; - } - } - return NULL; -} - -/******************************************************************************/ -/* - * Return the next symbol in the hashtable if there is one. See symFirst. - */ - -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); - -/* - * Find the first symbol in the hashtable and return a pointer to it. - */ - for (i = htIndex; i < tp->hash_size; i++) { - 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; - } - next = tp->hash_table[i + 1]; - } - return NULL; -} - -/******************************************************************************/ -/* - * Lookup a symbol and return a pointer to the symbol entry. If not present - * then return a NULL. - */ - -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; - } - -/* - * Do an initial hash and then follow the link chain to find the right entry - */ - 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; -} - -/******************************************************************************/ -/* - * Enter a symbol into the table. If already there, update its value. - * Always succeeds if memory available. We allocate a copy of "name" here - * so it can be a volatile variable. The value "v" is just a copy of the - * passed in value, so it MUST be persistent. - */ - -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); - -/* - * Calculate the first daisy-chain from the hash table. If non-zero, then - * we have daisy-chain, so scan it and look for the symbol. - */ - 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) { -/* - * Found, so update the value - * If the caller stores handles which require freeing, they - * will be lost here. It is the callers responsibility to free - * resources before overwriting existing contents. We will here - * free allocated strings which occur due to value_instring(). - * We should consider providing the cleanup function on the open rather - * than the close and then we could call it here and solve the problem. - */ - if (sp->content.valid) { - valueFree(&sp->content); - } - sp->content = v; - sp->arg = arg; - return sp; - } -/* - * Not found so allocate and append to the daisy-chain - */ - sp = (sym_t*) balloc(B_L, sizeof(sym_t)); - if (sp == NULL) { - return NULL; - } - sp->name = valueString(name, VALUE_ALLOCATE); - sp->content = v; - sp->forw = (sym_t*) NULL; - sp->arg = arg; - last->forw = sp; - - } else { -/* - * Daisy chain is empty so we need to start the chain - */ - 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->forw = (sym_t*) NULL; - sp->content = v; - sp->arg = arg; - sp->name = valueString(name, VALUE_ALLOCATE); - } - return sp; -} - -/******************************************************************************/ -/* - * Delete a symbol from a table - */ - -int symDelete(sym_fd_t sd, char_t *name) -{ - sym_tabent_t *tp; - sym_t *sp, *last; - char_t *cp; - int hindex; - - a_assert(name && *name); - a_assert(0 <= sd && sd < symMax); - tp = sym[sd]; - a_assert(tp); - -/* - * Calculate the first daisy-chain from the hash table. If non-zero, then - * we have daisy-chain, so scan it and look for the symbol. - */ - 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 == (sym_t*) NULL) { /* Not Found */ - return -1; - } - -/* - * Unlink and free the symbol. Last will be set if the element to be deleted - * is not first in the chain. - */ - 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; -} - -/******************************************************************************/ -/* - * Hash a symbol and return a pointer to the hash daisy-chain list - * All symbols reside on the chain (ie. none stored in the hash table itself) - */ - -static sym_t *hash(sym_tabent_t *tp, char_t *name) -{ - a_assert(tp); - - return tp->hash_table[hashIndex(tp, name)]; -} - -/******************************************************************************/ -/* - * Compute the hash function and return an index into the hash table - * We use a basic additive function that is then made modulo the size of the - * table. - */ - -static int hashIndex(sym_tabent_t *tp, char_t *name) -{ - unsigned int sum; - int i; - - a_assert(tp); -/* - * Add in each character shifted up progressively by 7 bits. The shift - * amount is rounded so as to not shift too far. It thus cycles with each - * new cycle placing character shifted up by one bit. - */ - i = 0; - sum = 0; - while (*name) { - sum += (((int) *name++) << i); - i = (i + 7) % (BITS(int) - BITSPERBYTE); - } - return sum % tp->hash_size; -} - -/******************************************************************************/ -/* - * Check if this number is a prime - */ - -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; -} - -/******************************************************************************/ -/* - * Calculate the largest prime smaller than size. - */ - -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/c/src/libnetworking/rtems_webserver/uemf.c b/c/src/libnetworking/rtems_webserver/uemf.c deleted file mode 100644 index ffe6a04cd1..0000000000 --- a/c/src/libnetworking/rtems_webserver/uemf.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * uemf.c -- GoAhead Micro Embedded Management Framework - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/********************************** Description *******************************/ - -/* - * This module provides compatibility with the full GoAhead EMF. - * It is a collection of routines which permits the GoAhead WebServer to - * run stand-alone and to also load as a solution pack under the GoAhead EMF. - */ - -/*********************************** Includes *********************************/ - -#include "uemf.h" - -/********************************** Local Data ********************************/ - -int emfInst; /* Application instance handle */ - -/****************************** Forward Declarations **************************/ - -extern void defaultErrorHandler(int etype, char_t *buf); -static void (*errorHandler)(int etype, char_t *msg) = defaultErrorHandler; - -extern void defaultTraceHandler(int level, char_t *buf); -static void (*traceHandler)(int level, char_t *buf) = defaultTraceHandler; - -/************************************* Code ***********************************/ -/* - * Error message that doesn't need user attention. Customize this code - * to direct error messages to wherever the developer wishes - */ - -void error(E_ARGS_DEC, int etype, char_t *fmt, ...) -{ - va_list args; - 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); - } - /* - * bugfix -- if etype is not E_LOG, E_ASSERT, or E_USER, the call to - * bfreeSafe(B_L, buf) below will fail, because 'buf' is randomly - * initialized. To be nice, we format a message saying that this is an - * unknown message type, and in doing so give buf a valid value. Thanks - * to Simon Byholm. - */ - else { - fmtAlloc(&buf, E_MAX_ERROR, T("Unknown error")); - } - va_end(args); - - bfree(B_L, fmtBuf); - - if (errorHandler) { - errorHandler(etype, buf); - } - - bfreeSafe(B_L, buf); -} - -/******************************************************************************/ -/* - * Replace the default error handler. Return pointer to old error handler. - */ - -void (*errorSetHandler(void (*function)(int etype, char_t *msg))) \ - (int etype, char_t *msg) -{ - void (*oldHandler)(int etype, char_t *buf); - - oldHandler = errorHandler; - errorHandler = function; - return oldHandler; -} - -/******************************************************************************/ -/* - * Trace log. Customize this function to log trace output - */ - -void trace(int level, char_t *fmt, ...) -{ - va_list args; - char_t *buf; - - va_start(args, fmt); - fmtValloc(&buf, VALUE_MAX_STRING, fmt, args); - - if (traceHandler) { - traceHandler(level, buf); - } - bfreeSafe(B_L, buf); - va_end(args); -} - -/******************************************************************************/ -/* - * Trace log. Customize this function to log trace output - */ - -void traceRaw(char_t *buf) -{ - if (traceHandler) { - traceHandler(0, buf); - } -} - -/******************************************************************************/ -/* - * Replace the default trace handler. Return a pointer to the old handler. - */ - -void (*traceSetHandler(void (*function)(int level, char_t *buf))) - (int level, char *buf) -{ - void (*oldHandler)(int level, char_t *buf); - - oldHandler = traceHandler; - if (function) { - traceHandler = function; - } - return oldHandler; -} - -/******************************************************************************/ -/* - * Save the instance handle - */ - -void emfInstSet(int inst) -{ - emfInst = inst; -} - -/******************************************************************************/ -/* - * Get the instance handle - */ - -int emfInstGet() -{ - return emfInst; -} - -/******************************************************************************/ -/* - * Convert a string to lower case - */ - -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; -} - -/******************************************************************************/ -/* - * Convert a string to upper case - */ - -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; -} - -/******************************************************************************/ -/* - * Convert integer to ascii string. Allow a NULL string in which case we - * allocate a dynamic buffer. - */ - -char_t *stritoa(int n, char_t *string, int width) -{ - char_t *cp, *lim, *s; - char_t buf[16]; /* Just temp to hold number */ - int next, minus; - - 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 = buf; - lim = &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 > buf) { - *s++ = *--cp; - } - - *s++ = '\0'; - return string; -} - -/******************************************************************************/ -/* - * Stubs - */ - -char_t *basicGetProduct() -{ - return T("uemf"); -} - -char_t *basicGetAddress() -{ - return T("localhost"); -} - -int errorOpen(char_t *pname) -{ - return 0; -} - -void errorClose() -{ -} - -/******************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/uemf.h b/c/src/libnetworking/rtems_webserver/uemf.h deleted file mode 100644 index 2e5b76dafb..0000000000 --- a/c/src/libnetworking/rtems_webserver/uemf.h +++ /dev/null @@ -1,1110 +0,0 @@ -/* - * uemf.h -- GoAhead Micro Embedded Management Framework Header - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -#ifndef _h_UEMF -#define _h_UEMF 1 - -/******************************** Description *********************************/ - -/* - * GoAhead Web Server header. This defines the Web public APIs - */ - -/******************************* Per O/S Includes *****************************/ - -#ifdef WIN - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include -#endif /* WIN */ - -#ifdef CE - #include - #include - #include - #include - #include - #include - #include "CE/wincompat.h" - #include -#endif /* CE */ - -#ifdef NW - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #define EINTR EINUSE - #define WEBS 1 - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include -#endif /* NW */ - -#ifdef SCOV5 - #include - #include - #include "sys/socket.h" - #include "sys/select.h" - #include "netinet/in.h" - #include "arpa/inet.h" - #include "netdb.h" -#endif /* SCOV5 */ - -#ifdef UNIX - #include -#endif /* UNIX */ - -#if LINUX || __rtems__ - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include -#endif /* LINUX */ - -#ifdef LYNX - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include -#endif /* LYNX */ - -#ifdef MACOSX - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include -#endif /* MACOSX */ - -#ifdef UW - #include -#endif /* UW */ - -#ifdef VXWORKS - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include -#endif /* VXWORKS */ - -#ifdef SOLARIS - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include -#endif /* SOLARIS */ - -#ifdef QNX4 - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include -#endif /* QNX4 */ - -#ifdef ECOS - #include - #include - #include - #include - #include - #include -#endif /* ECOS */ - -/********************************** Includes **********************************/ - -#include -#include -#include - -#ifndef WEBS -#include "messages.h" -#endif /* ! WEBS */ - -/******************************* Per O/S Defines *****************************/ - -#if defined(__rtems__) -#define __NO_PACK 1 -#endif - -#ifdef UW - #define __NO_PACK 1 -#endif /* UW */ - -#if (defined (SCOV5) || defined (VXWORKS) || defined (LINUX) || defined (LYNX) || defined (MACOSX) || defined (__rtems__)) -#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)) -/* - * __NO_FCNTL means can't access fcntl function. Fcntl.h is still available. - */ -#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(__rtems__) && !defined (_STRUCT_TIMEVAL)) -struct timeval -{ - time_t tv_sec; /* Seconds. */ - time_t tv_usec; /* Microseconds. */ -}; -#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 to avoid kernel inline functions - */ - #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 */ - -/********************************** Unicode ***********************************/ -/* - * Constants and limits. Also FNAMESIZE and PATHSIZE are currently defined - * in param.h to be 128 and 512 - */ -#define TRACE_MAX (4096 - 48) -#define VALUE_MAX_STRING (4096 - 48) -#define SYM_MAX (512) -#define XML_MAX 4096 /* Maximum size for tags/tokens */ -#define BUF_MAX 4096 /* General sanity check for bufs */ -#define FMT_STATIC_MAX 256 /* Maximum for fmtStatic calls */ - -#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 -/* - * To convert strings to UNICODE. We have a level of indirection so things - * like T(__FILE__) will expand properly. - */ -#define T(x) __TXT(x) -#define __TXT(s) L ## s -typedef unsigned short char_t; -typedef unsigned short uchar_t; - -/* - * Text size of buffer macro. A buffer bytes will hold (size / char size) - * characters. - */ -#define TSZ(x) (sizeof(x) / sizeof(char_t)) - -/* - * How many ASCII bytes are required to represent this UNICODE string? - */ -#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 */ - -/* - * "Boolean" constants - */ - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -/* - * GoAhead Copyright. - */ -#define GOAHEAD_COPYRIGHT \ - T("Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.") - -/* - * The following include has to be after the unicode defines. By putting it - * here, many modules in various parts of the tree are cleaner. - */ -#if (defined (LITTLEFOOT) && defined (INMEM)) - #include "lf/inmem.h" -#endif /* LITTLEFOOT && INMEM */ - -/* - * Type for unicode systems - */ -#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 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 */ - -#ifndef gopen -#if INMEM -#define gchdir imChdir -#define gmkdir imMkdir -#define grmdir imRmdir -#define gclose imClose -#define gclosedir imClosedir -#define gchmod imChmod -#define ggetcwd imGetcwd -#define glseek imLseek -#define gloadModule imLoadModule -#define gopen imOpen -#define gopendir imOpendir -#define gread imRead -#define greaddir imReaddir -#define grename imRename -#define gstat imStat -#define gunlink imUnlink -#define gwrite imWrite -#else -#if 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 -#endif /* INMEM */ -#endif /* ! gopen */ - -#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 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 */ - -/* - * Include inmem.h here because it redefines many of the file access fucntions. - * Otherwise there would be lots more #if-#elif-#else-#endif ugliness. - */ -#ifdef INMEM - #include "lf/inmem.h" -#endif - -/********************************** Defines ***********************************/ - -#ifndef FNAMESIZE -#define FNAMESIZE 254 /* Max length of file names */ -#endif /* FNAMESIZE */ - -#define E_MAX_ERROR 4096 -#define URL_MAX 4096 - -/* - * Error types - */ -#define E_ASSERT 0x1 /* Assertion error */ -#define E_LOG 0x2 /* Log error to log file */ -#define E_USER 0x3 /* Error that must be displayed */ - -#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 */ - -/******************************************************************************/ -/* VALUE */ -/******************************************************************************/ -/* - * These values are not prefixed so as to aid code readability - */ - -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; /* String was balloced */ -} value_t; - -#ifndef __NO_PACK -#pragma pack() -#endif /* __NO_PACK */ - -/* - * Allocation flags - */ -#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 } - -/******************************************************************************/ -/* - * A ring queue allows maximum utilization of memory for data storage and is - * ideal for input/output buffering. This module provides a highly effecient - * implementation and a vehicle for dynamic strings. - * - * WARNING: This is a public implementation and callers have full access to - * the queue structure and pointers. Change this module very carefully. - * - * This module follows the open/close model. - * - * Operation of a ringq where rq is a pointer to a ringq : - * - * rq->buflen contains the size of the buffer. - * rq->buf will point to the start of the buffer. - * rq->servp will point to the first (un-consumed) data byte. - * rq->endp will point to the next free location to which new data is added - * rq->endbuf will point to one past the end of the buffer. - * - * Eg. If the ringq contains the data "abcdef", it might look like : - * - * +-------------------------------------------------------------------+ - * | | | | | | | | a | b | c | d | e | f | | | | | - * +-------------------------------------------------------------------+ - * ^ ^ ^ ^ - * | | | | - * rq->buf rq->servp rq->endp rq->enduf - * - * The queue is empty when servp == endp. This means that the queue will hold - * at most rq->buflen -1 bytes. It is the fillers responsibility to ensure - * the ringq is never filled such that servp == endp. - * - * It is the fillers responsibility to "wrap" the endp back to point to - * rq->buf when the pointer steps past the end. Correspondingly it is the - * consumers responsibility to "wrap" the servp when it steps to rq->endbuf. - * The ringqPutc and ringqGetc routines will do this automatically. - */ - -/* - * Ring queue buffer structure - */ -typedef struct { - unsigned char *buf; /* Holding buffer for data */ - unsigned char *servp; /* Pointer to start of data */ - unsigned char *endp; /* Pointer to end of data */ - unsigned char *endbuf; /* Pointer to end of buffer */ - int buflen; /* Length of ring queue */ - int maxsize; /* Maximum size */ - int increment; /* Growth increment */ -} ringq_t; - -/* - * Block allocation (balloc) definitions - */ -#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 */ - -/* - * Block classes are: 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, - * 16384, 32768, 65536 - */ -typedef struct { - union { - void *next; /* Pointer to next in q */ - int size; /* Actual requested size */ - } u; - int flags; /* Per block allocation flags */ -} bType; - -#define B_SHIFT 4 /* Convert size to class */ -#define B_ROUND ((1 << (B_SHIFT)) - 1) -#define B_MAX_CLASS 13 /* Maximum class number + 1 */ -#define B_MALLOCED 0x80000000 /* Block was malloced */ -#define B_DEFAULT_MEM (64 * 1024) /* Default memory allocation */ -#define B_MAX_FILES (512) /* Maximum number of files */ -#define B_FILL_CHAR (0x77) /* Fill byte for buffers */ -#define B_FILL_WORD (0x77777777) /* Fill word for buffers */ -#define B_MAX_BLOCKS (64 * 1024) /* Maximum allocated blocks */ - -/* - * Flags. The integrity value is used as an arbitrary value to fill the flags. - */ -#define B_INTEGRITY 0x8124000 /* Integrity value */ -#define B_INTEGRITY_MASK 0xFFFF000 /* Integrity mask */ -#define B_USE_MALLOC 0x1 /* Okay to use malloc if required */ -#define B_USER_BUF 0x2 /* User supplied buffer for mem */ - -/* - * The symbol table record for each symbol entry - */ - -typedef struct sym_t { - struct sym_t *forw; /* Pointer to next hash list */ - value_t name; /* Name of symbol */ - value_t content; /* Value of symbol */ - int arg; /* Parameter value */ -} sym_t; - -typedef int sym_fd_t; /* Returned by symOpen */ - -/* - * Script engines - */ -#define EMF_SCRIPT_JSCRIPT 0 /* javascript */ -#define EMF_SCRIPT_TCL 1 /* tcl */ -#define EMF_SCRIPT_EJSCRIPT 2 /* Ejscript */ -#define EMF_SCRIPT_MAX 3 - -#define MAXINT INT_MAX -#define BITSPERBYTE CHAR_BIT -#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 */ - -/******************************************************************************/ -/* CRON */ -/******************************************************************************/ - -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); - -/******************************************************************************/ -/* SOCKET */ -/******************************************************************************/ -/* - * Socket flags - */ - -#if ((defined (WIN) || defined (CE)) && defined (WEBS)) -#define EWOULDBLOCK WSAEWOULDBLOCK -#define ENETDOWN WSAENETDOWN -#define ECONNRESET WSAECONNRESET -#endif /* (WIN || CE) && WEBS) */ - -#define SOCKET_EOF 0x1 /* Seen end of file */ -#define SOCKET_CONNECTING 0x2 /* Connect in progress */ -#define SOCKET_BROADCAST 0x4 /* Broadcast mode */ -#define SOCKET_PENDING 0x8 /* Message pending on this socket */ -#define SOCKET_FLUSHING 0x10 /* Background flushing */ -#define SOCKET_DATAGRAM 0x20 /* Use datagrams */ -#define SOCKET_ASYNC 0x40 /* Use async connect */ -#define SOCKET_BLOCK 0x80 /* Use blocking I/O */ -#define SOCKET_LISTENING 0x100 /* Socket is server listener */ -#define SOCKET_CLOSING 0x200 /* Socket is closing */ -#define SOCKET_CONNRESET 0x400 /* Socket connection was reset */ - -#define SOCKET_PORT_MAX 0xffff /* Max Port size */ - -/* - * Socket error values - */ -#define SOCKET_WOULDBLOCK 1 /* Socket would block on I/O */ -#define SOCKET_RESET 2 /* Socket has been reset */ -#define SOCKET_NETDOWN 3 /* Network is down */ -#define SOCKET_AGAIN 4 /* Issue the request again */ -#define SOCKET_INTR 5 /* Call was interrupted */ -#define SOCKET_INVAL 6 /* Invalid */ - -/* - * Handler event masks - */ -#define SOCKET_READABLE 0x2 /* Make socket readable */ -#define SOCKET_WRITABLE 0x4 /* Make socket writable */ -#define SOCKET_EXCEPTION 0x8 /* Interested in exceptions */ -#define EMF_SOCKET_MESSAGE (WM_USER+13) - -#ifdef LITTLEFOOT -#define SOCKET_BUFSIZ 510 /* Underlying buffer size */ -#else -#define SOCKET_BUFSIZ 1024 /* Underlying buffer size */ -#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]; /* Host name */ - ringq_t inBuf; /* Input ring queue */ - ringq_t outBuf; /* Output ring queue */ - ringq_t lineBuf; /* Line ring queue */ - socketAccept_t accept; /* Accept handler */ - socketHandler_t handler; /* User I/O handler */ - int handler_data; /* User handler data */ - int handlerMask; /* Handler events of interest */ - int sid; /* Index into socket[] */ - int port; /* Port to listen on */ - int flags; /* Current state flags */ - int sock; /* Actual socket handle */ - int fileHandle; /* ID of the file handler */ - int interestEvents; /* Mask of events to watch for */ - int currentEvents; /* Mask of ready events (FD_xx) */ - int selectEvents; /* Events being selected */ - int saveMask; /* saved Mask for socketFlush */ - int error; /* Last error */ -} socket_t; - -/********************************* Prototypes *********************************/ -/* - * Balloc module - * - */ - -extern void bclose(); -extern int bopen(void *buf, int bufsize, int flags); - -/* - * Define NO_BALLOC to turn off our balloc module altogether - * #define NO_BALLOC 1 - */ - -#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, ...)); - -/* - * Flags. The integrity value is used as an arbitrary value to fill the flags. - */ -#define B_USE_MALLOC 0x1 /* Okay to use malloc if required */ -#define B_USER_BUF 0x2 /* User supplied buffer for mem */ - - -#if !LINUX && !__rtems__ -extern char_t *basename(char_t *name); -#endif /* !LINUX */ - -#if (defined (UEMF) && defined (WEBS)) -/* - * The open source webserver uses a different callback/timer mechanism - * than other emf derivative products such as FieldUpgrader agents - * so redefine those API for webserver so that they can coexist in the - * same address space as the others. - */ -#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/c/src/libnetworking/rtems_webserver/um.c b/c/src/libnetworking/rtems_webserver/um.c deleted file mode 100644 index e960f02719..0000000000 --- a/c/src/libnetworking/rtems_webserver/um.c +++ /dev/null @@ -1,1435 +0,0 @@ -/* - * um.c -- User Management - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/******************************** Description *********************************/ -/* - * User Management routines for adding/deleting/changing users and groups - * Also, routines for determining user access - */ - -/********************************* Includes ***********************************/ - -#include "um.h" -#include "emfdb.h" -#include "webs.h" - -/********************************** Defines ***********************************/ - -#define UM_DB_FILENAME T("um.xml") -#define UM_TXT_FILENAME T("umconfig.txt") - -/* - * Table names - */ -#define UM_USER_TABLENAME T("users") -#define UM_GROUP_TABLENAME T("groups") -#define UM_ACCESS_TABLENAME T("access") - -/* - * Column names - */ -#define UM_NAME T("name") -#define UM_PASS T("password") -#define UM_GROUP T("group") -#define UM_PROT T("prot") -#define UM_DISABLE T("disable") -#define UM_METHOD T("method") -#define UM_PRIVILEGE T("priv") -#define UM_SECURE T("secure") - -/* - * XOR encryption mask - * Note: This string should be modified for individual sites - * in order to enhance user password security. - */ -#define UM_XOR_ENCRYPT T("*j7a(L#yZ98sSd5HfSgGjMj8;Ss;d)(*&^#@$a2s0i3g") - -/******************************** Local Data **********************************/ - -#ifdef qHierarchicalAccess -/* - * user-provided function to allow hierarchical access protection. See below. - * for details. - */ -extern bool_t dmfCanAccess(const char_t* usergroup, const char_t* group); -#endif -#ifdef UEMF -/* - * User table definition - */ -#define NUMBER_OF_USER_COLUMNS 5 - -char_t *userColumnNames[NUMBER_OF_USER_COLUMNS] = { - UM_NAME, UM_PASS, UM_GROUP, UM_PROT, UM_DISABLE -}; - -int userColumnTypes[NUMBER_OF_USER_COLUMNS] = { - T_STRING, T_STRING, T_STRING, T_INT, T_INT -}; - -dbTable_t userTable = { - UM_USER_TABLENAME, - NUMBER_OF_USER_COLUMNS, - userColumnNames, - userColumnTypes, - 0, - NULL -}; - -/* - * Group table definition - */ -#define NUMBER_OF_GROUP_COLUMNS 5 - -char_t *groupColumnNames[NUMBER_OF_GROUP_COLUMNS] = { - UM_NAME, UM_PRIVILEGE, UM_METHOD, UM_PROT, UM_DISABLE -}; - -int groupColumnTypes[NUMBER_OF_GROUP_COLUMNS] = { - T_STRING, T_INT, T_INT, T_INT, T_INT -}; - -dbTable_t groupTable = { - UM_GROUP_TABLENAME, - NUMBER_OF_GROUP_COLUMNS, - groupColumnNames, - groupColumnTypes, - 0, - NULL -}; - -/* - * Access Limit table definition - */ -#define NUMBER_OF_ACCESS_COLUMNS 4 - -char_t *accessColumnNames[NUMBER_OF_ACCESS_COLUMNS] = { - UM_NAME, UM_METHOD, UM_SECURE, UM_GROUP -}; - -int accessColumnTypes[NUMBER_OF_ACCESS_COLUMNS] = { - T_STRING, T_INT, T_INT, T_STRING -}; - -dbTable_t accessTable = { - UM_ACCESS_TABLENAME, - NUMBER_OF_ACCESS_COLUMNS, - accessColumnNames, - accessColumnTypes, - 0, - NULL -}; -#endif /* #ifdef UEMF */ - -/* - * Database Identifier returned from dbOpen() - */ -static int didUM = -1; - -/* - * Configuration database persist filename - */ -static char_t *saveFilename = NULL; - -static int umOpenCount = 0; /* count of apps using this module */ - -/*************************** Forward Declarations *****************************/ - -static bool_t umCheckName(char_t *name); - -/*********************************** Code *************************************/ -/* - * umOpen() registers the UM tables in the fake emf-database - */ - -int umOpen() -{ - if (++umOpenCount != 1) { - return didUM; - } -/* - * Do not initialize if intialization has already taken place - */ - if (didUM == -1) { - didUM = dbOpen(UM_USER_TABLENAME, UM_DB_FILENAME, NULL, 0); -#ifdef UEMF - dbRegisterDBSchema(&userTable); - dbRegisterDBSchema(&groupTable); - dbRegisterDBSchema(&accessTable); -#endif - } - - if (saveFilename == NULL) { - saveFilename = bstrdup(B_L, UM_TXT_FILENAME); - } - - return didUM; -} - -/******************************************************************************/ -/* - * umClose() frees up the UM tables in the fake emf-database - */ - -void umClose() -{ - if (--umOpenCount > 0) { - return; - } -/* - * Do not close if intialization has not taken place - */ - if (didUM != -1) { - dbClose(didUM); - didUM = -1; - } - - if (saveFilename != NULL) { - bfree(B_L, saveFilename); - saveFilename = NULL; - } -} - -/******************************************************************************/ -/* - * umCommit() persists all of the UM tables - */ - -int umCommit(char_t *filename) -{ - if (filename && *filename) { - if (saveFilename != NULL) { - bfree(B_L, saveFilename); - } - - saveFilename = bstrdup(B_L, filename); - } - - a_assert (saveFilename && *saveFilename); - trace(3, T("UM: Writing User Configuration to file <%s>\n"), - saveFilename); - - return dbSave(didUM, saveFilename, 0); -} - -/******************************************************************************/ -/* - * umRestore() loads up the UM tables with persisted data - */ - -int umRestore(char_t *filename) -{ - if (filename && *filename) { - if (saveFilename != NULL) { - bfree(B_L, saveFilename); - } - - saveFilename = bstrdup(B_L, filename); - } - - a_assert(saveFilename && *saveFilename); - - trace(3, T("UM: Loading User Configuration from file <%s>\n"), - saveFilename); - -/* - * First empty the database, otherwise we wind up with duplicates! - */ - dbZero(didUM); - return dbLoad(didUM, saveFilename, 0); -} - -/******************************************************************************/ -/* - * Encrypt/Decrypt a text string. - * Returns the number of characters encrypted. - */ - -static int umEncryptString(char_t *textString) -{ - char_t *enMask; - char_t enChar; - int numChars; - - a_assert(textString); - - enMask = UM_XOR_ENCRYPT; - numChars = 0; - - while (*textString) { - enChar = *textString ^ *enMask; -/* - * Do not produce encrypted text with embedded linefeeds or tabs. - * Simply use existing character. - */ - if (enChar && !gisspace(enChar)) - *textString = enChar; -/* - * Increment all pointers. - */ - enMask++; - textString++; - numChars++; -/* - * Wrap encryption mask pointer if at end of length. - */ - if (*enMask == '\0') { - enMask = UM_XOR_ENCRYPT; - } - } - - return numChars; -} - -/******************************************************************************/ -/* - * umGetFirstRowData() - return a pointer to the first non-blank key value - * in the given column for the given table. - */ - -static char_t *umGetFirstRowData(char_t *tableName, char_t *columnName) -{ - char_t *columnData; - int row; - int check; - - a_assert(tableName && *tableName); - a_assert(columnName && *columnName); - - row = 0; -/* - * Move through table until we retrieve the first row with non-null - * column data. - */ - columnData = NULL; - while ((check = dbReadStr(didUM, tableName, columnName, row++, - &columnData)) == 0 || (check == DB_ERR_ROW_DELETED)) { - if (columnData && *columnData) { - return columnData; - } - } - - return NULL; -} - -/******************************************************************************/ -/* - * umGetNextRowData() - return a pointer to the first non-blank - * key value following the given one. - */ - -static char_t *umGetNextRowData(char_t *tableName, char_t *columnName, - char_t *keyLast) -{ - char_t *key; - int row; - int check; - - a_assert(tableName && *tableName); - a_assert(columnName && *columnName); - a_assert(keyLast && *keyLast); -/* - * Position row counter to row where the given key value was found - */ - row = 0; - key = NULL; - - while ((((check = dbReadStr(didUM, tableName, columnName, row++, - &key)) == 0) || (check == DB_ERR_ROW_DELETED)) && - ((key == NULL) || (gstrcmp(key, keyLast) != 0))) { - } -/* - * If the last key value was not found, return NULL - */ - if (!key || gstrcmp(key, keyLast) != 0) { - return NULL; - } -/* - * Move through table until we retrieve the next row with a non-null key - */ - while (((check = dbReadStr(didUM, tableName, columnName, row++, &key)) - == 0) || (check == DB_ERR_ROW_DELETED)) { - if (key && *key && (gstrcmp(key, keyLast) != 0)) { - return key; - } - } - - return NULL; -} - -/******************************************************************************/ -/* - * umAddUser() - Adds a user to the "users" table. - */ - -int umAddUser(char_t *user, char_t *pass, char_t *group, - bool_t prot, bool_t disabled) -{ - int row; - char_t *password; - - a_assert(user && *user); - a_assert(pass && *pass); - a_assert(group && *group); - - trace(3, T("UM: Adding User <%s>\n"), user); - -/* - * Do not allow duplicates - */ - if (umUserExists(user)) { - return UM_ERR_DUPLICATE; - } - -/* - * Make sure user name and password contain valid characters - */ - if (!umCheckName(user)) { - return UM_ERR_BAD_NAME; - } - - if (!umCheckName(pass)) { - return UM_ERR_BAD_PASSWORD; - } - -/* - * Make sure group exists - */ - if (!umGroupExists(group)) { - return UM_ERR_NOT_FOUND; - } - -/* - * Now create the user record - */ - row = dbAddRow(didUM, UM_USER_TABLENAME); - - if (row < 0) { - return UM_ERR_GENERAL; - } - - if (dbWriteStr(didUM, UM_USER_TABLENAME, UM_NAME, row, user) != 0) { - return UM_ERR_GENERAL; - } - - password = bstrdup(B_L, pass); - umEncryptString(password); - dbWriteStr(didUM, UM_USER_TABLENAME, UM_PASS, row, password); - bfree(B_L, password); - dbWriteStr(didUM, UM_USER_TABLENAME, UM_GROUP, row, group); - dbWriteInt(didUM, UM_USER_TABLENAME, UM_PROT, row, prot); - dbWriteInt(didUM, UM_USER_TABLENAME, UM_DISABLE, row, disabled); - - return 0; -} - -/******************************************************************************/ -/* - * umDeleteUser() - remove a user from the "users" table - */ - -int umDeleteUser(char_t *user) -{ - int row; - - a_assert(user && *user); - trace(3, T("UM: Deleting User <%s>\n"), user); -/* - * Check to see if user is delete-protected - */ - if (umGetUserProtected(user)) { - return UM_ERR_PROTECTED; - } - -/* - * If found, delete the user from the database - */ - if ((row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0)) >= 0) { - return dbDeleteRow(didUM, UM_USER_TABLENAME, row); - } - - return UM_ERR_NOT_FOUND; -} - -/******************************************************************************/ -/* - * umGetFirstUser() - Returns the user ID of the first user found in the - * "users" table. - */ - -char_t *umGetFirstUser() -{ - return umGetFirstRowData(UM_USER_TABLENAME, UM_NAME); -} - -/******************************************************************************/ -/* - * umGetNextUser() Returns the next user found in the "users" table after - * the given user. - */ - -char_t *umGetNextUser(char_t *userLast) -{ - return umGetNextRowData(UM_USER_TABLENAME, UM_NAME, userLast); -} - -/******************************************************************************/ -/* - * umUserExists() Returns TRUE if userid exists. - */ - -bool_t umUserExists(char_t *user) -{ - a_assert(user && *user); - - if (dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0) >= 0) { - return TRUE; - } else { - return FALSE; - } -} - -/******************************************************************************/ -/* - * umGetUserPassword() returns a de-crypted copy of the user password - */ - -char_t *umGetUserPassword(char_t *user) -{ - char_t *password; - int row; - - a_assert(user && *user); - - password = NULL; - row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0); - - if (row >= 0) { - char_t *pass = NULL; - dbReadStr(didUM, UM_USER_TABLENAME, UM_PASS, row, &pass); -/* - * Decrypt password - * Note, this function returns a copy of the password, which must - * be deleted at some time in the future. - */ - password = bstrdup(B_L, pass); - umEncryptString(password); - } - - return password; -} - -/******************************************************************************/ -/* - * umSetUserPassword() updates the user password in the user "table" after - * encrypting the given password - */ - -int umSetUserPassword(char_t *user, char_t *pass) -{ - int row, nRet; - char_t *password; - - a_assert(user && *user); - a_assert(pass && *pass); - trace(3, T("UM: Attempting to change the password for user <%s>\n"), user); -/* - * Find the row of the user - */ - if ((row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0)) < 0) { - return UM_ERR_NOT_FOUND; - } - - password = bstrdup(B_L, pass); - umEncryptString(password); - nRet = dbWriteStr(didUM, UM_USER_TABLENAME, UM_PASS, row, password); - bfree(B_L, password); - - return nRet; -} - -/******************************************************************************/ -/* - * umGetUserGroup() returns the name of the user group - */ - -char_t *umGetUserGroup(char_t *user) -{ - char_t *group; - int row; - - a_assert(user && *user); - group = NULL; -/* - * Find the row of the user - */ - row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0); - - if (row >= 0) { - dbReadStr(didUM, UM_USER_TABLENAME, UM_GROUP, row, &group); - } - - return group; -} - -/******************************************************************************/ -/* - * umSetUserGroup() Sets the name of the user group for the user - */ - -int umSetUserGroup(char_t *user, char_t *group) -{ - int row; - - a_assert(user && *user); - a_assert(group && *group); -/* - * Find the row of the user - */ - row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0); - - if (row >= 0) { - return dbWriteStr(didUM, UM_USER_TABLENAME, UM_GROUP, row, group); - } else { - return UM_ERR_NOT_FOUND; - } -} - -/******************************************************************************/ -/* - * umGetUserEnabled() - returns if the user is enabled - * Returns FALSE if the user is not found. - */ - -bool_t umGetUserEnabled(char_t *user) -{ - int disabled, row; - - a_assert(user && *user); - - disabled = 1; -/* - * Find the row of the user - */ - row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0); - - if (row >= 0) { - dbReadInt(didUM, UM_USER_TABLENAME, UM_DISABLE, row, &disabled); - } - - return (bool_t)!disabled; -} - -/******************************************************************************/ -/* - * umSetUserEnabled() Enables/disables the user - */ -int umSetUserEnabled(char_t *user, bool_t enabled) -{ - int row; - - a_assert(user && *user); -/* - * Find the row of the user - */ - row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0); - if (row >= 0) { - return dbWriteInt(didUM, UM_USER_TABLENAME, UM_DISABLE, row, !enabled); - } else { - return UM_ERR_NOT_FOUND; - } -} - -/******************************************************************************/ -/* - * umGetUserProtected() - determine deletability of user - */ - -bool_t umGetUserProtected(char_t *user) -{ - int protect, row; - - a_assert(user && *user); -/* - * Find the row of the user - */ - row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0); - protect = FALSE; - - if (row >= 0) { - dbReadInt(didUM, UM_USER_TABLENAME, UM_PROT, row, &protect); - } - - return (bool_t)protect; -} - -/******************************************************************************/ -/* - * umSetUserProtected() sets the delete protection for the user - */ -int umSetUserProtected(char_t *user, bool_t protect) -{ - int row; - - a_assert(user && *user); -/* - * Find the row of the user - */ - row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0); - - if (row >= 0) { - return dbWriteInt(didUM, UM_USER_TABLENAME, UM_PROT, row, protect); - } else { - return UM_ERR_NOT_FOUND; - } -} - - -/******************************************************************************/ -/* - * umAddGroup() adds a group to the "Group" table - */ - -int umAddGroup(char_t *group, short priv, accessMeth_t am, - bool_t prot, bool_t disabled) -{ - int row; - - a_assert(group && *group); - trace(3, T("UM: Adding group <%s>\n"), group); - -/* - * Do not allow duplicates - */ - if (umGroupExists(group)) { - return UM_ERR_DUPLICATE; - } - -/* - * Only allow valid characters in key field - */ - if (!umCheckName(group)) { - return UM_ERR_BAD_NAME; - } - -/* - * Add a new row to the table - */ - if ((row = dbAddRow(didUM, UM_GROUP_TABLENAME)) < 0) { - return UM_ERR_GENERAL; - } - -/* - * Write the key field - */ - if (dbWriteStr(didUM, UM_GROUP_TABLENAME, UM_NAME, row, group) != 0) { - return UM_ERR_GENERAL; - } - -/* - * Write the remaining fields - */ - dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PRIVILEGE, row, priv); - dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_METHOD, row, (int) am); - dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PROT, row, prot); - dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_DISABLE, row, disabled); - - return 0; -} - -/******************************************************************************/ -/* - * umDeleteGroup() - Delete a user group, if not protected - */ - -int umDeleteGroup(char_t *group) -{ - int row; - - a_assert(group && *group); - trace(3, T("UM: Deleting Group <%s>\n"), group); - -/* - * Check to see if the group is in use - */ - if (umGetGroupInUse(group)) { - return UM_ERR_IN_USE; - } - -/* - * Check to see if the group is delete-protected - */ - if (umGetGroupProtected(group)) { - return UM_ERR_PROTECTED; - } - -/* - * Find the row of the group to delete - */ - if ((row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0)) < 0) { - return UM_ERR_NOT_FOUND; - } - - return dbDeleteRow(didUM, UM_GROUP_TABLENAME, row); -} - -/******************************************************************************/ -/* - * umGroupExists() returns TRUE if group exists, FALSE otherwise - */ - -bool_t umGroupExists(char_t *group) -{ - a_assert(group && *group); - - if (dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0) >= 0) { - return TRUE; - } else { - return FALSE; - } -} - - -/******************************************************************************/ -/* - * umGetGroupInUse() returns TRUE if the group is referenced by a user or by - * an access limit. - */ - -bool_t umGetGroupInUse(char_t *group) -{ - a_assert(group && *group); - -/* - * First, check the user table - */ - if (dbSearchStr(didUM, UM_USER_TABLENAME, UM_GROUP, group, 0) >= 0) { - return TRUE; - } - -/* - * Second, check the access limit table - */ - if (dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, group, 0) >= 0) { - return TRUE; - } - - return FALSE; -} - - -/******************************************************************************/ -/* - * umGetFirstGroup() - return a pointer to the first non-blank group name - */ - -char_t *umGetFirstGroup() -{ - return umGetFirstRowData(UM_GROUP_TABLENAME, UM_NAME); -} - -/******************************************************************************/ -/* - * umGetNextGroup() - return a pointer to the first non-blank group name - * following the given group name - */ - -char_t *umGetNextGroup(char_t *groupLast) -{ - return umGetNextRowData(UM_GROUP_TABLENAME, UM_NAME, groupLast); -} - -/******************************************************************************/ -/* - * Returns the default access method to use for a given group - */ - -accessMeth_t umGetGroupAccessMethod(char_t *group) -{ - int am, row; - - a_assert(group && *group); - row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0); - - if (row >= 0) { - dbReadInt(didUM, UM_GROUP_TABLENAME, UM_METHOD, row, (int *)&am); - } else { - am = AM_INVALID; - } - - return (accessMeth_t) am; -} - -/******************************************************************************/ -/* - * Set the default access method to use for a given group - */ - -int umSetGroupAccessMethod(char_t *group, accessMeth_t am) -{ - int row; - - a_assert(group && *group); - row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0); - - if (row >= 0) { - return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_METHOD, row, (int) am); - } else { - return UM_ERR_NOT_FOUND; - } -} - -/******************************************************************************/ -/* - * Returns the privilege mask for a given group - */ - -short umGetGroupPrivilege(char_t *group) -{ - int privilege, row; - - a_assert(group && *group); - privilege = -1; - row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0); - - if (row >= 0) { - dbReadInt(didUM, UM_GROUP_TABLENAME, UM_PRIVILEGE, row, &privilege); - } - - return (short) privilege; -} - -/******************************************************************************/ -/* - * Set the privilege mask for a given group - */ - -int umSetGroupPrivilege(char_t *group, short privilege) -{ - int row; - - a_assert(group && *group); - row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0); - - if (row >= 0) { - return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PRIVILEGE, row, - (int)privilege); - } else { - return UM_ERR_NOT_FOUND; - } -} - -/******************************************************************************/ -/* - * Returns the enabled setting for a given group. - * Returns FALSE if group is not found. - */ - -bool_t umGetGroupEnabled(char_t *group) -{ - int disabled, row; - - a_assert(group && *group); - row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0); - disabled = 1; - - if (row >= 0) { - dbReadInt(didUM, UM_GROUP_TABLENAME, UM_DISABLE, row, &disabled); - } - - return (bool_t) !disabled; -} - -/******************************************************************************/ -/* - * Sets the enabled setting for a given group. - */ - -int umSetGroupEnabled(char_t *group, bool_t enabled) -{ - int row; - - a_assert(group && *group); - row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0); - - if (row >= 0) { - return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_DISABLE, row, - (int) !enabled); - } else { - return UM_ERR_NOT_FOUND; - } -} - -/******************************************************************************/ -/* - * Returns the protected setting for a given group - * Returns FALSE if user is not found - */ - -bool_t umGetGroupProtected(char_t *group) -{ - int protect, row; - - a_assert(group && *group); - - protect = 0; - row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0); - if (row >= 0) { - dbReadInt(didUM, UM_GROUP_TABLENAME, UM_PROT, row, &protect); - } - - return (bool_t) protect; -} - -/******************************************************************************/ -/* - * Sets the protected setting for a given group - */ - -int umSetGroupProtected(char_t *group, bool_t protect) -{ - int row; - - a_assert(group && *group); - row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0); - - if (row >= 0) { - return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PROT, row, - (int) protect); - } else { - return UM_ERR_NOT_FOUND; - } -} - - -/******************************************************************************/ -/* - * umAddAccessLimit() adds an access limit to the "access" table - */ - -int umAddAccessLimit(char_t *url, accessMeth_t am, short secure, char_t *group) -{ - int row; - - a_assert(url && *url); - trace(3, T("UM: Adding Access Limit for <%s>\n"), url); - -/* - * Do not allow duplicates - */ - if (umAccessLimitExists(url)) { - return UM_ERR_DUPLICATE; - } - -/* - * Add a new row to the table - */ - if ((row = dbAddRow(didUM, UM_ACCESS_TABLENAME)) < 0) { - return UM_ERR_GENERAL; - } - -/* - * Write the key field - */ - if(dbWriteStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, row, url) < 0) { - return UM_ERR_GENERAL; - } - -/* - * Write the remaining fields - */ - dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_METHOD, row, (int)am); - dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_SECURE, row, (int)secure); - dbWriteStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, row, group); - - return 0; -} - -/******************************************************************************/ -/* - * umDeleteAccessLimit() - */ - -int umDeleteAccessLimit(char_t *url) -{ - int row; - - a_assert(url && *url); - trace(3, T("UM: Deleting Access Limit for <%s>\n"), url); -/* - * Find the row of the access limit to delete - */ - if ((row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0)) < 0) { - return UM_ERR_NOT_FOUND; - } - - return dbDeleteRow(didUM, UM_ACCESS_TABLENAME, row); -} - -/******************************************************************************/ -/* - * umGetFirstGroup() - return a pointer to the first non-blank access limit - */ - -char_t *umGetFirstAccessLimit() -{ - return umGetFirstRowData(UM_ACCESS_TABLENAME, UM_NAME); -} - -/******************************************************************************/ -/* - * umGetNextAccessLimit() - return a pointer to the first non-blank - * access limit following the given one - */ - -char_t *umGetNextAccessLimit(char_t *urlLast) -{ - return umGetNextRowData(UM_ACCESS_TABLENAME, UM_NAME, urlLast); -} - -/******************************************************************************/ -/* - * umAccessLimitExists() returns TRUE if this access limit exists - */ - -bool_t umAccessLimitExists(char_t *url) -{ - a_assert(url && *url); - - if (dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0) < 0) { - return FALSE; - } else { - return TRUE; - } -} - -/******************************************************************************/ -/* - * umGetAccessLimit() returns the Access Method for the URL - */ - -accessMeth_t umGetAccessLimitMethod(char_t *url) -{ - int am, row; - - am = (int) AM_INVALID; - row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0); - - if (row >= 0) { - dbReadInt(didUM, UM_ACCESS_TABLENAME, UM_METHOD, row, &am); - } - - return (accessMeth_t) am; -} - -/******************************************************************************/ -/* - * umSetAccessLimitMethod() - set Access Method for Access Limit - */ - -int umSetAccessLimitMethod(char_t *url, accessMeth_t am) -{ - int row; - - a_assert(url && *url); - row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0); - - if (row >= 0) { - return dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_METHOD, row, (int) am); - } else { - return UM_ERR_NOT_FOUND; - } -} - -/******************************************************************************/ -/* - * umGetAccessLimitSecure() - returns secure switch for access limit - */ - -short umGetAccessLimitSecure(char_t *url) -{ - int secure, row; - - a_assert(url && *url); - secure = -1; - row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0); - - if (row >= 0) { - dbReadInt(didUM, UM_ACCESS_TABLENAME, UM_SECURE, row, &secure); - } - - return (short)secure; -} - -/******************************************************************************/ -/* - * umSetAccessLimitSecure() - sets the secure flag for the URL - */ - -int umSetAccessLimitSecure(char_t *url, short secure) -{ - int row; - - a_assert(url && *url); - row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0); - - if (row >= 0) { - return dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_SECURE, row, - (int)secure); - } else { - return UM_ERR_NOT_FOUND; - } -} - -/******************************************************************************/ -/* - * umGetAccessLimitGroup() - returns the user group of the access limit - */ - -char_t *umGetAccessLimitGroup(char_t *url) -{ - char_t *group; - int row; - - a_assert(url && *url); - group = NULL; - row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0); - - if (row >= 0) { - dbReadStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, row, &group); - } - - return group; -} - -/******************************************************************************/ -/* - * umSetAccessLimitGroup() - sets the user group for the access limit. - */ - -int umSetAccessLimitGroup(char_t *url, char_t *group) -{ - int row; - - a_assert(url && *url); - row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0); - - if (row >= 0) { - return dbWriteStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, row, group); - } else { - return UM_ERR_NOT_FOUND; - } -} - -/******************************************************************************/ -/* - * Returns the access limit to use for a given URL, by checking for URLs up - * the directory tree. Creates a new string that must be deleted. - */ - -char_t *umGetAccessLimit(char_t *url) -{ - char_t *urlRet, *urlCheck, *lastChar; - int len; - - a_assert(url && *url); - urlRet = NULL; - urlCheck = bstrdup(B_L, url); - a_assert(urlCheck); - len = gstrlen(urlCheck); -/* - * Scan back through URL to see if there is a "parent" access limit - */ - while (len && !urlRet) { - if (umAccessLimitExists(urlCheck)) { - urlRet = bstrdup(B_L, urlCheck); - } else { -/* - * Trim the end portion of the URL to the previous directory marker - */ - lastChar = urlCheck + len; - lastChar--; - - while ((lastChar >= urlCheck) && ((*lastChar == '/') || - (*lastChar == '\\'))) { - *lastChar = 0; - lastChar--; - } - - while ((lastChar >= urlCheck) && (*lastChar != '/') && - (*lastChar != '\\')) { - *lastChar = 0; - lastChar--; - } - - len = gstrlen(urlCheck); - } - } - bfree (B_L, urlCheck); - - return urlRet; -} - -/******************************************************************************/ -/* - * Returns the access method to use for a given URL - */ - -accessMeth_t umGetAccessMethodForURL(char_t *url) -{ - accessMeth_t amRet; - char_t *urlHavingLimit, *group; - - urlHavingLimit = umGetAccessLimit(url); - if (urlHavingLimit) { - group = umGetAccessLimitGroup(urlHavingLimit); - - if (group && *group) { - amRet = umGetGroupAccessMethod(group); - } else { - amRet = umGetAccessLimitMethod(urlHavingLimit); - } - - bfree(B_L, urlHavingLimit); - } else { - amRet = AM_FULL; - } - - return amRet; -} - -/******************************************************************************/ -/* - * Returns TRUE if user can access URL - */ - -bool_t umUserCanAccessURL(char_t *user, char_t *url) -{ - accessMeth_t amURL; - char_t *group, *usergroup, *urlHavingLimit; - short priv; - - a_assert(user && *user); - a_assert(url && *url); - -/* - * Make sure user exists - */ - if (!umUserExists(user)) { - return FALSE; - } - -/* - * Make sure user is enabled - */ - if (!umGetUserEnabled(user)) { - return FALSE; - } - -/* - * Make sure user has sufficient privileges (any will do) - */ - usergroup = umGetUserGroup(user); - priv = umGetGroupPrivilege(usergroup); - if (priv == 0) { - return FALSE; - } - -/* - * Make sure user's group is enabled - */ - if (!umGetGroupEnabled(usergroup)) { - return FALSE; - } - -/* - * The access method of the user group must not be AM_NONE - */ - if (umGetGroupAccessMethod(usergroup) == AM_NONE) { - return FALSE; - } - -/* - * Check to see if there is an Access Limit for this URL - */ - urlHavingLimit = umGetAccessLimit(url); - if (urlHavingLimit) { - amURL = umGetAccessLimitMethod(urlHavingLimit); - group = umGetAccessLimitGroup(urlHavingLimit); - bfree(B_L, urlHavingLimit); - } else { -/* - * If there isn't an access limit for the URL, user has full access - */ - return TRUE; - } - -/* - * If the access method for the URL is AM_NONE then - * the file "doesn't exist". - */ - if (amURL == AM_NONE) { - return FALSE; - } - -/* - * If Access Limit has a group specified, then the user must be a - * member of that group - */ - if (group && *group) { -#ifdef qHierarchicalAccess - /* - * If we are compiling with the hierarchical access extensions, we - * instead call the user-provided function that checks to see whether - * the current user's access level is greater than or equal to the - * access level required for this URL. - */ - return dmfCanAccess(usergroup, group); - -#else - if (usergroup && (gstrcmp(group, usergroup) != 0)) { - return FALSE; - - } -#endif - } - -/* - * Otherwise, user can access the URL - */ - return TRUE; - -} - -/******************************************************************************/ -/* - * Returns TRUE if given name has only valid chars - */ - -static bool_t umCheckName(char_t *name) -{ - a_assert(name && *name); - - if (name && *name) { - while (*name) { - if (gisspace(*name)) { - return FALSE; - } - - name++; - } - - return TRUE; - } - - return FALSE; -} - -/******************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/um.h b/c/src/libnetworking/rtems_webserver/um.h deleted file mode 100644 index b520893275..0000000000 --- a/c/src/libnetworking/rtems_webserver/um.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * um.h -- GoAhead User Management public header - * - * Copyright (c) GoAhead Software Inc., 1992-2000. All Rights Reserved. - * - * See the file "license.txt" for information on usage and redistribution - * - * $Id$ - */ - -#ifndef _h_UM -#define _h_UM 1 - -/******************************** Description *********************************/ - -/* - * GoAhead User Management header. This defines the User Management - * public APIs. Include this header for files that contain access to - * user inquiry or management. - */ - -/********************************* Includes ***********************************/ - -#ifndef UEMF - #include "basic/basic.h" - #include "emf/emf.h" -#else - #include "uemf.h" -#endif - -/********************************** Defines ***********************************/ - -/* - * Error Return Flags - */ -#define UM_OK 0 -#define UM_ERR_GENERAL -1 -#define UM_ERR_NOT_FOUND -2 -#define UM_ERR_PROTECTED -3 -#define UM_ERR_DUPLICATE -4 -#define UM_ERR_IN_USE -5 -#define UM_ERR_BAD_NAME -6 -#define UM_ERR_BAD_PASSWORD -7 - -/* - * Privilege Masks - */ -#define PRIV_NONE 0x00 -#define PRIV_READ 0x01 -#define PRIV_WRITE 0x02 -#define PRIV_ADMIN 0x04 - -/* - * User classes - */ -typedef short bool_t; - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -typedef enum { - AM_NONE = 0, - AM_FULL, - AM_BASIC, - AM_DIGEST, - AM_INVALID -} accessMeth_t; - -/********************************** Prototypes ********************************/ - -/* - * umOpen() must be called before accessing User Management functions - */ -extern int umOpen(); - -/* - * umClose() should be called before shutdown to free memory - */ -extern void umClose(); - -/* - * umCommit() persists the user management database - */ -extern int umCommit(char_t *filename); - -/* - * umRestore() loads the user management database - */ -extern int umRestore(char_t *filename); - -/* - * umUser functions use a user ID for a key - */ -extern int umAddUser(char_t *user, char_t *password, - char_t *group, bool_t protect, bool_t disabled); - -extern int umDeleteUser(char_t *user); - -extern char_t *umGetFirstUser(); -extern char_t *umGetNextUser(char_t *lastUser); - -extern bool_t umUserExists(char_t *user); - -extern char_t *umGetUserPassword(char_t *user); -extern int umSetUserPassword(char_t *user, char_t *password); - -extern char_t *umGetUserGroup(char_t *user); -extern int umSetUserGroup(char_t *user, char_t *password); - -extern bool_t umGetUserEnabled(char_t *user); -extern int umSetUserEnabled(char_t *user, bool_t enabled); - -extern bool_t umGetUserProtected(char_t *user); -extern int umSetUserProtected(char_t *user, bool_t protect); - -/* - * umGroup functions use a group name for a key - */ -extern int umAddGroup(char_t *group, short privilege, - accessMeth_t am, bool_t protect, bool_t disabled); - -extern int umDeleteGroup(char_t *group); - -extern char_t *umGetFirstGroup(); -extern char_t *umGetNextGroup(char_t *lastUser); - -extern bool_t umGroupExists(char_t *group); -extern bool_t umGetGroupInUse(char_t *group); - -extern accessMeth_t umGetGroupAccessMethod(char_t *group); -extern int umSetGroupAccessMethod(char_t *group, accessMeth_t am); - -extern bool_t umGetGroupEnabled(char_t *group); -extern int umSetGroupEnabled(char_t *group, bool_t enabled); - -extern short umGetGroupPrivilege(char_t *group); -extern int umSetGroupPrivilege(char_t *group, short privileges); - -extern bool_t umGetGroupProtected(char_t *group); -extern int umSetGroupProtected(char_t *group, bool_t protect); - -/* - * umAccessLimit functions use a URL as a key - */ -extern int umAddAccessLimit(char_t *url, accessMeth_t am, - short secure, char_t *group); - -extern int umDeleteAccessLimit(char_t *url); - -extern char_t *umGetFirstAccessLimit(); -extern char_t *umGetNextAccessLimit(char_t *lastUser); - -/* - * Returns the name of an ancestor access limit if - */ -extern char_t *umGetAccessLimit(char_t *url); - -extern bool_t umAccessLimitExists(char_t *url); - -extern accessMeth_t umGetAccessLimitMethod(char_t *url); -extern int umSetAccessLimitMethod(char_t *url, accessMeth_t am); - -extern short umGetAccessLimitSecure(char_t *url); -extern int umSetAccessLimitSecure(char_t *url, short secure); - -extern char_t *umGetAccessLimitGroup(char_t *url); -extern int umSetAccessLimitGroup(char_t *url, char_t *group); - -/* - * Convenience Functions - */ - -extern accessMeth_t umGetAccessMethodForURL(char_t *url); -extern bool_t umUserCanAccessURL(char_t *user, char_t *url); - -#endif /* _h_UM */ - -/******************************************************************************/ diff --git a/c/src/libnetworking/rtems_webserver/umui.c b/c/src/libnetworking/rtems_webserver/umui.c deleted file mode 100644 index 971b059bc7..0000000000 --- a/c/src/libnetworking/rtems_webserver/umui.c +++ /dev/null @@ -1,641 +0,0 @@ -/* - * umui.c -- User Management GoForm Processing - * - * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. - * - * See the file "license.txt" for usage and redistribution license requirements - * - * $Id$ - */ - -/******************************** Description *********************************/ - -/* - * This module provides GoForm functions for User management - */ - -/********************************* Includes ***********************************/ - -#include "wsIntrn.h" -#include "um.h" - -/********************************* Defines ************************************/ - -#define NONE_OPTION T("") -#define MSG_START T("

") -#define MSG_END T("

") - -/**************************** Forward Declarations ****************************/ - -static void formAddUser(webs_t wp, char_t *path, char_t *query); -static void formDeleteUser(webs_t wp, char_t *path, char_t *query); -static void formDisplayUser(webs_t wp, char_t *path, char_t *query); -static int aspGenerateUserList(int eid, webs_t wp, - int argc, char_t **argv); - -static void formAddGroup(webs_t wp, char_t *path, char_t *query); -static void formDeleteGroup(webs_t wp, char_t *path, char_t *query); -static int aspGenerateGroupList(int eid, webs_t wp, - int argc, char_t **argv); - -static void formAddAccessLimit(webs_t wp, char_t *path, char_t *query); -static void formDeleteAccessLimit(webs_t wp, char_t *path, char_t *query); -static int aspGenerateAccessLimitList(int eid, webs_t wp, - int argc, char_t **argv); - -static int aspGenerateAccessMethodList(int eid, webs_t wp, - int argc, char_t **argv); -static int aspGeneratePrivilegeList(int eid, webs_t wp, - int argc, char_t **argv); - -static void formSaveUserManagement(webs_t wp, char_t *path, char_t *query); -static void formLoadUserManagement(webs_t wp, char_t *path, char_t *query); - -static void websMsgStart(webs_t wp); -static void websMsgEnd(webs_t wp); - -/*********************************** Code *************************************/ -/* - * Set up the User Management form handlers - */ - -void formDefineUserMgmt(void) -{ - websAspDefine(T("MakeGroupList"), aspGenerateGroupList); - websAspDefine(T("MakeUserList"), aspGenerateUserList); - websAspDefine(T("MakeAccessLimitList"), aspGenerateAccessLimitList); - websAspDefine(T("MakeAccessMethodList"), aspGenerateAccessMethodList); - websAspDefine(T("MakePrivilegeList"), aspGeneratePrivilegeList); - - websFormDefine(T("AddUser"), formAddUser); - websFormDefine(T("DeleteUser"), formDeleteUser); - websFormDefine(T("DisplayUser"), formDisplayUser); - websFormDefine(T("AddGroup"), formAddGroup); - websFormDefine(T("DeleteGroup"), formDeleteGroup); - websFormDefine(T("AddAccessLimit"), formAddAccessLimit); - websFormDefine(T("DeleteAccessLimit"), formDeleteAccessLimit); - - websFormDefine(T("SaveUserManagement"), formSaveUserManagement); - websFormDefine(T("LoadUserManagement"), formLoadUserManagement); -} - -/******************************************************************************/ -/* - * Add a user - */ - -static void formAddUser(webs_t wp, char_t *path, char_t *query) -{ - char_t *userid, *pass1, *pass2, *group, *enabled, *ok; - bool_t bDisable; - int nCheck; - - a_assert(wp); - - userid = websGetVar(wp, T("user"), T("")); - pass1 = websGetVar(wp, T("password"), T("")); - pass2 = websGetVar(wp, T("passconf"), T("")); - group = websGetVar(wp, T("group"), T("")); - enabled = websGetVar(wp, T("enabled"), T("")); - ok = websGetVar(wp, T("ok"), T("")); - - websHeader(wp); - websMsgStart(wp); - - if (gstricmp(ok, T("ok")) != 0) { - websWrite(wp, T("Add User Cancelled")); - } else if (gstrcmp(pass1, pass2) != 0) { - websWrite(wp, T("Confirmation Password did not match.")); - } else { - if (enabled && *enabled && (gstrcmp(enabled, T("on")) == 0)) { - bDisable = FALSE; - } else { - bDisable = TRUE; - } - - nCheck = umAddUser(userid, pass1, group, 0, bDisable); - if (nCheck != 0) { - char_t * strError; - - switch (nCheck) { - case UM_ERR_DUPLICATE: - strError = T("User already exists."); - break; - - case UM_ERR_BAD_NAME: - strError = T("Invalid user name."); - break; - - case UM_ERR_BAD_PASSWORD: - strError = T("Invalid password."); - break; - - case UM_ERR_NOT_FOUND: - strError = T("Invalid or unselected group."); - break; - - default: - strError = T("Error writing user record."); - break; - } - - websWrite(wp, T("Unable to add user, \"%s\". %s"), - userid, strError); - } else { - websWrite(wp, T("User, \"%s\" was successfully added."), - userid); - } - } - - websMsgEnd(wp); - websFooter(wp); - websDone(wp, 200); -} - -/******************************************************************************/ -/* - * Delete a user - */ - -static void formDeleteUser(webs_t wp, char_t *path, char_t *query) -{ - char_t *userid, *ok; - - a_assert(wp); - - userid = websGetVar(wp, T("user"), T("")); - ok = websGetVar(wp, T("ok"), T("")); - - websHeader(wp); - websMsgStart(wp); - - if (gstricmp(ok, T("ok")) != 0) { - websWrite(wp, T("Delete User Cancelled")); - } else if (umUserExists(userid) == FALSE) { - websWrite(wp, T("ERROR: User \"%s\" not found"), userid); - } else if (umGetUserProtected(userid)) { - websWrite(wp, T("ERROR: User, \"%s\" is delete-protected."), userid); - } else if (umDeleteUser(userid) != 0) { - websWrite(wp, T("ERROR: Unable to delete user, \"%s\" "), userid); - } else { - websWrite(wp, T("User, \"%s\" was successfully deleted."), userid); - } - - websMsgEnd(wp); - websFooter(wp); - websDone(wp, 200); -} - -/******************************************************************************/ -/* - * Display the user info - */ - -static void formDisplayUser(webs_t wp, char_t *path, char_t *query) -{ - char_t *userid, *ok, *temp; - bool_t enabled; - - a_assert(wp); - - userid = websGetVar(wp, T("user"), T("")); - ok = websGetVar(wp, T("ok"), T("")); - - websHeader(wp); - websWrite(wp, T("")); - - if (gstricmp(ok, T("ok")) != 0) { - websWrite(wp, T("Display User Cancelled")); - } else if (umUserExists(userid) == FALSE) { - websWrite(wp, T("ERROR: User %s not found.\n"), userid); - } else { - websWrite(wp, T("

User ID: %s

\n"), userid); - temp = umGetUserGroup(userid); - websWrite(wp, T("

User Group: %s

\n"), temp); - enabled = umGetUserEnabled(userid); - websWrite(wp, T("

Enabled: %d

\n"), enabled); - } - - websWrite(wp, T("\n")); - websFooter(wp); - websDone(wp, 200); -} - - -/******************************************************************************/ -/* - * Generate HTML to create a list box containing the users - */ - -static int aspGenerateUserList(int eid, webs_t wp, int argc, char_t **argv) -{ - char_t *userid; - int row, nBytesSent, nBytes; - - a_assert(wp); - - nBytes = websWrite(wp, - T("")); - - return nBytesSent; -} - -/******************************************************************************/ -/* - * Add a group - */ - -static void formAddGroup(webs_t wp, char_t *path, char_t *query) -{ - char_t *group, *enabled, *privilege, *method, *ok, *pChar; - int nCheck; - short priv; - accessMeth_t am; - bool_t bDisable; - - a_assert(wp); - - group = websGetVar(wp, T("group"), T("")); - method = websGetVar(wp, T("method"), T("")); - enabled = websGetVar(wp, T("enabled"), T("")); - privilege = websGetVar(wp, T("privilege"), T("")); - ok = websGetVar(wp, T("ok"), T("")); - - websHeader(wp); - websMsgStart(wp); - - if (gstricmp(ok, T("ok")) != 0) { - websWrite(wp, T("Add Group Cancelled.")); - } else if ((group == NULL) || (*group == 0)) { - websWrite(wp, T("No Group Name was entered.")); - } else if (umGroupExists(group)) { - websWrite(wp, T("ERROR: Group, \"%s\" already exists."), group); - } else { - if (privilege && *privilege) { -/* - * privilege is a mulitple ")); -/* - * Add a special "" element to allow de-selection - */ - nBytes = websWrite(wp, T("