mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-08-23 07:42:47 +08:00
Remove (Moved to cpukit/http).
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
|
||||
@@ -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 <antti.p.miettinen@nokia.com>.
|
||||
|
||||
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
|
||||
|
||||
@@ -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("<h2><b>ASP Error: %s</b></h2>\n"),
|
||||
result);
|
||||
websWrite(wp, T("<pre>%s</pre>"), nextp);
|
||||
bfree(B_L, result);
|
||||
} else {
|
||||
websWrite(wp, T("<h2><b>ASP Error</b></h2>\n%s\n"),
|
||||
nextp);
|
||||
}
|
||||
websWrite(wp, T("</body></html>\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;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/******************************************************************************/
|
||||
@@ -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 <b>%s</b>"), url);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (websPageStat(wp, lpath, path, &sbuf) < 0) {
|
||||
websError(wp, 400, T("Cannot stat page for URL <b>%s</b>"), 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);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -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 */
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -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 <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef CE
|
||||
#ifndef UEMF
|
||||
#include <io.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef LYNX
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef QNX4
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#ifdef UEMF
|
||||
#include "uemf.h"
|
||||
#else
|
||||
#include <param.h>
|
||||
#include <stat.h>
|
||||
#include "basic/basicInternal.h"
|
||||
#include "emf/emfInternal.h"
|
||||
#endif
|
||||
|
||||
#include "ej.h"
|
||||
|
||||
/********************************** 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 */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -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("<html>\n"));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Write a webs footer
|
||||
*/
|
||||
|
||||
void websFooter(webs_t wp)
|
||||
{
|
||||
a_assert(websValid(wp));
|
||||
|
||||
websWrite(wp, T("</html>\n"));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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},
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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 <stdlib.h>
|
||||
|
||||
#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 */
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -1,6 +0,0 @@
|
||||
/*
|
||||
* rtems_webserver.h --
|
||||
*
|
||||
*/
|
||||
|
||||
int rtems_initialize_webserver();
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -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()
|
||||
{
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
|
||||
/******************************************************************************/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,212 +0,0 @@
|
||||
/*
|
||||
* url.c -- Parse URLs
|
||||
*
|
||||
* 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 parses URLs into their components.
|
||||
*/
|
||||
|
||||
/********************************* Includes ***********************************/
|
||||
|
||||
#include "wsIntrn.h"
|
||||
|
||||
/********************************* Statics ************************************/
|
||||
/*
|
||||
* htmExt is declared in this way to avoid a Linux and Solaris segmentation
|
||||
* fault when a constant string is passed to strlower which could change its
|
||||
* argument.
|
||||
*/
|
||||
|
||||
char_t htmExt[] = T(".htm");
|
||||
|
||||
|
||||
/*********************************** Code *************************************/
|
||||
/*
|
||||
* Return the mime type for the given URL given a URL.
|
||||
* The caller supplies the buffer to hold the result.
|
||||
* charCnt is the number of characters the buffer will hold, ascii or UNICODE.
|
||||
*/
|
||||
|
||||
char_t *websUrlType(char_t *url, char_t *buf, int charCnt)
|
||||
{
|
||||
sym_t *sp;
|
||||
char_t *ext, *parsebuf;
|
||||
|
||||
a_assert(url && *url);
|
||||
a_assert(buf && charCnt > 0);
|
||||
|
||||
if (url == NULL || *url == '\0') {
|
||||
gstrcpy(buf, T("text/plain"));
|
||||
return buf;
|
||||
}
|
||||
if (websUrlParse(url, &parsebuf, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, &ext) < 0) {
|
||||
gstrcpy(buf, T("text/plain"));
|
||||
return buf;
|
||||
}
|
||||
strlower(ext);
|
||||
|
||||
/*
|
||||
* Lookup the mime type symbol table to find the relevant content type
|
||||
*/
|
||||
if ((sp = symLookup(websMime, ext)) != NULL) {
|
||||
gstrncpy(buf, sp->content.value.string, charCnt);
|
||||
} else {
|
||||
gstrcpy(buf, T("text/plain"));
|
||||
}
|
||||
bfree(B_L, parsebuf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Parse the URL. A buffer is allocated to store the parsed URL in *pbuf.
|
||||
* This must be freed by the caller. NOTE: tag is not yet fully supported.
|
||||
*/
|
||||
|
||||
int websUrlParse(char_t *url, char_t **pbuf, char_t **phost, char_t **ppath,
|
||||
char_t **pport, char_t **pquery, char_t **pproto, char_t **ptag,
|
||||
char_t **pext)
|
||||
{
|
||||
char_t *tok, *cp, *host, *path, *port, *proto, *tag, *query, *ext;
|
||||
char_t *last_delim, *hostbuf, *portbuf, *buf;
|
||||
int c, len, ulen;
|
||||
|
||||
a_assert(url);
|
||||
a_assert(pbuf);
|
||||
|
||||
ulen = gstrlen(url);
|
||||
/*
|
||||
* We allocate enough to store separate hostname and port number fields.
|
||||
* As there are 3 strings in the one buffer, we need room for 3 null chars.
|
||||
* We allocate MAX_PORT_LEN char_t's for the port number.
|
||||
*/
|
||||
len = ulen * 2 + MAX_PORT_LEN + 3;
|
||||
if ((buf = balloc(B_L, len * sizeof(char_t))) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
portbuf = &buf[len - MAX_PORT_LEN - 1];
|
||||
hostbuf = &buf[ulen+1];
|
||||
gstrcpy(buf, url);
|
||||
url = buf;
|
||||
|
||||
/*
|
||||
* Convert the current listen port to a string. We use this if the URL has
|
||||
* no explicit port setting
|
||||
*/
|
||||
stritoa(websGetPort(), portbuf, MAX_PORT_LEN);
|
||||
port = portbuf;
|
||||
path = T("/");
|
||||
proto = T("http");
|
||||
host = T("localhost");
|
||||
query = T("");
|
||||
ext = htmExt;
|
||||
tag = T("");
|
||||
|
||||
if (gstrncmp(url, T("http://"), 7) == 0) {
|
||||
tok = &url[7];
|
||||
tok[-3] = '\0';
|
||||
proto = url;
|
||||
host = tok;
|
||||
for (cp = tok; *cp; cp++) {
|
||||
if (*cp == '/') {
|
||||
break;
|
||||
}
|
||||
if (*cp == ':') {
|
||||
*cp++ = '\0';
|
||||
port = cp;
|
||||
tok = cp;
|
||||
}
|
||||
}
|
||||
if ((cp = gstrchr(tok, '/')) != NULL) {
|
||||
/*
|
||||
* If a full URL is supplied, we need to copy the host and port
|
||||
* portions into static buffers.
|
||||
*/
|
||||
c = *cp;
|
||||
*cp = '\0';
|
||||
gstrncpy(hostbuf, host, ulen);
|
||||
gstrncpy(portbuf, port, MAX_PORT_LEN);
|
||||
*cp = c;
|
||||
host = hostbuf;
|
||||
port = portbuf;
|
||||
path = cp;
|
||||
tok = cp;
|
||||
}
|
||||
|
||||
} else {
|
||||
path = url;
|
||||
tok = url;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the query string
|
||||
*/
|
||||
if ((cp = gstrchr(tok, '?')) != NULL) {
|
||||
*cp++ = '\0';
|
||||
query = cp;
|
||||
path = tok;
|
||||
tok = query;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the fragment identifier
|
||||
*/
|
||||
if ((cp = gstrchr(tok, '#')) != NULL) {
|
||||
*cp++ = '\0';
|
||||
if (*query == 0) {
|
||||
path = tok;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Only do the following if asked for the extension
|
||||
*/
|
||||
if (pext) {
|
||||
if ((cp = gstrrchr(path, '.')) != NULL) {
|
||||
if ((last_delim = gstrrchr(path, '/')) != NULL) {
|
||||
if (last_delim > cp) {
|
||||
ext = htmExt;
|
||||
} else {
|
||||
ext = cp;
|
||||
}
|
||||
} else {
|
||||
ext = cp;
|
||||
}
|
||||
} else {
|
||||
if (path[gstrlen(path) - 1] == '/') {
|
||||
ext = htmExt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass back the fields requested (if not NULL)
|
||||
*/
|
||||
if (phost)
|
||||
*phost = host;
|
||||
if (ppath)
|
||||
*ppath = path;
|
||||
if (pport)
|
||||
*pport = port;
|
||||
if (pproto)
|
||||
*pproto = proto;
|
||||
if (pquery)
|
||||
*pquery = query;
|
||||
if (ptag)
|
||||
*ptag = tag;
|
||||
if (pext)
|
||||
*pext = ext;
|
||||
*pbuf = buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* base64.c -- Base64 Mime encoding
|
||||
*
|
||||
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
|
||||
*
|
||||
* See the file "license.txt" for usage and redistribution license requirements
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/******************************** Description *********************************/
|
||||
|
||||
/*
|
||||
* The base64 command encodes and decodes a string in mime base64 format
|
||||
*/
|
||||
|
||||
/********************************* Includes ***********************************/
|
||||
|
||||
#include "wsIntrn.h"
|
||||
|
||||
/******************************** Local Data **********************************/
|
||||
/*
|
||||
* Mapping of ANSI chars to base64 Mime encoding alphabet (see below)
|
||||
*/
|
||||
|
||||
static char_t map64[] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
|
||||
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
};
|
||||
|
||||
static char_t alphabet64[] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||
'4', '5', '6', '7', '8', '9', '+', '/',
|
||||
};
|
||||
|
||||
/*********************************** Code *************************************/
|
||||
/*
|
||||
* Decode a buffer from "string" and into "outbuf"
|
||||
*/
|
||||
|
||||
int websDecode64(char_t *outbuf, char_t *string, int outlen)
|
||||
{
|
||||
unsigned long shiftbuf;
|
||||
char_t *cp, *op;
|
||||
int c, i, j, shift;
|
||||
|
||||
op = outbuf;
|
||||
*op = '\0';
|
||||
cp = string;
|
||||
while (*cp && *cp != '=') {
|
||||
/*
|
||||
* Map 4 (6bit) input bytes and store in a single long (shiftbuf)
|
||||
*/
|
||||
shiftbuf = 0;
|
||||
shift = 18;
|
||||
for (i = 0; i < 4 && *cp && *cp != '='; i++, cp++) {
|
||||
c = map64[*cp & 0xff];
|
||||
if (c == -1) {
|
||||
error(E_L, E_LOG, T("Bad string: %s at %c index %d"), string,
|
||||
c, i);
|
||||
return -1;
|
||||
}
|
||||
shiftbuf = shiftbuf | (c << shift);
|
||||
shift -= 6;
|
||||
}
|
||||
/*
|
||||
* Interpret as 3 normal 8 bit bytes (fill in reverse order).
|
||||
* Check for potential buffer overflow before filling.
|
||||
*/
|
||||
--i;
|
||||
if ((op + i) >= &outbuf[outlen]) {
|
||||
gstrcpy(outbuf, T("String too big"));
|
||||
return -1;
|
||||
}
|
||||
for (j = 0; j < i; j++) {
|
||||
*op++ = (char_t) ((shiftbuf >> (8 * (2 - j))) & 0xff);
|
||||
}
|
||||
*op = '\0';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Encode a buffer from "string" into "outbuf"
|
||||
*/
|
||||
|
||||
void websEncode64(char_t *outbuf, char_t *string, int outlen)
|
||||
{
|
||||
unsigned long shiftbuf;
|
||||
char_t *cp, *op;
|
||||
int x, i, j, shift;
|
||||
|
||||
op = outbuf;
|
||||
*op = '\0';
|
||||
cp = string;
|
||||
while (*cp) {
|
||||
/*
|
||||
* Take three characters and create a 24 bit number in shiftbuf
|
||||
*/
|
||||
shiftbuf = 0;
|
||||
for (j = 2; j >= 0 && *cp; j--, cp++) {
|
||||
shiftbuf |= ((*cp & 0xff) << (j * 8));
|
||||
}
|
||||
/*
|
||||
* Now convert shiftbuf to 4 base64 letters. The i,j magic calculates
|
||||
* how many letters need to be output.
|
||||
*/
|
||||
shift = 18;
|
||||
for (i = ++j; i < 4 && op < &outbuf[outlen] ; i++) {
|
||||
x = (shiftbuf >> shift) & 0x3f;
|
||||
*op++ = alphabet64[(shiftbuf >> shift) & 0x3f];
|
||||
shift -= 6;
|
||||
}
|
||||
/*
|
||||
* Pad at the end with '='
|
||||
*/
|
||||
while (j-- > 0) {
|
||||
*op++ = '=';
|
||||
}
|
||||
*op = '\0';
|
||||
}
|
||||
}
|
||||
/******************************************************************************/
|
||||
@@ -1,188 +0,0 @@
|
||||
/*
|
||||
* webcomp -- Compile web pages into C source
|
||||
*
|
||||
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
|
||||
*
|
||||
* See the file "license.txt" for usage and redistribution license requirements
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/******************************** Description *********************************/
|
||||
|
||||
/*
|
||||
* Usage: webcomp prefix filelist >webrom.c
|
||||
*
|
||||
* filelist is a file containing the pathnames of all web pages
|
||||
* prefix is a path prefix to remove from all the web page pathnames
|
||||
* webrom.c is the resulting C source file to compile and link.
|
||||
*/
|
||||
|
||||
/********************************* Includes ***********************************/
|
||||
|
||||
#include "wsIntrn.h"
|
||||
|
||||
/**************************** Forward Declarations ****************************/
|
||||
|
||||
static int compile(char_t *fileList, char_t *prefix);
|
||||
static void usage();
|
||||
|
||||
/*********************************** Code *************************************/
|
||||
/*
|
||||
* Main program for webpack test harness
|
||||
*/
|
||||
|
||||
int gmain(int argc, char_t* argv[])
|
||||
{
|
||||
char_t *fileList, *prefix;
|
||||
|
||||
fileList = NULL;
|
||||
|
||||
if (argc != 3) {
|
||||
usage();
|
||||
}
|
||||
|
||||
prefix = argv[1];
|
||||
fileList = argv[2];
|
||||
|
||||
if (compile(fileList, prefix) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Output usage message
|
||||
*/
|
||||
|
||||
static void usage()
|
||||
{
|
||||
fprintf(stderr, "usage: webcomp prefix filelist >output.c\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Compile the web pages
|
||||
*/
|
||||
|
||||
static int compile(char_t *fileList, char_t *prefix)
|
||||
{
|
||||
gstat_t sbuf;
|
||||
FILE *lp;
|
||||
time_t now;
|
||||
char_t file[FNAMESIZE];
|
||||
char_t *cp, *sl;
|
||||
char buf[512];
|
||||
unsigned char *p;
|
||||
int j, i, len, fd, nFile;
|
||||
|
||||
/*
|
||||
* Open list of files
|
||||
*/
|
||||
if ((lp = fopen(fileList, "r")) == NULL) {
|
||||
fprintf(stderr, "Can't open file list %s\n", fileList);
|
||||
return -1;
|
||||
}
|
||||
|
||||
time(&now);
|
||||
fprintf(stdout, "/*\n * webrom.c -- Compiled Web Pages\n *\n");
|
||||
fprintf(stdout, " * Compiled by GoAhead WebCompile: %s */\n\n",
|
||||
gctime(&now));
|
||||
fprintf(stdout, "#include \"wsIntrn.h\"\n\n");
|
||||
fprintf(stdout, "#ifndef WEBS_PAGE_ROM\n");
|
||||
fprintf(stdout, "websRomPageIndexType websRomPageIndex[] = {\n");
|
||||
fprintf(stdout, " { 0, 0, 0 },\n};\n");
|
||||
fprintf(stdout, "#else\n");
|
||||
|
||||
/*
|
||||
* Open each input file and compile each web page
|
||||
*/
|
||||
nFile = 0;
|
||||
while (fgets(file, sizeof(file), lp) != NULL) {
|
||||
if ((p = strchr(file, '\n')) || (p = strchr(file, '\r'))) {
|
||||
*p = '\0';
|
||||
}
|
||||
if (*file == '\0') {
|
||||
continue;
|
||||
}
|
||||
if (gstat(file, &sbuf) == 0 && sbuf.st_mode & S_IFDIR) {
|
||||
continue;
|
||||
}
|
||||
if ((fd = gopen(file, O_RDONLY | O_BINARY)) < 0) {
|
||||
fprintf(stderr, "Can't open file %s\n", file);
|
||||
return -1;
|
||||
}
|
||||
fprintf(stdout, "static unsigned char page_%d[] = {\n", nFile);
|
||||
|
||||
while ((len = read(fd, buf, sizeof(buf))) > 0) {
|
||||
p = buf;
|
||||
for (i = 0; i < len; ) {
|
||||
fprintf(stdout, " ");
|
||||
for (j = 0; p < &buf[len] && j < 16; j++, p++) {
|
||||
fprintf(stdout, "%3d,", *p);
|
||||
}
|
||||
i += j;
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
}
|
||||
fprintf(stdout, " 0 };\n\n");
|
||||
|
||||
close(fd);
|
||||
nFile++;
|
||||
}
|
||||
fclose(lp);
|
||||
|
||||
/*
|
||||
* Now output the page index
|
||||
*/
|
||||
fprintf(stdout, "websRomPageIndexType websRomPageIndex[] = {\n");
|
||||
|
||||
if ((lp = fopen(fileList, "r")) == NULL) {
|
||||
fprintf(stderr, "Can't open file list %s\n", fileList);
|
||||
return -1;
|
||||
}
|
||||
nFile = 0;
|
||||
while (fgets(file, sizeof(file), lp) != NULL) {
|
||||
if ((p = strchr(file, '\n')) || (p = strchr(file, '\r'))) {
|
||||
*p = '\0';
|
||||
}
|
||||
if (*file == '\0') {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Remove the prefix and add a leading "/" when we print the path
|
||||
*/
|
||||
if (strncmp(file, prefix, gstrlen(prefix)) == 0) {
|
||||
cp = &file[gstrlen(prefix)];
|
||||
} else {
|
||||
cp = file;
|
||||
}
|
||||
while((sl = strchr(file, '\\')) != NULL) {
|
||||
*sl = '/';
|
||||
}
|
||||
if (*cp == '/') {
|
||||
cp++;
|
||||
}
|
||||
|
||||
if (gstat(file, &sbuf) == 0 && sbuf.st_mode & S_IFDIR) {
|
||||
fprintf(stdout, " { T(\"/%s\"), 0, 0 },\n", cp);
|
||||
continue;
|
||||
}
|
||||
fprintf(stdout, " { T(\"/%s\"), page_%d, %d },\n", cp, nFile,
|
||||
sbuf.st_size);
|
||||
nFile++;
|
||||
}
|
||||
fclose(lp);
|
||||
|
||||
fprintf(stdout, " { 0, 0, 0 },\n");
|
||||
fprintf(stdout, "};\n");
|
||||
fprintf(stdout, "#endif /* WEBS_PAGE_ROM */\n");
|
||||
|
||||
fclose(lp);
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -1,499 +0,0 @@
|
||||
/*
|
||||
* main.c -- Main program for the GoAhead WebServer (RTEMS version)
|
||||
*
|
||||
* Copyright (c) Go Ahead Software Inc., 1995-1999. All Rights Reserved.
|
||||
*
|
||||
* See the file "license.txt" for usage and redistribution license requirements
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/******************************** Description *********************************/
|
||||
|
||||
/*
|
||||
* Main program for for the GoAhead WebServer. This is a demonstration
|
||||
* main program to initialize and configure the web server.
|
||||
*/
|
||||
|
||||
/********************************* Includes ***********************************/
|
||||
|
||||
#include "uemf.h"
|
||||
#include "wsIntrn.h"
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/error.h>
|
||||
|
||||
#ifdef WEBS_SSL_SUPPORT
|
||||
#include "websSSL.h"
|
||||
#endif
|
||||
|
||||
#ifdef USER_MANAGEMENT_SUPPORT
|
||||
#include "um.h"
|
||||
void formDefineUserMgmt(void);
|
||||
#endif
|
||||
|
||||
/*********************************** Locals ***********************************/
|
||||
/*
|
||||
* Change configuration here
|
||||
*/
|
||||
|
||||
extern const char *tftpServer;
|
||||
/* static char_t *rootWeb = T("goahead"); * Root web directory */
|
||||
static char_t *password = T(""); /* Security password */
|
||||
static int port = 80; /* Server port */
|
||||
static int retries = 5; /* Server port retries */
|
||||
static int finished; /* Finished flag */
|
||||
|
||||
/*
|
||||
* Structure to hold timer events
|
||||
*/
|
||||
typedef struct {
|
||||
void (*routine)(long arg); /* Timer routine */
|
||||
long arg; /* Argument to routine */
|
||||
} websTimer_t;
|
||||
|
||||
/* The following holds the pointer to an allocated websTimer_t structure .
|
||||
* Using this method only one timer can be active at a time, but
|
||||
* for the WebServer, this should be OK.
|
||||
*/
|
||||
websTimer_t *tp;
|
||||
|
||||
/****************************** Forward Declarations **************************/
|
||||
|
||||
static int initWebs();
|
||||
static int aspTest(int eid, webs_t wp, int argc, char_t **argv);
|
||||
static void formTest(webs_t wp, char_t *path, char_t *query);
|
||||
static int websHomePageHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
|
||||
int arg, char_t* url, char_t* path, char_t* query);
|
||||
static void timerProc(int signo);
|
||||
#if B_STATS
|
||||
static void printMemStats(int handle, char_t *fmt, ...);
|
||||
static void memLeaks();
|
||||
#endif
|
||||
static timer_t timer_id;
|
||||
static void rtems_httpd_daemon();
|
||||
|
||||
/*********************************** Code *************************************/
|
||||
/*
|
||||
* Main -- entry point from RTEMS
|
||||
*/
|
||||
int rtems_initialize_webserver()
|
||||
{
|
||||
rtems_status_code sc;
|
||||
rtems_id tid;
|
||||
int priority;
|
||||
|
||||
/***********************************************************************
|
||||
* Default HTTPD priority.
|
||||
**********************************************************************/
|
||||
priority = 40;
|
||||
|
||||
sc = rtems_task_create(rtems_build_name('H', 'T', 'P', 'D'),
|
||||
priority, 8*1024,
|
||||
RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_NO_ASR |
|
||||
RTEMS_INTERRUPT_LEVEL(0),
|
||||
RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
|
||||
&tid);
|
||||
if (sc != RTEMS_SUCCESSFUL)
|
||||
{
|
||||
return(RTEMS_UNSATISFIED);
|
||||
}
|
||||
|
||||
sc = rtems_task_start(tid, rtems_httpd_daemon, 0);
|
||||
if (sc != RTEMS_SUCCESSFUL)
|
||||
{
|
||||
return(RTEMS_UNSATISFIED);
|
||||
}
|
||||
|
||||
return(RTEMS_SUCCESSFUL);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
rtems_httpd_daemon()
|
||||
{
|
||||
/*
|
||||
* Initialize the memory allocator. Allow use of malloc and start with a
|
||||
* 10K heap.
|
||||
*/
|
||||
bopen(NULL, (10 * 1024), B_USE_MALLOC);
|
||||
|
||||
/*
|
||||
* Initialize the web server
|
||||
*/
|
||||
if (initWebs() < 0) {
|
||||
rtems_panic("Unable to initialize Web server !!\n");
|
||||
}
|
||||
|
||||
#ifdef WEBS_SSL_SUPPORT
|
||||
websSSLOpen();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Basic event loop. SocketReady returns true when a socket is ready for
|
||||
* service. SocketSelect will block until an event occurs. SocketProcess
|
||||
* will actually do the servicing.
|
||||
*/
|
||||
while (!finished) {
|
||||
if (socketReady(-1) || socketSelect(-1, 2000)) {
|
||||
socketProcess(-1);
|
||||
}
|
||||
/*websCgiCleanup();*/
|
||||
emfSchedProcess();
|
||||
}
|
||||
|
||||
#ifdef WEBS_SSL_SUPPORT
|
||||
websSSLClose();
|
||||
#endif
|
||||
|
||||
#ifdef USER_MANAGEMENT_SUPPORT
|
||||
umClose();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Close the socket module, report memory leaks and close the memory allocator
|
||||
*/
|
||||
websCloseServer();
|
||||
websDefaultClose();
|
||||
socketClose();
|
||||
symSubClose();
|
||||
#if B_STATS
|
||||
memLeaks();
|
||||
#endif
|
||||
bclose();
|
||||
rtems_task_delete( RTEMS_SELF );
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Initialize the web server.
|
||||
*/
|
||||
|
||||
static int initWebs()
|
||||
{
|
||||
struct hostent* hp;
|
||||
struct in_addr intaddr;
|
||||
char host[128], webdir[128];
|
||||
char_t wbuf[128];
|
||||
|
||||
/*
|
||||
* Initialize the socket subsystem
|
||||
*/
|
||||
socketOpen();
|
||||
|
||||
/*
|
||||
* Define the local Ip address, host name, default home page and the
|
||||
* root web directory.
|
||||
*/
|
||||
if (gethostname(host, sizeof(host)) < 0) {
|
||||
error(E_L, E_LOG, T("Can't get hostname"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* intaddr.s_addr = (unsigned long) hostGetByName(host); */
|
||||
if ((hp = gethostbyname(host)) == NULL) {
|
||||
error(E_L, E_LOG, T("Can't get host address"));
|
||||
return -1;
|
||||
}
|
||||
memcpy((char *) &intaddr, (char *) hp->h_addr_list[0],
|
||||
(size_t) hp->h_length);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Set /TFTP/x.y.z.w/goahead as the root web. Modify to suit your needs
|
||||
*/
|
||||
sprintf(webdir, "/TFTP/%s/%s", tftpServer, rootWeb);
|
||||
#else
|
||||
sprintf(webdir, "/");
|
||||
#endif
|
||||
/*
|
||||
* Configure the web server options before opening the web server
|
||||
*/
|
||||
websSetDefaultDir(webdir);
|
||||
ascToUni(wbuf, inet_ntoa(intaddr), sizeof(wbuf));
|
||||
websSetIpaddr(wbuf);
|
||||
ascToUni(wbuf, host, sizeof(wbuf));
|
||||
websSetHost(wbuf);
|
||||
|
||||
/*
|
||||
* Configure the web server options before opening the web server
|
||||
*/
|
||||
#if 0
|
||||
websSetDefaultPage(T("default.asp"));
|
||||
#else
|
||||
websSetDefaultPage(T("index.html"));
|
||||
#endif
|
||||
websSetPassword(password);
|
||||
|
||||
/*
|
||||
* Open the web server on the given port. If that port is taken, try
|
||||
* the next sequential port for up to "retries" attempts.
|
||||
*/
|
||||
websOpenServer(port, retries);
|
||||
|
||||
/*
|
||||
* First create the URL handlers. Note: handlers are called in sorted order
|
||||
* with the longest path handler examined first. Here we define the security
|
||||
* handler, forms handler and the default web page handler.
|
||||
*/
|
||||
websUrlHandlerDefine(T(""), NULL, 0, websSecurityHandler,
|
||||
WEBS_HANDLER_FIRST);
|
||||
websUrlHandlerDefine(T("/goform"), NULL, 0, websFormHandler, 0);
|
||||
websUrlHandlerDefine(T(""), NULL, 0, websDefaultHandler,
|
||||
WEBS_HANDLER_LAST);
|
||||
|
||||
/*
|
||||
* Now define two test procedures. Replace these with your application
|
||||
* relevant ASP script procedures and form functions.
|
||||
*/
|
||||
websAspDefine(T("aspTest"), aspTest);
|
||||
websFormDefine(T("formTest"), formTest);
|
||||
|
||||
/*
|
||||
* Create a handler for the default home page
|
||||
*/
|
||||
websUrlHandlerDefine(T("/"), NULL, 0, websHomePageHandler, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Test Javascript binding for ASP. This will be invoked when "aspTest" is
|
||||
* embedded in an ASP page. See web/asp.asp for usage. Set browser to
|
||||
* "localhost/asp.asp" to test.
|
||||
*/
|
||||
|
||||
static int aspTest(int eid, webs_t wp, int argc, char_t **argv)
|
||||
{
|
||||
char_t *name, *address;
|
||||
|
||||
if (ejArgs(argc, argv, T("%s %s"), &name, &address) < 2) {
|
||||
websError(wp, 400, T("Insufficient args\n"));
|
||||
return -1;
|
||||
}
|
||||
return websWrite(wp, T("Name: %s, Address %s"), name, address);
|
||||
}
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Test form for posted data (in-memory CGI). This will be called when the
|
||||
* form in web/asp.asp is invoked. Set browser to "localhost/asp.asp" to test.
|
||||
*/
|
||||
|
||||
static void formTest(webs_t wp, char_t *path, char_t *query)
|
||||
{
|
||||
char_t *name, *address;
|
||||
|
||||
name = websGetVar(wp, T("name"), T("Joe Smith"));
|
||||
address = websGetVar(wp, T("address"), T("1212 Milky Way Ave."));
|
||||
|
||||
websHeader(wp);
|
||||
websWrite(wp, T("<body><h2>Name: %s, Address: %s</h2>\n"), name, address);
|
||||
websFooter(wp);
|
||||
websDone(wp, 200);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Create a timer to invoke the routine in "delay" milliseconds.
|
||||
*/
|
||||
|
||||
void *emfCreateTimer(int delay, void (*routine)(long arg), long arg)
|
||||
{
|
||||
/* this variable is only used in the if'ed 0 section below */
|
||||
#if 0
|
||||
struct sigaction act;
|
||||
#endif
|
||||
struct itimerspec its = { {0,0}, {0,0} };
|
||||
struct sigevent se;
|
||||
int status;
|
||||
|
||||
if ((tp = balloc(B_L, sizeof(websTimer_t)))) {
|
||||
tp->routine = routine;
|
||||
tp->arg = arg;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
se.sigev_notify = SIGEV_THREAD;
|
||||
se.sigev_value.sival_ptr = tp;
|
||||
se.sigev_notify_function = (void (*)(union sigval)) timerProc;
|
||||
|
||||
/*
|
||||
* NOT POSIX?
|
||||
* se.sigev_notify_attributes = NULL;
|
||||
*/
|
||||
|
||||
|
||||
status = timer_create(CLOCK_REALTIME, &se, &timer_id);
|
||||
if (status != 0) {
|
||||
bfree(B_L, tp);
|
||||
return NULL;
|
||||
}
|
||||
/* convert delay millisecs to secs and usecs required by struct */
|
||||
its.it_value.tv_sec = delay / 1000;
|
||||
its.it_value.tv_nsec = (delay % 1000) * 1000000;
|
||||
|
||||
status = timer_settime(timer_id, 0, &its, 0);
|
||||
if (status != 0) {
|
||||
bfree(B_L, tp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
act.sa_flags = 0;
|
||||
sigemptyset(&act.sa_mask);
|
||||
act.sa_handler = timerProc;
|
||||
sigaction(SIGALRM, &act, NULL);
|
||||
|
||||
/* convert delay millisecs to secs and usecs required by struct */
|
||||
its.it_value.tv_sec = delay / 1000;
|
||||
its.it_value.tv_usec = (delay % 1000) * 1000;
|
||||
|
||||
if (setitimer(ITIMER_REAL, &its, NULL) == -1) {
|
||||
bfree(B_L, tp);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
return tp;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Delete a timer
|
||||
*/
|
||||
|
||||
void emfDeleteTimer(void * id)
|
||||
{
|
||||
websTimer_t *wtp;
|
||||
/*struct itimerval its = { {0,0}, {0,0} };*/
|
||||
|
||||
wtp = (websTimer_t *)id;
|
||||
/* setitimer(ITIMER_REAL, &its, NULL);*/
|
||||
timer_delete(timer_id);
|
||||
bfree(B_L, wtp);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Timer handler
|
||||
*/
|
||||
|
||||
static void timerProc(int signo)
|
||||
{
|
||||
websTimer_t wtp = *tp;
|
||||
|
||||
/* Copy the timer structure to a local first and delete it before calling
|
||||
* the function, since the function could create another timer. In this
|
||||
* implementation, only one timer can be allocated at a time.
|
||||
*/
|
||||
|
||||
bfree(B_L, tp);
|
||||
(wtp.routine)(wtp.arg);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Home page handler
|
||||
*/
|
||||
|
||||
static int websHomePageHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
|
||||
int arg, char_t* url, char_t* path, char_t* query)
|
||||
{
|
||||
/*
|
||||
* If the empty or "/" URL is invoked, redirect default URLs to the home page
|
||||
*/
|
||||
if (*url == '\0' || gstrcmp(url, T("/")) == 0) {
|
||||
#if 0
|
||||
websRedirect(wp, T("home.asp"));
|
||||
#else
|
||||
websRedirect(wp, T("index.html"));
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#if B_STATS
|
||||
static void memLeaks()
|
||||
{
|
||||
int fd=1;
|
||||
|
||||
/* if ((fd = gopen(T("leak.txt"), O_CREAT | O_TRUNC | O_WRONLY)) >= 0) { */
|
||||
bstats(fd, printMemStats);
|
||||
/*
|
||||
close(fd);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Print memory usage / leaks
|
||||
*/
|
||||
|
||||
static void printMemStats(int handle, char_t *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char_t buf[256];
|
||||
|
||||
va_start(args, fmt);
|
||||
vsprintf(buf, fmt, args);
|
||||
va_end(args);
|
||||
write(handle, buf, strlen(buf));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* Default error handler. The developer should insert code to handle
|
||||
* error messages in the desired manner.
|
||||
*/
|
||||
|
||||
void defaultErrorHandler(int etype, char_t *msg)
|
||||
{
|
||||
#if 1
|
||||
write(1, msg, gstrlen(msg));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* Trace log. Customize this function to log trace output
|
||||
*/
|
||||
|
||||
void defaultTraceHandler(int level, char_t *buf)
|
||||
{
|
||||
/*
|
||||
* The following code would write all trace regardless of level
|
||||
* to stdout.
|
||||
*/
|
||||
#if 1
|
||||
if (buf) {
|
||||
write(1, buf, gstrlen(buf));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* Returns a pointer to an allocated qualified unique temporary file name.
|
||||
* This filename must eventually be deleted with bfree();
|
||||
*/
|
||||
|
||||
char_t *websGetCgiCommName()
|
||||
{
|
||||
char_t *pname1, *pname2;
|
||||
|
||||
pname1 = tempnam(NULL, T("cgi"));
|
||||
pname2 = bstrdup(B_L, pname1);
|
||||
free(pname1);
|
||||
return pname2;
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
* Page.c -- Support for 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 page retrieval handling. It provides support for
|
||||
* reading web pages from file systems and has expansion for ROMed web
|
||||
* pages.
|
||||
*/
|
||||
|
||||
/********************************* Includes ***********************************/
|
||||
|
||||
#include "wsIntrn.h"
|
||||
|
||||
/*********************************** Code *************************************/
|
||||
/*
|
||||
* Open a web page. lpath is the local filename. path is the URL path name.
|
||||
*/
|
||||
|
||||
int websPageOpen(webs_t wp, char_t *lpath, char_t *path, int mode, int perm)
|
||||
{
|
||||
a_assert(websValid(wp));
|
||||
|
||||
#ifdef WEBS_PAGE_ROM
|
||||
return websRomPageOpen(wp, path, mode, perm);
|
||||
#else
|
||||
return (wp->docfd = gopen(lpath, mode, perm));
|
||||
#endif /* WEBS_PAGE_ROM */
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Close a web page
|
||||
*/
|
||||
|
||||
void websPageClose(webs_t wp)
|
||||
{
|
||||
a_assert(websValid(wp));
|
||||
|
||||
#ifdef WEBS_PAGE_ROM
|
||||
websRomPageClose(wp->docfd);
|
||||
#else
|
||||
if (wp->docfd >= 0) {
|
||||
close(wp->docfd);
|
||||
wp->docfd = -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Stat a web page lpath is the local filename. path is the URL path name.
|
||||
*/
|
||||
|
||||
int websPageStat(webs_t wp, char_t *lpath, char_t *path, websStatType* sbuf)
|
||||
{
|
||||
#ifdef WEBS_PAGE_ROM
|
||||
return websRomPageStat(path, sbuf);
|
||||
#else
|
||||
gstat_t s;
|
||||
|
||||
if (gstat(lpath, &s) < 0) {
|
||||
return -1;
|
||||
}
|
||||
sbuf->size = s.st_size;
|
||||
sbuf->mtime = s.st_mtime;
|
||||
sbuf->isDir = s.st_mode & S_IFDIR;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Is this file a directory?
|
||||
*/
|
||||
|
||||
int websPageIsDirectory(char_t *lpath)
|
||||
{
|
||||
#ifdef WEBS_PAGE_ROM
|
||||
websStatType sbuf;
|
||||
|
||||
if (websRomPageStat(lpath, &sbuf) >= 0) {
|
||||
return(sbuf.isDir);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
gstat_t sbuf;
|
||||
|
||||
if (gstat(lpath, &sbuf) >= 0) {
|
||||
return(sbuf.st_mode & S_IFDIR);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Read a web page. Returns the number of _bytes_ read.
|
||||
* len is the size of buf, in bytes.
|
||||
*/
|
||||
|
||||
int websPageReadData(webs_t wp, char *buf, int nBytes)
|
||||
{
|
||||
|
||||
#ifdef WEBS_PAGE_ROM
|
||||
a_assert(websValid(wp));
|
||||
return websRomPageReadData(wp, buf, nBytes);
|
||||
#else
|
||||
a_assert(websValid(wp));
|
||||
return read(wp->docfd, buf, nBytes);
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Move file pointer offset bytes.
|
||||
*/
|
||||
|
||||
void websPageSeek(webs_t wp, long offset)
|
||||
{
|
||||
a_assert(websValid(wp));
|
||||
|
||||
#ifdef WEBS_PAGE_ROM
|
||||
websRomPageSeek(wp, offset, SEEK_CUR);
|
||||
#else
|
||||
lseek(wp->docfd, offset, SEEK_CUR);
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
* webrom.c -- Compiled Web Pages
|
||||
*
|
||||
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
|
||||
*
|
||||
* See the file "license.txt" for usage and redistribution license requirements
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "wsIntrn.h"
|
||||
|
||||
websRomPageIndexType websRomPageIndex[] = {
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,233 +0,0 @@
|
||||
/*
|
||||
* webs.h -- GoAhead Web 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_WEBS
|
||||
#define _h_WEBS 1
|
||||
|
||||
/******************************** Description *********************************/
|
||||
|
||||
/*
|
||||
* GoAhead Web Server header. This defines the Web public APIs.
|
||||
* Include this header for files that contain ASP or Form procedures.
|
||||
* Include wsIntrn.h when creating URL handlers.
|
||||
*/
|
||||
|
||||
/********************************* Includes ***********************************/
|
||||
|
||||
#include "ej.h"
|
||||
#ifdef WEBS_SSL_SUPPORT
|
||||
#include "websSSL.h"
|
||||
#endif
|
||||
|
||||
/********************************** Defines ***********************************/
|
||||
/*
|
||||
* By license terms the server software name defined in the following line of
|
||||
* code must not be modified.
|
||||
*/
|
||||
#define WEBS_NAME T("GoAhead-Webs")
|
||||
#define WEBS_VERSION T("2.1.3")
|
||||
|
||||
#define WEBS_HEADER_BUFINC 512 /* Header buffer size */
|
||||
#define WEBS_ASP_BUFINC 512 /* Asp expansion increment */
|
||||
#define WEBS_MAX_PASS 32 /* Size of password */
|
||||
#define WEBS_BUFSIZE 1000 /* websWrite max output string */
|
||||
#define WEBS_MAX_HEADER (5 * 1024) /* Sanity check header */
|
||||
#define WEBS_MAX_URL 4096 /* Maximum URL size for sanity */
|
||||
#define WEBS_SOCKET_BUFSIZ 256 /* Bytes read from socket */
|
||||
|
||||
#define WEBS_HTTP_PORT T("httpPort")
|
||||
#define CGI_BIN T("cgi-bin")
|
||||
|
||||
/*
|
||||
* Request flags. Also returned by websGetRequestFlags().
|
||||
*/
|
||||
#define WEBS_LOCAL_PAGE 0x1 /* Request for local webs page */
|
||||
#define WEBS_KEEP_ALIVE 0x2 /* HTTP/1.1 keep alive */
|
||||
#define WEBS_DONT_USE_CACHE 0x4 /* Not implemented cache support */
|
||||
#define WEBS_COOKIE 0x8 /* Cookie supplied in request */
|
||||
#define WEBS_IF_MODIFIED 0x10 /* If-modified-since in request */
|
||||
#define WEBS_POST_REQUEST 0x20 /* Post request operation */
|
||||
#define WEBS_LOCAL_REQUEST 0x40 /* Request from this system */
|
||||
#define WEBS_HOME_PAGE 0x80 /* Request for the home page */
|
||||
#define WEBS_ASP 0x100 /* ASP request */
|
||||
#define WEBS_HEAD_REQUEST 0x200 /* Head request */
|
||||
#define WEBS_CLEN 0x400 /* Request had a content length */
|
||||
#define WEBS_FORM 0x800 /* Request is a form */
|
||||
#define WEBS_REQUEST_DONE 0x1000 /* Request complete */
|
||||
#define WEBS_POST_DATA 0x2000 /* Already appended post data */
|
||||
#define WEBS_CGI_REQUEST 0x4000 /* cgi-bin request */
|
||||
#define WEBS_SECURE 0x8000 /* connection uses SSL */
|
||||
#define WEBS_AUTH_BASIC 0x10000 /* Basic authentication request */
|
||||
#define WEBS_AUTH_DIGEST 0x20000 /* Digest authentication request */
|
||||
#define WEBS_HEADER_DONE 0x40000 /* Already output the HTTP header */
|
||||
|
||||
/*
|
||||
* URL handler flags
|
||||
*/
|
||||
#define WEBS_HANDLER_FIRST 0x1 /* Process this handler first */
|
||||
#define WEBS_HANDLER_LAST 0x2 /* Process this handler last */
|
||||
|
||||
/*
|
||||
* Per socket connection webs structure
|
||||
*/
|
||||
typedef struct websRec {
|
||||
ringq_t header; /* Header dynamic string */
|
||||
time_t since; /* Parsed if-modified-since time */
|
||||
sym_fd_t cgiVars; /* CGI standard variables */
|
||||
sym_fd_t cgiQuery; /* CGI decoded query string */
|
||||
time_t timestamp; /* Last transaction with browser */
|
||||
int timeout; /* Timeout handle */
|
||||
char_t ipaddr[32]; /* Connecting ipaddress */
|
||||
char_t type[64]; /* Mime type */
|
||||
char_t *dir; /* Directory containing the page */
|
||||
char_t *path; /* Path name without query */
|
||||
char_t *url; /* Full request url */
|
||||
char_t *host; /* Requested host */
|
||||
char_t *lpath; /* Cache local path name */
|
||||
char_t *query; /* Request query */
|
||||
char_t *decodedQuery; /* Decoded request query */
|
||||
char_t *authType; /* Authorization type (Basic/DAA) */
|
||||
char_t *password; /* Authorization password */
|
||||
char_t *userName; /* Authorization username */
|
||||
char_t *cookie; /* Cookie string */
|
||||
char_t *userAgent; /* User agent (browser) */
|
||||
char_t *protocol; /* Protocol (normally HTTP) */
|
||||
char_t *protoVersion; /* Protocol version */
|
||||
int sid; /* Socket id (handler) */
|
||||
int listenSid; /* Listen Socket id */
|
||||
int port; /* Request port number */
|
||||
int state; /* Current state */
|
||||
int flags; /* Current flags -- see above */
|
||||
int code; /* Request result code */
|
||||
int clen; /* Content length */
|
||||
int wid; /* Index into webs */
|
||||
char_t *cgiStdin; /* filename for CGI stdin */
|
||||
int docfd; /* Document file descriptor */
|
||||
int numbytes; /* Bytes to transfer to browser */
|
||||
int written; /* Bytes actually transferred */
|
||||
void (*writeSocket)(struct websRec *wp);
|
||||
#ifdef DIGEST_ACCESS_SUPPORT
|
||||
char_t *realm; /* usually the same as "host" from websRec */
|
||||
char_t *nonce; /* opaque-to-client string sent by server */
|
||||
char_t *digest; /* digest form of user password */
|
||||
char_t *uri; /* URI found in DAA header */
|
||||
char_t *opaque; /* opaque value passed from server */
|
||||
char_t *nc; /* nonce count */
|
||||
char_t *cnonce; /* check nonce */
|
||||
char_t *qop; /* quality operator */
|
||||
#endif
|
||||
#ifdef WEBS_SSL_SUPPORT
|
||||
websSSL_t *wsp; /* SSL data structure */
|
||||
#endif
|
||||
} websRec;
|
||||
|
||||
typedef websRec *webs_t;
|
||||
typedef websRec websType;
|
||||
|
||||
/******************************** Prototypes **********************************/
|
||||
extern int websAccept(int sid, char *ipaddr, int port, int listenSid);
|
||||
extern int websAspDefine(char_t *name,
|
||||
int (*fn)(int ejid, webs_t wp, int argc, char_t **argv));
|
||||
extern int websAspRequest(webs_t wp, char_t *lpath);
|
||||
extern void websCloseListen();
|
||||
extern int websDecode64(char_t *outbuf, char_t *string, int buflen);
|
||||
extern void websDecodeUrl(char_t *token, char_t *decoded, int len);
|
||||
extern void websDone(webs_t wp, int code);
|
||||
extern void websEncode64(char_t *outbuf, char_t *string, int buflen);
|
||||
extern void websError(webs_t wp, int code, char_t *msg, ...);
|
||||
/* function websErrorMsg() made extern 03 Jun 02 BgP */
|
||||
extern char_t *websErrorMsg(int code);
|
||||
extern void websFooter(webs_t wp);
|
||||
extern int websFormDefine(char_t *name, void (*fn)(webs_t wp,
|
||||
char_t *path, char_t *query));
|
||||
extern char_t *websGetDefaultDir();
|
||||
extern char_t *websGetDefaultPage();
|
||||
extern char_t *websGetHostUrl();
|
||||
extern char_t *websGetIpaddrUrl();
|
||||
extern char_t *websGetPassword();
|
||||
extern int websGetPort();
|
||||
extern char_t *websGetPublishDir(char_t *path, char_t **urlPrefix);
|
||||
extern char_t *websGetRealm();
|
||||
extern int websGetRequestBytes(webs_t wp);
|
||||
extern char_t *websGetRequestDir(webs_t wp);
|
||||
extern int websGetRequestFlags(webs_t wp);
|
||||
extern char_t *websGetRequestIpaddr(webs_t wp);
|
||||
extern char_t *websGetRequestLpath(webs_t wp);
|
||||
extern char_t *websGetRequestPath(webs_t wp);
|
||||
extern char_t *websGetRequestPassword(webs_t wp);
|
||||
extern char_t *websGetRequestType(webs_t wp);
|
||||
extern int websGetRequestWritten(webs_t wp);
|
||||
extern char_t *websGetVar(webs_t wp, char_t *var, char_t *def);
|
||||
extern int websCompareVar(webs_t wp, char_t *var, char_t *value);
|
||||
extern void websHeader(webs_t wp);
|
||||
extern int websOpenListen(int port, int retries);
|
||||
extern int websPageOpen(webs_t wp, char_t *lpath, char_t *path,
|
||||
int mode, int perm);
|
||||
extern void websPageClose(webs_t wp);
|
||||
extern int websPublish(char_t *urlPrefix, char_t *path);
|
||||
extern void websRedirect(webs_t wp, char_t *url);
|
||||
extern void websSecurityDelete();
|
||||
extern int websSecurityHandler(webs_t wp, char_t *urlPrefix,
|
||||
char_t *webDir, int arg, char_t *url, char_t *path,
|
||||
char_t *query);
|
||||
extern void websSetDefaultDir(char_t *dir);
|
||||
extern void websSetDefaultPage(char_t *page);
|
||||
extern void websSetEnv(webs_t wp);
|
||||
extern void websSetHost(char_t *host);
|
||||
extern void websSetIpaddr(char_t *ipaddr);
|
||||
extern void websSetPassword(char_t *password);
|
||||
extern void websSetRealm(char_t *realmName);
|
||||
extern void websSetRequestBytes(webs_t wp, int bytes);
|
||||
extern void websSetRequestFlags(webs_t wp, int flags);
|
||||
extern void websSetRequestLpath(webs_t wp, char_t *lpath);
|
||||
extern void websSetRequestPath(webs_t wp, char_t *dir, char_t *path);
|
||||
extern char_t *websGetRequestUserName(webs_t wp);
|
||||
extern void websSetRequestWritten(webs_t wp, int written);
|
||||
extern void websSetVar(webs_t wp, char_t *var, char_t *value);
|
||||
extern int websTestVar(webs_t wp, char_t *var);
|
||||
extern void websTimeoutCancel(webs_t wp);
|
||||
extern int websUrlHandlerDefine(char_t *urlPrefix, char_t *webDir,
|
||||
int arg, int (*fn)(webs_t wp, char_t *urlPrefix,
|
||||
char_t *webDir, int arg, char_t *url, char_t *path,
|
||||
char_t *query), int flags);
|
||||
extern int websUrlHandlerDelete(int (*fn)(webs_t wp, char_t *urlPrefix,
|
||||
char_t *webDir, int arg, char_t *url, char_t *path,
|
||||
char_t *query));
|
||||
extern int websUrlHandlerRequest(webs_t wp);
|
||||
extern int websUrlParse(char_t *url, char_t **buf, char_t **host,
|
||||
char_t **path, char_t **port, char_t **query,
|
||||
char_t **proto, char_t **tag, char_t **ext);
|
||||
extern char_t *websUrlType(char_t *webs, char_t *buf, int charCnt);
|
||||
extern int websWrite(webs_t wp, char_t* fmt, ...);
|
||||
extern int websWriteBlock(webs_t wp, char_t *buf, int nChars);
|
||||
extern int websWriteDataNonBlock(webs_t wp, char *buf, int nChars);
|
||||
extern int websValid(webs_t wp);
|
||||
extern int websValidateUrl(webs_t wp, char_t *path);
|
||||
extern void websSetTimeMark(webs_t wp);
|
||||
|
||||
/*
|
||||
* The following prototypes are used by the SSL patch found in websSSL.c
|
||||
*/
|
||||
extern int websAlloc(int sid);
|
||||
extern void websFree(webs_t wp);
|
||||
extern void websTimeout(void *arg, int id);
|
||||
extern void websReadEvent(webs_t wp);
|
||||
|
||||
/*
|
||||
* Prototypes for functions available when running as part of the
|
||||
* GoAhead Embedded Management Framework (EMF)
|
||||
*/
|
||||
#ifdef EMF
|
||||
extern void websFormExplain(webs_t wp, char_t *path, char_t *query);
|
||||
#endif
|
||||
|
||||
#endif /* _h_WEBS */
|
||||
|
||||
/******************************************************************************/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* websSSL.h -- SSL Patch 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_websSSL
|
||||
#define _h_websSSL 1
|
||||
|
||||
/******************************** Description *********************************/
|
||||
|
||||
/*
|
||||
* Header file for the GoAhead Patch for SSL. This defines the interface to
|
||||
* integrate SSL into the GoAhead Webserver.
|
||||
*/
|
||||
|
||||
/********************************* Includes ***********************************/
|
||||
|
||||
|
||||
#ifdef OPENSSL
|
||||
#define SSLEAY /* turn off a few special case MONOLITH macros */
|
||||
#define USE_SOCKETS /* needed for the _O_BINARY defs in the MS world */
|
||||
#include <openssl/ssl.h>
|
||||
#else
|
||||
#include <sslc.h>
|
||||
#endif
|
||||
|
||||
#ifndef UEMF
|
||||
#include "basic/basic.h"
|
||||
#include "emf/emf.h"
|
||||
#else
|
||||
#include "uemf.h"
|
||||
#endif
|
||||
|
||||
/********************************** Defines ***********************************/
|
||||
|
||||
typedef struct {
|
||||
SSL *ssl;
|
||||
BIO *bio;
|
||||
} websSSL_t;
|
||||
|
||||
|
||||
/******************************** Prototypes **********************************/
|
||||
|
||||
extern int websSSLOpen();
|
||||
extern int websSSLIsOpen();
|
||||
extern void websSSLClose();
|
||||
|
||||
extern int websSSLWrite(websSSL_t *wsp, char_t *buf, int nChars);
|
||||
extern int websSSLGets(websSSL_t *wsp, char_t **buf);
|
||||
extern int websSSLRead(websSSL_t *wsp, char_t *buf, int nChars);
|
||||
extern int websSSLEof(websSSL_t *wsp);
|
||||
|
||||
extern int websSSLFree(websSSL_t *wsp);
|
||||
extern int websSSLFlush(websSSL_t *wsp);
|
||||
|
||||
extern int websSSLSetKeyFile(char_t *keyFile);
|
||||
extern int websSSLSetCertFile(char_t *certFile);
|
||||
|
||||
|
||||
#endif /* _h_websSSL */
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -1,244 +0,0 @@
|
||||
/*
|
||||
* websda.c -- Digest Access Authentication routines
|
||||
*
|
||||
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
|
||||
*
|
||||
* See the file "license.txt" for usage and redistribution license requirements
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/******************************** Description *********************************/
|
||||
|
||||
/*
|
||||
* Routines for generating DAA data. The module uses the
|
||||
* "RSA Data Security, Inc. MD5 Message-Digest Algorithm" found in md5c.c
|
||||
*/
|
||||
|
||||
/********************************* Includes ***********************************/
|
||||
|
||||
#ifndef CE
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include "websda.h"
|
||||
#include "md5.h"
|
||||
|
||||
/******************************** Local Data **********************************/
|
||||
|
||||
#define RANDOMKEY T("onceuponatimeinparadise")
|
||||
#define NONCE_SIZE 34
|
||||
#define HASH_SIZE 16
|
||||
|
||||
/*********************************** Code *************************************/
|
||||
/*
|
||||
* websMD5binary returns the MD5 hash
|
||||
*/
|
||||
|
||||
char *websMD5binary(unsigned char *buf, int length)
|
||||
{
|
||||
const char *hex = "0123456789abcdef";
|
||||
MD5_CONTEXT md5ctx;
|
||||
unsigned char hash[HASH_SIZE];
|
||||
char *r, *strReturn;
|
||||
char result[(HASH_SIZE * 2) + 1];
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Take the MD5 hash of the string argument.
|
||||
*/
|
||||
MD5Init(&md5ctx);
|
||||
MD5Update(&md5ctx, buf, (unsigned int)length);
|
||||
MD5Final(hash, &md5ctx);
|
||||
|
||||
/*
|
||||
* Prepare the resulting hash string
|
||||
*/
|
||||
for (i = 0, r = result; i < 16; i++) {
|
||||
*r++ = hex[hash[i] >> 4];
|
||||
*r++ = hex[hash[i] & 0xF];
|
||||
}
|
||||
|
||||
/*
|
||||
* Zero terminate the hash string
|
||||
*/
|
||||
*r = '\0';
|
||||
|
||||
/*
|
||||
* Allocate a new copy of the hash string
|
||||
*/
|
||||
strReturn = balloc(B_L, sizeof(result));
|
||||
strcpy(strReturn, result);
|
||||
|
||||
return strReturn;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* Convenience call to websMD5binary
|
||||
* (Performs char_t to char conversion and back)
|
||||
*/
|
||||
|
||||
char_t *websMD5(char_t *string)
|
||||
{
|
||||
char_t *strReturn;
|
||||
|
||||
a_assert(string && *string);
|
||||
|
||||
if (string && *string) {
|
||||
char *strTemp, *strHash;
|
||||
int nLen;
|
||||
/*
|
||||
* Convert input char_t string to char string
|
||||
*/
|
||||
nLen = gstrlen(string);
|
||||
strTemp = ballocUniToAsc(string, nLen + 1);
|
||||
/*
|
||||
* Execute the digest calculation
|
||||
*/
|
||||
strHash = websMD5binary((unsigned char *)strTemp, nLen);
|
||||
/*
|
||||
* Convert the returned char string digest to a char_t string
|
||||
*/
|
||||
nLen = strlen(strHash);
|
||||
strReturn = ballocAscToUni(strHash, nLen);
|
||||
/*
|
||||
* Free up the temporary allocated resources
|
||||
*/
|
||||
bfree(B_L, strTemp);
|
||||
bfree(B_L, strHash);
|
||||
} else {
|
||||
strReturn = NULL;
|
||||
}
|
||||
|
||||
return strReturn;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Get a Nonce value for passing along to the client. This function
|
||||
* composes the string "RANDOMKEY:timestamp:myrealm" and
|
||||
* calculates the MD5 digest placing it in output.
|
||||
*/
|
||||
|
||||
char_t *websCalcNonce(webs_t wp)
|
||||
{
|
||||
char_t *nonce, *prenonce;
|
||||
struct tm *newtime;
|
||||
time_t longTime;
|
||||
|
||||
a_assert(wp);
|
||||
/*
|
||||
* Get time as long integer.
|
||||
*/
|
||||
time(&longTime);
|
||||
/*
|
||||
* Convert to local time.
|
||||
*/
|
||||
newtime = localtime(&longTime);
|
||||
/*
|
||||
* Create prenonce string.
|
||||
*/
|
||||
prenonce = NULL;
|
||||
#ifdef DIGEST_ACCESS_SUPPORT
|
||||
fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, gasctime(newtime),
|
||||
wp->realm);
|
||||
#else
|
||||
fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, gasctime(newtime),
|
||||
RANDOMKEY);
|
||||
#endif
|
||||
a_assert(prenonce);
|
||||
/*
|
||||
* Create the nonce
|
||||
*/
|
||||
nonce = websMD5(prenonce);
|
||||
/*
|
||||
* Cleanup
|
||||
*/
|
||||
bfreeSafe(B_L, prenonce);
|
||||
|
||||
return nonce;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Get an Opaque value for passing along to the client
|
||||
*/
|
||||
|
||||
char_t *websCalcOpaque(webs_t wp)
|
||||
{
|
||||
char_t *opaque;
|
||||
a_assert(wp);
|
||||
/*
|
||||
* Temporary stub!
|
||||
*/
|
||||
opaque = bstrdup(B_L, T("5ccc069c403ebaf9f0171e9517f40e41"));
|
||||
|
||||
return opaque;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Get a Digest value using the MD5 algorithm
|
||||
*/
|
||||
|
||||
char_t *websCalcDigest(webs_t wp)
|
||||
{
|
||||
#ifdef DIGEST_ACCESS_SUPPORT
|
||||
char_t *digest, *a1, *a1prime, *a2, *a2prime, *preDigest, *method;
|
||||
|
||||
a_assert(wp);
|
||||
digest = NULL;
|
||||
|
||||
/*
|
||||
* Calculate first portion of digest H(A1)
|
||||
*/
|
||||
a1 = NULL;
|
||||
fmtAlloc(&a1, 255, T("%s:%s:%s"), wp->userName, wp->realm, wp->password);
|
||||
a_assert(a1);
|
||||
a1prime = websMD5(a1);
|
||||
bfreeSafe(B_L, a1);
|
||||
/*
|
||||
* Calculate second portion of digest H(A2)
|
||||
*/
|
||||
method = websGetVar(wp, T("REQUEST_METHOD"), NULL);
|
||||
a_assert(method);
|
||||
a2 = NULL;
|
||||
fmtAlloc(&a2, 255, T("%s:%s"), method, wp->uri);
|
||||
a_assert(a2);
|
||||
a2prime = websMD5(a2);
|
||||
bfreeSafe(B_L, a2);
|
||||
/*
|
||||
* Construct final digest KD(H(A1):nonce:H(A2))
|
||||
*/
|
||||
a_assert(a1prime);
|
||||
a_assert(a2prime);
|
||||
a_assert(wp->nonce);
|
||||
|
||||
preDigest = NULL;
|
||||
if (!wp->qop) {
|
||||
fmtAlloc(&preDigest, 255, T("%s:%s:%s"), a1prime, wp->nonce, a2prime);
|
||||
} else {
|
||||
fmtAlloc(&preDigest, 255, T("%s:%s:%s:%s:%s:%s"),
|
||||
a1prime,
|
||||
wp->nonce,
|
||||
wp->nc,
|
||||
wp->cnonce,
|
||||
wp->qop,
|
||||
a2prime);
|
||||
}
|
||||
|
||||
a_assert(preDigest);
|
||||
digest = websMD5(preDigest);
|
||||
/*
|
||||
* Now clean up
|
||||
*/
|
||||
bfreeSafe(B_L, a1prime);
|
||||
bfreeSafe(B_L, a2prime);
|
||||
bfreeSafe(B_L, preDigest);
|
||||
return digest;
|
||||
#else
|
||||
return NULL;
|
||||
#endif /* DIGEST_ACCESS_SUPPORT */
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* websda.h -- GoAhead Digest Access Authentication 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_WEBSDA
|
||||
#define _h_WEBSDA 1
|
||||
|
||||
/******************************** Description *********************************/
|
||||
|
||||
/*
|
||||
* GoAhead Digest Access Authentication header. This defines the Digest
|
||||
* access authentication public APIs. Include this header for files that
|
||||
* use DAA functions
|
||||
*/
|
||||
|
||||
/********************************* Includes ***********************************/
|
||||
|
||||
#ifndef UEMF
|
||||
#include "basic/basic.h"
|
||||
#include "emf/emf.h"
|
||||
#else
|
||||
#include "uemf.h"
|
||||
#endif
|
||||
|
||||
#include "webs.h"
|
||||
|
||||
/****************************** Definitions ***********************************/
|
||||
|
||||
extern char_t *websCalcNonce(webs_t wp);
|
||||
extern char_t *websCalcOpaque(webs_t wp);
|
||||
extern char_t *websCalcDigest(webs_t wp);
|
||||
|
||||
#endif /* _h_WEBSDA */
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -1,217 +0,0 @@
|
||||
/*
|
||||
* websuemf.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 modules provides compatibility with the full GoAhead EMF.
|
||||
*/
|
||||
|
||||
/*********************************** Includes *********************************/
|
||||
|
||||
#include "ejIntrn.h"
|
||||
#include "wsIntrn.h"
|
||||
|
||||
/*********************************** Defines **********************************/
|
||||
|
||||
/*
|
||||
* This structure stores scheduled events.
|
||||
*/
|
||||
typedef struct {
|
||||
void (*routine)(void *arg, int id);
|
||||
void *arg;
|
||||
time_t at;
|
||||
int schedid;
|
||||
} sched_t;
|
||||
|
||||
/*********************************** Locals ***********************************/
|
||||
|
||||
static sched_t **sched;
|
||||
static int schedMax;
|
||||
|
||||
/************************************* Code ***********************************/
|
||||
/*
|
||||
* Evaluate a script
|
||||
*/
|
||||
|
||||
int scriptEval(int engine, char_t *cmd, char_t **result, int chan)
|
||||
{
|
||||
int ejid;
|
||||
|
||||
if (engine == EMF_SCRIPT_EJSCRIPT) {
|
||||
ejid = (int) chan;
|
||||
/*
|
||||
* NOTE -- to disable better reporting of ASP errors, change the
|
||||
* following line of code to
|
||||
* if (ejEval(ejid, cmd, NULL) ) {
|
||||
*/
|
||||
if (ejEval(ejid, cmd, result) ) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Compare strings, ignoring case: normal strcmp return codes.
|
||||
*
|
||||
* WARNING: It is not good form to increment or decrement pointers inside a
|
||||
* "call" to tolower et al. These can be MACROS, and have undesired side
|
||||
* effects.
|
||||
*/
|
||||
|
||||
int strcmpci(char_t *s1, char_t *s2)
|
||||
{
|
||||
int rc;
|
||||
|
||||
a_assert(s1 && s2);
|
||||
if (s1 == NULL || s2 == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (s1 == s2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
do {
|
||||
rc = gtolower(*s1) - gtolower(*s2);
|
||||
if (*s1 == '\0') {
|
||||
break;
|
||||
}
|
||||
s1++;
|
||||
s2++;
|
||||
} while (rc == 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* This function is called when a scheduled process time has come.
|
||||
*/
|
||||
|
||||
void TimerProc(int schedid)
|
||||
{
|
||||
sched_t *s;
|
||||
|
||||
a_assert(0 <= schedid && schedid < schedMax);
|
||||
s = sched[schedid];
|
||||
a_assert(s);
|
||||
|
||||
(s->routine)(s->arg, s->schedid);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Schedule an event in delay milliseconds time. We will use 1 second
|
||||
* granularity for webServer.
|
||||
*/
|
||||
|
||||
int emfSchedCallback(int delay, emfSchedProc *proc, void *arg)
|
||||
{
|
||||
sched_t *s;
|
||||
int schedid;
|
||||
|
||||
if ((schedid = hAllocEntry((void*) &sched, &schedMax,
|
||||
sizeof(sched_t))) < 0) {
|
||||
return -1;
|
||||
}
|
||||
s = sched[schedid];
|
||||
s->routine = proc;
|
||||
s->arg = arg;
|
||||
s->schedid = schedid;
|
||||
|
||||
/*
|
||||
* Round the delay up to seconds.
|
||||
*/
|
||||
s->at = ((delay + 500) / 1000) + time(0);
|
||||
|
||||
return schedid;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Reschedule to a new delay.
|
||||
*/
|
||||
|
||||
void emfReschedCallback(int schedid, int delay)
|
||||
{
|
||||
sched_t *s;
|
||||
|
||||
if (sched == NULL || schedid == -1 || schedid >= schedMax ||
|
||||
(s = sched[schedid]) == NULL) {
|
||||
return;
|
||||
}
|
||||
s->at = ((delay + 500) / 1000) + time(0);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void emfUnschedCallback(int schedid)
|
||||
{
|
||||
sched_t *s;
|
||||
|
||||
if (sched == NULL || schedid == -1 || schedid >= schedMax ||
|
||||
(s = sched[schedid]) == NULL) {
|
||||
return;
|
||||
}
|
||||
bfree(B_L, s);
|
||||
schedMax = hFree((void*) &sched, schedid);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Take the tasks off the queue in a round robin fashion.
|
||||
*/
|
||||
|
||||
void emfSchedProcess()
|
||||
{
|
||||
sched_t *s;
|
||||
int schedid;
|
||||
static int next = 0;
|
||||
|
||||
/*
|
||||
* If schedMax is 0, there are no tasks scheduled, so just return.
|
||||
*/
|
||||
if (schedMax <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If next >= schedMax, the schedule queue was reduced in our absence
|
||||
* so reset next to 0 to start from the begining of the queue again.
|
||||
*/
|
||||
if (next >= schedMax) {
|
||||
next = 0;
|
||||
}
|
||||
|
||||
schedid = next;
|
||||
for (;;) {
|
||||
if ((s = sched[schedid]) != NULL && (int)s->at <= (int)time(0)) {
|
||||
TimerProc(schedid);
|
||||
next = schedid + 1;
|
||||
return;
|
||||
}
|
||||
if (++schedid >= schedMax) {
|
||||
schedid = 0;
|
||||
}
|
||||
if (schedid == next) {
|
||||
/*
|
||||
* We've gone all the way through the queue without finding
|
||||
* anything to do so just return.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -1,309 +0,0 @@
|
||||
/*
|
||||
* wsIntrn.h -- Internal GoAhead Web server 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_WEBS_INTERNAL
|
||||
#define _h_WEBS_INTERNAL 1
|
||||
|
||||
/******************************** Description *********************************/
|
||||
|
||||
/*
|
||||
* Internal GoAhead Web Server header. This defines the Web private APIs
|
||||
* Include this header when you want to create URL handlers.
|
||||
*/
|
||||
|
||||
/*********************************** Defines **********************************/
|
||||
|
||||
/*
|
||||
* Define this to enable logging of web accesses to a file
|
||||
* #define WEBS_LOG_SUPPORT 1
|
||||
*
|
||||
* Define this to enable HTTP/1.1 keep alive support
|
||||
* #define WEBS_KEEP_ALIVE_SUPPORT 1
|
||||
*
|
||||
* Define this to enable if-modified-since support
|
||||
* #define WEBS_IF_MODIFIED_SUPPORT 1
|
||||
*
|
||||
* Define this to support proxy capability and track local vs remote request
|
||||
* Note: this is not yet fully implemented.
|
||||
* #define WEBS_PROXY_SUPPORT 1
|
||||
*
|
||||
* Define this to support reading pages from ROM
|
||||
* #define WEBS_PAGE_ROM 1
|
||||
*
|
||||
* Define this to enable memory allocation and stack usage tracking
|
||||
* #define B_STATS 1
|
||||
*/
|
||||
|
||||
/********************************** Includes **********************************/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef NETWARE
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#ifdef CE
|
||||
#ifndef UEMF
|
||||
#include <io.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef NW
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#ifdef SCOV5
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef LYNX
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef UNIX
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef QNX4
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <unix.h>
|
||||
#endif
|
||||
|
||||
#ifdef UW
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#ifdef VXWORKS
|
||||
#include <vxWorks.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#ifdef SOLARIS
|
||||
#include <macros.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#ifdef UEMF
|
||||
#include "uemf.h"
|
||||
#include "ejIntrn.h"
|
||||
#else
|
||||
#include "emf/emfInternal.h"
|
||||
#include "ej/ejIntrn.h"
|
||||
#endif
|
||||
|
||||
#include "webs.h"
|
||||
|
||||
/********************************** Defines ***********************************/
|
||||
/*
|
||||
* Read handler flags and state
|
||||
*/
|
||||
#define WEBS_BEGIN 0x1 /* Beginning state */
|
||||
#define WEBS_HEADER 0x2 /* Ready to read first line */
|
||||
#define WEBS_POST 0x4 /* POST without content */
|
||||
#define WEBS_POST_CLEN 0x8 /* Ready to read content for POST */
|
||||
#define WEBS_PROCESSING 0x10 /* Processing request */
|
||||
#define WEBS_KEEP_TIMEOUT 15000 /* Keep-alive timeout (15 secs) */
|
||||
#define WEBS_TIMEOUT 60000 /* General request timeout (60) */
|
||||
|
||||
#define PAGE_READ_BUFSIZE 512 /* bytes read from page files */
|
||||
#define MAX_PORT_LEN 10 /* max digits in port number */
|
||||
#define WEBS_SYM_INIT 64 /* initial # of sym table entries */
|
||||
|
||||
/*
|
||||
* URL handler structure. Stores the leading URL path and the handler
|
||||
* function to call when the URL path is seen.
|
||||
*/
|
||||
typedef struct {
|
||||
int (*handler)(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
|
||||
char_t *url, char_t *path,
|
||||
char_t *query); /* Callback URL handler function */
|
||||
char_t *webDir; /* Web directory if required */
|
||||
char_t *urlPrefix; /* URL leading prefix */
|
||||
int len; /* Length of urlPrefix for speed */
|
||||
int arg; /* Argument to provide to handler */
|
||||
int flags; /* Flags */
|
||||
} websUrlHandlerType;
|
||||
|
||||
/*
|
||||
* Webs statistics
|
||||
*/
|
||||
typedef struct {
|
||||
long errors; /* General errors */
|
||||
long redirects;
|
||||
long net_requests;
|
||||
long activeNetRequests;
|
||||
long activeBrowserRequests;
|
||||
long timeouts;
|
||||
long access; /* Access violations */
|
||||
long localHits;
|
||||
long remoteHits;
|
||||
long formHits;
|
||||
long cgiHits;
|
||||
long handlerHits;
|
||||
} websStatsType;
|
||||
|
||||
extern websStatsType websStats; /* Web access stats */
|
||||
|
||||
/*
|
||||
* Error code list
|
||||
*/
|
||||
typedef struct {
|
||||
int code; /* HTTP error code */
|
||||
char_t *msg; /* HTTP error message */
|
||||
} websErrorType;
|
||||
|
||||
/*
|
||||
* Mime type list
|
||||
*/
|
||||
typedef struct {
|
||||
char_t *type; /* Mime type */
|
||||
char_t *ext; /* File extension */
|
||||
} websMimeType;
|
||||
|
||||
/*
|
||||
* File information structure.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned long size; /* File length */
|
||||
int isDir; /* Set if directory */
|
||||
time_t mtime; /* Modified time */
|
||||
} websStatType;
|
||||
|
||||
/*
|
||||
* Compiled Rom Page Index
|
||||
*/
|
||||
typedef struct {
|
||||
char_t *path; /* Web page URL path */
|
||||
unsigned char *page; /* Web page data */
|
||||
int size; /* Size of web page in bytes */
|
||||
int pos; /* Current read position */
|
||||
} websRomPageIndexType;
|
||||
|
||||
/*
|
||||
* Defines for file open.
|
||||
*/
|
||||
#ifndef CE
|
||||
#define SOCKET_RDONLY O_RDONLY
|
||||
#define SOCKET_BINARY O_BINARY
|
||||
#else /* CE */
|
||||
#define SOCKET_RDONLY 0x1
|
||||
#define SOCKET_BINARY 0x2
|
||||
#endif /* CE */
|
||||
|
||||
extern websRomPageIndexType websRomPageIndex[];
|
||||
extern websMimeType websMimeList[]; /* List of mime types */
|
||||
extern sym_fd_t websMime; /* Set of mime types */
|
||||
extern webs_t* webs; /* Session list head */
|
||||
extern int websMax; /* List size */
|
||||
extern char_t websHost[64]; /* Name of this host */
|
||||
extern char_t websIpaddr[64]; /* IP address of this host */
|
||||
extern char_t *websHostUrl; /* URL for this host */
|
||||
extern char_t *websIpaddrUrl; /* URL for this host */
|
||||
extern int websPort; /* Port number */
|
||||
|
||||
/******************************** Prototypes **********************************/
|
||||
|
||||
extern int websAspOpen();
|
||||
extern void websAspClose();
|
||||
extern void websFormOpen();
|
||||
extern void websFormClose();
|
||||
extern int websAspWrite(int ejid, webs_t wp, int argc, char_t **argv);
|
||||
extern void websDefaultClose();
|
||||
extern int websDefaultHandler(webs_t wp, char_t *urlPrefix,
|
||||
char_t *webDir, int arg, char_t *url, char_t *path,
|
||||
char_t *query);
|
||||
extern int websFormHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
|
||||
int arg, char_t *url, char_t *path, char_t *query);
|
||||
extern int websCgiHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
|
||||
int arg, char_t *url, char_t *path, char_t *query);
|
||||
extern void websCgiCleanup();
|
||||
extern int websCheckCgiProc(int handle);
|
||||
extern char_t *websGetCgiCommName();
|
||||
|
||||
extern int websLaunchCgiProc(char_t *cgiPath, char_t **argp,
|
||||
char_t **envp, char_t *stdIn, char_t *stdOut);
|
||||
extern int websOpen(int sid);
|
||||
extern void websResponse(webs_t wp, int code, char_t *msg,
|
||||
char_t *redirect);
|
||||
extern int websJavaScriptEval(webs_t wp, char_t *script);
|
||||
extern int websPageReadData(webs_t wp, char *buf, int nBytes);
|
||||
extern int websPageOpen(webs_t wp, char_t *lpath, char_t *path, int mode,
|
||||
int perm);
|
||||
extern void websPageClose(webs_t wp);
|
||||
extern void websPageSeek(webs_t wp, long offset);
|
||||
extern int websPageStat(webs_t wp, char_t *lpath, char_t *path,
|
||||
websStatType *sbuf);
|
||||
extern int websPageIsDirectory(char_t *lpath);
|
||||
extern int websRomOpen();
|
||||
extern void websRomClose();
|
||||
extern int websRomPageOpen(webs_t wp, char_t *path, int mode, int perm);
|
||||
extern void websRomPageClose(int fd);
|
||||
extern int websRomPageReadData(webs_t wp, char *buf, int len);
|
||||
extern int websRomPageStat(char_t *path, websStatType *sbuf);
|
||||
extern long websRomPageSeek(webs_t wp, long offset, int origin);
|
||||
extern void websSetRequestSocketHandler(webs_t wp, int mask,
|
||||
void (*fn)(webs_t wp));
|
||||
extern int websSolutionHandler(webs_t wp, char_t *urlPrefix,
|
||||
char_t *webDir, int arg, char_t *url, char_t *path,
|
||||
char_t *query);
|
||||
extern void websUrlHandlerClose();
|
||||
extern int websUrlHandlerOpen();
|
||||
extern int websOpenServer(int port, int retries);
|
||||
extern void websCloseServer();
|
||||
extern char_t* websGetDateString(websStatType* sbuf);
|
||||
|
||||
extern int strcmpci(char_t* s1, char_t* s2);
|
||||
|
||||
/*
|
||||
* Prototypes for functions available when running as part of the
|
||||
* GoAhead Embedded Management Framework (EMF)
|
||||
*/
|
||||
#ifdef EMF
|
||||
extern int websEmfOpen();
|
||||
extern void websEmfClose();
|
||||
extern void websSetEmfEnvironment(webs_t wp);
|
||||
#endif
|
||||
|
||||
#ifdef CE
|
||||
extern int writeUniToAsc(int fid, void *buf, unsigned int len);
|
||||
extern int readAscToUni(int fid, void **buf, unsigned int len);
|
||||
#endif
|
||||
|
||||
#endif /* _h_WEBS_INTERNAL */
|
||||
|
||||
/******************************************************************************/
|
||||
Reference in New Issue
Block a user