~ubuntu-branches/ubuntu/vivid/postfix/vivid-proposed

« back to all changes in this revision

Viewing changes to src/util/dict_open.c

  • Committer: Package Import Robot
  • Author(s): LaMont Jones
  • Date: 2012-03-20 13:47:16 UTC
  • mfrom: (1.1.33)
  • mto: This revision was merged to the branch mainline in revision 44.
  • Revision ID: package-import@ubuntu.com-20120320134716-v7ab94fmor2z9pvp
Tags: upstream-2.9.1
ImportĀ upstreamĀ versionĀ 2.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
/*      int     open_flags;
18
18
/*      int     dict_flags;
19
19
/*
20
 
/*      void    dict_put(dict, key, value)
 
20
/*      int     dict_put(dict, key, value)
21
21
/*      DICT    *dict;
22
22
/*      const char *key;
23
23
/*      const char *value;
30
30
/*      DICT    *dict;
31
31
/*      const char *key;
32
32
/*
33
 
/*      void    dict_seq(dict, func, key, value)
 
33
/*      int     dict_seq(dict, func, key, value)
34
34
/*      DICT    *dict;
35
35
/*      int     func;
36
36
/*      const char **key;
99
99
/*      With file-based maps, flush I/O buffers to file after each update.
100
100
/*      Thus feature is not supported with some file-based dictionaries.
101
101
/* .IP DICT_FLAG_NO_REGSUB
102
 
/*      Disallow regular expression substitution from left-hand side data
 
102
/*      Disallow regular expression substitution from left-hand side data
103
103
/*      into the right-hand side.
104
104
/* .IP DICT_FLAG_NO_PROXY
105
105
/*      Disallow access through the \fBproxymap\fR service.
148
148
/*      or if the result is to survive multiple table lookups.
149
149
/*
150
150
/*      dict_put() stores the specified key and value into the named
151
 
/*      dictionary.
 
151
/*      dictionary. A zero (DICT_STAT_SUCCESS) result means the
 
152
/*      update was made.
152
153
/*
153
 
/*      dict_del() removes a dictionary entry, and returns zero
154
 
/*      in case of success.
 
154
/*      dict_del() removes a dictionary entry, and returns
 
155
/*      DICT_STAT_SUCCESS in case of success.
155
156
/*
156
157
/*      dict_seq() iterates over all members in the named dictionary.
157
158
/*      func is define DICT_SEQ_FUN_FIRST (select first member) or
158
 
/*      DICT_SEQ_FUN_NEXT (select next member). A zero result means
159
 
/*      that an entry was found.
 
159
/*      DICT_SEQ_FUN_NEXT (select next member). A zero (DICT_STAT_SUCCESS)
 
160
/*      result means that an entry was found.
160
161
/*
161
162
/*      dict_close() closes the specified dictionary and cleans up the
162
163
/*      associated data structures.
168
169
/* DIAGNOSTICS
169
170
/*      Fatal error: open error, unsupported dictionary type, attempt to
170
171
/*      update non-writable dictionary.
 
172
/*
 
173
/*      The lookup routine returns non-null when the request is
 
174
/*      satisfied. The update, delete and sequence routines return
 
175
/*      zero (DICT_STAT_SUCCESS) when the request is satisfied.
 
176
/*      The dict->errno value is non-zero only when the last operation
 
177
/*      was not satisfied due to a dictionary access error. This
 
178
/*      can have the following values:
 
179
/* .IP DICT_ERR_NONE(zero)
 
180
/*      There was no dictionary access error. For example, the
 
181
/*      request was satisfied, the requested information did not
 
182
/*      exist in the dictionary, or the information already existed
 
183
/*      when it should not exist (collision).
 
184
/* .IP DICT_ERR_RETRY(<0)
 
185
/*      The dictionary was temporarily unavailable. This can happen
 
186
/*      with network-based services.
 
187
/* .IP DICT_ERR_CONFIG(<0)
 
188
/*      The dictionary was unavailable due to a configuration error.
 
189
/* .PP
 
190
/*      Generally, a program is expected to test the function result
 
191
/*      value for "success" first. If the operation was not successful,
 
192
/*      a program is expected to test for a non-zero dict->error
 
193
/*      status to distinguish between a data notfound/collision
 
194
/*      condition or a dictionary access error.
171
195
/* LICENSE
172
196
/* .ad
173
197
/* .fi
211
235
#include <dict_cidr.h>
212
236
#include <dict_ht.h>
213
237
#include <dict_thash.h>
 
238
#include <dict_fail.h>
214
239
#include <stringops.h>
215
240
#include <split_at.h>
216
241
#include <htable.h>
260
285
    DICT_TYPE_STATIC, dict_static_open,
261
286
    DICT_TYPE_CIDR, dict_cidr_open,
262
287
    DICT_TYPE_THASH, dict_thash_open,
 
288
    DICT_TYPE_FAIL, dict_fail_open,
263
289
    0,
264
290
};
265
291
 
313
339
    if (dict_open_hash == 0)
314
340
        dict_open_init();
315
341
    if ((dp = (DICT_OPEN_INFO *) htable_find(dict_open_hash, dict_type)) == 0)
316
 
        msg_fatal("unsupported dictionary type: %s", dict_type);
 
342
        return (dict_surrogate(dict_type, dict_name, open_flags, dict_flags,
 
343
                             "unsupported dictionary type: %s", dict_type));
317
344
    if ((dict = dp->open(dict_name, open_flags, dict_flags)) == 0)
318
 
        msg_fatal("opening %s:%s %m", dict_type, dict_name);
 
345
        return (dict_surrogate(dict_type, dict_name, open_flags, dict_flags,
 
346
                            "cannot open %s:%s: %m", dict_type, dict_name));
319
347
    if (msg_verbose)
320
348
        msg_info("%s: %s:%s", myname, dict_type, dict_name);
321
349
    /* XXX the choice between wait-for-lock or no-wait is hard-coded. */
