~ubuntu-branches/ubuntu/vivid/samba/vivid

« back to all changes in this revision

Viewing changes to lib/iniparser/src/iniparser.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*-------------------------------------------------------------------------*/
 
3
/**
 
4
   @file    iniparser.c
 
5
   @author  N. Devillard
 
6
   @date    Mar 2000
 
7
   @version $Revision: 2.17 $
 
8
   @brief   Parser for ini files.
 
9
*/
 
10
/*--------------------------------------------------------------------------*/
 
11
 
 
12
/*
 
13
    $Id: iniparser.c,v 2.17 2007-05-27 13:03:43 ndevilla Exp $
 
14
    $Author: ndevilla $
 
15
    $Date: 2007-05-27 13:03:43 $
 
16
    $Revision: 2.17 $
 
17
*/
 
18
 
 
19
/*---------------------------------------------------------------------------
 
20
                                Includes
 
21
 ---------------------------------------------------------------------------*/
 
22
 
 
23
#include "iniparser.h"
 
24
#include "strlib.h"
 
25
 
 
26
#define ASCIILINESZ         1024
 
27
#define INI_INVALID_KEY     ((char*)-1)
 
28
 
 
29
/*---------------------------------------------------------------------------
 
30
                        Private to this module
 
31
 ---------------------------------------------------------------------------*/
 
32
 
 
33
/* Private: add an entry to the dictionary */
 
34
static void iniparser_add_entry(
 
35
    dictionary * d,
 
36
    char * sec,
 
37
    char * key,
 
38
    char * val)
 
39
{
 
40
    char longkey[2*ASCIILINESZ+1];
 
41
 
 
42
    /* Make a key as section:keyword */
 
43
    if (key!=NULL) {
 
44
        sprintf(longkey, "%s:%s", sec, key);
 
45
    } else {
 
46
        strcpy(longkey, sec);
 
47
    }
 
48
 
 
49
    /* Add (key,val) to dictionary */
 
50
    dictionary_set(d, longkey, val);
 
51
    return ;
 
52
}
 
53
 
 
54
 
 
55
/*-------------------------------------------------------------------------*/
 
56
/**
 
57
  @brief    Get number of sections in a dictionary
 
58
  @param    d   Dictionary to examine
 
59
  @return   int Number of sections found in dictionary
 
60
 
 
61
  This function returns the number of sections found in a dictionary.
 
62
  The test to recognize sections is done on the string stored in the
 
63
  dictionary: a section name is given as "section" whereas a key is
 
64
  stored as "section:key", thus the test looks for entries that do not
 
65
  contain a colon.
 
66
 
 
67
  This clearly fails in the case a section name contains a colon, but
 
68
  this should simply be avoided.
 
69
 
 
70
  This function returns -1 in case of error.
 
71
 */
 
72
/*--------------------------------------------------------------------------*/
 
73
 
 
74
int iniparser_getnsec(dictionary * d)
 
75
{
 
76
    int i ;
 
77
    int nsec ;
 
78
 
 
79
    if (d==NULL) return -1 ;
 
80
    nsec=0 ;
 
81
    for (i=0 ; i<d->size ; i++) {
 
82
        if (d->key[i]==NULL)
 
83
            continue ;
 
84
        if (strchr(d->key[i], ':')==NULL) {
 
85
            nsec ++ ;
 
86
        }
 
87
    }
 
88
    return nsec ;
 
89
}
 
90
 
 
91
 
 
92
/*-------------------------------------------------------------------------*/
 
93
/**
 
94
  @brief    Get name for section n in a dictionary.
 
95
  @param    d   Dictionary to examine
 
96
  @param    n   Section number (from 0 to nsec-1).
 
97
  @return   Pointer to char string
 
98
 
 
99
  This function locates the n-th section in a dictionary and returns
 
100
  its name as a pointer to a string statically allocated inside the
 
101
  dictionary. Do not free or modify the returned string!
 
102
 
 
103
  This function returns NULL in case of error.
 
104
 */
 
105
/*--------------------------------------------------------------------------*/
 
106
 
 
107
char * iniparser_getsecname(dictionary * d, int n)
 
