Postfix3.3.1
dict_ni.c
[詳解]
1 /*++
2 /* NAME
3 /* dict_ni 3
4 /* SUMMARY
5 /* dictionary manager interface to NetInfo
6 /* SYNOPSIS
7 /* #include <dict_ni.h>
8 /*
9 /* DICT *dict_ni_open(path, dummy, dict_flags)
10 /* char *path;
11 /* int dummy;
12 /* int dict_flags;
13 /* DESCRIPTION
14 /* dict_ni_open() `opens' the named NetInfo database. The result is
15 /* a pointer to a structure that can be used to access the dictionary
16 /* using the generic methods documented in dict_open(3).
17 /* DIAGNOSTICS
18 /* dict_ni_register() returns 0 in case of success, -1 in case
19 /* of problems.
20 /* Fatal errors: NetInfo errors, out of memory.
21 /* SEE ALSO
22 /* dict(3) generic dictionary manager
23 /* netinfo(3N) data base subroutines
24 /* AUTHOR(S)
25 /* Pieter Schoenmakers
26 /* Eindhoven University of Technology
27 /* P.O. Box 513
28 /* 5600 MB Eindhoven
29 /* The Netherlands
30 /*--*/
31 
32 #include "sys_defs.h"
33 
34 #ifdef HAS_NETINFO
35 
36 /* System library. */
37 
38 #include <stdio.h>
39 #include <netinfo/ni.h>
40 
41 /* Utility library. */
42 
43 #include "dict.h"
44 #include "dict_ni.h"
45 #include "msg.h"
46 #include "mymalloc.h"
47 #include "stringops.h"
48 
49 typedef struct {
50  DICT dict; /* my super */
51  char *path; /* directory path */
52 } DICT_NI;
53 
54  /*
55  * We'd like other possibilities, but that is not possible in the current
56  * dictionary setup... An example of a different setup: use `members' for
57  * multi-valued lookups (to be compatible with /aliases), and `value' for
58  * single-valued tables.
59  */
60 #define NETINFO_PROP_KEY "name"
61 #define NETINFO_PROP_VALUE "members"
62 #define NETINFO_VALUE_SEP ","
63 
64 #define NETINFO_MAX_DOMAIN_DEPTH 100
65 
66 /* Hard worker doing lookups. Returned value is statically allocated and
67  reused each call. */
68 static const char *dict_ni_do_lookup(char *path, char *key_prop,
69  const char *key_value, char *val_prop)
70 {
71  unsigned int result_cap = 0;
72  static char *result = 0;
73 
74  char *return_val = 0;
75  ni_namelist values;
76  int depth = 0;
77  void *domain;
78  void *next_domain;
79  char *query;
80  ni_status r;
81  ni_id dir;
82 
83  if (msg_verbose)
84  msg_info("ni_lookup %s %s=%s", path, key_prop, key_value);
85 
86  r = ni_open(NULL, ".", &domain);
87  if (r != NI_OK) {
88  msg_warn("ni_open `.': %d", r);
89  return NULL;
90  }
91  query = mymalloc(strlen(path) + strlen(key_prop) + 3 + strlen(key_value));
92  sprintf(query, "%s/%s=%s", path, key_prop, key_value);
93 
94  for (;;) {
95 
96  /*
97  * What does it _mean_ if we find the directory but not the value?
98  */
99  if (ni_pathsearch(domain, &dir, query) == NI_OK
100  && ni_lookupprop(domain, &dir, val_prop, &values) == NI_OK)
101  if (values.ni_namelist_len <= 0)
102  ni_namelist_free(&values);
103  else {
104  unsigned int i, l, n;
105 
106  for (i = l = 0; i < values.ni_namelist_len; i++)
107  l += 1 + strlen(values.ni_namelist_val[i]);
108  if (result_cap < l) {
109  if (result)
110  myfree(result);
111  result_cap = l + 100;
112  result = mymalloc(result_cap);
113  }
114  for (i = l = 0; i < values.ni_namelist_len; i++) {
115  n = strlen(values.ni_namelist_val[i]);
116  memcpy(result + l, values.ni_namelist_val[i], n);
117  l += n;
118  if (i < values.ni_namelist_len - 1)
119  result[l++] = ',';
120  }
121  result[l] = '\0';
122  return_val = result;
123  break;
124  }
125 
126  if (++depth >= NETINFO_MAX_DOMAIN_DEPTH) {
127  msg_warn("ni_open: domain depth limit");
128  break;
129  }
130  r = ni_open(domain, "..", &next_domain);
131  if (r != NI_OK) {
132  if (r != NI_FAILED)
133  msg_warn("ni_open `..': %d", r);
134  break;
135  }
136  ni_free(domain);
137  domain = next_domain;
138  }
139 
140  ni_free(domain);
141  myfree(query);
142 
143  return return_val;
144 }
145 
146 /* dict_ni_lookup - find table entry */
147 
148 static const char *dict_ni_lookup(DICT *dict, const char *key)
149 {
150  DICT_NI *d = (DICT_NI *) dict;
151 
152  dict->error = 0;
153 
154  /*
155  * Optionally fold the key.
156  */
157  if (dict->flags & DICT_FLAG_FOLD_FIX) {
158  if (dict->fold_buf == 0)
159  dict->fold_buf = vstring_alloc(10);
160  vstring_strcpy(dict->fold_buf, key);
161  key = lowercase(vstring_str(dict->fold_buf));
162  }
163  return dict_ni_do_lookup(d->dict.name, NETINFO_PROP_KEY,
164  key, NETINFO_PROP_VALUE);
165 }
166 
167 /* dict_ni_close - disassociate from NetInfo map */
168 
169 static void dict_ni_close(DICT *dict)
170 {
171  DICT_NI *d = (DICT_NI *) dict;
172 
173  if (dict->fold_buf)
174  vstring_free(dict->fold_buf);
175  dict_free(dict);
176 }
177 
178 /* dict_ni_open - create association with NetInfo map */
179 
180 DICT *dict_ni_open(const char *path, int unused_flags, int dict_flags)
181 {
182  DICT_NI *d = (void *) dict_alloc(DICT_TYPE_NETINFO, path, sizeof(*d));
183 
184  d->dict.lookup = dict_ni_lookup;
185  d->dict.close = dict_ni_close;
186  d->dict.flags = dict_flags | DICT_FLAG_FIXED;
187  if (dict_flags & DICT_FLAG_FOLD_FIX)
188  d->dict.fold_buf = vstring_alloc(10);
189  d->dict.owner.status = DICT_OWNER_TRUSTED;
190 
191  return (DICT_DEBUG (&d->dict));
192 }
193 
194 #endif
int msg_verbose
Definition: msg.c:177
void myfree(void *ptr)
Definition: mymalloc.c:207
#define vstring_str(vp)
Definition: vstring.h:71
#define DICT_FLAG_FIXED
Definition: dict.h:114
int flags
Definition: dict.h:81
DICT * dict_ni_open(const char *, int, int)
#define DICT_FLAG_FOLD_FIX
Definition: dict.h:124
VSTRING * vstring_strcpy(VSTRING *vp, const char *src)
Definition: vstring.c:431
Definition: dict.h:78
#define DICT_OWNER_TRUSTED
Definition: dict.h:46
void msg_warn(const char *fmt,...)
Definition: msg.c:215
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
int error
Definition: dict.h:94
char * lowercase(char *string)
Definition: lowercase.c:34
const char *(* lookup)(struct DICT *, const char *)
Definition: dict.h:82
void dict_free(DICT *)
Definition: dict_alloc.c:163
#define DICT_TYPE_NETINFO
Definition: dict_ni.h:22
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
DICT * dict_alloc(const char *, const char *, ssize_t)
Definition: dict_alloc.c:135
VSTRING * fold_buf
Definition: dict.h:92
void * mymalloc(ssize_t len)
Definition: mymalloc.c:150
void msg_info(const char *fmt,...)
Definition: msg.c:199