279
279
key_buffer = vstring_alloc(100);
280
280
value_buffer = vstring_alloc(100);
281
281
if ((open_flags & O_TRUNC) == 0) {
282
/* Incremental mode. */
282
283
source_fp = VSTREAM_IN;
283
284
vstream_control(source_fp, VSTREAM_CTL_PATH, "stdin", VSTREAM_CTL_END);
284
} else if (strcmp(map_type, DICT_TYPE_PROXY) == 0) {
285
msg_fatal("can't create maps via the proxy service");
286
} else if ((source_fp = vstream_fopen(path_name, O_RDONLY, 0)) == 0) {
287
msg_fatal("open %s: %m", path_name);
286
/* Create database. */
287
if (strcmp(map_type, DICT_TYPE_PROXY) == 0)
288
msg_fatal("can't create maps via the proxy service");
289
dict_flags |= DICT_FLAG_BULK_UPDATE;
290
if ((source_fp = vstream_fopen(path_name, O_RDONLY, 0)) == 0)
291
msg_fatal("open %s: %m", path_name);
289
293
if (fstat(vstream_fileno(source_fp), &st) < 0)
290
294
msg_fatal("fstat %s: %m", path_name);
318
322
umask(saved_mask);
321
* Add records to the database.
325
* Trap "exceptions" so that we can restart a bulk-mode update after a
324
while (readlline(line_buffer, source_fp, &lineno)) {
327
* Tokenize the input, so that we do the right thing when a quoted
328
* localpart contains special characters such as "@", ":" and so on.
330
if ((tok_list = tok822_scan(STR(line_buffer), (TOK822 **) 0)) == 0)
334
* Enforce the key:value format. Disallow missing keys, multi-address
335
* keys, or missing values. In order to specify an empty string or
336
* value, enclose it in double quotes.
338
if ((colon = tok822_find_type(tok_list, ':')) == 0
339
|| colon->prev == 0 || colon->next == 0
340
|| tok822_rfind_type(colon, ',')) {
341
msg_warn("%s, line %d: need name:value pair",
342
VSTREAM_PATH(source_fp), lineno);
343
tok822_free_tree(tok_list);
348
* Key must be local. XXX We should use the Postfix rewriting and
349
* resolving services to handle all address forms correctly. However,
350
* we can't count on the mail system being up when the alias database
351
* is being built, so we're guessing a bit.
353
if (tok822_rfind_type(colon, '@') || tok822_rfind_type(colon, '%')) {
354
msg_warn("%s, line %d: name must be local",
355
VSTREAM_PATH(source_fp), lineno);
356
tok822_free_tree(tok_list);
361
* Split the input into key and value parts, and convert from token
362
* representation back to string representation. Convert the key to
363
* internal (unquoted) form, because the resolver produces addresses
364
* in internal form. Convert the value to external (quoted) form,
365
* because it will have to be re-parsed upon lookup. Discard the
366
* token representation when done.
370
value_list = tok822_cut_after(colon);
371
tok822_unlink(colon);
374
tok822_internalize(key_buffer, key_list, TOK822_STR_DEFL);
375
tok822_free_tree(key_list);
377
tok822_externalize(value_buffer, value_list, TOK822_STR_DEFL);
378
tok822_free_tree(value_list);
381
* Store the value under a case-insensitive key.
383
mkmap_append(mkmap, STR(key_buffer), STR(value_buffer));
384
if (mkmap->dict->error)
385
msg_fatal("table %s:%s: write error: %m",
386
mkmap->dict->type, mkmap->dict->name);
329
if (dict_isjmp(mkmap->dict) != 0
330
&& dict_setjmp(mkmap->dict) != 0
331
&& vstream_fseek(source_fp, SEEK_SET, 0) < 0)
332
msg_fatal("seek %s: %m", VSTREAM_PATH(source_fp));
335
* Add records to the database.
338
while (readlline(line_buffer, source_fp, &lineno)) {
341
* Tokenize the input, so that we do the right thing when a
342
* quoted localpart contains special characters such as "@", ":"
345
if ((tok_list = tok822_scan(STR(line_buffer), (TOK822 **) 0)) == 0)
349
* Enforce the key:value format. Disallow missing keys,
350
* multi-address keys, or missing values. In order to specify an
351
* empty string or value, enclose it in double quotes.
353
if ((colon = tok822_find_type(tok_list, ':')) == 0
354
|| colon->prev == 0 || colon->next == 0
355
|| tok822_rfind_type(colon, ',')) {
356
msg_warn("%s, line %d: need name:value pair",
357
VSTREAM_PATH(source_fp), lineno);
358
tok822_free_tree(tok_list);
363
* Key must be local. XXX We should use the Postfix rewriting and
364
* resolving services to handle all address forms correctly.
365
* However, we can't count on the mail system being up when the
366
* alias database is being built, so we're guessing a bit.
368
if (tok822_rfind_type(colon, '@') || tok822_rfind_type(colon, '%')) {
369
msg_warn("%s, line %d: name must be local",
370
VSTREAM_PATH(source_fp), lineno);
371
tok822_free_tree(tok_list);
376
* Split the input into key and value parts, and convert from
377
* token representation back to string representation. Convert
378
* the key to internal (unquoted) form, because the resolver
379
* produces addresses in internal form. Convert the value to
380
* external (quoted) form, because it will have to be re-parsed
381
* upon lookup. Discard the token representation when done.
385
value_list = tok822_cut_after(colon);
386
tok822_unlink(colon);
389
tok822_internalize(key_buffer, key_list, TOK822_STR_DEFL);
390
tok822_free_tree(key_list);
392
tok822_externalize(value_buffer, value_list, TOK822_STR_DEFL);
393
tok822_free_tree(value_list);
396
* Store the value under a case-insensitive key.
398
mkmap_append(mkmap, STR(key_buffer), STR(value_buffer));
399
if (mkmap->dict->error)
400
msg_fatal("table %s:%s: write error: %m",
401
mkmap->dict->type, mkmap->dict->name);