108
{
 
109
    int i ;
 
110
    int foundsec ;
 
111
 
 
112
    if (d==NULL || n<0) return NULL ;
 
113
    foundsec=0 ;
 
114
    for (i=0 ; i<d->size ; i++) {
 
115
        if (d->key[i]==NULL)
 
116
            continue ;
 
117
        if (strchr(d->key[i], ':')==NULL) {
 
118
            foundsec++ ;
 
119
            if (foundsec>n)
 
120
                break ;
 
121
        }
 
122
    }
 
123
    if (foundsec<=n) {
 
124
        return NULL ;
 
125
    }
 
126
    return d->key[i] ;
 
127
}
 
128
 
 
129
 
 
130
/*-------------------------------------------------------------------------*/
 
131
/**
 
132
  @brief    Dump a dictionary to an opened file pointer.
 
133
  @param    d   Dictionary to dump.
 
134
  @param    f   Opened file pointer to dump to.
 
135
  @return   void
 
136
 
 
137
  This function prints out the contents of a dictionary, one element by
 
138
  line, onto the provided file pointer. It is OK to specify @c stderr
 
139
  or @c stdout as output files. This function is meant for debugging
 
140
  purposes mostly.
 
141
 */
 
142
/*--------------------------------------------------------------------------*/
 
143
void iniparser_dump(dictionary * d, FILE * f)
 
144
{
 
145
    int     i ;
 
146
 
 
147
    if (d==NULL || f==NULL) return ;
 
148
    for (i=0 ; i<d->size ; i++) {
 
149
        if (d->key[i]==NULL)
 
150
            continue ;
 
151
        if (d->val[i]!=NULL) {
 
152
            fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]);
 
153
        } else {
 
154
            fprintf(f, "[%s]=UNDEF\n", d->key[i]);
 
155
        }
 
156
    }
 
157
    return ;
 
158
}
 
159
 
 
160
/*-------------------------------------------------------------------------*/
 
161
/**
 
162
  @brief    Save a dictionary to a loadable ini file
 
163
  @param    d   Dictionary to dump
 
164
  @param    f   Opened file pointer to dump to
 
165
  @return   void
 
166
 
 
167
  This function dumps a given dictionary into a loadable ini file.
 
168
  It is Ok to specify @c stderr or @c stdout as output files.
 
169
 */
 
170
/*--------------------------------------------------------------------------*/
 
171
 
 
172
void iniparser_dump_ini(dictionary * d, FILE * f)
 
173
{
 
174
    int     i, j ;
 
175
    char    keym[ASCIILINESZ+1];
 
176
    int     nsec ;
 
177
    char *  secname ;
 
178
    int     seclen ;
 
179
 
 
180
    if (d==NULL || f==NULL) return ;
 
181
 
 
182
    nsec = iniparser_getnsec(d);
 
183
    if (nsec<1) {
 
184
        /* No section in file: dump all keys as they are */
 
185
        for (i=0 ; i<d->size ; i++) {
 
186
            if (d->key[i]==NULL)
 
187
                continue ;
 
188
            fprintf(f, "%s = %s\n", d->key[i], d->val[i]);
 
189
        }
 
190
        return ;
 
191
    }
 
192
    for (i=0 ; i<nsec ; i++) {
 
193
        secname = iniparser_getsecname(d, i) ;
 
194
        seclen  = (int)strlen(secname);
 
195
        fprintf(f, "\n[%s]\n", secname);
 
196
        sprintf(keym, "%s:", secname);
 
197
        for (j=0 ; j<d->size ; j++) {
 
198
            if (d->key[j]==NULL)
 
199
                continue ;
 
200
            if (!strncmp(d->key[j], keym, seclen+1)) {
 
201
                fprintf(f,
 
202
                        "%-30s = %s\n",
 
203
                        d->key[j]+seclen+1,
 
204
                        d->val[j] ? d->val[j] : "");
 
205
            }
 
206
        }
 
207
    }
 
208
    fprintf(f, "\n");
 
209
    return ;
 
210
}
 
211
 
 
212
 
 
213
 
 
214
 
 
215
/*-------------------------------------------------------------------------*/
 
