source: rtems/cpukit/httpd/asp.c @ 7fcc26ac

4.104.114.84.95
Last change on this file since 7fcc26ac was a6b4c0df, checked in by Joel Sherrill <joel.sherrill@…>, on 09/01/00 at 10:57:21

2000-08-30 Joel Sherrill <joel@…>

  • Merged version 2.1 of GoAhead? webserver. This update was submitted by Antti P Miettinen <antti.p.miettinen@…>.
  • NOTES, base64.c, ejIntrn.h, emfdb.c, emfdb.h, md5.h, md5c.c, um.c, um.h: New files.
  • wbase64.c: Removed.
  • Makefile.am, asp.c, balloc.c, default.c, ej.h, ejlex.c, ejparse.c, form.c, h.c, handler.c, mime.c, misc.c, ringq.c, rom.c, security.c, socket.c, sym.c, uemf.c, uemf.h, url.c, value.c, webcomp.c, webmain.c, webpage.c, webrom.c, webs.c, webs.h, websuemf.c, wsIntrn.h: Modified.
  • Property mode set to 100644
File size: 6.9 KB
Line 
1/*
2 * asp.c -- Active Server Page Support
3 *
4 * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
5 *
6 * See the file "license.txt" for usage and redistribution license requirements
7 */
8
9/******************************** Description *********************************/
10
11/*
12 *      The ASP module processes ASP pages and executes embedded scripts. It
13 *      support an open scripting architecture with in-built support for
14 *      Ejscript(TM).
15 */
16
17/********************************* Includes ***********************************/
18
19#include        "wsIntrn.h"
20
21/********************************** Locals ************************************/
22
23static sym_fd_t websAspFunctions = -1;  /* Symbol table of functions */
24static int              aspOpenCount = 0;               /* count of apps using this module */
25
26/***************************** Forward Declarations ***************************/
27
28static char_t   *strtokcmp(char_t *s1, char_t *s2);
29static char_t   *skipWhite(char_t *s);
30
31/************************************* Code ***********************************/
32/*
33 *      Create script spaces and commands
34 */
35
36int websAspOpen()
37{
38        if (++aspOpenCount == 1) {
39/*
40 *      Create the table for ASP functions
41 */
42                websAspFunctions = symOpen(WEBS_SYM_INIT * 2);
43
44/*
45 *      Create standard ASP commands
46 */
47                websAspDefine(T("write"), websAspWrite);
48        }
49        return 0;
50}
51
52/************************************* Code ***********************************/
53/*
54 *      Close Asp symbol table.
55 */
56
57void websAspClose()
58{
59        if (--aspOpenCount <= 0) {
60                if (websAspFunctions != -1) {
61                        symClose(websAspFunctions);
62                        websAspFunctions = -1;
63                }
64        }
65}
66
67/******************************************************************************/
68/*
69 *      Process ASP requests and expand all scripting commands. We read the
70 *      entire ASP page into memory and then process. If you have really big
71 *      documents, it is better to make them plain HTML files rather than ASPs.
72 */
73
74int websAspRequest(webs_t wp, char_t *lpath)
75{
76        websStatType    sbuf;
77        char                    *rbuf;
78        char_t                  *token, *lang, *result, *path, *ep, *cp, *buf, *nextp;
79        char_t                  *last;
80        int                             rc, engine, len, ejid;
81
82        a_assert(websValid(wp));
83        a_assert(lpath && *lpath);
84
85        rc = -1;
86        buf = NULL;
87        rbuf = NULL;
88        engine = EMF_SCRIPT_EJSCRIPT;
89        wp->flags |= WEBS_HEADER_DONE;
90        path = websGetRequestPath(wp);
91
92/*
93 *      Create Ejscript instance in case it is needed
94 */
95        ejid = ejOpenEngine(wp->cgiVars, websAspFunctions);
96        if (ejid < 0) {
97                websError(wp, 200, T("Can't create Ejscript engine"));
98                goto done;
99        }
100        ejSetUserHandle(ejid, (int) wp);
101
102        if (websPageStat(wp, lpath, path, &sbuf) < 0) {
103                websError(wp, 200, T("Can't stat %s"), lpath);
104                goto done;
105        }
106
107/*
108 *      Create a buffer to hold the ASP file in-memory
109 */
110        len = sbuf.size * sizeof(char);
111        if ((rbuf = balloc(B_L, len + 1)) == NULL) {
112                websError(wp, 200, T("Can't get memory"));
113                goto done;
114        }
115        rbuf[len] = '\0';
116
117        if (websPageReadData(wp, rbuf, len) != len) {
118                websError(wp, 200, T("Cant read %s"), lpath);
119                goto done;
120        }
121        websPageClose(wp);
122
123/*
124 *      Convert to UNICODE if necessary.
125 */
126        if ((buf = ballocAscToUni(rbuf, len)) == NULL) {
127                websError(wp, 200, T("Can't get memory"));
128                goto done;
129        }
130
131/*
132 *      Scan for the next "<%"
133 */
134        last = buf;
135        rc = 0;
136        while (rc == 0 && *last && ((nextp = gstrstr(last, T("<%"))) != NULL)) {
137                websWriteBlock(wp, last, (nextp - last));
138                nextp = skipWhite(nextp + 2);
139
140/*
141 *              Decode the language
142 */
143                token = T("language");
144
145                if ((lang = strtokcmp(nextp, token)) != NULL) {
146                        if ((cp = strtokcmp(lang, T("=javascript"))) != NULL) {
147                                engine = EMF_SCRIPT_EJSCRIPT;
148                        } else {
149                                cp = nextp;
150                        }
151                        nextp = cp;
152                }
153
154/*
155 *              Find tailing bracket and then evaluate the script
156 */
157                if ((ep = gstrstr(nextp, T("%>"))) != NULL) {
158
159                        *ep = '\0';
160                        last = ep + 2;
161                        nextp = skipWhite(nextp);
162/*
163 *                      Handle backquoted newlines
164 */
165                        for (cp = nextp; *cp; ) {
166                                if (*cp == '\\' && (cp[1] == '\r' || cp[1] == '\n')) {
167                                        *cp++ = ' ';
168                                        while (*cp == '\r' || *cp == '\n') {
169                                                *cp++ = ' ';
170                                        }
171                                } else {
172                                        cp++;
173                                }
174                        }
175
176/*
177 *                      Now call the relevant script engine. Output is done directly
178 *                      by the ASP script procedure by calling websWrite()
179 */
180                        if (*nextp) {
181                                result = NULL;
182                                if (engine == EMF_SCRIPT_EJSCRIPT) {
183                                        rc = scriptEval(engine, nextp, &result, ejid);
184                                } else {
185                                        rc = scriptEval(engine, nextp, &result, (int) wp);
186                                }
187                                if (rc < 0) {
188/*
189 *                                      On an error, discard all output accumulated so far
190 *                                      and store the error in the result buffer. Be careful if the
191 *                                      user has called websError() already.
192 */
193                                        if (websValid(wp)) {
194                                                if (result) {
195                                                        websWrite(wp, T("<h2><b>ASP Error: %s</b></h2>\n"),
196                                                                result);
197                                                        websWrite(wp, T("<pre>%s</pre>"), nextp);
198                                                        bfree(B_L, result);
199                                                } else {
200                                                        websWrite(wp, T("<h2><b>ASP Error</b></h2>\n%s\n"),
201                                                                nextp);
202                                                }
203                                                websWrite(wp, T("</body></html>\n"));
204                                                rc = 0;
205                                        }
206                                        goto done;
207                                }
208                        }
209
210                } else {
211                        websError(wp, 200, T("Unterminated script in %s: \n"), lpath);
212                        rc = -1;
213                        goto done;
214                }
215        }
216/*
217 *      Output any trailing HTML page text
218 */
219        if (last && *last && rc == 0) {
220                websWriteBlock(wp, last, gstrlen(last));
221        }
222        rc = 0;
223
224/*
225 *      Common exit and cleanup
226 */
227done:
228        if (websValid(wp)) {
229                websPageClose(wp);
230                if (ejid >= 0) {
231                        ejCloseEngine(ejid);
232                }
233        }
234        bfreeSafe(B_L, buf);
235        bfreeSafe(B_L, rbuf);
236        return rc;
237}
238
239/******************************************************************************/
240/*
241 *      Define an ASP Ejscript function. Bind an ASP name to a C procedure.
242 */
243
244int websAspDefine(char_t *name,
245        int (*fn)(int ejid, webs_t wp, int argc, char_t **argv))
246{
247        return ejSetGlobalFunctionDirect(websAspFunctions, name,
248                (int (*)(int, void*, int, char_t**)) fn);
249}
250
251/******************************************************************************/
252/*
253 *      Asp write command. This implemements <% write("text"); %> command
254 */
255
256int websAspWrite(int ejid, webs_t wp, int argc, char_t **argv)
257{
258        int             i;
259
260        a_assert(websValid(wp));
261       
262        for (i = 0; i < argc; ) {
263                a_assert(argv);
264                if (websWriteBlock(wp, argv[i], gstrlen(argv[i])) < 0) {
265                        return -1;
266                }
267                if (++i < argc) {
268                        if (websWriteBlock(wp, T(" "), 2) < 0) {
269                                return -1;
270                        }
271                }
272        }
273        return 0;
274}
275
276/******************************************************************************/
277/*
278 *      strtokcmp -- Find s2 in s1. We skip leading white space in s1.
279 *      Return a pointer to the location in s1 after s2 ends.
280 */
281
282static char_t *strtokcmp(char_t *s1, char_t *s2)
283{
284        int             len;
285
286        s1 = skipWhite(s1);
287        len = gstrlen(s2);
288        for (len = gstrlen(s2); len > 0 && (tolower(*s1) == tolower(*s2)); len--) {
289                if (*s2 == '\0') {
290                        return s1;
291                }
292                s1++;
293                s2++;
294        }
295        if (len == 0) {
296                return s1;
297        }
298        return NULL;
299}
300
301/******************************************************************************/
302/*
303 *      Skip white space
304 */
305
306static char_t *skipWhite(char_t *s)
307{
308        a_assert(s);
309
310        if (s == NULL) {
311                return s;
312        }
313        while (*s && gisspace(*s)) {
314                s++;
315        }
316        return s;
317}
318
319/******************************************************************************/
Note: See TracBrowser for help on using the repository browser.