source: rtems/cpukit/httpd/asp.c @ 0a7278e

4.104.115
Last change on this file since 0a7278e was 0a7278e, checked in by Ralf Corsepius <ralf.corsepius@…>, on 11/29/09 at 13:20:53

Whitespace removal.

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