216
/**
 
217
  @brief        Get the string associated to a key, return NULL if not found
 
218
  @param    d   Dictionary to search
 
219
  @param    key Key string to look for
 
220
  @return   pointer to statically allocated character string, or NULL.
 
221
 
 
222
  This function queries a dictionary for a key. A key as read from an
 
223
  ini file is given as "section:key". If the key cannot be found,
 
224
  NULL is returned.
 
225
  The returned char pointer is pointing to a string allocated in
 
226
  the dictionary, do not free or modify it.
 
227
 
 
228
  This function is only provided for backwards compatibility with 
 
229
  previous versions of iniparser. It is recommended to use
 
230
  iniparser_getstring() instead.
 
231
 */
 
232
/*--------------------------------------------------------------------------*/
 
233
char * iniparser_getstr(dictionary * d, const char * key)
 
234
{
 
235
    return iniparser_getstring(d, key, NULL);
 
236
}
 
237
 
 
238
 
 
239
/*-------------------------------------------------------------------------*/
 
240
/**
 
241
  @brief    Get the string associated to a key
 
242
  @param    d       Dictionary to search
 
243
  @param    key     Key string to look for
 
244
  @param    def     Default value to return if key not found.
 
245
  @return   pointer to statically allocated character string
 
246
 
 
247
  This function queries a dictionary for a key. A key as read from an
 
248
  ini file is given as "section:key". If the key cannot be found,
 
249
  the pointer passed as 'def' is returned.
 
250
  The returned char pointer is pointing to a string allocated in
 
251
  the dictionary, do not free or modify it.
 
252
 */
 
253
/*--------------------------------------------------------------------------*/
 
254
char * iniparser_getstring(dictionary * d, const char * key, char * def)
 
255
{
 
256
    char * lc_key ;
 
257
    char * sval ;
 
258
 
 
259
    if (d==NULL || key==NULL)
 
260
        return def ;
 
261
 
 
262
    if (!(lc_key = strdup(strlwc(key)))) {
 
263
            return NULL;
 
264
    }
 
265
    sval = dictionary_get(d, lc_key, def);
 
266
    free(lc_key);
 
267
    return sval ;
 
268
}
 
269
 
 
270
 
 
271
 
 
272
/*-------------------------------------------------------------------------*/
 
273
/**
 
274
  @brief    Get the string associated to a key, convert to an int
 
275
  @param    d Dictionary to search
 
276
  @param    key Key string to look for
 
277
  @param    notfound Value to return in case of error
 
278
  @return   integer
 
279
 
 
280
  This function queries a dictionary for a key. A key as read from an
 
281
  ini file is given as "section:key". If the key cannot be found,
 
282
  the notfound value is returned.
 
283
 
 
284
  Supported values for integers include the usual C notation
 
285
  so decimal, octal (starting with 0) and hexadecimal (starting with 0x)
 
286
  are supported. Examples:
 
287
 
 
288
  "42"      ->  42
 
289
  "042"     ->  34 (octal -> decimal)
 
290
  "0x42"    ->  66 (hexa  -> decimal)
 
291
 
 
292
  Warning: the conversion may overflow in various ways. Conversion is
 
293
  totally outsourced to strtol(), see the associated man page for overflow
 
294
  handling.
 
295
 
 
296
  Credits: Thanks to A. Becker for suggesting strtol()
 
297
 */
 
298
/*--------------------------------------------------------------------------*/
 
299
int iniparser_getint(dictionary * d, const char * key, int notfound)
 
300
{
 
301
    char    *   str ;
 
302
 
 
303
    str = iniparser_getstring(d, key, INI_INVALID_KEY);
 
304
    if (str==INI_INVALID_KEY) return notfound ;
 
305
    return (int)strtol(str, NULL, 0);
 
306
}
 
307
 
 
308
 
 
309
/*-------------------------------------------------------------------------*/
 
310
/**
 
311
  @brief    Get the string associated to a key, convert to a double
 
312
  @param    d Dictionary to search
 
313
  @param    key Key string to look for
 
314
  @param    notfound Value to return in case of error
 
315
  @return   double
 
316
 
 
317
  This function queries a dictionary for a key. A key as read from an
 
318
  ini file is given as "section:key". If the key cannot be found,
 
319
  the notfound value is returned.
 
320
 */
 
321
/*--------------------------------------------------------------------------*/
 
322
double iniparser_getdouble(dictionary * d, char * key, double notfound)
 
