webmain.c
来自「RTEMS (Real-Time Executive for Multiproc」· C语言 代码 · 共 500 行
C
500 行
/* * main.c -- Main program for the GoAhead WebServer (RTEMS version) * * Copyright (c) Go Ahead Software Inc., 1995-1999. All Rights Reserved. * * See the file "license.txt" for usage and redistribution license requirements * * $Id: webmain.c,v 1.7 2002/08/31 14:44:15 joel Exp $ *//******************************** Description *********************************//* * Main program for for the GoAhead WebServer. This is a demonstration * main program to initialize and configure the web server. *//********************************* Includes ***********************************/#include "uemf.h"#include "wsIntrn.h"#include <signal.h>#include <sys/time.h>#include <pthread.h>#include <rtems.h>#include <rtems/error.h>#ifdef WEBS_SSL_SUPPORT#include "websSSL.h"#endif#ifdef USER_MANAGEMENT_SUPPORT#include "um.h"void formDefineUserMgmt(void);#endif/*********************************** Locals ***********************************//* * Change configuration here */extern const char *tftpServer;/* static char_t *rootWeb = T("goahead"); * Root web directory */static char_t *password = T(""); /* Security password */static int port = 80; /* Server port */static int retries = 5; /* Server port retries */static int finished; /* Finished flag *//* * Structure to hold timer events */typedef struct { void (*routine)(long arg); /* Timer routine */ long arg; /* Argument to routine */} websTimer_t;/* The following holds the pointer to an allocated websTimer_t structure . * Using this method only one timer can be active at a time, but * for the WebServer, this should be OK. */websTimer_t *tp;/****************************** Forward Declarations **************************/static int initWebs();static int aspTest(int eid, webs_t wp, int argc, char_t **argv);static void formTest(webs_t wp, char_t *path, char_t *query);static int websHomePageHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, char_t* url, char_t* path, char_t* query);static void timerProc(int signo);#if B_STATSstatic void printMemStats(int handle, char_t *fmt, ...);static void memLeaks();#endifstatic timer_t timer_id;static void rtems_httpd_daemon(); /*********************************** Code *************************************//* * Main -- entry point from RTEMS */int rtems_initialize_webserver(){ rtems_status_code sc; rtems_id tid; int priority; /*********************************************************************** * Default HTTPD priority. **********************************************************************/ priority = 40; sc = rtems_task_create(rtems_build_name('H', 'T', 'P', 'D'), priority, 8*1024, RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_NO_ASR | RTEMS_INTERRUPT_LEVEL(0), RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL, &tid); if (sc != RTEMS_SUCCESSFUL) { return(RTEMS_UNSATISFIED); } sc = rtems_task_start(tid, rtems_httpd_daemon, 0); if (sc != RTEMS_SUCCESSFUL) { return(RTEMS_UNSATISFIED); } return(RTEMS_SUCCESSFUL);}static voidrtems_httpd_daemon(){/* * Initialize the memory allocator. Allow use of malloc and start with a * 10K heap. */ bopen(NULL, (10 * 1024), B_USE_MALLOC);/* * Initialize the web server */ if (initWebs() < 0) { rtems_panic("Unable to initialize Web server !!\n"); }#ifdef WEBS_SSL_SUPPORT websSSLOpen();#endif/* * Basic event loop. SocketReady returns true when a socket is ready for * service. SocketSelect will block until an event occurs. SocketProcess * will actually do the servicing. */ while (!finished) { if (socketReady(-1) || socketSelect(-1, 2000)) { socketProcess(-1); } /*websCgiCleanup();*/ emfSchedProcess(); }#ifdef WEBS_SSL_SUPPORT websSSLClose();#endif#ifdef USER_MANAGEMENT_SUPPORT umClose();#endif/* * Close the socket module, report memory leaks and close the memory allocator */ websCloseServer(); websDefaultClose(); socketClose(); symSubClose();#if B_STATS memLeaks();#endif bclose(); rtems_task_delete( RTEMS_SELF );}/******************************************************************************//* * Initialize the web server. */static int initWebs(){ struct hostent* hp; struct in_addr intaddr; char host[128], webdir[128]; char_t wbuf[128];/* * Initialize the socket subsystem */ socketOpen();/* * Define the local Ip address, host name, default home page and the * root web directory. */ if (gethostname(host, sizeof(host)) < 0) { error(E_L, E_LOG, T("Can't get hostname")); return -1; } /* intaddr.s_addr = (unsigned long) hostGetByName(host); */ if ((hp = gethostbyname(host)) == NULL) { error(E_L, E_LOG, T("Can't get host address")); return -1; } memcpy((char *) &intaddr, (char *) hp->h_addr_list[0], (size_t) hp->h_length);#if 0/* * Set /TFTP/x.y.z.w/goahead as the root web. Modify to suit your needs */ sprintf(webdir, "/TFTP/%s/%s", tftpServer, rootWeb);#else sprintf(webdir, "/");#endif/* * Configure the web server options before opening the web server */ websSetDefaultDir(webdir); ascToUni(wbuf, inet_ntoa(intaddr), sizeof(wbuf)); websSetIpaddr(wbuf); ascToUni(wbuf, host, sizeof(wbuf)); websSetHost(wbuf);/* * Configure the web server options before opening the web server */#if 0 websSetDefaultPage(T("default.asp"));#else websSetDefaultPage(T("index.html"));#endif websSetPassword(password);/* * Open the web server on the given port. If that port is taken, try * the next sequential port for up to "retries" attempts. */ websOpenServer(port, retries);/* * First create the URL handlers. Note: handlers are called in sorted order * with the longest path handler examined first. Here we define the security * handler, forms handler and the default web page handler. */ websUrlHandlerDefine(T(""), NULL, 0, websSecurityHandler, WEBS_HANDLER_FIRST); websUrlHandlerDefine(T("/goform"), NULL, 0, websFormHandler, 0); websUrlHandlerDefine(T(""), NULL, 0, websDefaultHandler, WEBS_HANDLER_LAST); /* * Now define two test procedures. Replace these with your application * relevant ASP script procedures and form functions. */ websAspDefine(T("aspTest"), aspTest); websFormDefine(T("formTest"), formTest);/* * Create a handler for the default home page */ websUrlHandlerDefine(T("/"), NULL, 0, websHomePageHandler, 0); return 0;}/******************************************************************************//* * Test Javascript binding for ASP. This will be invoked when "aspTest" is * embedded in an ASP page. See web/asp.asp for usage. Set browser to * "localhost/asp.asp" to test. */static int aspTest(int eid, webs_t wp, int argc, char_t **argv){ char_t *name, *address; if (ejArgs(argc, argv, T("%s %s"), &name, &address) < 2) { websError(wp, 400, T("Insufficient args\n")); return -1; } return websWrite(wp, T("Name: %s, Address %s"), name, address);}/******************************************************************************//* * Test form for posted data (in-memory CGI). This will be called when the * form in web/asp.asp is invoked. Set browser to "localhost/asp.asp" to test. */static void formTest(webs_t wp, char_t *path, char_t *query){ char_t *name, *address; name = websGetVar(wp, T("name"), T("Joe Smith")); address = websGetVar(wp, T("address"), T("1212 Milky Way Ave.")); websHeader(wp); websWrite(wp, T("<body><h2>Name: %s, Address: %s</h2>\n"), name, address); websFooter(wp); websDone(wp, 200);}/******************************************************************************//* * Create a timer to invoke the routine in "delay" milliseconds. */void *emfCreateTimer(int delay, void (*routine)(long arg), long arg){/* this variable is only used in the if'ed 0 section below */#if 0 struct sigaction act;#endif struct itimerspec its = { {0,0}, {0,0} }; struct sigevent se; int status; if ((tp = balloc(B_L, sizeof(websTimer_t)))) { tp->routine = routine; tp->arg = arg; } else { return NULL; } se.sigev_notify = SIGEV_THREAD; se.sigev_value.sival_ptr = tp; se.sigev_notify_function = (void (*)(union sigval)) timerProc; /* * NOT POSIX? * se.sigev_notify_attributes = NULL; */ status = timer_create(CLOCK_REALTIME, &se, &timer_id); if (status != 0) { bfree(B_L, tp); return NULL; } /* convert delay millisecs to secs and usecs required by struct */ its.it_value.tv_sec = delay / 1000; its.it_value.tv_nsec = (delay % 1000) * 1000000; status = timer_settime(timer_id, 0, &its, 0); if (status != 0) { bfree(B_L, tp); return NULL; } #if 0 act.sa_flags = 0; sigemptyset(&act.sa_mask); act.sa_handler = timerProc; sigaction(SIGALRM, &act, NULL); /* convert delay millisecs to secs and usecs required by struct */ its.it_value.tv_sec = delay / 1000; its.it_value.tv_usec = (delay % 1000) * 1000; if (setitimer(ITIMER_REAL, &its, NULL) == -1) { bfree(B_L, tp); return NULL; }#endif return tp;}/******************************************************************************//* * Delete a timer */void emfDeleteTimer(void * id){ websTimer_t *wtp; /*struct itimerval its = { {0,0}, {0,0} };*/ wtp = (websTimer_t *)id; /* setitimer(ITIMER_REAL, &its, NULL);*/ timer_delete(timer_id); bfree(B_L, wtp);}/******************************************************************************//* * Timer handler */static void timerProc(int signo){ websTimer_t wtp = *tp;/* Copy the timer structure to a local first and delete it before calling * the function, since the function could create another timer. In this * implementation, only one timer can be allocated at a time. */ bfree(B_L, tp); (wtp.routine)(wtp.arg);}/******************************************************************************//* * Home page handler */static int websHomePageHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, char_t* url, char_t* path, char_t* query){/* * If the empty or "/" URL is invoked, redirect default URLs to the home page */ if (*url == '\0' || gstrcmp(url, T("/")) == 0) {#if 0 websRedirect(wp, T("home.asp"));#else websRedirect(wp, T("index.html"));#endif return 1; } return 0;}/******************************************************************************/#if B_STATSstatic void memLeaks() { int fd=1; /* if ((fd = gopen(T("leak.txt"), O_CREAT | O_TRUNC | O_WRONLY)) >= 0) { */ bstats(fd, printMemStats); /* close(fd); } */}/******************************************************************************//* * Print memory usage / leaks */static void printMemStats(int handle, char_t *fmt, ...){ va_list args; char_t buf[256]; va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); write(handle, buf, strlen(buf));}#endif/*****************************************************************************//*****************************************************************************//* * Default error handler. The developer should insert code to handle * error messages in the desired manner. */void defaultErrorHandler(int etype, char_t *msg){#if 1 write(1, msg, gstrlen(msg));#endif}/*****************************************************************************//* * Trace log. Customize this function to log trace output */void defaultTraceHandler(int level, char_t *buf){/* * The following code would write all trace regardless of level * to stdout. */#if 1 if (buf) { write(1, buf, gstrlen(buf)); }#endif}/*****************************************************************************//* * Returns a pointer to an allocated qualified unique temporary file name. * This filename must eventually be deleted with bfree(); */char_t *websGetCgiCommName(){ char_t *pname1, *pname2; pname1 = tempnam(NULL, T("cgi")); pname2 = bstrdup(B_L, pname1); free(pname1); return pname2;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?