source: rtems/cpukit/httpd/asp.c @ df49c60

4.104.114.84.95
Last change on this file since df49c60 was c1cdaa0, checked in by Joel Sherrill <joel.sherrill@…>, on 10/27/99 at 12:50:33

Patch from Emmanuel Raguet <raguet@…> and Eric Valette
<valette@…> to add a port of the GoAhead? web server
(httpd) to the RTEMS build tree. They have successfully used
this BSP on i386/pc386 and PowerPC/mcp750.

Mark and Joel spoke with Nick Berliner <nickb@…> on
26 Oct 1999 about this port and got verbal approval to include
it in RTEMS distributions.

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