iniparser.c

Go to the documentation of this file.
00001 /*
00002 * $Id: iniparser.c 4585 2008-08-06 08:20:30Z klaus_darilion $
00003 *
00004 * Kamailio LDAP Module
00005 *
00006 * Copyright (C) 2007 University of North Carolina
00007 *
00008 * Original author: Christian Schlatter, cs@unc.edu
00009 *
00010 *
00011 * This file is part of Kamailio, a free SIP server.
00012 *
00013 * Kamailio is free software; you can redistribute it and/or modify
00014 * it under the terms of the GNU General Public License as published by
00015 * the Free Software Foundation; either version 2 of the License, or
00016 * (at your option) any later version
00017 *
00018 * Kamailio is distributed in the hope that it will be useful,
00019 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021 * GNU General Public License for more details.
00022 *
00023 * You should have received a copy of the GNU General Public License
00024 * along with this program; if not, write to the Free Software
00025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026 *
00027 * History:
00028 * --------
00029 * 2007-02-18: Initial version
00030 */
00031 
00032 
00033 
00034 /*
00035 Based upon libiniparser, by Nicolas Devillard
00036 Hacked into 1 file (m-iniparser) by Freek/2005
00037 Original terms following:
00038 
00039 -- -
00040 
00041 Copyright (c) 2000 by Nicolas Devillard (ndevilla AT free DOT fr).
00042 
00043 Written by Nicolas Devillard. Not derived from licensed software.
00044 
00045 Permission is granted to anyone to use this software for any
00046 purpose on any computer system, and to redistribute it freely,
00047 subject to the following restrictions:
00048 
00049 1. The author is not responsible for the consequences of use of
00050 this software, no matter how awful, even if they arise
00051 from defects in it.
00052 
00053 2. The origin of this software must not be misrepresented, either
00054 by explicit claim or by omission.
00055 
00056 3. Altered versions must be plainly marked as such, and must not
00057 be misrepresented as being the original software.
00058 
00059 4. This notice may not be removed or altered.
00060 
00061 */
00062 
00063 
00064 #include <stdio.h>
00065 #include <stdlib.h>
00066 #include <string.h>
00067 #include <unistd.h>
00068 
00069 #include "iniparser.h"
00070 
00071 #ifdef __cplusplus
00072 extern "C" {
00073 #endif
00074 
00075    /* strlib.c following */
00076 
00077 #define ASCIILINESZ 1024
00078    /*-------------------------------------------------------------------------*/
00079    /**
00080 @brief    Convert a string to lowercase.
00081 @param    s   String to convert.
00082 @return   ptr to statically allocated string.
00083 
00084 This function returns a pointer to a statically allocated string
00085 containing a lowercased version of the input string. Do not free
00086 or modify the returned string! Since the returned string is statically
00087 allocated, it will be modified at each function call (not re-entrant).
00088 */
00089    /*--------------------------------------------------------------------------*/
00090 
00091    static char * strlwc(char * s)
00092    {
00093       static char l[ASCIILINESZ+1];
00094       int i ;
00095 
00096       if (s==NULL) return NULL ;
00097       memset(l, 0, ASCIILINESZ+1);
00098       i=0 ;
00099       while (s[i] && i<ASCIILINESZ) {
00100          l[i] = (char)tolower((int)s[i]);
00101          i++ ;
00102       }
00103       l[ASCIILINESZ]=(char)0;
00104       return l ;
00105    }
00106 
00107 
00108 
00109    /*-------------------------------------------------------------------------*/
00110    /**
00111 @brief    Convert a string to uppercase.
00112 @param    s   String to convert.
00113 @return   ptr to statically allocated string.
00114 
00115 This function returns a pointer to a statically allocated string
00116 containing an uppercased version of the input string. Do not free
00117 or modify the returned string! Since the returned string is statically
00118 allocated, it will be modified at each function call (not re-entrant).
00119 */
00120    /*--------------------------------------------------------------------------*/
00121 
00122    /*
00123 static char * strupc(char * s)
00124 {
00125    static char l[ASCIILINESZ+1];
00126    int i ;
00127 
00128    if (s==NULL) return NULL ;
00129    memset(l, 0, ASCIILINESZ+1);
00130    i=0 ;
00131    while (s[i] && i<ASCIILINESZ) {
00132       l[i] = (char)toupper((int)s[i]);
00133       i++ ;
00134    }
00135    l[ASCIILINESZ]=(char)0;
00136    return l ;
00137 }
00138 */
00139 
00140 
00141 
00142    /*-------------------------------------------------------------------------*/
00143    /**
00144 @brief    Skip blanks until the first non-blank character.
00145 @param    s   String to parse.
00146 @return   Pointer to char inside given string.
00147 
00148 This function returns a pointer to the first non-blank character in the
00149 given string.
00150 */
00151    /*--------------------------------------------------------------------------*/
00152 
00153    static char * strskp(char * s)
00154    {
00155       char * skip = s;
00156       if (s==NULL) return NULL ;
00157       while (isspace((int)*skip) && *skip) skip++;
00158       return skip ;
00159    }
00160 
00161 
00162 
00163    /*-------------------------------------------------------------------------*/
00164    /**
00165 @brief    Remove blanks at the end of a string.
00166 @param    s   String to parse.
00167 @return   ptr to statically allocated string.
00168 
00169 This function returns a pointer to a statically allocated string,
00170 which is identical to the input string, except that all blank
00171 characters at the end of the string have been removed.
00172 Do not free or modify the returned string! Since the returned string
00173 is statically allocated, it will be modified at each function call
00174 (not re-entrant).
00175 */
00176    /*--------------------------------------------------------------------------*/
00177 
00178    static char * strcrop(char * s)
00179    {
00180       static char l[ASCIILINESZ+1];
00181       char * last ;
00182 
00183       if (s==NULL) return NULL ;
00184       memset(l, 0, ASCIILINESZ+1);
00185       strcpy(l, s);
00186       last = l + strlen(l);
00187       while (last > l) {
00188          if (!isspace((int)*(last-1)))
00189          break ;
00190          last -- ;
00191       }
00192       *last = (char)0;
00193       return l ;
00194    }
00195 
00196 
00197 
00198    /*-------------------------------------------------------------------------*/
00199    /**
00200 @brief    Remove blanks at the beginning and the end of a string.
00201 @param    s   String to parse.
00202 @return   ptr to statically allocated string.
00203 
00204 This function returns a pointer to a statically allocated string,
00205 which is identical to the input string, except that all blank
00206 characters at the end and the beg. of the string have been removed.
00207 Do not free or modify the returned string! Since the returned string
00208 is statically allocated, it will be modified at each function call
00209 (not re-entrant).
00210 */
00211    /*--------------------------------------------------------------------------*/
00212    /*
00213 static char * strstrip(char * s)
00214 {
00215    static char l[ASCIILINESZ+1];
00216    char * last ;
00217 
00218    if (s==NULL) return NULL ;
00219 
00220    while (isspace((int)*s) && *s) s++;
00221 
00222    memset(l, 0, ASCIILINESZ+1);
00223    strcpy(l, s);
00224    last = l + strlen(l);
00225    while (last > l) {
00226       if (!isspace((int)*(last-1)))
00227          break ;
00228       last -- ;
00229    }
00230    *last = (char)0;
00231 
00232    return (char*)l ;
00233 }
00234 */
00235 
00236    /* dictionary.c.c following */
00237    /** Maximum value size for integers and doubles. */
00238 #define MAXVALSZ    1024
00239 
00240    /** Minimal allocated number of entries in a dictionary */
00241 #define DICTMINSZ   128
00242 
00243    /** Invalid key token */
00244 #define DICT_INVALID_KEY    ((char*)-1)
00245 
00246    /*
00247 Doubles the allocated size associated to a pointer
00248 'size' is the current allocated size.
00249 */
00250    static void * mem_double(void * ptr, int size)
00251    {
00252       void *newptr;
00253 
00254       newptr = calloc(2*size, 1);
00255       memcpy(newptr, ptr, size);
00256       free(ptr);
00257       return newptr ;
00258    }
00259 
00260 
00261    /*---------------------------------------------------------------------------
00262                      Function codes
00263 ---------------------------------------------------------------------------*/
00264 
00265    /*-------------------------------------------------------------------------*/
00266    /**
00267 @brief    Compute the hash key for a string.
00268 @param    key     Character string to use for key.
00269 @return   1 unsigned int on at least 32 bits.
00270 
00271 This hash function has been taken from an Article in Dr Dobbs Journal.
00272 This is normally a collision-free function, distributing keys evenly.
00273 The key is stored anyway in the struct so that collision can be avoided
00274 by comparing the key itself in last resort.
00275 */
00276    /*--------------------------------------------------------------------------*/
00277 
00278    static unsigned dictionary_hash(char * key)
00279    {
00280       int         len ;
00281       unsigned    hash ;
00282       int         i ;
00283 
00284       len = strlen(key);
00285       for (hash=0, i=0 ; i<len ; i++) {
00286          hash += (unsigned)key[i] ;
00287          hash += (hash<<10);
00288          hash ^= (hash>>6) ;
00289       }
00290       hash += (hash <<3);
00291       hash ^= (hash >>11);
00292       hash += (hash <<15);
00293       return hash ;
00294    }
00295 
00296 
00297    /*-------------------------------------------------------------------------*/
00298    /**
00299 @brief    Create a new dictionary object.
00300 @param    size    Optional initial size of the dictionary.
00301 @return   1 newly allocated dictionary objet.
00302 
00303 This function allocates a new dictionary object of given size and returns
00304 it. If you do not know in advance (roughly) the number of entries in the
00305 dictionary, give size=0.
00306 */
00307    /*--------------------------------------------------------------------------*/
00308 
00309    static dictionary * dictionary_new(int size)
00310    {
00311       dictionary *d ;
00312 
00313       /* If no size was specified, allocate space for DICTMINSZ */
00314       if (size<DICTMINSZ) size=DICTMINSZ ;
00315 
00316       d = (dictionary *)calloc(1, sizeof(dictionary));
00317       d->size = size ;
00318       d->val  = (char **)calloc(size, sizeof(char*));
00319       d->key  = (char **)calloc(size, sizeof(char*));
00320       d->hash = (unsigned int *)calloc(size, sizeof(unsigned));
00321 
00322       return d;
00323    }
00324 
00325 
00326    /*-------------------------------------------------------------------------*/
00327    /**
00328 @brief    Delete a dictionary object
00329 @param    d   dictionary object to deallocate.
00330 @return   void
00331 
00332 Deallocate a dictionary object and all memory associated to it.
00333 */
00334    /*--------------------------------------------------------------------------*/
00335 
00336    static void dictionary_del(dictionary * d)
00337    {
00338       int     i ;
00339 
00340       if (d==NULL) return ;
00341       for (i=0 ; i<d->size ; i++) {
00342          if (d->key[i]!=NULL)
00343          free(d->key[i]);
00344          if (d->val[i]!=NULL)
00345          free(d->val[i]);
00346       }
00347       free(d->val);
00348       free(d->key);
00349       free(d->hash);
00350       free(d);
00351 
00352       return;
00353    }
00354 
00355 
00356 
00357    /*-------------------------------------------------------------------------*/
00358    /**
00359 @brief    Get a value from a dictionary.
00360 @param    d       dictionary object to search.
00361 @param    key     Key to look for in the dictionary.
00362 @param    def     Default value to return if key not found.
00363 @return   1 pointer to internally allocated character string.
00364 
00365 This function locates a key in a dictionary and returns a pointer to its
00366 value, or the passed 'def' pointer if no such key can be found in
00367 dictionary. The returned character pointer points to data internal to the
00368 dictionary object, you should not try to free it or modify it.
00369 */
00370    /*--------------------------------------------------------------------------*/
00371    static char * dictionary_get(dictionary * d, char * key, char * def)
00372    {
00373       unsigned    hash ;
00374       int         i ;
00375 
00376       hash = dictionary_hash(key);
00377       for (i=0 ; i<d->size ; i++) {
00378          if (d->key==NULL)
00379          continue ;
00380          /* Compare hash */
00381          if (hash==d->hash[i]) {
00382             /* Compare string, to avoid hash collisions */
00383             if (!strcmp(key, d->key[i])) {
00384                return d->val[i] ;
00385             }
00386          }
00387       }
00388       return def ;
00389    }
00390 
00391 
00392    /*-------------------------------------------------------------------------*/
00393    /**
00394 @brief    Set a value in a dictionary.
00395 @param    d       dictionary object to modify.
00396 @param    key     Key to modify or add.
00397 @param    val     Value to add.
00398 @return   void
00399 
00400 If the given key is found in the dictionary, the associated value is
00401 replaced by the provided one. If the key cannot be found in the
00402 dictionary, it is added to it.
00403 
00404 It is Ok to provide a NULL value for val, but NULL values for the dictionary
00405 or the key are considered as errors: the function will return immediately
00406 in such a case.
00407 
00408 Notice that if you dictionary_set a variable to NULL, a call to
00409 dictionary_get will return a NULL value: the variable will be found, and
00410 its value (NULL) is returned. In other words, setting the variable
00411 content to NULL is equivalent to deleting the variable from the
00412 dictionary. It is not possible (in this implementation) to have a key in
00413 the dictionary without value.
00414 */
00415    /*--------------------------------------------------------------------------*/
00416 
00417    static void dictionary_set(dictionary * d, char * key, char * val)
00418    {
00419       int         i ;
00420       unsigned    hash ;
00421 
00422       if (d==NULL || key==NULL) return ;
00423 
00424       /* Compute hash for this key */
00425       hash = dictionary_hash(key) ;
00426       /* Find if value is already in blackboard */
00427       if (d->n>0) {
00428          for (i=0 ; i<d->size ; i++) {
00429             if (d->key[i]==NULL)
00430             continue ;
00431             if (hash==d->hash[i]) { /* Same hash value */
00432                if (!strcmp(key, d->key[i])) {   /* Same key */
00433                   /* Found a value: modify and return */
00434                   if (d->val[i]!=NULL)
00435                   free(d->val[i]);
00436                   d->val[i] = val ? strdup(val) : NULL ;
00437                   /* Value has been modified: return */
00438                   return ;
00439                }
00440             }
00441          }
00442       }
00443       /* Add a new value */
00444       /* See if dictionary needs to grow */
00445       if (d->n==d->size) {
00446 
00447          /* Reached maximum size: reallocate blackboard */
00448          d->val  = (char **)mem_double(d->val,  d->size * sizeof(char*)) ;
00449          d->key  = (char **)mem_double(d->key,  d->size * sizeof(char*)) ;
00450          d->hash = (unsigned int *)mem_double(d->hash, d->size * sizeof(unsigned)) ;
00451 
00452          /* Double size */
00453          d->size *= 2 ;
00454       }
00455 
00456       /* Insert key in the first empty slot */
00457       for (i=0 ; i<d->size ; i++) {
00458          if (d->key[i]==NULL) {
00459             /* Add key here */
00460             break ;
00461          }
00462       }
00463       /* Copy key */
00464       d->key[i]  = strdup(key);
00465       d->val[i]  = val ? strdup(val) : NULL ;
00466       d->hash[i] = hash;
00467       d->n ++ ;
00468       return ;
00469    }
00470 
00471    /*-------------------------------------------------------------------------*/
00472    /**
00473 @brief    Delete a key in a dictionary
00474 @param    d       dictionary object to modify.
00475 @param    key     Key to remove.
00476 @return   void
00477 
00478 This function deletes a key in a dictionary. Nothing is done if the
00479 key cannot be found.
00480 */
00481    /*--------------------------------------------------------------------------*/
00482    static void dictionary_unset(dictionary * d, char * key)
00483    {
00484       unsigned    hash ;
00485       int         i ;
00486 
00487       hash = dictionary_hash(key);
00488       for (i=0 ; i<d->size ; i++) {
00489          if (d->key[i]==NULL)
00490          continue ;
00491          /* Compare hash */
00492          if (hash==d->hash[i]) {
00493             /* Compare string, to avoid hash collisions */
00494             if (!strcmp(key, d->key[i])) {
00495                /* Found key */
00496                break ;
00497             }
00498          }
00499       }
00500       if (i>=d->size)
00501       /* Key not found */
00502       return ;
00503 
00504       free(d->key[i]);
00505       d->key[i] = NULL ;
00506       if (d->val[i]!=NULL) {
00507          free(d->val[i]);
00508          d->val[i] = NULL ;
00509       }
00510       d->hash[i] = 0 ;
00511       d->n -- ;
00512       return ;
00513    }
00514 
00515 
00516    /*-------------------------------------------------------------------------*/
00517    /**
00518 @brief    Dump a dictionary to an opened file pointer.
00519 @param    d   Dictionary to dump
00520 @param    f   Opened file pointer.
00521 @return   void
00522 
00523 Dumps a dictionary onto an opened file pointer. Key pairs are printed out
00524 as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as
00525 output file pointers.
00526 */
00527    /*--------------------------------------------------------------------------*/
00528 
00529    static void dictionary_dump(dictionary *d, FILE *f)
00530    {
00531       int i;
00532 
00533       if (d==NULL || f==NULL) return;
00534 
00535       for (i=0; i<d->size; i++) {
00536          if (d->key[i] == NULL)
00537          continue ;
00538          if (d->val[i] != NULL) {
00539             fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]);
00540          } else {
00541             fprintf(f, "[%s]=UNDEF\n", d->key[i]);
00542          }
00543       }
00544 
00545       return;
00546    }
00547 
00548 
00549    /* iniparser.c.c following */
00550 #define ASCIILINESZ         1024
00551 #define INI_INVALID_KEY     ((char*)-1)
00552 
00553    /* Private: add an entry to the dictionary */
00554    static void iniparser_add_entry(
00555    dictionary * d,
00556    char * sec,
00557    char * key,
00558    char * val)
00559    {
00560       char longkey[2*ASCIILINESZ+1];
00561 
00562       /* Make a key as section:keyword */
00563       if (key!=NULL) {
00564          sprintf(longkey, "%s:%s", sec, key);
00565       } else {
00566          strcpy(longkey, sec);
00567       }
00568 
00569       /* Add (key,val) to dictionary */
00570       dictionary_set(d, longkey, val);
00571       return ;
00572    }
00573 
00574 
00575    /*-------------------------------------------------------------------------*/
00576    /**
00577 @brief    Get number of sections in a dictionary
00578 @param    d   Dictionary to examine
00579 @return   int Number of sections found in dictionary
00580 
00581 This function returns the number of sections found in a dictionary.
00582 The test to recognize sections is done on the string stored in the
00583 dictionary: a section name is given as "section" whereas a key is
00584 stored as "section:key", thus the test looks for entries that do not
00585 contain a colon.
00586 
00587 This clearly fails in the case a section name contains a colon, but
00588 this should simply be avoided.
00589 
00590 This function returns -1 in case of error.
00591 */
00592    /*--------------------------------------------------------------------------*/
00593 
00594    int iniparser_getnsec(dictionary * d)
00595    {
00596       int i ;
00597       int nsec ;
00598 
00599       if (d==NULL) return -1 ;
00600       nsec=0 ;
00601       for (i=0 ; i<d->size ; i++) {
00602          if (d->key[i]==NULL)
00603          continue ;
00604          if (strchr(d->key[i], ':')==NULL) {
00605             nsec ++ ;
00606          }
00607       }
00608       return nsec ;
00609    }
00610 
00611 
00612    /*-------------------------------------------------------------------------*/
00613    /**
00614 @brief    Get name for section n in a dictionary.
00615 @param    d   Dictionary to examine
00616 @param    n   Section number (from 0 to nsec-1).
00617 @return   Pointer to char string
00618 
00619 This function locates the n-th section in a dictionary and returns
00620 its name as a pointer to a string statically allocated inside the
00621 dictionary. Do not free or modify the returned string!
00622 
00623 This function returns NULL in case of error.
00624 */
00625    /*--------------------------------------------------------------------------*/
00626 
00627    char * iniparser_getsecname(dictionary * d, int n)
00628    {
00629       int i ;
00630       int foundsec ;
00631 
00632       if (d==NULL || n<0) return NULL ;
00633       foundsec=0 ;
00634       for (i=0 ; i<d->size ; i++) {
00635          if (d->key[i]==NULL)
00636          continue ;
00637          if (strchr(d->key[i], ':')==NULL) {
00638             foundsec++ ;
00639             if (foundsec>n)
00640             break ;
00641          }
00642       }
00643       if (foundsec<=n) {
00644          return NULL ;
00645       }
00646       return d->key[i] ;
00647    }
00648 
00649 
00650    /*-------------------------------------------------------------------------*/
00651    /**
00652 @brief    Dump a dictionary to an opened file pointer.
00653 @param    d   Dictionary to dump.
00654 @param    f   Opened file pointer to dump to.
00655 @return   void
00656 
00657 This function prints out the contents of a dictionary, one element by
00658 line, onto the provided file pointer. It is OK to specify @c stderr
00659 or @c stdout as output files. This function is meant for debugging
00660 purposes mostly.
00661 */
00662    /*--------------------------------------------------------------------------*/
00663    void iniparser_dump(dictionary * d, FILE * f)
00664    {
00665       dictionary_dump(d,f);
00666    }
00667 
00668 
00669    /*-------------------------------------------------------------------------*/
00670    /**
00671 @brief    Save a dictionary to a loadable ini file
00672 @param    d   Dictionary to dump
00673 @param    f   Opened file pointer to dump to
00674 @return   void
00675 
00676 This function dumps a given dictionary into a loadable ini file.
00677 It is Ok to specify @c stderr or @c stdout as output files.
00678 */
00679    /*--------------------------------------------------------------------------*/
00680 
00681    void iniparser_dump_ini(dictionary * d, FILE * f)
00682    {
00683       int     i, j ;
00684       char    keym[ASCIILINESZ+1];
00685       int     nsec ;
00686       char *  secname ;
00687       int     seclen ;
00688 
00689       if (d==NULL || f==NULL) return ;
00690 
00691       nsec = iniparser_getnsec(d);
00692       if (nsec<1) {
00693          /* No section in file: dump all keys as they are */
00694          for (i=0 ; i<d->size ; i++) {
00695             if (d->key[i]==NULL)
00696             continue ;
00697             fprintf(f, "%s = %s\n", d->key[i], d->val[i]);
00698          }
00699          return ;
00700       }
00701       for (i=0 ; i<nsec ; i++) {
00702          secname = iniparser_getsecname(d, i) ;
00703          seclen  = (int)strlen(secname);
00704          fprintf(f, "\n[%s]\n", secname);
00705          sprintf(keym, "%s:", secname);
00706          for (j=0 ; j<d->size ; j++) {
00707             if (d->key[j]==NULL)
00708             continue ;
00709             if (!strncmp(d->key[j], keym, seclen+1)) {
00710                fprintf(f,
00711                "%-30s = %s\n",
00712                d->key[j]+seclen+1,
00713                d->val[j] ? d->val[j] : "");
00714             }
00715          }
00716       }
00717       fprintf(f, "\n");
00718       return ;
00719    }
00720 
00721    /*-------------------------------------------------------------------------*/
00722    /**
00723 @brief    Get the string associated to a key, return NULL if not found
00724 @param    d   Dictionary to search
00725 @param    key Key string to look for
00726 @return   pointer to statically allocated character string, or NULL.
00727 
00728 This function queries a dictionary for a key. A key as read from an
00729 ini file is given as "section:key". If the key cannot be found,
00730 NULL is returned.
00731 The returned char pointer is pointing to a string allocated in
00732 the dictionary, do not free or modify it.
00733 
00734 This function is only provided for backwards compatibility with
00735 previous versions of iniparser. It is recommended to use
00736 iniparser_getstring() instead.
00737 */
00738    /*--------------------------------------------------------------------------*/
00739    char * iniparser_getstr(dictionary * d, char * key)
00740    {
00741       return iniparser_getstring(d, key, NULL);
00742    }
00743 
00744 
00745    /*-------------------------------------------------------------------------*/
00746    /**
00747 @brief    Get the string associated to a key
00748 @param    d       Dictionary to search
00749 @param    key     Key string to look for
00750 @param    def     Default value to return if key not found.
00751 @return   pointer to statically allocated character string
00752 
00753 This function queries a dictionary for a key. A key as read from an
00754 ini file is given as "section:key". If the key cannot be found,
00755 the pointer passed as 'def' is returned.
00756 The returned char pointer is pointing to a string allocated in
00757 the dictionary, do not free or modify it.
00758 */
00759    /*--------------------------------------------------------------------------*/
00760    char * iniparser_getstring(dictionary * d, char * key, char * def)
00761    {
00762       char * lc_key ;
00763       char * sval ;
00764 
00765       if (d==NULL || key==NULL)
00766       return def ;
00767 
00768       lc_key = strdup(strlwc(key));
00769       sval = dictionary_get(d, lc_key, def);
00770       free(lc_key);
00771       return sval ;
00772    }
00773 
00774 
00775 
00776    /*-------------------------------------------------------------------------*/
00777    /**
00778 @brief    Get the string associated to a key, convert to an int
00779 @param    d Dictionary to search
00780 @param    key Key string to look for
00781 @param    notfound Value to return in case of error
00782 @return   integer
00783 
00784 This function queries a dictionary for a key. A key as read from an
00785 ini file is given as "section:key". If the key cannot be found,
00786 the notfound value is returned.
00787 */
00788    /*--------------------------------------------------------------------------*/
00789    int iniparser_getint(dictionary * d, char * key, int notfound)
00790    {
00791       char    *   str ;
00792 
00793       str = iniparser_getstring(d, key, INI_INVALID_KEY);
00794       if (str==INI_INVALID_KEY) return notfound ;
00795       return atoi(str);
00796    }
00797 
00798 
00799    /*-------------------------------------------------------------------------*/
00800    /**
00801 @brief    Get the string associated to a key, convert to a double
00802 @param    d Dictionary to search
00803 @param    key Key string to look for
00804 @param    notfound Value to return in case of error
00805 @return   double
00806 
00807 This function queries a dictionary for a key. A key as read from an
00808 ini file is given as "section:key". If the key cannot be found,
00809 the notfound value is returned.
00810 */
00811    /*--------------------------------------------------------------------------*/
00812    double iniparser_getdouble(dictionary * d, char * key, double notfound)
00813    {
00814       char    *   str ;
00815 
00816       str = iniparser_getstring(d, key, INI_INVALID_KEY);
00817       if (str==INI_INVALID_KEY) return notfound ;
00818       return atof(str);
00819    }
00820 
00821 
00822 
00823    /*-------------------------------------------------------------------------*/
00824    /**
00825 @brief    Get the string associated to a key, convert to a boolean
00826 @param    d Dictionary to search
00827 @param    key Key string to look for
00828 @param    notfound Value to return in case of error
00829 @return   integer
00830 
00831 This function queries a dictionary for a key. A key as read from an
00832 ini file is given as "section:key". If the key cannot be found,
00833 the notfound value is returned.
00834 
00835 A true boolean is found if one of the following is matched:
00836 
00837 - A string starting with 'y'
00838 - A string starting with 'Y'
00839 - A string starting with 't'
00840 - A string starting with 'T'
00841 - A string starting with '1'
00842 
00843 A false boolean is found if one of the following is matched:
00844 
00845 - A string starting with 'n'
00846 - A string starting with 'N'
00847 - A string starting with 'f'
00848 - A string starting with 'F'
00849 - A string starting with '0'
00850 
00851 The notfound value returned if no boolean is identified, does not
00852 necessarily have to be 0 or 1.
00853 */
00854    /*--------------------------------------------------------------------------*/
00855    int iniparser_getboolean(dictionary * d, char * key, int notfound)
00856    {
00857       char    *   c ;
00858       int         ret ;
00859 
00860       c = iniparser_getstring(d, key, INI_INVALID_KEY);
00861       if (c==INI_INVALID_KEY) return notfound ;
00862       if (c[0]=='y' || c[0]=='Y' || c[0]=='1' || c[0]=='t' || c[0]=='T') {
00863          ret = 1 ;
00864       } else if (c[0]=='n' || c[0]=='N' || c[0]=='0' || c[0]=='f' || c[0]=='F') {
00865          ret = 0 ;
00866       } else {
00867          ret = notfound ;
00868       }
00869       return ret;
00870    }
00871 
00872 
00873    /*-------------------------------------------------------------------------*/
00874    /**
00875 @brief    Finds out if a given entry exists in a dictionary
00876 @param    ini     Dictionary to search
00877 @param    entry   Name of the entry to look for
00878 @return   integer 1 if entry exists, 0 otherwise
00879 
00880 Finds out if a given entry exists in the dictionary. Since sections
00881 are stored as keys with NULL associated values, this is the only way
00882 of querying for the presence of sections in a dictionary.
00883 */
00884    /*--------------------------------------------------------------------------*/
00885 
00886    int iniparser_find_entry(
00887    dictionary  *   ini,
00888    char        *   entry
00889    )
00890    {
00891       int found=0 ;
00892       if (iniparser_getstring(ini, entry, INI_INVALID_KEY)!=INI_INVALID_KEY) {
00893          found = 1 ;
00894       }
00895       return found ;
00896    }
00897 
00898 
00899 
00900    /*-------------------------------------------------------------------------*/
00901    /**
00902 @brief    Set an entry in a dictionary.
00903 @param    ini     Dictionary to modify.
00904 @param    entry   Entry to modify (entry name)
00905 @param    val     New value to associate to the entry.
00906 @return   int 0 if Ok, -1 otherwise.
00907 
00908 If the given entry can be found in the dictionary, it is modified to
00909 contain the provided value. If it cannot be found, -1 is returned.
00910 It is Ok to set val to NULL.
00911 */
00912    /*--------------------------------------------------------------------------*/
00913 
00914    int iniparser_setstr(dictionary * ini, char * entry, char * val)
00915    {
00916       dictionary_set(ini, strlwc(entry), val);
00917       return 0 ;
00918    }
00919 
00920    /*-------------------------------------------------------------------------*/
00921    /**
00922 @brief    Delete an entry in a dictionary
00923 @param    ini     Dictionary to modify
00924 @param    entry   Entry to delete (entry name)
00925 @return   void
00926 
00927 If the given entry can be found, it is deleted from the dictionary.
00928 */
00929    /*--------------------------------------------------------------------------*/
00930    void iniparser_unset(dictionary * ini, char * entry)
00931    {
00932       dictionary_unset(ini, strlwc(entry));
00933    }
00934 
00935 
00936    /*-------------------------------------------------------------------------*/
00937    /**
00938 @brief    Parse an ini file and return an allocated dictionary object
00939 @param    ininame Name of the ini file to read.
00940 @return   Pointer to newly allocated dictionary
00941 
00942 This is the parser for ini files. This function is called, providing
00943 the name of the file to be read. It returns a dictionary object that
00944 should not be accessed directly, but through accessor functions
00945 instead.
00946 
00947 The returned dictionary must be freed using iniparser_free().
00948 */
00949    /*--------------------------------------------------------------------------*/
00950 
00951    dictionary * iniparser_new(char *ininame)
00952    {
00953       dictionary  *   d ;
00954       char        lin[ASCIILINESZ+1];
00955       char        sec[ASCIILINESZ+1];
00956       char        key[ASCIILINESZ+1];
00957       char        val[ASCIILINESZ+1];
00958       char    *   where ;
00959       FILE    *   ini ;
00960       int         lineno ;
00961 
00962       if ((ini=fopen(ininame, "r"))==NULL) {
00963          return NULL ;
00964       }
00965 
00966       sec[0]=0;
00967 
00968       /*
00969    * Initialize a new dictionary entry
00970    */
00971       d = dictionary_new(0);
00972       lineno = 0 ;
00973       while (fgets(lin, ASCIILINESZ, ini)!=NULL) {
00974          lineno++ ;
00975          where = strskp(lin); /* Skip leading spaces */
00976          if (*where==';' || *where=='#' || *where==0)
00977          continue ; /* Comment lines */
00978          else {
00979             if (sscanf(where, "[%[^]]", sec)==1) {
00980                /* Valid section name */
00981                strcpy(sec, strlwc(sec));
00982                iniparser_add_entry(d, sec, NULL, NULL);
00983             } else if (sscanf (where, "%[^=] = \"%[^\"]\"", key, val) == 2
00984                   ||  sscanf (where, "%[^=] = '%[^\']'",   key, val) == 2
00985                   ||  sscanf (where, "%[^=] = %[^;#]",     key, val) == 2) {
00986                strcpy(key, strlwc(strcrop(key)));
00987                /*
00988             * sscanf cannot handle "" or '' as empty value,
00989             * this is done here
00990             */
00991                if (!strcmp(val, "\"\"") || !strcmp(val, "''")) {
00992                   val[0] = (char)0;
00993                } else {
00994                   strcpy(val, strcrop(val));
00995                }
00996                iniparser_add_entry(d, sec, key, val);
00997             }
00998          }
00999       }
01000       fclose(ini);
01001       return d ;
01002    }
01003 
01004 
01005 
01006    /*-------------------------------------------------------------------------*/
01007    /**
01008 @brief    Free all memory associated to an ini dictionary
01009 @param    d Dictionary to free
01010 @return   void
01011 
01012 Free all memory associated to an ini dictionary.
01013 It is mandatory to call this function before the dictionary object
01014 gets out of the current context.
01015 */
01016    /*--------------------------------------------------------------------------*/
01017 
01018    void iniparser_free(dictionary * d)
01019    {
01020       dictionary_del(d);
01021    }
01022 
01023 #ifdef __cplusplus
01024 }
01025 #endif

Generated on Wed May 23 08:00:57 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6