1 /******************************************************************************
5 ** This file is part of the ABYSS Web server project.
7 ** Copyright (C) 2000 by Moez Mahfoudh <mmoez@bigfoot.com>.
8 ** All rights reserved.
10 ** Redistribution and use in source and binary forms, with or without
11 ** modification, are permitted provided that the following conditions
13 ** 1. Redistributions of source code must retain the above copyright
14 ** notice, this list of conditions and the following disclaimer.
15 ** 2. Redistributions in binary form must reproduce the above copyright
16 ** notice, this list of conditions and the following disclaimer in the
17 ** documentation and/or other materials provided with the distribution.
18 ** 3. The name of the author may not be used to endorse or promote products
19 ** derived from this software without specific prior written permission.
21 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 ** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 ******************************************************************************/
39 #if defined(WIN32) && !defined(__BORLANDC__)
47 #include "xmlrpc_config.h"
48 #include "xmlrpc-c/string_int.h"
49 #include "xmlrpc-c/abyss.h"
54 /*********************************************************************
55 ** Configuration Files Parsing Functions
56 *********************************************************************/
61 ConfReadLine(TFile *f,char *buffer,uint32_t len) {
67 if (FileRead(f,buffer,1)<1)
74 if ((*buffer==CR) || (*buffer==LF) )
81 while (FileRead(f,&c,1)==1)
82 if ((c==CR) || (c==LF))
87 /* Discard comments */
96 ConfNextToken(char **p) {
112 ConfGetToken(char **p) {
139 ConfReadInt(const char * const p,
143 /*----------------------------------------------------------------------------
144 Convert string 'p' to integer *n.
146 If it isn't a valid integer or is not with the bounds [min, max],
147 return FALSE. Otherwise, return TRUE.
148 -----------------------------------------------------------------------------*/
151 *n = strtol(p, &e, 10);
154 return ((e != p) && (*n >= min) && (*n <= max));
162 ConfReadBool(char *p, abyss_bool *b) {
163 if (strcasecmp(p,"yes")==0)
169 if (strcasecmp(p,"no")==0)
178 /*********************************************************************
180 *********************************************************************/
183 readMIMETypesFile(const char * const filename,
184 MIMEType ** const MIMETypePP) {
187 MIMEType * MIMETypeP;
189 MIMETypeP = MIMETypeCreate();
192 abyss_bool fileOpened;
194 fileOpened = FileOpen(&file, filename, O_RDONLY);
197 while (ConfReadLine(&file, z, 512)) {
201 if (ConfNextToken(&p)) {
202 const char * mimetype = ConfGetToken(&p);
204 while (ConfNextToken(&p)) {
205 const char * const ext = ConfGetToken(&p);
207 MIMETypeAdd2(MIMETypeP, mimetype, ext);
219 MIMETypeDestroy(MIMETypeP);
224 *MIMETypePP = MIMETypeP;
229 /*********************************************************************
230 ** Server Configuration File
231 *********************************************************************/
234 chdirx(const char * const newdir,
235 abyss_bool * const successP) {
237 #if defined(WIN32) && !defined(__BORLANDC__)
238 *successP = _chdir(newdir) == 0;
240 *successP = chdir(newdir) == 0;
247 parseUser(const char * const p,
248 struct _TServer * const srvP) {
253 if (!ConfReadInt(&p[1], &n, 0, 0))
254 TraceExit("Bad user number '%s'", p);
260 if (!(pwd = getpwnam(p)))
261 TraceExit("Unknown user '%s'", p);
263 srvP->uid = pwd->pw_uid;
264 if ((int)srvP->gid==(-1))
265 srvP->gid = pwd->pw_gid;
268 TraceMsg("User option ignored");
275 parsePidfile(const char * const p,
276 struct _TServer * const srvP) {
278 if (!FileOpenCreate(&srvP->pidfile, p, O_TRUNC | O_WRONLY)) {
280 TraceMsg("Bad PidFile value '%s'", p);
283 TraceMsg("PidFile option ignored");
290 ConfReadServerFile(const char * const filename,
291 TServer * const serverP) {
293 struct _TServer * const srvP = serverP->srvP;
298 unsigned int lineNum;
301 if (!FileOpen(&f, filename, O_RDONLY))
306 while (ConfReadLine(&f, z, 512)) {
310 if (ConfNextToken(&p)) {
311 const char * const option = ConfGetToken(&p);
315 if (strcasecmp(option, "port") == 0) {
317 if (ConfReadInt(p, &n, 1, 65535))
320 TraceExit("Invalid port '%s'", p);
321 } else if (strcasecmp(option, "serverroot") == 0) {
325 TraceExit("Invalid server root '%s'",p);
326 } else if (strcasecmp(option, "path") == 0) {
327 if (FileStat(p, &fs))
328 if (fs.st_mode & S_IFDIR) {
329 xmlrpc_strfree(srvP->filespath);
330 srvP->filespath = strdup(p);
333 TraceExit("Invalid path '%s'", p);
334 } else if (strcasecmp(option, "default") == 0) {
335 const char * filename;
337 while ((filename = ConfGetToken(&p))) {
338 ListAdd(&srvP->defaultfilenames, strdup(filename));
339 if (!ConfNextToken(&p))
342 } else if (strcasecmp(option, "keepalive") == 0) {
344 if (ConfReadInt(p, &n, 1, 65535))
345 srvP->keepalivemaxconn = n;
347 TraceExit("Invalid KeepAlive value '%s'", p);
348 } else if (strcasecmp(option, "timeout") == 0) {
350 if (ConfReadInt(p, &n, 1, 3600)) {
351 srvP->keepalivetimeout = n;
352 /* Must see what to do with that */
355 TraceExit("Invalid TimeOut value '%s'", p);
356 } else if (strcasecmp(option, "mimetypes") == 0) {
357 readMIMETypesFile(p, &srvP->mimeTypeP);
358 if (!srvP->mimeTypeP)
359 TraceExit("Can't read MIME Types file '%s'", p);
360 } else if (strcasecmp(option,"logfile") == 0) {
361 srvP->logfilename = strdup(p);
362 } else if (strcasecmp(option,"user") == 0) {
364 } else if (strcasecmp(option, "pidfile")==0) {
365 parsePidfile(p, srvP);
366 } else if (strcasecmp(option, "advertiseserver") == 0) {
367 if (!ConfReadBool(p, &srvP->advertise))
368 TraceExit("Invalid boolean value "
369 "for AdvertiseServer option");
371 TraceExit("Invalid option '%s' at line %u",