abyss_conf.c

Go to the documentation of this file.
00001 /******************************************************************************
00002 **
00003 ** conf.c
00004 **
00005 ** This file is part of the ABYSS Web server project.
00006 **
00007 ** Copyright (C) 2000 by Moez Mahfoudh <mmoez@bigfoot.com>.
00008 ** All rights reserved.
00009 **
00010 ** Redistribution and use in source and binary forms, with or without
00011 ** modification, are permitted provided that the following conditions
00012 ** are met:
00013 ** 1. Redistributions of source code must retain the above copyright
00014 **    notice, this list of conditions and the following disclaimer.
00015 ** 2. Redistributions in binary form must reproduce the above copyright
00016 **    notice, this list of conditions and the following disclaimer in the
00017 **    documentation and/or other materials provided with the distribution.
00018 ** 3. The name of the author may not be used to endorse or promote products
00019 **    derived from this software without specific prior written permission.
00020 ** 
00021 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
00022 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024 ** ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
00025 ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00026 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00027 ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00028 ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029 ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00030 ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00031 ** SUCH DAMAGE.
00032 **
00033 ******************************************************************************/
00034 
00035 #include <stdlib.h>
00036 #include <stdio.h>
00037 #include <string.h>
00038 
00039 #if defined(WIN32) && !defined(__BORLANDC__)
00040 #include <direct.h>
00041 #endif
00042 
00043 #ifdef _UNIX
00044 #include <pwd.h>
00045 #endif
00046 
00047 #include <xmlrpc-c/config.h>
00048 #include "abyss_xmlrpc_int.h"
00049 #include <xmlrpc-c/abyss.h>
00050 #include "abyss_trace.h"
00051 #include "abyss_server.h"
00052 #include "abyss_http.h"
00053 
00054 /*********************************************************************
00055 ** Configuration Files Parsing Functions
00056 *********************************************************************/
00057 
00058 
00059 
00060 static abyss_bool
00061 ConfReadLine(TFile *f,char *buffer,uint32_t len) {
00062     abyss_bool r=TRUE;
00063     char c,*p,*z=buffer;
00064 
00065     while ((--len)>0)
00066     {
00067         if (FileRead(f,buffer,1)<1)
00068         {
00069             if (z==buffer)
00070                 r=FALSE;
00071             break;
00072         };
00073 
00074         if ((*buffer==CR) || (*buffer==LF) )
00075             break;
00076 
00077         buffer++;
00078     };
00079 
00080     if (len==0)
00081         while (FileRead(f,&c,1)==1)
00082             if ((c==CR) || (c==LF))
00083                 break;
00084 
00085     *buffer='\0';
00086 
00087     /* Discard comments */
00088     p=strchr(z,'#');
00089     if (p)
00090         *p='\0';
00091 
00092     return r;
00093 }
00094 
00095 static abyss_bool
00096 ConfNextToken(char **p) {
00097     while (1)
00098         switch (**p)
00099         {
00100         case '\t':
00101         case ' ':
00102             (*p)++;
00103             break;
00104         case '\0':
00105             return FALSE;
00106         default:
00107             return TRUE;
00108         };
00109 }
00110 
00111 static char *
00112 ConfGetToken(char **p) {
00113     char *p0=*p;
00114 
00115     while (1)
00116         switch (**p)
00117         {
00118         case '\t':
00119         case ' ':
00120         case CR:
00121         case LF:
00122         case '\0':
00123             if (p0==*p)
00124                 return NULL;
00125 
00126             if (**p)
00127             {
00128                 **p='\0';
00129                 (*p)++;
00130             };
00131             return p0;
00132 
00133         default:
00134             (*p)++;
00135         };
00136 }
00137 
00138 static abyss_bool
00139 ConfReadInt(const char * const p,
00140             int32_t *    const n,
00141             int32_t      const min,
00142             int32_t      const max) {
00143 /*----------------------------------------------------------------------------
00144    Convert string 'p' to integer *n.
00145 
00146    If it isn't a valid integer or is not with the bounds [min, max],
00147    return FALSE.  Otherwise, return TRUE.
00148 -----------------------------------------------------------------------------*/
00149     char * e;
00150 
00151     *n = strtol(p, &e, 10);
00152 
00153     if (min != max)
00154         return ((e != p) && (*n >= min) && (*n <= max));
00155     else
00156         return (e != p);
00157 }
00158 
00159 
00160 
00161 static abyss_bool
00162 ConfReadBool(char *p, abyss_bool *b) {
00163     if (strcasecmp(p,"yes")==0)
00164     {
00165         *b=TRUE;
00166         return TRUE;
00167     };
00168 
00169     if (strcasecmp(p,"no")==0)
00170     {
00171         *b=FALSE;
00172         return TRUE;
00173     };
00174 
00175     return FALSE;
00176 }
00177 
00178 /*********************************************************************
00179 ** MIME Types File
00180 *********************************************************************/
00181 
00182 static void
00183 readMIMETypesFile(const char * const filename,
00184                   MIMEType **  const MIMETypePP) {
00185 
00186     abyss_bool success;
00187     MIMEType * MIMETypeP;
00188 
00189     MIMETypeP = MIMETypeCreate();
00190     if (MIMETypeP) {
00191         TFile file;
00192         abyss_bool fileOpened;
00193 
00194         fileOpened = FileOpen(&file, filename, O_RDONLY);
00195         if (fileOpened) {
00196             char z[512];
00197             while (ConfReadLine(&file, z, 512)) {
00198                 char * p;
00199                 p = &z[0];
00200             
00201                 if (ConfNextToken(&p)) {
00202                     const char * mimetype = ConfGetToken(&p);
00203                     if (mimetype) {
00204                         while (ConfNextToken(&p)) {
00205                             const char * const ext = ConfGetToken(&p);
00206                             if (ext)
00207                                 MIMETypeAdd2(MIMETypeP, mimetype, ext);
00208                             else
00209                                 break;
00210                         }
00211                     }
00212                 }
00213             }
00214             FileClose(&file);
00215             success = TRUE;
00216         } else
00217             success = FALSE;
00218         if (!success)
00219             MIMETypeDestroy(MIMETypeP);
00220     } else
00221         success = FALSE;
00222 
00223     if (success)
00224         *MIMETypePP = MIMETypeP;
00225     else
00226         *MIMETypePP = NULL;
00227 }
00228 
00229 /*********************************************************************
00230 ** Server Configuration File
00231 *********************************************************************/
00232 
00233 static void
00234 chdirx(const char * const newdir,
00235        abyss_bool * const successP) {
00236     
00237 #if defined(WIN32) && !defined(__BORLANDC__)
00238     *successP = _chdir(newdir) == 0;
00239 #else
00240     *successP = chdir(newdir) == 0;
00241 #endif
00242 }
00243 
00244 
00245 
00246 static void
00247 parseUser(const char *      const p, 
00248           struct _TServer * const srvP) {
00249 #ifdef _UNIX
00250     if (p[0] == '#') {
00251         int32_t n;
00252         
00253         if (!ConfReadInt(&p[1], &n, 0, 0))
00254             TraceExit("Bad user number '%s'", p);
00255         else
00256             srvP->uid = n;
00257     } else {
00258         struct passwd * pwd;
00259 
00260         if (!(pwd = getpwnam(p)))
00261             TraceExit("Unknown user '%s'", p);
00262         
00263         srvP->uid = pwd->pw_uid;
00264         if ((int)srvP->gid==(-1))
00265             srvP->gid = pwd->pw_gid;
00266     };
00267 #else
00268     TraceMsg("User option ignored");
00269 #endif  /* _UNIX */ 
00270 }
00271 
00272 
00273 
00274 static void
00275 parsePidfile(const char *      const p,
00276              struct _TServer * const srvP) {
00277 #ifdef _UNIX
00278     if (!FileOpenCreate(&srvP->pidfile, p, O_TRUNC | O_WRONLY)) {
00279         srvP->pidfile = -1;
00280         TraceMsg("Bad PidFile value '%s'", p);
00281     };
00282 #else
00283     TraceMsg("PidFile option ignored");
00284 #endif  /* _UNIX */ 
00285 }
00286 
00287 
00288 
00289 abyss_bool
00290 ConfReadServerFile(const char * const filename,
00291                    TServer *    const serverP) {
00292 
00293     struct _TServer * const srvP = serverP->srvP;
00294 
00295     TFile f;
00296     char z[512];
00297     char * p;
00298     unsigned int lineNum;
00299     TFileStat fs;
00300 
00301     if (!FileOpen(&f, filename, O_RDONLY))
00302         return FALSE;
00303 
00304     lineNum = 0;
00305 
00306     while (ConfReadLine(&f, z, 512)) {
00307         ++lineNum;
00308         p = z;
00309 
00310         if (ConfNextToken(&p)) {
00311             const char * const option = ConfGetToken(&p);
00312             if (option) {
00313                 ConfNextToken(&p);
00314 
00315                 if (strcasecmp(option, "port") == 0) {
00316                     int32_t n;
00317                     if (ConfReadInt(p, &n, 1, 65535))
00318                         srvP->port = n;
00319                     else
00320                         TraceExit("Invalid port '%s'", p);
00321                 } else if (strcasecmp(option, "serverroot") == 0) {
00322                     abyss_bool success;
00323                     chdirx(p, &success);
00324                     if (!success)
00325                         TraceExit("Invalid server root '%s'",p);
00326                 } else if (strcasecmp(option, "path") == 0) {
00327                     if (FileStat(p, &fs))
00328                         if (fs.st_mode & S_IFDIR) {
00329                             xmlrpc_strfree(srvP->filespath);
00330                             srvP->filespath = strdup(p);
00331                             continue;
00332                         }
00333                     TraceExit("Invalid path '%s'", p);
00334                 } else if (strcasecmp(option, "default") == 0) {
00335                     const char * filename;
00336                     
00337                     while ((filename = ConfGetToken(&p))) {
00338                         ListAdd(&srvP->defaultfilenames, strdup(filename));
00339                         if (!ConfNextToken(&p))
00340                             break;
00341                     }
00342                 } else if (strcasecmp(option, "keepalive") == 0) {
00343                     int32_t n;
00344                     if (ConfReadInt(p, &n, 1, 65535))
00345                         srvP->keepalivemaxconn = n;
00346                     else
00347                         TraceExit("Invalid KeepAlive value '%s'", p);
00348                 } else if (strcasecmp(option, "timeout") == 0) {
00349                     int32_t n;
00350                     if (ConfReadInt(p, &n, 1, 3600)) {
00351                         srvP->keepalivetimeout = n;
00352                         /* Must see what to do with that */
00353                         srvP->timeout = n;
00354                     } else
00355                         TraceExit("Invalid TimeOut value '%s'", p);
00356                 } else if (strcasecmp(option, "mimetypes") == 0) {
00357                     readMIMETypesFile(p, &srvP->mimeTypeP);
00358                     if (!srvP->mimeTypeP)
00359                         TraceExit("Can't read MIME Types file '%s'", p);
00360                 } else if (strcasecmp(option,"logfile") == 0) {
00361                     srvP->logfilename = strdup(p);
00362                 } else if (strcasecmp(option,"user") == 0) {
00363                     parseUser(p, srvP);
00364                 } else if (strcasecmp(option, "pidfile")==0) {
00365                     parsePidfile(p, srvP);
00366                 } else if (strcasecmp(option, "advertiseserver") == 0) {
00367                     if (!ConfReadBool(p, &srvP->advertise))
00368                         TraceExit("Invalid boolean value "
00369                                   "for AdvertiseServer option");
00370                 } else
00371                     TraceExit("Invalid option '%s' at line %u",
00372                               option, lineNum);
00373             }
00374         }
00375     }
00376 
00377     FileClose(&f);
00378     return TRUE;
00379 }

Generated on Thu May 17 10:00:23 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6