382
410
#ifdef TEST
383
411
 
384
412
 /*
385
 
  * Proof-of-concept test program. Create, update or read a database. When
386
 
  * the input is a name=value pair, the database is updated, otherwise the
387
 
  * program assumes that the input specifies a lookup key and prints the
388
 
  * corresponding value.
 
413
  * Proof-of-concept test program.
389
414
  */
390
 
 
391
 
/* System library. */
392
 
 
393
 
#include <stdlib.h>
394
 
#include <fcntl.h>
395
 
#include <unistd.h>
396
 
#include <signal.h>
397
 
 
398
 
/* Utility library. */
399
 
 
400
 
#include "vstring.h"
401
 
#include "vstream.h"
402
 
#include "msg_vstream.h"
403
 
#include "vstring_vstream.h"
404
 
 
405
 
static NORETURN usage(char *myname)
406
 
{
407
 
    msg_fatal("usage: %s type:file read|write|create [fold] [sync]", myname);
408
 
}
409
 
 
410
415
int     main(int argc, char **argv)
411
416
{
412
 
    VSTRING *keybuf = vstring_alloc(1);
413
 
    VSTRING *inbuf = vstring_alloc(1);
414
 
    DICT   *dict;
415
 
    char   *dict_name;
416
 
    int     open_flags;
417
 
    char   *bufp;
418
 
    char   *cmd;
419
 
    const char *key;
420
 
    const char *value;
421
 
    int     ch;
422
 
    int     dict_flags = DICT_FLAG_LOCK | DICT_FLAG_DUP_REPLACE;
423
 
    int     n;
424
 
 
425
 
    signal(SIGPIPE, SIG_IGN);
426
 
 
427
 
    msg_vstream_init(argv[0], VSTREAM_ERR);
428
 
    while ((ch = GETOPT(argc, argv, "v")) > 0) {
429
 
        switch (ch) {
430
 
        default:
431
 
            usage(argv[0]);
432
 
        case 'v':
433
 
            msg_verbose++;
434
 
            break;
435
 
        }
436
 
    }
437
 
    optind = OPTIND;
438
 
    if (argc - optind < 2)
439
 
        usage(argv[0]);
440
 
    if (strcasecmp(argv[optind + 1], "create") == 0)
441
 
        open_flags = O_CREAT | O_RDWR | O_TRUNC;
442
 
    else if (strcasecmp(argv[optind + 1], "write") == 0)
443
 
        open_flags = O_RDWR;
444
 
    else if (strcasecmp(argv[optind + 1], "read") == 0)
445
 
        open_flags = O_RDONLY;
446
 
    else
447
 
        msg_fatal("unknown access mode: %s", argv[2]);
448
 
    for (n = 2; argv[optind + n]; n++) {
449
 
        if (strcasecmp(argv[optind + 2], "fold") == 0)
450
 
            dict_flags |= DICT_FLAG_FOLD_ANY;
451
 
        else if (strcasecmp(argv[optind + 2], "sync") == 0)
452
 
            dict_flags |= DICT_FLAG_SYNC_UPDATE;
453
 
        else
454
 
            usage(argv[0]);
455
 
    }
456
 
    dict_name = argv[optind];
457
 
    dict = dict_open(dict_name, open_flags, dict_flags);
458
 
    dict_register(dict_name, dict);
459
 
    while (vstring_fgets_nonl(inbuf, VSTREAM_IN)) {
460
 
        bufp = vstring_str(inbuf);
461
 
        if (!isatty(0)) {
462
 
            vstream_printf("> %s\n", bufp);
463
 
            vstream_fflush(VSTREAM_OUT);
464
 
        }
465
 
        if (*bufp == '#')
466
 
            continue;
467
 
        if ((cmd = mystrtok(&bufp, " ")) == 0) {
468
 
            vstream_printf("usage: del key|get key|put key=value|first|next\n");
469
 
            vstream_fflush(VSTREAM_OUT);
470
 
            continue;
471
 
        }
472
 
        if (dict_changed_name())
473
 
            msg_warn("dictionary has changed");
474
 
        key = *bufp ? vstring_str(unescape(keybuf, mystrtok(&bufp, " ="))) : 0;
475
 
        value = mystrtok(&bufp, " =");
476
 
        if (strcmp(cmd, "del") == 0 && key && !value) {
477
 
            if (dict_del(dict, key))
478
 
                vstream_printf("%s: not found\n", key);
479
 
            else
480
 
                vstream_printf("%s: deleted\n", key);
481
 
        } else if (strcmp(cmd, "get") == 0 && key && !value) {
482
 
            if ((value = dict_get(dict, key)) == 0) {
483
 
                vstream_printf("%s: %s\n", key,
484
 
                               dict_errno == DICT_ERR_RETRY ?
485
 
                               "soft error" : "not found");
486
 
            } else {
487
 
                vstream_printf("%s=%s\n", key, value);
488
 
            }
489
 
        } else if (strcmp(cmd, "put") == 0 && key && value) {
490
 
            dict_put(dict, key, value);
491
 
            vstream_printf("%s=%s\n", key, value);
492
 
        } else if (strcmp(cmd, "first") == 0 && !key && !value) {
493
 
            if (dict_seq(dict, DICT_SEQ_FUN_FIRST, &key, &value) == 0)
494
 
                vstream_printf("%s=%s\n", key, value);
495
 
            else
496
 
                vstream_printf("%s\n",
497
 
                               dict_errno == DICT_ERR_RETRY ?
498
 
                               "soft error" : "not found");
499
 
        } else if (strcmp(cmd, "next") == 0 && !key && !value) {
500
 
            if (dict_seq(dict, DICT_SEQ_FUN_NEXT, &key, &value) == 0)
501
 
                vstream_printf("%s=%s\n", key, value);
502
 
            else
503
 
                vstream_printf("%s\n",
504
 
                               dict_errno == DICT_ERR_RETRY ?
505
 
                               "soft error" : "not found");
506
 
        } else {
507
 
            vstream_printf("usage: del key|get key|put key=value|first|next\n");
508
 
        }
509
 
        vstream_fflush(VSTREAM_OUT);
510
 
    }
511
 
    vstring_free(keybuf);
512
 
    vstring_free(inbuf);
513
 
    dict_close(dict);
 
417
    dict_test(argc, argv);
514
418
    return (0);
515
419
}
516
420