xdasd_conf.c

Go to the documentation of this file.
00001 /*----------------------------------------------------------------------------
00002  * Copyright (c) 2006, Novell, Inc.
00003  * All rights reserved.
00004  * 
00005  * Redistribution and use in source and binary forms, with or without 
00006  * modification, are permitted provided that the following conditions are 
00007  * met:
00008  * 
00009  *     * Redistributions of source code must retain the above copyright 
00010  *       notice, this list of conditions and the following disclaimer.
00011  *     * Redistributions in binary form must reproduce the above copyright 
00012  *       notice, this list of conditions and the following disclaimer in the 
00013  *       documentation and/or other materials provided with the distribution.
00014  *     * Neither the name of the Novell nor the names of its contributors 
00015  *       may be used to endorse or promote products derived from this 
00016  *       software without specific prior written permission.
00017  * 
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
00019  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00020  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
00021  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
00022  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00023  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00024  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
00025  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
00026  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
00027  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *--------------------------------------------------------------------------*/
00030 
00039 #include "xdas_base.h"
00040 #include "xdasd_conf.h"
00041 #include "xdasd_list.h"
00042 
00043 #include <xdas_debug.h>
00044 
00045 #include <stdio.h>
00046 #include <stddef.h>
00047 #include <stdlib.h>
00048 #include <string.h>
00049 #include <ctype.h>
00050 
00055 #ifdef _WIN32
00056 # define WIN32_LEAN_AND_MEAN
00057 # include <windows.h>
00058 # define strnenv(d,s,n) (ExpandEnvironmentStringsA((LPCSTR)(s),(LPSTR)(d),(n)-1),(d))
00059 # define XDASD_DEF_SLMOD_PATH "%SystemRoot%\\xdm_syslog.dll"
00060 #else
00061 # define strnenv(d,s,n) ((strncpy((d),(s),(n)-1)[(n)-1] = 0),(d))
00062 # define XDASD_DEF_SLMOD_PATH LIBDIR "/openxdas/libxdm_syslog.so"
00063 #endif
00064 
00066 typedef struct XDProp_tag
00067 {
00068    XDLItem listitem; 
00069    char * value;     
00070    char name[1];     
00071 } XDProp;
00072 
00074 static char g_config[FILENAME_MAX] = "";
00075 
00077 static XDList g_proplist = {0, 0, 0};
00078 
00088 static XDProp * xdasd_conf_find(const char * name)
00089 {
00090    XDProp * property = (XDProp *)g_proplist.head;
00091 
00092    /* property names are case sensitive, so use strcmp */
00093    while (property && strcmp(property->name, name) != 0)
00094       property = (XDProp *)property->listitem.next;
00095 
00096    return property;
00097 }
00098 
00111 static int xdasd_conf_setstr(const char * name, const char * value)
00112 {
00113    XDProp * oldprop;
00114    XDProp * newprop = 0;
00115 
00116    /* property names must not be null or empty */
00117    xdas_assert(name && *name);
00118 
00119    if (value)
00120    {
00121       size_t nsz, vsz;
00122 
00123 #ifdef _WIN32
00124       char xvbuf[4096];
00125 
00126       /* expand any env vars from value into xvbuf - point value to xvbuf */
00127       ExpandEnvironmentStringsA(value, xvbuf, sizeof(xvbuf)-1);
00128       value = xvbuf;
00129 #endif
00130 
00131       /* allocate property entry for this new value */
00132       nsz = strlen(name) + 1;
00133       vsz = strlen(value) + 1;
00134       if ((newprop = (XDProp *)malloc(sizeof(*newprop) - 1 + nsz + vsz)) == 0)
00135          return -1;
00136 
00137       /* set internal pointers to trailing buffer space, copy values */
00138       memcpy(newprop->name, name, nsz);
00139       newprop->value = newprop->name + nsz;
00140       memcpy(newprop->value, value, vsz);
00141    }
00142 
00143    /* locate and possibly remove old property */
00144    if ((oldprop = xdasd_conf_find(name))!= 0)
00145    {
00146       xdasd_list_unlink(&g_proplist, (XDLItem *)oldprop);
00147       free(oldprop);
00148    }
00149 
00150    /* link in new property, if specified and old property was removed */
00151    if (newprop)
00152       xdasd_list_link_head(&g_proplist, (XDLItem *)newprop);
00153 
00154    return 0;
00155 }
00156 
00157 #ifdef _WIN32
00158 
00171 static int xdas_get_w32reg_default(const char * name, char * buf, size_t bufsz)
00172 {
00173    HKEY key;
00174    LONG lerr = ERROR_SUCCESS;
00175 
00176    /* read registry time server name for time_source field */
00177    if ((lerr = RegOpenKeyA(HKEY_LOCAL_MACHINE, 
00178          "SYSTEM\\CurrentControlSet\\Services\\xdasd\\Parameters", 
00179          &key)) == ERROR_SUCCESS) 
00180    {
00181       DWORD dwBufSz = (DWORD)bufsz;
00182       lerr = RegQueryValueExA(key, name, 0, 0, (LPBYTE)buf, &dwBufSz);
00183       RegCloseKey(key);
00184    }
00185    return lerr == ERROR_SUCCESS? 0: -1;
00186 }
00187 #endif
00188 
00195 static int xdasd_conf_set_defaults(void)
00196 {
00197    static struct { const char * name; const char * value; } hard_defaults[] =
00198    {
00199       {"xdasd.loggers", XDASD_DEF_SLMOD_PATH},
00200 
00202    };
00203 
00204    int err = 0;
00205    unsigned i;
00206    char vbuf[2048];
00207 
00208    for (i = 0; i < xdas_elemcount(hard_defaults); i++)
00209    {
00210 #ifdef _WIN32
00211       if (xdas_get_w32reg_default(hard_defaults[i].name, vbuf, sizeof(vbuf)) < 0)
00212 #endif
00213          (void)strnenv(vbuf, hard_defaults[i].value, sizeof(vbuf));
00214 
00215       if (xdasd_conf_setstr(hard_defaults[i].name, vbuf) < 0)
00216          err = -1;
00217    }
00218    return err; /* -1 if at least one default value failed to be set. */
00219 }
00220 
00224 /*--------------------------------------------------------------------------*/
00225 
00241 char * xdasd_conf_getstr(const char * name, char * buffer, size_t * bufszp)
00242 {
00243    XDProp * property;
00244    size_t bufsz;
00245 
00246    /* parameter sanity check */
00247    xdas_assert(name && bufszp && (*bufszp || !buffer));
00248    if (!name || !bufszp || (buffer && !*bufszp))
00249       return 0;
00250 
00251    bufsz = *bufszp;
00252    *bufszp = 0;
00253 
00254    if ((property = xdasd_conf_find(name)) != 0)
00255    {
00256       size_t valsz = strlen(property->value) + 1;
00257       *bufszp = valsz;
00258       if (valsz > bufsz)
00259          valsz = bufsz;
00260       memcpy(buffer, property->value, valsz);
00261       if (valsz)
00262          buffer[valsz - 1] = 0;
00263    }
00264    return buffer;
00265 }
00266 
00279 int xdasd_conf_getint(const char * name)
00280 {
00281    XDProp * property = 0;
00282    int ivalue = 0;
00283 
00284    /* parameter sanity check */
00285    xdas_assert(name);
00286    if (name && (property = xdasd_conf_find(name)) != 0)
00287       ivalue = atoi(property->value);
00288 
00289    return property? ivalue: -1;
00290 }
00291 
00302 int xdasd_conf_init(const char * cfgpath)
00303 {
00304    FILE * fp;
00305 
00306    /* remove existing property list (if any) */
00307    xdasd_conf_exit();
00308 
00309    /* set default values */
00310    xdasd_conf_set_defaults();
00311 
00312    /* reset property file name (if specified) */
00313    if (cfgpath && *cfgpath)
00314       strcpy(g_config, cfgpath);
00315 
00316    /* there'd better be a file name in the buffer by now */
00317    xdas_assert(g_config && *g_config);
00318 
00319    if ((fp = fopen(g_config, "r")) != 0)
00320    {
00321       char buf[4096]; /* line buffer */
00322 
00323       while (fgets(buf, sizeof(buf), fp) != 0)
00324       {
00325          char * ep;
00326          char * name = buf;
00327          char * value;
00328 
00329          /* remove trailing '\n' chars, and fold continued lines */
00330          for(;;)
00331          {
00332             buf[sizeof(buf) - 1] = 0;  /* terminate in case too long */
00333             ep = buf + strlen(buf);    /* find string limit */
00334             if (*--ep == '\n')         /* remove trailing '\n' char */
00335                *ep = 0;
00336             if (ep <= buf || *--ep != '\\')  /* break if not continued */
00337                break;
00338             fgets(ep, (int)(sizeof(buf) - (ep - buf)), fp);
00339          }
00340 
00341          /* trim leading line white space */
00342          while (isspace(*name))
00343             name++;
00344 
00345          /* skip empty and comment lines */
00346          if (!*name || *name == '#')
00347             continue;
00348 
00349          /* remove trailing line comments */
00350          if ((ep = strchr(name, '#')) != 0)
00351             *ep = 0;
00352 
00353          /* skip ill-formatted lines (missing '=' sign) */
00354          if ((value = strchr(name, '=')) == 0)
00355             continue;
00356 
00357          /* terminate name, trim leading value white space */
00358          *value++ = 0;
00359          while (isspace(*value))
00360             value++;
00361 
00362          /* trim trailing name white space */
00363          ep = name + strlen(name);
00364          while (ep > name && isspace(ep[-1]))
00365             *--ep = 0;
00366 
00367          /* skip empty name or value lines */
00368          if (!*name || !*value)
00369             continue;
00370 
00371          /* trim trailing value whitespace */
00372          ep = value + strlen(value);
00373          while (ep > value && isspace(ep[-1]))
00374             *--ep = 0;
00375 
00376          /* add name,value pair to property list */
00377          xdasd_conf_setstr(name, value);
00378       }
00379       fclose(fp);
00380    }
00381    return fp? -1: 0;
00382 }
00383 
00388 void xdasd_conf_exit(void)
00389 {
00390    XDLItem * ip = g_proplist.head;
00391    while (ip)
00392    {
00393       XDLItem * del = ip;
00394       ip = ip->next;
00395       free(del);
00396    }
00397 }
00398 

Generated on Thu Aug 20 22:33:05 2009 for OpenXDAS by  doxygen 1.5.6