📄 conf.c
字号:
/********************************************************************************** conf.c**** This file is part of the ABYSS Web server project.**** Copyright (C) 2000 by Moez Mahfoudh <mmoez@bigfoot.com>.** All rights reserved.**** Redistribution and use in source and binary forms, with or without** modification, are permitted provided that the following conditions** are met:** 1. Redistributions of source code must retain the above copyright** notice, this list of conditions and the following disclaimer.** 2. Redistributions in binary form must reproduce the above copyright** notice, this list of conditions and the following disclaimer in the** documentation and/or other materials provided with the distribution.** 3. The name of the author may not be used to endorse or promote products** derived from this software without specific prior written permission.** ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF** SUCH DAMAGE.********************************************************************************/#include <stdlib.h>#include <stdio.h>#include <string.h>#if defined(WIN32) && !defined(__BORLANDC__)#include <direct.h>#endif#ifdef _UNIX#include <pwd.h>#endif#include "xmlrpc_config.h"#include "xmlrpc-c/string_int.h"#include "xmlrpc-c/abyss.h"#include "trace.h"#include "server.h"#include "http.h"/*********************************************************************** Configuration Files Parsing Functions*********************************************************************/static abyss_boolConfReadLine(TFile *f,char *buffer,uint32_t len) { abyss_bool r=TRUE; char c,*p,*z=buffer; while ((--len)>0) { if (FileRead(f,buffer,1)<1) { if (z==buffer) r=FALSE; break; }; if ((*buffer==CR) || (*buffer==LF) ) break; buffer++; }; if (len==0) while (FileRead(f,&c,1)==1) if ((c==CR) || (c==LF)) break; *buffer='\0'; /* Discard comments */ p=strchr(z,'#'); if (p) *p='\0'; return r;}static abyss_boolConfNextToken(char **p) { while (1) switch (**p) { case '\t': case ' ': (*p)++; break; case '\0': return FALSE; default: return TRUE; };}static char *ConfGetToken(char **p) { char *p0=*p; while (1) switch (**p) { case '\t': case ' ': case CR: case LF: case '\0': if (p0==*p) return NULL; if (**p) { **p='\0'; (*p)++; }; return p0; default: (*p)++; };}static abyss_boolConfReadInt(const char * const p, int32_t * const n, int32_t const min, int32_t const max) {/*---------------------------------------------------------------------------- Convert string 'p' to integer *n. If it isn't a valid integer or is not with the bounds [min, max], return FALSE. Otherwise, return TRUE.-----------------------------------------------------------------------------*/ char * e; *n = strtol(p, &e, 10); if (min != max) return ((e != p) && (*n >= min) && (*n <= max)); else return (e != p);}static abyss_boolConfReadBool(char *p, abyss_bool *b) { if (strcasecmp(p,"yes")==0) { *b=TRUE; return TRUE; }; if (strcasecmp(p,"no")==0) { *b=FALSE; return TRUE; }; return FALSE;}/*********************************************************************** MIME Types File*********************************************************************/static voidreadMIMETypesFile(const char * const filename, MIMEType ** const MIMETypePP) { abyss_bool success; MIMEType * MIMETypeP; MIMETypeP = MIMETypeCreate(); if (MIMETypeP) { TFile file; abyss_bool fileOpened; fileOpened = FileOpen(&file, filename, O_RDONLY); if (fileOpened) { char z[512]; while (ConfReadLine(&file, z, 512)) { char * p; p = &z[0]; if (ConfNextToken(&p)) { const char * mimetype = ConfGetToken(&p); if (mimetype) { while (ConfNextToken(&p)) { const char * const ext = ConfGetToken(&p); if (ext) MIMETypeAdd2(MIMETypeP, mimetype, ext); else break; } } } } FileClose(&file); success = TRUE; } else success = FALSE; if (!success) MIMETypeDestroy(MIMETypeP); } else success = FALSE; if (success) *MIMETypePP = MIMETypeP; else *MIMETypePP = NULL;}/*********************************************************************** Server Configuration File*********************************************************************/static voidchdirx(const char * const newdir, abyss_bool * const successP) { #if defined(WIN32) && !defined(__BORLANDC__) *successP = _chdir(newdir) == 0;#else *successP = chdir(newdir) == 0;#endif}static voidparseUser(const char * const p, struct _TServer * const srvP) {#ifdef _UNIX if (p[0] == '#') { int32_t n; if (!ConfReadInt(&p[1], &n, 0, 0)) TraceExit("Bad user number '%s'", p); else srvP->uid = n; } else { struct passwd * pwd; if (!(pwd = getpwnam(p))) TraceExit("Unknown user '%s'", p); srvP->uid = pwd->pw_uid; if ((int)srvP->gid==(-1)) srvP->gid = pwd->pw_gid; };#else TraceMsg("User option ignored");#endif /* _UNIX */ }static voidparsePidfile(const char * const p, struct _TServer * const srvP) {#ifdef _UNIX if (!FileOpenCreate(&srvP->pidfile, p, O_TRUNC | O_WRONLY)) { srvP->pidfile = -1; TraceMsg("Bad PidFile value '%s'", p); };#else TraceMsg("PidFile option ignored");#endif /* _UNIX */ }abyss_boolConfReadServerFile(const char * const filename, TServer * const serverP) { struct _TServer * const srvP = serverP->srvP; TFile f; char z[512]; char * p; unsigned int lineNum; TFileStat fs; if (!FileOpen(&f, filename, O_RDONLY)) return FALSE; lineNum = 0; while (ConfReadLine(&f, z, 512)) { ++lineNum; p = z; if (ConfNextToken(&p)) { const char * const option = ConfGetToken(&p); if (option) { ConfNextToken(&p); if (strcasecmp(option, "port") == 0) { int32_t n; if (ConfReadInt(p, &n, 1, 65535)) srvP->port = n; else TraceExit("Invalid port '%s'", p); } else if (strcasecmp(option, "serverroot") == 0) { abyss_bool success; chdirx(p, &success); if (!success) TraceExit("Invalid server root '%s'",p); } else if (strcasecmp(option, "path") == 0) { if (FileStat(p, &fs)) if (fs.st_mode & S_IFDIR) { xmlrpc_strfree(srvP->filespath); srvP->filespath = strdup(p); continue; } TraceExit("Invalid path '%s'", p); } else if (strcasecmp(option, "default") == 0) { const char * filename; while ((filename = ConfGetToken(&p))) { ListAdd(&srvP->defaultfilenames, strdup(filename)); if (!ConfNextToken(&p)) break; } } else if (strcasecmp(option, "keepalive") == 0) { int32_t n; if (ConfReadInt(p, &n, 1, 65535)) srvP->keepalivemaxconn = n; else TraceExit("Invalid KeepAlive value '%s'", p); } else if (strcasecmp(option, "timeout") == 0) { int32_t n; if (ConfReadInt(p, &n, 1, 3600)) { srvP->keepalivetimeout = n; /* Must see what to do with that */ srvP->timeout = n; } else TraceExit("Invalid TimeOut value '%s'", p); } else if (strcasecmp(option, "mimetypes") == 0) { readMIMETypesFile(p, &srvP->mimeTypeP); if (!srvP->mimeTypeP) TraceExit("Can't read MIME Types file '%s'", p); } else if (strcasecmp(option,"logfile") == 0) { srvP->logfilename = strdup(p); } else if (strcasecmp(option,"user") == 0) { parseUser(p, srvP); } else if (strcasecmp(option, "pidfile")==0) { parsePidfile(p, srvP); } else if (strcasecmp(option, "advertiseserver") == 0) { if (!ConfReadBool(p, &srvP->advertise)) TraceExit("Invalid boolean value " "for AdvertiseServer option"); } else TraceExit("Invalid option '%s' at line %u", option, lineNum); } } } FileClose(&f); return TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -