Remove (Moved to cpukit/http).

This commit is contained in:
Ralf Corsepius
2004-10-27 06:08:56 +00:00
parent cc870803f9
commit f1959d65e2
49 changed files with 0 additions and 23576 deletions
@@ -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
-36
View File
@@ -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
-321
View File
@@ -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
-331
View File
@@ -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);
}
/******************************************************************************/
-46
View File
@@ -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
-101
View File
@@ -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 */
/******************************************************************************/
-168
View File
@@ -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"));
}
/******************************************************************************/
-194
View File
@@ -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 GoAheads 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 GoAheads 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 GoAheads 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
-50
View File
@@ -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 */
-337
View File
@@ -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;
}
-116
View File
@@ -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
-193
View File
@@ -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
-474
View File
@@ -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;
}
/******************************************************************************/
-293
View File
@@ -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
-183
View File
@@ -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
-212
View File
@@ -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
-233
View File
@@ -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 */
/******************************************************************************/