source: rtems/cpukit/httpd/webmain.c @ 70810dc

4.104.114.84.95
Last change on this file since 70810dc was 3f4b575, checked in by Joel Sherrill <joel.sherrill@…>, on 10/27/99 at 13:58:58

Warnings removed. Still don't know what to do about the pragma
pack warnings in uemf.h.

  • Property mode set to 100644
File size: 10.2 KB
Line 
1/*
2 * main.c -- Main program for the GoAhead WebServer (RTEMS version)
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 *  $Id$
9 */
10
11/******************************** Description *********************************/
12
13/*
14 *      Main program for for the GoAhead WebServer. This is a demonstration
15 *      main program to initialize and configure the web server.
16 */
17
18/********************************* Includes ***********************************/
19
20#include        "uemf.h"
21#include        "wsIntrn.h"
22#include        <signal.h>
23#include        <sys/time.h>
24#include        <pthread.h>
25
26#include        <rtems/error.h>
27
28/*********************************** Locals ***********************************/
29/*
30 *      Change configuration here
31 */
32
33static char_t           *rootWeb = T("web");                    /* Root web directory */
34static char_t           *password = T("");                              /* Security password */
35static int                      port = 80;                                              /* Server port */
36static int                      retries = 5;                                    /* Server port retries */
37static int                      finished;                                               /* Finished flag */
38
39/*
40 *      Structure to hold timer events
41 */
42typedef struct {
43        void    (*routine)(long arg);   /* Timer routine */
44        long    arg;                                    /* Argument to routine */
45} websTimer_t;
46
47/* The following holds the pointer to an allocated websTimer_t structure .
48 * Using this method only one timer can be active at a time, but
49 * for the WebServer, this should be OK.
50 */
51websTimer_t *tp;
52
53/****************************** Forward Declarations **************************/
54
55static int      initWebs();
56static int      aspTest(int eid, webs_t wp, int argc, char_t **argv);
57static void formTest(webs_t wp, char_t *path, char_t *query);
58static int  websHomePageHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
59                                int arg, char_t* url, char_t* path, char_t* query);
60static void timerProc(int signo);
61#if B_STATS
62static void printMemStats(int handle, char_t *fmt, ...);
63static void memLeaks();
64#endif
65static timer_t timer_id;
66static void rtems_httpd_daemon();
67 
68/*********************************** Code *************************************/
69/*
70 *      Main -- entry point from RTEMS
71 */
72int rtems_initialize_webserver()
73{
74  rtems_status_code   sc;
75  rtems_id            tid;
76  int                 priority;
77
78  /***********************************************************************
79   * Default HTTPD priority.
80   **********************************************************************/
81  priority = 40;
82 
83  sc = rtems_task_create(rtems_build_name('H', 'T', 'P', 'D'),
84                         priority, 8*1024,
85                         RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_NO_ASR |
86                         RTEMS_INTERRUPT_LEVEL(0),
87                         RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
88                         &tid);
89   if (sc != RTEMS_SUCCESSFUL)
90   {
91      return(RTEMS_UNSATISFIED);
92   }
93
94   sc = rtems_task_start(tid, rtems_httpd_daemon, 0);
95   if (sc != RTEMS_SUCCESSFUL)
96   {
97      return(RTEMS_UNSATISFIED);
98   }   
99
100   return(RTEMS_SUCCESSFUL);
101
102}
103
104static void
105rtems_httpd_daemon()
106{
107/*
108 *      Initialize the memory allocator. Allow use of malloc and start with a
109 *      10K heap.
110 */
111        bopen(NULL, (10 * 1024), B_USE_MALLOC);
112
113/*
114 *      Initialize the web server
115 */
116        if (initWebs() < 0) {
117          rtems_panic("Unable to initialize Web server !!\n");
118        }
119
120/*
121 *      Basic event loop. SocketReady returns true when a socket is ready for
122 *      service. SocketSelect will block until an event occurs. SocketProcess
123 *      will actually do the servicing.
124 */
125        while (!finished) {
126          if (socketReady() || socketSelect()) {
127                        socketProcess();
128          }
129        }
130
131/*
132 *      Close the socket module, report memory leaks and close the memory allocator
133 */
134        websCloseServer();
135        socketClose();
136#if B_STATS
137        memLeaks();
138#endif
139        bclose();
140        rtems_task_delete( RTEMS_SELF );
141}
142
143/******************************************************************************/
144/*
145 *      Initialize the web server.
146 */
147
148static int initWebs()
149{
150        struct hostent* hp;
151        struct in_addr  intaddr;
152        char                    host[128], dir[128], webdir[128];
153        char                    *cp;
154        char_t                  wbuf[128];
155
156/*
157 *      Initialize the socket subsystem
158 */
159        socketOpen();
160
161/*
162 *      Define the local Ip address, host name, default home page and the
163 *      root web directory.
164 */
165        if (gethostname(host, sizeof(host)) < 0) {
166                error(E_L, E_LOG, T("Can't get hostname"));
167                return -1;
168                }
169       
170/*      intaddr.s_addr = (unsigned long) hostGetByName(host); */
171        if ((hp = gethostbyname(host)) == NULL) {
172                error(E_L, E_LOG, T("Can't get host address"));
173                return -1;
174        }
175        memcpy((char *) &intaddr, (char *) hp->h_addr_list[0],
176                (size_t) hp->h_length);
177
178/*
179 *      Set ../web as the root web. Modify this to suit your needs
180 */
181        getcwd(dir, sizeof(dir));
182        if ((cp = strrchr(dir, '/'))) {
183                *cp = '\0';
184        }
185        sprintf(webdir, "%s/%s", dir, rootWeb);
186
187/*
188 *      Configure the web server options before opening the web server
189 */
190        websSetDefaultDir(webdir);
191        ascToUni(wbuf, inet_ntoa(intaddr), sizeof(wbuf));
192        websSetIpaddr(wbuf);
193        ascToUni(wbuf, host, sizeof(wbuf));
194        websSetHost(wbuf);
195
196/*
197 *      Configure the web server options before opening the web server
198 */
199        websSetDefaultPage(T("default.asp"));
200        websSetPassword(password);
201
202/*
203 *      Open the web server on the given port. If that port is taken, try
204 *      the next sequential port for up to "retries" attempts.
205 */
206        websOpenServer(port, retries);
207
208/*
209 *      First create the URL handlers. Note: handlers are called in sorted order
210 *      with the longest path handler examined first. Here we define the security
211 *      handler, forms handler and the default web page handler.
212 */
213        websUrlHandlerDefine(T(""), NULL, 0, websSecurityHandler,
214                WEBS_HANDLER_FIRST);
215        websUrlHandlerDefine(T("/goform"), NULL, 0, websFormHandler, 0);
216        websUrlHandlerDefine(T(""), NULL, 0, websDefaultHandler,
217                WEBS_HANDLER_LAST);
218
219/*
220 *      Now define two test procedures. Replace these with your application
221 *      relevant ASP script procedures and form functions.
222 */
223        websAspDefine(T("aspTest"), aspTest);
224        websFormDefine(T("formTest"), formTest);
225
226/*
227 *      Create a handler for the default home page
228 */
229        websUrlHandlerDefine(T("/"), NULL, 0, websHomePageHandler, 0);
230        return 0;
231}
232
233/******************************************************************************/
234/*
235 *      Test Javascript binding for ASP. This will be invoked when "aspTest" is
236 *      embedded in an ASP page. See web/asp.asp for usage. Set browser to
237 *      "localhost/asp.asp" to test.
238 */
239
240static int aspTest(int eid, webs_t wp, int argc, char_t **argv)
241{
242        char_t  *name, *address;
243
244        if (ejArgs(argc, argv, T("%s %s"), &name, &address) < 2) {
245                websError(wp, 400, T("Insufficient args\n"));
246                return -1;
247        }
248        return websWrite(wp, T("Name: %s, Address %s"), name, address);
249}
250/******************************************************************************/
251/*
252 *      Test form for posted data (in-memory CGI). This will be called when the
253 *      form in web/asp.asp is invoked. Set browser to "localhost/asp.asp" to test.
254 */
255
256static void formTest(webs_t wp, char_t *path, char_t *query)
257{
258        char_t  *name, *address;
259
260        name = websGetVar(wp, T("name"), T("Joe Smith"));
261        address = websGetVar(wp, T("address"), T("1212 Milky Way Ave."));
262
263        websHeader(wp);
264        websWrite(wp, T("<body><h2>Name: %s, Address: %s</h2>\n"), name, address);
265        websFooter(wp);
266        websDone(wp, 200);
267}
268
269/******************************************************************************/
270/*
271 *      Create a timer to invoke the routine in "delay" milliseconds.
272 */
273
274void *emfCreateTimer(int delay, void (*routine)(long arg),      long arg)
275{
276/* this variable is only used in the if'ed 0 section below */
277#if 0
278        struct sigaction        act;
279#endif
280        struct itimerspec its = { {0,0}, {0,0} };
281        struct sigevent se;
282        int     status;
283
284        if ((tp = balloc(B_L, sizeof(websTimer_t)))) {
285                tp->routine = routine;
286                tp->arg = arg;
287        }
288        else {
289                return NULL;
290        }
291
292        se.sigev_notify = SIGEV_THREAD;
293        se.sigev_value.sival_ptr = tp;
294        se.sigev_notify_function = (void (*)(union sigval)) timerProc;
295
296        /*
297         * NOT POSIX?
298         * se.sigev_notify_attributes = NULL;
299         */
300
301
302        status = timer_create(CLOCK_REALTIME, &se, &timer_id);
303        if (status != 0) {
304                bfree(B_L, tp);
305                return NULL;
306        }
307        /* convert delay millisecs to secs and usecs required by struct */
308        its.it_value.tv_sec = delay / 1000;
309        its.it_value.tv_nsec = (delay % 1000) * 1000000;
310
311        status = timer_settime(timer_id, 0, &its, 0);
312        if (status != 0) {
313                bfree(B_L, tp);
314                return NULL;
315        }
316       
317#if 0
318        act.sa_flags = 0;
319        sigemptyset(&act.sa_mask);
320        act.sa_handler = timerProc;
321        sigaction(SIGALRM, &act, NULL);
322
323        /* convert delay millisecs to secs and usecs required by struct */
324        its.it_value.tv_sec = delay / 1000;
325        its.it_value.tv_usec = (delay % 1000) * 1000;
326
327        if (setitimer(ITIMER_REAL, &its, NULL) ==  -1) {
328                bfree(B_L, tp);
329                return NULL;
330        }
331#endif
332        return tp;
333}
334
335/******************************************************************************/
336/*
337 *      Delete a timer
338 */
339
340void emfDeleteTimer(void * id)
341{
342        websTimer_t *wtp;
343        /*struct itimerval its = { {0,0}, {0,0} };*/
344
345        wtp = (websTimer_t *)id;
346        /*      setitimer(ITIMER_REAL, &its, NULL);*/
347        timer_delete(timer_id);
348        bfree(B_L, wtp);
349}
350
351/******************************************************************************/
352/*
353 *      Timer handler
354 */
355
356static void timerProc(int signo)
357{
358        websTimer_t wtp = *tp;
359
360/* Copy the timer structure to a local first and delete it before calling
361 * the function, since the function could create another timer.  In this
362 * implementation, only one timer can be allocated at a time.
363 */
364
365        bfree(B_L, tp);
366        (wtp.routine)(wtp.arg);
367}
368
369/******************************************************************************/
370/*
371 *      Home page handler
372 */
373
374static int websHomePageHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
375        int arg, char_t* url, char_t* path, char_t* query)
376{
377/*
378 *      If the empty or "/" URL is invoked, redirect default URLs to the home page
379 */
380        if (*url == '\0' || gstrcmp(url, T("/")) == 0) {
381                websRedirect(wp, T("home.asp"));
382                return 1;
383        }
384        return 0;
385}
386
387/******************************************************************************/
388
389#if B_STATS
390static void memLeaks()
391{
392        int             fd;
393
394        if ((fd = gopen(T("leak.txt"), O_CREAT | O_TRUNC | O_WRONLY)) >= 0) {
395                bstats(fd, printMemStats);
396                close(fd);
397        }
398}
399
400/******************************************************************************/
401/*
402 *      Print memory usage / leaks
403 */
404
405static void printMemStats(int handle, char_t *fmt, ...)
406{
407        va_list         args;
408        char_t          buf[256];
409
410        va_start(args, fmt);
411        vsprintf(buf, fmt, args);
412        va_end(args);
413        write(handle, buf, strlen(buf));
414}
415#endif
416
417/******************************************************************************/
Note: See TracBrowser for help on using the repository browser.