323
{
 
324
    char    *   str ;
 
325
 
 
326
    str = iniparser_getstring(d, key, INI_INVALID_KEY);
 
327
    if (str==INI_INVALID_KEY) return notfound ;
 
328
    return atof(str);
 
329
}
 
330
 
 
331
 
 
332
 
 
333
/*-------------------------------------------------------------------------*/
 
334
/**
 
335
  @brief    Get the string associated to a key, convert to a boolean
 
336
  @param    d Dictionary to search
 
337
  @param    key Key string to look for
 
338
  @param    notfound Value to return in case of error
 
339
  @return   integer
 
340
 
 
341
  This function queries a dictionary for a key. A key as read from an
 
342
  ini file is given as "section:key". If the key cannot be found,
 
343
  the notfound value is returned.
 
344
 
 
345
  A true boolean is found if one of the following is matched:
 
346
 
 
347
  - A string starting with 'y'
 
348
  - A string starting with 'Y'
 
349
  - A string starting with 't'
 
350
  - A string starting with 'T'
 
351
  - A string starting with '1'
 
352
 
 
353
  A false boolean is found if one of the following is matched:
 
354
 
 
355
  - A string starting with 'n'
 
356
  - A string starting with 'N'
 
357
  - A string starting with 'f'
 
358
  - A string starting with 'F'
 
359
  - A string starting with '0'
 
360
 
 
361
  The notfound value returned if no boolean is identified, does not
 
362
  necessarily have to be 0 or 1.
 
363
 */
 
364
/*--------------------------------------------------------------------------*/
 
365
int iniparser_getboolean(dictionary * d, const char * key, int notfound)
 
366
{
 
367
    char    *   c ;
 
368
    int         ret ;
 
369
 
 
370
    c = iniparser_getstring(d, key, INI_INVALID_KEY);
 
371
    if (c==INI_INVALID_KEY) return notfound ;
 
372
    if (c[0]=='y' || c[0]=='Y' || c[0]=='1' || c[0]=='t' || c[0]=='T') {
 
373
        ret = 1 ;
 
374
    } else if (c[0]=='n' || c[0]=='N' || c[0]=='0' || c[0]=='f' || c[0]=='F') {
 
375
        ret = 0 ;
 
376
    } else {
 
377
        ret = notfound ;
 
378
    }
 
379
    return ret;
 
380
}
 
381
 
 
382
 
 
383
/*-------------------------------------------------------------------------*/
 
384
/**
 
385
  @brief    Finds out if a given entry exists in a dictionary
 
386
  @param    ini     Dictionary to search
 
387
  @param    entry   Name of the entry to look for
 
388
  @return   integer 1 if entry exists, 0 otherwise
 
389
 
 
390
  Finds out if a given entry exists in the dictionary. Since sections
 
391
  are stored as keys with NULL associated values, this is the only way
 
392
  of querying for the presence of sections in a dictionary.
 
393
 */
 
394
/*--------------------------------------------------------------------------*/
 
395
 
 
396
int iniparser_find_entry(
 
397
    dictionary  *   ini,
 
398
    char        *   entry
 
399
)
 
400
{
 
401
    int found=0 ;
 
402
    if (iniparser_getstring(ini, entry, INI_INVALID_KEY)!=INI_INVALID_KEY) {
 
403
        found = 1 ;
 
404
    }
 
405
    return found ;
 
406
}
 
407
 
 
408
 
 
409
 
 
410
/*-------------------------------------------------------------------------*/
 
411
/**
 
412
  @brief    Set an entry in a dictionary.
 
413
  @param    ini     Dictionary to modify.
 
414
  @param    entry   Entry to modify (entry name)
 
415
  @param    val     New value to associate to the entry.
 
416
  @return   int 0 if Ok, -1 otherwise.
 
417
 
 
418
  If the given entry can be found in the dictionary, it is modified to
 
419
  contain the provided value. If it cannot be found, -1 is returned.
 
420
  It is Ok to set val to NULL.
 
421
 */
 
422
/*--------------------------------------------------------------------------*/
 
423
 
 
424
int iniparser_setstr(dictionary * ini, char * entry, char * val)
 
425
{
 
426
    dictionary_set(ini, strlwc(entry), val);
 
427
    return 0 ;
 
428
}
 
429
 
 
430
/*-------------------------------------------------------------------------*/
 
