diff options
Diffstat (limited to 'cpukit/httpd/asp.c')
-rw-r--r-- | cpukit/httpd/asp.c | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/cpukit/httpd/asp.c b/cpukit/httpd/asp.c new file mode 100644 index 0000000000..4611a8f422 --- /dev/null +++ b/cpukit/httpd/asp.c @@ -0,0 +1,313 @@ +/* + * asp.c -- Active Server Page Support + * + * Copyright (c) Go Ahead Software Inc., 1995-1999. All Rights Reserved. + * + * See the file "license.txt" for usage and redistribution license requirements + */ + +/******************************** 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 */ + +/***************************** 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() +{ +/* + * Create the table for ASP functions + */ + websAspFunctions = symOpen(128); + +/* + * Create standard ASP commands + */ + websAspDefine(T("write"), websAspWrite); + return 0; +} + +/************************************* Code ***********************************/ +/* + * Close Asp symbol table. + */ + +void websAspClose() +{ + if (websAspFunctions != -1) { + symClose(websAspFunctions, NULL); + } +} + +/******************************************************************************/ +/* + * 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 incase 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; + } + websCloseFileHandle(wp); + +/* + * Convert to UNICODE if necessary. + */ + if ((buf = ballocAscToUni(rbuf)) == 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)) { + websCloseFileHandle(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)); + a_assert(argv); + + for (i = 0; i < argc; ) { + 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; +} + +/******************************************************************************/
\ No newline at end of file |