全部博文(436)
分类: C/C++
2013-08-13 09:04:26
1、解读了/root/031202/LINUX中的main.c文件:
/*
* main.c -- Main program for the GoAhead WebServer (LINUX version)
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*
* $Id: main.c,v 1.5 2003/09/11 14:03:46 bporter 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
#include
#include
#ifdef WEBS_SSL_SUPPORT
#include "../websSSL.h"
#endif
#ifdef USER_MANAGEMENT_SUPPORT
#include "../um.h"
void formDefineUserMgmt(void);
#endif
/*********************************** Locals ***********************************/
/*
* Change configuration here
*/
static char_t *rootWeb = T("web"); /* Root web directory */ctory */
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 */
/****************************** 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); (Handler 处理器)
extern void defaultErrorHandler(int etype, char_t *msg);
extern void defaultTraceHandler(int level, char_t *buf); (Trace 痕迹,踪迹)
#ifdef B_STATS
static void printMemStats(int handle, char_t *fmt, ...);
static void memLeaks(); (Leak 泄露)
#endif
/*********************************** Code *************************************/
/*
* Main -- entry point from LINUX
*/
int main(int argc, char** argv)
{
/*
* Initialize the memory allocator. Allow use of malloc and start
(初始化内存分配器。允许使用malloc和开始)
* with a 60K heap. For each page request approx 8KB is allocated.
(一个60 k堆。对于每个页面请求分配大约8 kb。)
* 60KB allows for several concurrent page requests. If more space
* is required, malloc will be used for the overflow.
(60 kb页面请求允许几个并发。如果需要更多的空间,malloc将用于溢出。)
*/
bopen(NULL, (60 * 1024), B_USE_MALLOC);
signal(SIGPIPE, SIG_IGN);
/*
* Initialize the web server
*/
if (initWebs() < 0) {
return -1;
}
#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.
(基本事件循环。SocketReady返回true当套接字准备好
服务。SocketSelect将阻塞,直到一个事件发生。SocketProcess
会做维修。)
(socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。)
*/
while (!finished) {
if (socketReady(-1) || socketSelect(-1, 1000)) {
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();
socketClose();
#ifdef B_STATS
memLeaks();
#endif
bclose();
return 0;
}
/******************************************************************************/
/*
* Initialize the web server.
*/
static int initWebs()
{
struct hostent *hp;
struct in_addr intaddr;
char host[128], dir[128], webdir[128];
char *cp;
char_t wbuf[128];
/*
* Initialize the socket subsystem(子系统初始化套接字)
*/
socketOpen();
#ifdef USER_MANAGEMENT_SUPPORT
/*
* Initialize the User Management database (初始化用户管理数据库)
*/
umOpen();
umRestore(T("umconfig.txt"));
#endif
/*
* Define the local Ip address, host name, default home page and the
* root web directory.
(定义本地Ip地址、主机名、默认主页和根web目录。)
*/
if (gethostname(host, sizeof(host)) < 0) {
error(E_L, E_LOG, T("Can't get hostname"));
return -1;
}
if ((hp = gethostbyname(host)) == NULL) {
error(E_L, E_LOG, T("Can't get host address"));
return -1;
}
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);
/*
* Set ../web as the root web. Modify this to suit your needs(根据需要对此进行修改)
*/
getcwd(dir, sizeof(dir));
if ((cp = strrchr(dir, '/'))) {
*cp = '\0';
}
sprintf(webdir, "%s/%s", dir, rootWeb);
/*
* Configure the web server options before opening the web server
(配置web服务器选项之前打开web服务器)
*/
websSetDefaultDir(webdir);
cp = inet_ntoa(intaddr);
ascToUni(wbuf, cp, min(strlen(cp) + 1, sizeof(wbuf)));
websSetIpaddr(wbuf);
ascToUni(wbuf, host, min(strlen(host) + 1, sizeof(wbuf)));
websSetHost(wbuf);
/*
* Configure the web server options before opening the web server
*/
websSetDefaultPage(T("default.asp"));
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.
(打开web服务器在给定的端口。如果该端口被占用,试试第二序列端口为“重试”的尝试。)
*/
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.
(首先创建URL处理程序。注意:处理程序被称为排序后的最长的路径处理程序检查第一。这里我们定义安全处理程序、表单处理程序和默认的web页面处理程序。)
*/
websUrlHandlerDefine(T(""), NULL, 0, websSecurityHandler,
WEBS_HANDLER_FIRST);
websUrlHandlerDefine(T("/goform"), NULL, 0, websFormHandler, 0);
websUrlHandlerDefine(T("/cgi-bin"), NULL, 0, websCgiHandler, 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.
(现在定义两个测试程序。取代这些与应用程序相关的ASP脚本程序和表单功能。)
*/
websAspDefine(T("aspTest"), aspTest);
websFormDefine(T("formTest"), formTest);
/*
* Create the Form handlers for the User Management pages
*/
#ifdef USER_MANAGEMENT_SUPPORT
formDefineUserMgmt();
#endif
/*
* 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.
(测试Javascript绑定为ASP。当“ aspTest”嵌入在一个ASP页面时它将被调用。看到使用web/ asp.asp,设置浏览器“localhost / asp.asp”测试。)
*/
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/forms.asp is invoked. Set browser to "localhost/forms.asp" to test.
(测试表单提交数据(内存中的CGI)。这将被称为当web/forms.asp被调用,设置浏览器“localhost/forms.asp”测试。)
*/
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("
websFooter(wp);
websDone(wp, 200);
}
/******************************************************************************/
/*
* 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
(如果空的或“/”URL被调用时,默认URL重定向到主页)
*/
if (*url == '\0' || gstrcmp(url, T("/")) == 0) {
websRedirect(wp, T("home.asp"));
return 1;
}
return 0;
}
/******************************************************************************/
/*
* Default error handler. The developer should insert code to handle
* error messages in the desired manner.
(默认的错误处理程序。开发人员应该插入代码来处理错误消息以期望的方式。)
*/
void defaultErrorHandler(int etype, char_t *msg)
{
#if 0
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.(下面的代码将编写所有跟踪)(stdout标准输出)
*/
#if 0
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();
(返回一个指向一个具有分配资格独特的临时文件名称的指针。
这个文件名必须最终被bfree()删除)
*/
char_t *websGetCgiCommName()
{
char_t *pname1, *pname2;
pname1 = tempnam(NULL, T("cgi"));
pname2 = bstrdup(B_L, pname1);
free(pname1);
return pname2;
}
/******************************************************************************/
/*
* Launch the CGI process and return a handle to it.
(启动CGI进程并返回一个它的句柄。)
*/
int websLaunchCgiProc(char_t *cgiPath, char_t **argp, char_t **envp,
char_t *stdIn, char_t *stdOut)
{
int pid, fdin, fdout, hstdin, hstdout, rc;
fdin = fdout = hstdin = hstdout = rc = -1;
if ((fdin = open(stdIn, O_RDWR | O_CREAT, 0666)) < 0 ||
(fdout = open(stdOut, O_RDWR | O_CREAT, 0666)) < 0 ||
(hstdin = dup(0)) == -1 ||
(hstdout = dup(1)) == -1 ||
dup2(fdin, 0) == -1 ||
dup2(fdout, 1) == -1) {
goto DONE;
}
rc = pid = fork();
if (pid == 0) {
/*
* if pid == 0, then we are in the child process(子进程)
*/
if (execve(cgiPath, argp, envp) == -1) {
printf("content-type: text/html\n\n"
"Execution of cgi process failed\n");
}
exit (0);
}
DONE:
if (hstdout >= 0) {
dup2(hstdout, 1);
close(hstdout);
}
if (hstdin >= 0) {
dup2(hstdin, 0);
close(hstdin);
}
if (fdout >= 0) {
close(fdout);
}
if (fdin >= 0) {
close(fdin);
}
return rc;
}
/******************************************************************************/
/*
* Check the CGI process. Return 0 if it does not exist; non 0 if it does.
(检查CGI进程。如果它不存在,返回0;如果非0,它存在。)
*/
int websCheckCgiProc(int handle)
{
/*
* Check to see if the CGI child process has terminated or not yet.
(看看CGI子进程终止没有)
*/
if (waitpid(handle, NULL, WNOHANG) == handle) {
return 0;
} else {
return 1;
}
}
/******************************************************************************/
#ifdef B_STATS
static void memLeaks()
{
int fd;
if ((fd = gopen(T("leak.txt"), O_CREAT | O_TRUNC | O_WRONLY, 0666)) >= 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
/******************************************************************************/
2、学习了Main Features链接里的
(1)、Active Server Pages:ASP是实现创建动态网页的。我们的.asp文件都是一个动态网页文件。JavaScript是一种有指定规则语言。我们现在看到的都是。
(2)CGI:是一个标准,我认为就是一个规则。main.c文件里有Launch the CGI process and return a handle to it.(启动CGI进程并返回一个它的句柄。)。还有,测试表单提交数据(内存中的CGI)。这两个是CGI代码包含在一个文件中,需要调用到它的指令、注释。
(3)GoForms是一个程序:这个程序是干什么的?我认为是:访问CGI中的变量的,怎么调用这个程序呢?相当于一个吴立锋课上的API函数,调用GoForm程序。
(4)安全:我认为有三个认证:
(1)客户端 (浏览器)和服务器(网络)使用DAA 之间的互动。
(2)安全套接字层是一个协议,它有自己的事件的序列,即过程。好像计网里的客户/服务器模式一样。
(3)用户管理。我们很需要:介绍了一些权限访问限制,像个用户类一样,有名称、密码、特权、是否启用等元素,进行的操作呢?就是添加用户、删除用户、更改权限、更改密码、 添加用户属性组什么的。浏览器每当请求一个页面时:最先做的就是用户管理这块儿
(5)、URL处理程序:是网页地址的处理程序。但URL处理程序的指定路径前缀匹配,没有看懂?规则什么的。
(6)、就是各种API函数了:基本的、管数据库的、负责语言的、负责Web服务器的API、用户身份验证的。。。。。。都是给好了的,我们只需要调用。
#include "../um.h"就是用户管理的API