OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [c/] [src/] [libnetworking/] [rtems_webserver/] [webmain.c] - Blame information for rev 1780

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.