431
/**
 
432
  @brief    Delete an entry in a dictionary
 
433
  @param    ini     Dictionary to modify
 
434
  @param    entry   Entry to delete (entry name)
 
435
  @return   void
 
436
 
 
437
  If the given entry can be found, it is deleted from the dictionary.
 
438
 */
 
439
/*--------------------------------------------------------------------------*/
 
440
void iniparser_unset(dictionary * ini, char * entry)
 
441
{
 
442
    dictionary_unset(ini, strlwc(entry));
 
443
}
 
444
 
 
445
 
 
446
/*-------------------------------------------------------------------------*/
 
447
/**
 
448
  @brief    Parse an ini file and return an allocated dictionary object
 
449
  @param    ininame Name of the ini file to read.
 
450
  @return   Pointer to newly allocated dictionary
 
451
 
 
452
  This is the parser for ini files. This function is called, providing
 
453
  the name of the file to be read. It returns a dictionary object that
 
454
  should not be accessed directly, but through accessor functions
 
455
  instead.
 
456
 
 
457
  The returned dictionary must be freed using iniparser_freedict().
 
458
 */
 
459
/*--------------------------------------------------------------------------*/
 
460
 
 
461
dictionary * iniparser_load(const char * ininame)
 
462
{
 
463
    dictionary  *   d ;
 
464
    char        lin[ASCIILINESZ+1];
 
465
    char        sec[ASCIILINESZ+1];
 
466
    char        key[ASCIILINESZ+1];
 
467
    char        val[ASCIILINESZ+1];
 
468
    char    *   where ;
 
469
    FILE    *   ini ;
 
470
    int         lineno ;
 
471
 
 
472
    if ((ini=fopen(ininame, "r"))==NULL) {
 
473
        return NULL ;
 
474
    }
 
475
 
 
476
    sec[0]=0;
 
477
 
 
478
    /*
 
479
     * Initialize a new dictionary entry
 
480
     */
 
481
    if (!(d = dictionary_new(0))) {
 
482
            fclose(ini);
 
483
            return NULL;
 
484
    }
 
485
    lineno = 0 ;
 
486
    while (fgets(lin, ASCIILINESZ, ini)!=NULL) {
 
487
        lineno++ ;
 
488
        where = strskp(lin); /* Skip leading spaces */
 
489
        if (*where==';' || *where=='#' || *where==0)
 
490
            continue ; /* Comment lines */
 
491
        else {
 
492
            if (sscanf(where, "[%[^]]", sec)==1) {
 
493
                /* Valid section name */
 
494
                strcpy(sec, strlwc(sec));
 
495
                iniparser_add_entry(d, sec, NULL, NULL);
 
496
            } else if (sscanf (where, "%[^=] = \"%[^\"]\"", key, val) == 2
 
497
                   ||  sscanf (where, "%[^=] = '%[^\']'",   key, val) == 2
 
498
                   ||  sscanf (where, "%[^=] = %[^;#]",     key, val) == 2) {
 
499
                strcpy(key, strlwc(strcrop(key)));
 
500
                /*
 
501
                 * sscanf cannot handle "" or '' as empty value,
 
502
                 * this is done here
 
503
                 */
 
504
                if (!strcmp(val, "\"\"") || !strcmp(val, "''")) {
 
505
                    val[0] = (char)0;
 
506
                } else {
 
507
                    strcpy(val, strcrop(val));
 
508
                }
 
509
                iniparser_add_entry(d, sec, key, val);
 
510
            }
 
511
        }
 
512
    }
 
513
    fclose(ini);
 
514
    return d ;
 
515
}
 
516
 
 
517
 
 
518
 
 
519
/*-------------------------------------------------------------------------*/
 
520
/**
 
521
  @brief    Free all memory associated to an ini dictionary
 
522
  @param    d Dictionary to free
 
523
  @return   void
 
524
 
 
525
  Free all memory associated to an ini dictionary.
 
526
  It is mandatory to call this function before the dictionary object
 
527
  gets out of the current context.
 
528
 */
 
529
/*--------------------------------------------------------------------------*/
 
530
 
 
531
void iniparser_freedict(dictionary * d)
 
532
{
 
533
    dictionary_del(d);
 
534
}
 
535
 
 
536
/* vim: set ts=4 et sw=4 tw=75 */