1 #line 982 "../../src/builtin/snarf.m4"
2 /* -*- buffer-read-only: t -*- vi: set ro:
3 THIS FILE IS GENERATED AUTOMATICALLY. PLEASE DO NOT EDIT.
4 */
5 #line 982
6 #ifdef HAVE_CONFIG_H
7 #line 982
8 # include <config.h>
9 #line 982
10 #endif
11 #line 982
12 #include <sys/types.h>
13 #line 982
14
15 #line 982
16 #include "mailfromd.h"
17 #line 982
18 #include "prog.h"
19 #line 982
20 #include "builtin.h"
21 #line 982
22
23 #line 211 "db.bi"
24 static mu_debug_handle_t debug_handle;
25 #line 982 "../../src/builtin/snarf.m4"
26
27 #line 1022 "../../src/builtin/snarf.m4"
28
29 /* End of snarf.m4 */
30 #line 1 "db.bi"
31 /* This file is part of Mailfromd. -*- c -*-
32 Copyright (C) 2006-2021 Sergey Poznyakoff
33
34 This program is free software; you can redistribute it and/or modify
35 it under the terms of the GNU General Public License as published by
36 the Free Software Foundation; either version 3, or (at your option)
37 any later version.
38
39 This program is distributed in the hope that it will be useful,
40 but WITHOUT ANY WARRANTY; without even the implied warranty of
41 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
42 GNU General Public License for more details.
43
44 You should have received a copy of the GNU General Public License
45 along with this program. If not, see <http://www.gnu.org/licenses/>. */
46
47
48 #define DEFAULT_DB_MODE 0640
49 #include <fnmatch.h>
50
51 struct db_prop { /* Database properties */
52 char *pat; /* Database name pattern */
53 mode_t mode; /* File mode */
54 int null; /* Null byte */
55 mu_url_t hint; /* Hint to use instead of the default one */
56 };
57
58 static mu_list_t db_prop_list;
59
60 static int
db_prop_compare(const void * item,const void * data)61 db_prop_compare(const void *item, const void *data)
62 {
63 const struct db_prop *prop = item;
64 const char *name = data;
65 return strcmp(prop->pat, name);
66 }
67
68 static int
strtomode(char * str,mode_t * pmode)69 strtomode(char *str, mode_t *pmode)
70 {
71 mode_t mode = 0;
72 struct { char c; unsigned mask; } modetab[] = {
73 { 'r', S_IRUSR },
74 { 'w', S_IWUSR },
75 { 'x', S_IXUSR },
76 { 'r', S_IRGRP },
77 { 'w', S_IWGRP },
78 { 'x', S_IXGRP },
79 { 'r', S_IROTH },
80 { 'w', S_IWOTH },
81 { 'x', S_IXOTH },
82 { 0 }
83 };
84 int i;
85
86 for (i = 0; modetab[i].c; i++) {
87 if (!str[i])
88 return i + 1;
89 if (str[i] == modetab[i].c)
90 mode |= modetab[i].mask;
91 else if (str[i] != '-')
92 return i + 1;
93 }
94 if (str[i])
95 return i + 1;
96 *pmode = mode;
97 return 0;
98 }
99
100 static int
is_url(const char * p)101 is_url(const char *p)
102 {
103 for (; *p && mu_isalnum(*p); p++)
104 ;
105 return *p == ':';
106 }
107
108 /* #pragma dbprop <name> [null] [mode] [hint]
109 At least one of the bracketed parameters must be present. Two or more
110 parameters can be given in arbitrary order.
111 */
112 #line 82 "db.bi"
113
114 #line 82
_pragma_dbprop(int argc,char ** argv,const char * text)115 static void _pragma_dbprop (int argc, char **argv, const char *text)
116 #line 82
117
118 {
119 int null = 0;
120 mode_t mode = DEFAULT_DB_MODE;
121 struct db_prop *prop;
122 int rc;
123 char *pat;
124 mu_url_t hint = NULL;
125
126 --argc;
127 pat = *++argv;
128
129 while (--argc) {
130 char *p = *++argv;
131
132 if (strcmp(p, "null") == 0)
133 null = 1;
134 else if (mu_isdigit(*p)) {
135 unsigned long n = strtoul(p, &p, 8);
136 if (*p || (mode = n) != n) {
137 parse_error(_("bad numeric file mode"));
138 return;
139 }
140 } else if (is_url(p)) {
141 rc = mu_url_create(&hint, p);
142 if (rc) {
143 parse_error(_("not a valid URL: %s"),
144 mu_strerror(rc));
145 return;
146 }
147 } else if (rc = strtomode(p, &mode)) {
148 parse_error(_("bad symbolic file mode (near %s)"),
149 p + rc - 1);
150 return;
151 }
152 }
153
154 if (!db_prop_list) {
155 rc = mu_list_create(&db_prop_list);
156 if (rc) {
157 parse_error(_("cannot create list: %s"),
158 mu_strerror(rc));
159 return;
160 }
161 mu_list_set_comparator(db_prop_list, db_prop_compare);
162 }
163
164 if (mu_list_locate(db_prop_list, pat, (void**) &prop)) {
165 prop = mu_alloc(sizeof(*prop));
166 prop->pat = mu_strdup(pat);
167 rc = mu_list_append(db_prop_list, prop);
168 if (rc) {
169 parse_error(_("Cannot create list: %s"),
170 mu_strerror(rc));
171 return;
172 }
173 }
174 prop->mode = mode;
175 prop->null = null;
176 prop->hint = hint;
177 }
178
179 const struct db_prop *
db_prop_lookup(const char * name)180 db_prop_lookup(const char *name)
181 {
182 mu_iterator_t itr;
183 const struct db_prop *found = NULL;
184
185 if (db_prop_list
186 && mu_list_get_iterator(db_prop_list, &itr) == 0) {
187 for (mu_iterator_first(itr);
188 !mu_iterator_is_done(itr);
189 mu_iterator_next(itr)) {
190 const struct db_prop *p;
191 mu_iterator_current(itr, (void**)&p);
192 if (strcmp(p->pat, name) == 0) {
193 found = p;
194 break;
195 } else if (fnmatch(p->pat, name, 0) == 0)
196 found = p;
197 }
198 mu_iterator_destroy(&itr);
199 }
200 return found;
201 }
202
203 int
_open_dbm(mu_dbm_file_t * pdb,char * dbname,int access,int mode,mu_url_t hint)204 _open_dbm(mu_dbm_file_t *pdb, char *dbname, int access, int mode,
205 mu_url_t hint)
206 {
207 mu_dbm_file_t db;
208 int rc;
209 mu_url_t url;
210
211 if (!hint)
212 hint = mu_dbm_get_hint();
213 rc = mu_url_create_hint(&url, dbname, 0, hint);
214 if (rc) {
215 mu_error(_("cannot create database URL for %s: %s"),
216 dbname, mu_strerror(rc));
217 return rc;
218 }
219 rc = mu_dbm_create_from_url(url, &db,
220 mf_file_mode_to_safety_criteria(mode));
221 mu_url_destroy(&url);
222 if (rc)
223 return rc;
224
225 rc = mu_dbm_safety_check(db);
226 if (rc && rc != ENOENT) {
227 mu_error(_("%s fails safety check: %s"),
228 dbname, mu_strerror(rc));
229 mu_dbm_destroy(&db);
230 return rc;
231 }
232
233 rc = mu_dbm_open(db, access, mode);
234 if (rc) {
235 mu_dbm_destroy(&db);
236 return rc;
237 }
238 *pdb = db;
239 return rc;
240 }
241
242
243 #define LOOKUP_NULL_BYTE 0x1
244 #define LOOKUP_TEST_ONLY 0x2
245
246
247 #line 211
248
249 #line 211
250 static int
251 #line 211
dbmap_lookup(eval_environ_t env,char * dbname,const char * keystr,const char * defval,const struct db_prop * prop,int flags)252 dbmap_lookup(eval_environ_t env, char *dbname, const char *keystr,
253 #line 211
254 const char *defval, const struct db_prop *prop, int flags)
255 #line 211
256 {
257 #line 211
258 int rc;
259 #line 211
260 mu_dbm_file_t db;
261 #line 211
262 struct mu_dbm_datum key;
263 #line 211
264 struct mu_dbm_datum contents;
265 #line 211
266
267 #line 211
268 if (!defval)
269 #line 211
270 defval = "";
271 #line 211
272 rc = _open_dbm(&db, dbname, MU_STREAM_READ,
273 #line 211
274 prop ? prop->mode : DEFAULT_DB_MODE,
275 #line 211
276 prop ? prop->hint : NULL);
277 #line 211
278 if (rc)
279 #line 211
280 (
281 #line 211
282 env_throw_bi(env, mfe_dbfailure, NULL, _("mf_dbm_open(%s) failed: %s"),dbname,mu_strerror(rc))
283 #line 211
284 );
285 #line 211
286
287 #line 211
288 memset(&key, 0, sizeof key);
289 #line 211
290 memset(&contents, 0, sizeof contents);
291 #line 211
292 key.mu_dptr = (void*) keystr;
293 #line 211
294 key.mu_dsize = strlen(keystr);
295 #line 211
296 if (flags & LOOKUP_NULL_BYTE)
297 #line 211
298 key.mu_dsize++;
299 #line 211
300 rc = mu_dbm_fetch(db, &key, &contents);
301 #line 211
302 if (rc && rc != MU_ERR_NOENT) {
303 #line 211
304 mu_dbm_destroy(&db);
305 #line 211
306 (
307 #line 211
308 env_throw_bi(env, mfe_dbfailure, NULL, _("cannot fetch data: %s"),mu_dbm_strerror(db))
309 #line 211
310 );
311 #line 211
312 }
313 #line 211
314
315 #line 211 "db.bi"
316
317 #line 211
318 mu_debug(debug_handle, MU_DEBUG_TRACE5,("Looking up %s: %s", keystr, rc ? "false" : "true"));
319 #line 211
320 if (flags & LOOKUP_TEST_ONLY)
321 #line 211
322 push(env, (STKVAL) (rc == 0));
323 #line 211
324 else {
325 #line 211
326 if (rc) {
327 #line 211
328 if (defval)
329 #line 211
330 pushs(env, defval);
331 #line 211
332 else
333 #line 211
334 push(env, (STKVAL) 0L);
335 #line 211
336 } else if (((char*)contents.mu_dptr)[contents.mu_dsize-1]) {
337 #line 211
338 size_t off;
339 #line 211
340 size_t len = contents.mu_dsize;
341 #line 211
342 char *s = (char*) env_data_ref(env, (off = heap_reserve(env, len + 1)));
343 #line 211
344 memcpy(s, contents.mu_dptr, len);
345 #line 211
346 s[len] = 0;
347 #line 211
348 push(env, (STKVAL) off);
349 #line 211
350 } else
351 #line 211
352 pushs(env, contents.mu_dptr);
353 #line 211
354 }
355 #line 211
356 mu_dbm_datum_free(&contents);
357 #line 211
358 mu_dbm_destroy(&db);
359 #line 211
360 return rc;
361 #line 211
362 }
363 #line 211
364
365 #line 211
366
367 #line 211
368
369 #line 269
370
371
372
373 void
374 #line 272
bi_dbmap(eval_environ_t env)375 bi_dbmap(eval_environ_t env)
376 #line 272
377
378 #line 272
379
380 #line 272 "db.bi"
381 {
382 #line 272
383
384 #line 272
385
386 #line 272
387 long __bi_argcnt;
388 #line 272
389 char * MFL_DATASEG dbname;
390 #line 272
391 char * MFL_DATASEG key;
392 #line 272
393 long null;
394 #line 272
395
396 #line 272
397 get_string_arg(env, 1, &dbname);
398 #line 272
399 get_string_arg(env, 2, &key);
400 #line 272
401 get_numeric_arg(env, 3, &null);
402 #line 272
403
404 #line 272
405 get_numeric_arg(env, 0, &__bi_argcnt);
406 #line 272
407 adjust_stack(env, __bi_argcnt + 1);
408 #line 272
409
410 #line 272
411
412 #line 272
413 if (builtin_module_trace(BUILTIN_IDX_db))
414 #line 272
415 prog_trace(env, "dbmap %s %s %lu",dbname, key, ((__bi_argcnt > 2) ? null : 0));;
416 #line 272
417
418 {
419 const struct db_prop *prop = db_prop_lookup(dbname);
420
421 #line 275
422 dbmap_lookup(env,dbname,key,NULL,prop,LOOKUP_TEST_ONLY |
423 (((__bi_argcnt > 2) ? null : prop && prop->null)
424 ? LOOKUP_NULL_BYTE : 0));
425 #line 280
426 }
427
428 #line 281
429 env_function_cleanup_flush(env, NULL);
430 #line 281
431 return;
432 #line 281
433 }
434
435 void
436 #line 283
bi_dbget(eval_environ_t env)437 bi_dbget(eval_environ_t env)
438 #line 283
439
440 #line 283
441
442 #line 283 "db.bi"
443 {
444 #line 283
445
446 #line 283
447
448 #line 283
449 long __bi_argcnt;
450 #line 283
451 char * MFL_DATASEG dbname;
452 #line 283
453 char * MFL_DATASEG key;
454 #line 283
455 char * MFL_DATASEG defval;
456 #line 283
457 long null;
458 #line 283
459
460 #line 283
461 get_string_arg(env, 1, &dbname);
462 #line 283
463 get_string_arg(env, 2, &key);
464 #line 283
465 get_string_arg(env, 3, &defval);
466 #line 283
467 get_numeric_arg(env, 4, &null);
468 #line 283
469
470 #line 283
471 get_numeric_arg(env, 0, &__bi_argcnt);
472 #line 283
473 adjust_stack(env, __bi_argcnt + 1);
474 #line 283
475
476 #line 283
477
478 #line 283
479 if (builtin_module_trace(BUILTIN_IDX_db))
480 #line 283
481 prog_trace(env, "dbget %s %s %s %lu",dbname, key, ((__bi_argcnt > 2) ? defval : ""), ((__bi_argcnt > 3) ? null : 0));;
482
483 {
484 const struct db_prop *prop = db_prop_lookup(dbname);
485
486 #line 287
487 dbmap_lookup(env,dbname,key,((__bi_argcnt > 2) ? defval : 0),prop,((__bi_argcnt > 3) ? null : prop && prop->null)
488 ? LOOKUP_NULL_BYTE : 0);
489 #line 292
490 }
491
492 #line 293
493 env_function_cleanup_flush(env, NULL);
494 #line 293
495 return;
496 #line 293
497 }
498
499 void
500 #line 295
bi_dbput(eval_environ_t env)501 bi_dbput(eval_environ_t env)
502 #line 295
503
504 #line 295
505
506 #line 295 "db.bi"
507 {
508 #line 295
509
510 #line 295
511
512 #line 295
513 long __bi_argcnt;
514 #line 295
515 char * dbname;
516 #line 295
517 char * keystr;
518 #line 295
519 char * value;
520 #line 295
521 long null;
522 #line 295
523 long mode;
524 #line 295
525
526 #line 295
527 get_string_arg(env, 1, &dbname);
528 #line 295
529 get_string_arg(env, 2, &keystr);
530 #line 295
531 get_string_arg(env, 3, &value);
532 #line 295
533 get_numeric_arg(env, 4, &null);
534 #line 295
535 get_numeric_arg(env, 5, &mode);
536 #line 295
537
538 #line 295
539 get_numeric_arg(env, 0, &__bi_argcnt);
540 #line 295
541 adjust_stack(env, __bi_argcnt + 1);
542 #line 295
543
544 #line 295
545
546 #line 295
547 if (builtin_module_trace(BUILTIN_IDX_db))
548 #line 295
549 prog_trace(env, "dbput %s %s %s %lu %lu",dbname, keystr, value, ((__bi_argcnt > 3) ? null : 0), ((__bi_argcnt > 4) ? mode : 0));;
550
551 {
552 int rc;
553 mu_dbm_file_t db;
554 struct mu_dbm_datum key;
555 struct mu_dbm_datum contents;
556 const struct db_prop *prop = db_prop_lookup(dbname);
557
558 rc = _open_dbm(&db, dbname, MU_STREAM_RDWR,
559 ((__bi_argcnt > 4) ? mode : (prop ? prop->mode : DEFAULT_DB_MODE)),
560 #line 307
561 prop ? prop->hint : NULL);
562 if (rc)
563 (
564 #line 309
565 env_throw_bi(env, mfe_dbfailure, "dbput", _("mf_dbm_open(%s) failed: %s"),dbname,mu_strerror(rc))
566 #line 309
567 );
568 #line 313
569 memset(&key, 0, sizeof key);
570 key.mu_dptr = keystr;
571 key.mu_dsize = strlen(keystr);
572 if (((__bi_argcnt > 3) ? null : prop && prop->null))
573 key.mu_dsize++;
574
575 memset(&contents, 0, sizeof contents);
576 contents.mu_dptr = value;
577 contents.mu_dsize = strlen(value) + 1;
578
579 rc = mu_dbm_store(db, &key, &contents, 1);
580 if (rc) {
581 const char *errstr = mu_dbm_strerror(db);
582 mu_dbm_destroy(&db);
583 (
584 #line 327
585 env_throw_bi(env, mfe_dbfailure, "dbput", _("failed to insert data to %s: %s %s: %s"),dbname,keystr,value,errstr)
586 #line 327
587 );
588 #line 333
589 }
590 mu_dbm_destroy(&db);
591 }
592
593 #line 336
594 env_function_cleanup_flush(env, NULL);
595 #line 336
596 return;
597 #line 336
598 }
599
600 void
601 #line 338
bi_dbinsert(eval_environ_t env)602 bi_dbinsert(eval_environ_t env)
603 #line 338
604
605 #line 338
606
607 #line 338 "db.bi"
608 {
609 #line 338
610
611 #line 338
612
613 #line 338
614 long __bi_argcnt;
615 #line 338
616 char * dbname;
617 #line 338
618 char * keystr;
619 #line 338
620 char * value;
621 #line 338
622 long replace;
623 #line 338
624 long null;
625 #line 338
626 long mode;
627 #line 338
628
629 #line 338
630 get_string_arg(env, 1, &dbname);
631 #line 338
632 get_string_arg(env, 2, &keystr);
633 #line 338
634 get_string_arg(env, 3, &value);
635 #line 338
636 get_numeric_arg(env, 4, &replace);
637 #line 338
638 get_numeric_arg(env, 5, &null);
639 #line 338
640 get_numeric_arg(env, 6, &mode);
641 #line 338
642
643 #line 338
644 get_numeric_arg(env, 0, &__bi_argcnt);
645 #line 338
646 adjust_stack(env, __bi_argcnt + 1);
647 #line 338
648
649 #line 338
650
651 #line 338
652 if (builtin_module_trace(BUILTIN_IDX_db))
653 #line 338
654 prog_trace(env, "dbinsert %s %s %s %lu %lu %lu",dbname, keystr, value, ((__bi_argcnt > 3) ? replace : 0), ((__bi_argcnt > 4) ? null : 0), ((__bi_argcnt > 5) ? mode : 0));;
655
656 {
657 int rc;
658 mu_dbm_file_t db;
659 struct mu_dbm_datum key;
660 struct mu_dbm_datum contents;
661 const struct db_prop *prop = db_prop_lookup(dbname);
662 const char *errstr;
663
664 rc = _open_dbm(&db, dbname, MU_STREAM_RDWR,
665 ((__bi_argcnt > 5) ? mode : (prop ? prop->mode : DEFAULT_DB_MODE)),
666 #line 351
667 prop ? prop->hint : NULL);
668 if (rc)
669 (
670 #line 353
671 env_throw_bi(env, mfe_dbfailure, "dbinsert", _("mf_dbm_open(%s) failed: %s"),dbname,mu_strerror(rc))
672 #line 353
673 );
674 #line 357
675 memset(&key, 0, sizeof key);
676 key.mu_dptr = keystr;
677 key.mu_dsize = strlen(keystr);
678 if (((__bi_argcnt > 4) ? null : prop && prop->null))
679 key.mu_dsize++;
680
681 memset(&contents, 0, sizeof contents);
682 contents.mu_dptr = value;
683 contents.mu_dsize = strlen(value) + 1;
684
685 rc = mu_dbm_store(db, &key, &contents, ((__bi_argcnt > 3) ? replace : 0));
686 if (rc && rc != MU_ERR_EXISTS)
687 errstr = mu_dbm_strerror(db);
688 mu_dbm_destroy(&db);
689 if (rc == MU_ERR_EXISTS)
690 (
691 #line 372
692 env_throw_bi(env, mfe_exists, "dbinsert", _("record already exists"))
693 #line 372
694 );
695
696 if (!(rc == 0))
697 #line 374
698 (
699 #line 374
700 env_throw_bi(env, mfe_dbfailure, "dbinsert", _("failed to insert data to %s: %s %s: %s"),dbname,keystr,value,errstr)
701 #line 374
702 )
703 #line 380
704 ;
705 }
706
707 #line 382
708 env_function_cleanup_flush(env, NULL);
709 #line 382
710 return;
711 #line 382
712 }
713
714 void
715 #line 384
bi_dbdel(eval_environ_t env)716 bi_dbdel(eval_environ_t env)
717 #line 384
718
719 #line 384
720
721 #line 384 "db.bi"
722 {
723 #line 384
724
725 #line 384
726
727 #line 384
728 long __bi_argcnt;
729 #line 384
730 char * dbname;
731 #line 384
732 char * keystr;
733 #line 384
734 long null;
735 #line 384
736 long mode;
737 #line 384
738
739 #line 384
740 get_string_arg(env, 1, &dbname);
741 #line 384
742 get_string_arg(env, 2, &keystr);
743 #line 384
744 get_numeric_arg(env, 3, &null);
745 #line 384
746 get_numeric_arg(env, 4, &mode);
747 #line 384
748
749 #line 384
750 get_numeric_arg(env, 0, &__bi_argcnt);
751 #line 384
752 adjust_stack(env, __bi_argcnt + 1);
753 #line 384
754
755 #line 384
756
757 #line 384
758 if (builtin_module_trace(BUILTIN_IDX_db))
759 #line 384
760 prog_trace(env, "dbdel %s %s %lu %lu",dbname, keystr, ((__bi_argcnt > 2) ? null : 0), ((__bi_argcnt > 3) ? mode : 0));;
761
762 {
763 mu_dbm_file_t db;
764 struct mu_dbm_datum key;
765 int rc;
766 const struct db_prop *prop = db_prop_lookup(dbname);
767
768 rc = _open_dbm(&db, dbname, MU_STREAM_RDWR,
769 ((__bi_argcnt > 3) ? mode : (prop ? prop->mode : DEFAULT_DB_MODE)),
770 #line 395
771 prop ? prop->hint : NULL);
772 if (!(rc == 0))
773 #line 396
774 (
775 #line 396
776 env_throw_bi(env, mfe_dbfailure, "dbdel", _("mf_dbm_open(%s) failed: %s"),dbname,mu_strerror(rc))
777 #line 396
778 )
779 #line 400
780 ;
781 memset(&key, 0, sizeof key);
782 key.mu_dptr = keystr;
783 key.mu_dsize = strlen(keystr);
784 if (((__bi_argcnt > 2) ? null : prop && prop->null))
785 key.mu_dsize++;
786 rc = mu_dbm_delete(db, &key);
787 mu_dbm_destroy(&db);
788 if (!(rc == 0 || rc == MU_ERR_NOENT))
789 #line 408
790 (
791 #line 408
792 env_throw_bi(env, mfe_dbfailure, "dbdel", _("failed to delete data `%s' from `%s': %s"),keystr,dbname,mu_strerror(rc))
793 #line 408
794 )
795 #line 413
796 ;
797 }
798
799 #line 415
800 env_function_cleanup_flush(env, NULL);
801 #line 415
802 return;
803 #line 415
804 }
805
806
807 #define NUMDB 128
808
809 struct db_tab {
810 int used;
811 mu_dbm_file_t db;
812 struct mu_dbm_datum key;
813 };
814
815 static void *
alloc_db_tab()816 alloc_db_tab()
817 {
818 return mu_calloc(NUMDB, sizeof(struct db_tab));
819 }
820
821 static void
close_db_tab(struct db_tab * dbt)822 close_db_tab(struct db_tab *dbt)
823 {
824 if (dbt->used) {
825 mu_dbm_datum_free(&dbt->key);
826 mu_dbm_destroy(&dbt->db);
827 dbt->used = 0;
828 }
829 }
830
831 static void
destroy_db_tab(void * data)832 destroy_db_tab(void *data)
833 {
834 int i;
835 struct db_tab *db = data;
836 for (i = 0; i < NUMDB; i++)
837 close_db_tab(db + i);
838 free(db);
839 }
840
841
842 #line 452
843
844 #line 452
845 static int DBTAB_id;
846 #line 452 "db.bi"
847 ;
848
849 static int
new_db_tab(struct db_tab * dbt)850 new_db_tab(struct db_tab *dbt)
851 {
852 int i;
853 for (i = 0; i < NUMDB; i++)
854 if (!dbt[i].used) {
855 dbt[i].used = 1;
856 return i;
857 }
858 return -1;
859 }
860
861
862
863 void
864 #line 468
bi_dbfirst(eval_environ_t env)865 bi_dbfirst(eval_environ_t env)
866 #line 468
867
868 #line 468
869
870 #line 468 "db.bi"
871 {
872 #line 468
873
874 #line 468
875
876 #line 468
877
878 #line 468
879 char * dbname;
880 #line 468
881
882 #line 468
883 get_string_arg(env, 0, &dbname);
884 #line 468
885
886 #line 468
887
888 #line 468
889 adjust_stack(env, 1);
890 #line 468
891
892 #line 468
893
894 #line 468
895 if (builtin_module_trace(BUILTIN_IDX_db))
896 #line 468
897 prog_trace(env, "dbfirst %s",dbname);;
898 #line 468
899
900 {
901 int rc;
902 int n;
903 struct db_tab *dbt = env_get_builtin_priv(env,DBTAB_id);
904 mu_dbm_file_t db;
905 struct mu_dbm_datum key;
906 const struct db_prop *prop = db_prop_lookup(dbname);
907
908 rc = _open_dbm(&db, dbname, MU_STREAM_READ,
909 prop ? prop->mode : DEFAULT_DB_MODE,
910 prop ? prop->hint : NULL);
911 if (!(rc == 0))
912 #line 480
913 (
914 #line 480
915 env_throw_bi(env, mfe_dbfailure, "dbfirst", _("mf_dbm_open(%s) failed: %s"),dbname,mu_strerror(rc))
916 #line 480
917 )
918 #line 484
919 ;
920 memset(&key, 0, sizeof key);
921 rc = mu_dbm_firstkey(db, &key);
922 if (rc) {
923 if (rc == MU_ERR_NOENT) {
924 mu_dbm_destroy(&db);
925
926 #line 490
927 do {
928 #line 490
929 push(env, (STKVAL)(mft_number)(0));
930 #line 490
931 goto endlab;
932 #line 490
933 } while (0);
934 } else if (rc) {
935 mu_dbm_destroy(&db);
936 (
937 #line 493
938 env_throw_bi(env, mfe_dbfailure, "dbfirst", _("mf_dbm_firstkey failed: %s"),mu_strerror(rc))
939 #line 493
940 );
941 #line 496
942 }
943 }
944 n = new_db_tab(dbt);
945 if (!(n >= 0))
946 #line 499
947 (
948 #line 499
949 env_throw_bi(env, mfe_failure, "dbfirst", _("no more database entries available"))
950 #line 499
951 )
952 #line 501
953 ;
954 dbt += n;
955 dbt->db = db;
956 dbt->key = key;
957
958 #line 505
959 do {
960 #line 505
961 push(env, (STKVAL)(mft_number)(n));
962 #line 505
963 goto endlab;
964 #line 505
965 } while (0);
966 }
967 endlab:
968 #line 507
969 env_function_cleanup_flush(env, NULL);
970 #line 507
971 return;
972 #line 507
973 }
974
975 void
976 #line 509
bi_dbnext(eval_environ_t env)977 bi_dbnext(eval_environ_t env)
978 #line 509
979
980 #line 509
981
982 #line 509 "db.bi"
983 {
984 #line 509
985
986 #line 509
987
988 #line 509
989
990 #line 509
991 long dn;
992 #line 509
993
994 #line 509
995 get_numeric_arg(env, 0, &dn);
996 #line 509
997
998 #line 509
999
1000 #line 509
1001 adjust_stack(env, 1);
1002 #line 509
1003
1004 #line 509
1005
1006 #line 509
1007 if (builtin_module_trace(BUILTIN_IDX_db))
1008 #line 509
1009 prog_trace(env, "dbnext %lu",dn);;
1010 #line 509
1011
1012 {
1013 struct db_tab *dbt = env_get_builtin_priv(env,DBTAB_id) + dn;
1014 struct mu_dbm_datum nextkey;
1015 int rc;
1016
1017 if (!(dn >= 0 && dn < NUMDB && dbt->used))
1018 #line 515
1019 (
1020 #line 515
1021 env_throw_bi(env, mfe_range, "dbnext", _("invalid database descriptor"))
1022 #line 515
1023 )
1024 #line 517
1025 ;
1026
1027 memset (&nextkey, 0, sizeof nextkey);
1028 rc = mu_dbm_nextkey(dbt->db, &nextkey);
1029 if (rc) {
1030 if (rc == MU_ERR_FAILURE)
1031 mu_error(_("mu_dbm_nextkey: %s"),
1032 mu_dbm_strerror(dbt->db));
1033 close_db_tab(dbt);
1034
1035 #line 526
1036 do {
1037 #line 526
1038 push(env, (STKVAL)(mft_number)(0));
1039 #line 526
1040 goto endlab;
1041 #line 526
1042 } while (0);
1043 }
1044 mu_dbm_datum_free(&nextkey);
1045 dbt->key = nextkey;
1046
1047 #line 530
1048 do {
1049 #line 530
1050 push(env, (STKVAL)(mft_number)(1));
1051 #line 530
1052 goto endlab;
1053 #line 530
1054 } while (0);
1055 }
1056 endlab:
1057 #line 532
1058 env_function_cleanup_flush(env, NULL);
1059 #line 532
1060 return;
1061 #line 532
1062 }
1063
1064 void
1065 #line 534
bi_dbkey(eval_environ_t env)1066 bi_dbkey(eval_environ_t env)
1067 #line 534
1068
1069 #line 534
1070
1071 #line 534 "db.bi"
1072 {
1073 #line 534
1074
1075 #line 534
1076
1077 #line 534
1078
1079 #line 534
1080 long dn;
1081 #line 534
1082
1083 #line 534
1084 get_numeric_arg(env, 0, &dn);
1085 #line 534
1086
1087 #line 534
1088
1089 #line 534
1090 adjust_stack(env, 1);
1091 #line 534
1092
1093 #line 534
1094
1095 #line 534
1096 if (builtin_module_trace(BUILTIN_IDX_db))
1097 #line 534
1098 prog_trace(env, "dbkey %lu",dn);;
1099 #line 534
1100
1101 {
1102 size_t off, len;
1103 char *s;
1104 struct db_tab *dbt = env_get_builtin_priv(env,DBTAB_id) + dn;
1105
1106 if (!(dn >= 0 && dn < NUMDB && dbt->used))
1107 #line 540
1108 (
1109 #line 540
1110 env_throw_bi(env, mfe_range, "dbkey", _("invalid database descriptor"))
1111 #line 540
1112 )
1113 #line 542
1114 ;
1115
1116 len = dbt->key.mu_dsize;
1117 s = (char*) env_data_ref(env, (off = heap_reserve(env, len + 1)));
1118 memcpy(s, dbt->key.mu_dptr, len);
1119 s[len] = 0;
1120
1121 #line 548
1122 do {
1123 #line 548
1124 push(env, (STKVAL) (mft_size) (off));
1125 #line 548
1126 goto endlab;
1127 #line 548
1128 } while (0);
1129 }
1130 endlab:
1131 #line 550
1132 env_function_cleanup_flush(env, NULL);
1133 #line 550
1134 return;
1135 #line 550
1136 }
1137
1138 void
1139 #line 552
bi_dbvalue(eval_environ_t env)1140 bi_dbvalue(eval_environ_t env)
1141 #line 552
1142
1143 #line 552
1144
1145 #line 552 "db.bi"
1146 {
1147 #line 552
1148
1149 #line 552
1150
1151 #line 552
1152
1153 #line 552
1154 long dn;
1155 #line 552
1156
1157 #line 552
1158 get_numeric_arg(env, 0, &dn);
1159 #line 552
1160
1161 #line 552
1162
1163 #line 552
1164 adjust_stack(env, 1);
1165 #line 552
1166
1167 #line 552
1168
1169 #line 552
1170 if (builtin_module_trace(BUILTIN_IDX_db))
1171 #line 552
1172 prog_trace(env, "dbvalue %lu",dn);;
1173 #line 552
1174
1175 {
1176 int rc;
1177 size_t off, len;
1178 char *s;
1179 struct db_tab *dbt = env_get_builtin_priv(env,DBTAB_id) + dn;
1180 struct mu_dbm_datum contents;
1181
1182 if (!(dn >= 0 && dn < NUMDB && dbt->used))
1183 #line 560
1184 (
1185 #line 560
1186 env_throw_bi(env, mfe_range, "dbvalue", _("invalid database descriptor"))
1187 #line 560
1188 )
1189 #line 562
1190 ;
1191
1192 memset(&contents, 0, sizeof contents);
1193 rc = mu_dbm_fetch(dbt->db, &dbt->key, &contents);
1194 if (!(rc == 0))
1195 #line 566
1196 (
1197 #line 566
1198 env_throw_bi(env, mfe_dbfailure, "dbvalue", _("cannot fetch key: %s"),rc == MU_ERR_FAILURE ?
1199 mu_dbm_strerror(dbt->db) : mu_strerror (rc))
1200 #line 566
1201 )
1202 #line 570
1203 ;
1204
1205 len = contents.mu_dsize;
1206 s = (char*) env_data_ref(env, (off = heap_reserve(env, len + 1)));
1207 memcpy(s, contents.mu_dptr, len);
1208 s[len] = 0;
1209 mu_dbm_datum_free(&contents);
1210
1211 #line 577
1212 do {
1213 #line 577
1214 push(env, (STKVAL) (mft_size) (off));
1215 #line 577
1216 goto endlab;
1217 #line 577
1218 } while (0);
1219 }
1220 endlab:
1221 #line 579
1222 env_function_cleanup_flush(env, NULL);
1223 #line 579
1224 return;
1225 #line 579
1226 }
1227
1228
1229 enum greylist_semantics
1230 {
1231 greylist_traditional,
1232 greylist_ct
1233 };
1234
1235 static enum greylist_semantics greylist_semantics = greylist_traditional;
1236
1237 /* #pragma greylist {traditional|gray|ct|con-tassios}*/
1238 #line 591 "db.bi"
1239
1240 #line 591
_pragma_greylist(int argc,char ** argv,const char * text)1241 static void _pragma_greylist (int argc, char **argv, const char *text)
1242 #line 591
1243
1244 {
1245 if (strcmp(argv[1], "traditional") == 0
1246 || strcmp(argv[1], "gray") == 0)
1247 greylist_semantics = greylist_traditional;
1248 else if (strcmp(argv[1], "ct") == 0
1249 || strcmp(argv[1], "con-tassios") == 0)
1250 greylist_semantics = greylist_ct;
1251 else
1252 /* TRANSLATORS: Do not translate keywords:
1253 traditional, gray, ct, con-tassios */
1254 parse_error(_("unknown semantics; allowed values are: "
1255 "traditional (or gray) and "
1256 "ct (or con-tassios)"));
1257 }
1258
1259 /* FIXME: Duplicated in lib/cache.c */
1260 static char *
format_timestr(time_t timestamp,char * timebuf,size_t bufsize)1261 format_timestr(time_t timestamp, char *timebuf, size_t bufsize)
1262 {
1263 struct tm tm;
1264 gmtime_r(×tamp, &tm);
1265 strftime(timebuf, bufsize, "%c", &tm);
1266 return timebuf;
1267 }
1268
1269 static size_t greylist_seconds_left_loc
1270 #line 617 "db.bi"
1271 ;
1272
1273 /* The traditional (aka gray's) greylist implementation: the greylist
1274 database keeps the time the greylisting was activated.
1275 */
1276 static int
do_greylist_traditional(eval_environ_t env,char * email,long interval)1277 do_greylist_traditional(eval_environ_t env, char *email, long interval)
1278 {
1279 int rc;
1280 mu_dbm_file_t db;
1281 struct mu_dbm_datum key;
1282 struct mu_dbm_datum contents;
1283 int readonly = 0;
1284 time_t now;
1285
1286 rc = _open_dbm(&db, greylist_format->dbname, MU_STREAM_RDWR, 0600,
1287 NULL);
1288 if (rc) {
1289 rc = _open_dbm(&db, greylist_format->dbname,
1290 MU_STREAM_READ, 0600, NULL);
1291 readonly = 1;
1292 }
1293 if (!(rc == 0))
1294 #line 639
1295 (
1296 #line 639
1297 env_throw_bi(env, mfe_dbfailure, NULL, _("mf_dbm_open(%s) failed: %s"),greylist_format->dbname,mu_strerror(rc))
1298 #line 639
1299 )
1300 ;
1301
1302 memset(&key, 0, sizeof key);
1303 memset(&contents, 0, sizeof contents);
1304 key.mu_dptr = email;
1305 key.mu_dsize = strlen(email)+1;
1306
1307 time(&now);
1308 rc = mu_dbm_fetch(db, &key, &contents);
1309 if (rc == 0) {
1310 time_t timestamp, diff;
1311
1312 if (!(contents.mu_dsize == sizeof timestamp))
1313 #line 652
1314 (
1315 #line 652
1316 env_throw_bi(env, mfe_dbfailure, NULL, _("greylist database %s has wrong data size"),greylist_format->dbname)
1317 #line 652
1318 )
1319 #line 655
1320 ;
1321
1322 timestamp = *(time_t*) contents.mu_dptr;
1323 diff = now - timestamp;
1324
1325 if (mu_debug_level_p(debug_handle, MU_DEBUG_TRACE5)) {
1326 char timebuf[32];
1327 mu_debug_log("%s entered greylist database on %s, "
1328 "%ld seconds ago",
1329 email,
1330 format_timestr(timestamp, timebuf,
1331 sizeof timebuf),
1332 (long) diff);
1333 }
1334
1335 if (diff < interval) {
1336 diff = interval - diff;
1337
1338 mf_c_val(*env_data_ref(env, greylist_seconds_left_loc),ulong) = (diff);//FIXME
1339
1340
1341 #line 675
1342
1343 #line 675
1344 mu_debug(debug_handle, MU_DEBUG_TRACE6,("%s still greylisted (for %lu sec.)",
1345 email,
1346 (unsigned long) diff));
1347 #line 679
1348 rc = 1;
1349 } else if (diff > greylist_format->expire_interval) {
1350
1351 #line 681
1352
1353 #line 681
1354 mu_debug(debug_handle, MU_DEBUG_TRACE6,("greylist record for %s expired", email));
1355 #line 683
1356 mf_c_val(*env_data_ref(env, greylist_seconds_left_loc),long) = (interval);
1357 if (!readonly) {
1358 memcpy(contents.mu_dptr, &now, sizeof now);
1359 rc = mu_dbm_store(db, &key, &contents, 1);
1360 if (rc)
1361 mu_error(_("cannot insert datum `%-.*s' in "
1362 "greylist database %s: %s"),
1363 (int)key.mu_dsize,
1364 (char*)key.mu_dptr,
1365 greylist_format->dbname,
1366 rc == MU_ERR_FAILURE ?
1367 mu_dbm_strerror(db) :
1368 mu_strerror(rc));
1369 } else
1370
1371 #line 697
1372
1373 #line 697
1374 mu_debug(debug_handle, MU_DEBUG_TRACE6,("database opened in readonly mode: "
1375 "not updating"));
1376 #line 700
1377 rc = 1;
1378 } else {
1379
1380 #line 702
1381
1382 #line 702
1383 mu_debug(debug_handle, MU_DEBUG_TRACE6,("%s finished greylisting period", email));
1384 #line 704
1385 rc = 0;
1386 }
1387 mu_dbm_datum_free(&contents);
1388 } else if (!readonly) {
1389
1390 #line 708
1391
1392 #line 708
1393 mu_debug(debug_handle, MU_DEBUG_TRACE6,("greylisting %s", email));
1394 mf_c_val(*env_data_ref(env, greylist_seconds_left_loc),long) = (interval);
1395 contents.mu_dptr = (void*)&now;
1396 contents.mu_dsize = sizeof now;
1397 rc = mu_dbm_store(db, &key, &contents, 1);
1398 if (rc)
1399 mu_error(_("Cannot insert datum `%-.*s' in greylist "
1400 "database %s: %s"),
1401 (int)key.mu_dsize, (char*)key.mu_dptr,
1402 greylist_format->dbname,
1403 rc == MU_ERR_FAILURE ?
1404 mu_dbm_strerror(db) : mu_strerror(rc));
1405 rc = 1;
1406 } else
1407 rc = 0;
1408
1409 mu_dbm_destroy(&db);
1410
1411 return rc;
1412 }
1413
1414 /* Implementation of the is_greylisted predicate has no sense for
1415 traditional greylist databases, because greylisting interval is
1416 not known beforehand.
1417 FIXME: keep the reference below up to date.
1418 */
1419 static int
is_greylisted_traditional(eval_environ_t env,char * email)1420 is_greylisted_traditional(eval_environ_t env, char *email)
1421 {
1422 (
1423 #line 737
1424 env_throw_bi(env, mfe_failure, NULL, _("is_greylisted is not implemented for traditional greylist databases; "
1425 "see documentation, chapter %s %s for more info"),"5.30","Greylisting functions")
1426 #line 737
1427 );
1428 #line 741
1429 return 0;
1430 }
1431
1432 /* New greylist implementation (by Con Tassios): the database keeps
1433 the time the greylisting period is set to expire (`interval' seconds
1434 from now)
1435 */
1436 static int
do_greylist_ct(eval_environ_t env,char * email,long interval)1437 do_greylist_ct(eval_environ_t env, char *email, long interval)
1438 {
1439 int rc;
1440 mu_dbm_file_t db;
1441 struct mu_dbm_datum key;
1442 struct mu_dbm_datum contents;
1443 int readonly = 0;
1444 time_t now;
1445
1446 rc = _open_dbm(&db, greylist_format->dbname, MU_STREAM_RDWR, 0600,
1447 NULL);
1448 if (rc) {
1449 rc = _open_dbm(&db, greylist_format->dbname,
1450 MU_STREAM_READ, 0600, NULL);
1451 readonly = 1;
1452 }
1453 if (!(rc == 0))
1454 #line 765
1455 (
1456 #line 765
1457 env_throw_bi(env, mfe_dbfailure, NULL, _("mf_dbm_open(%s) failed: %s"),greylist_format->dbname,mu_strerror(rc))
1458 #line 765
1459 )
1460 ;
1461
1462 memset(&key, 0, sizeof key);
1463 memset(&contents, 0, sizeof contents);
1464 key.mu_dptr = email;
1465 key.mu_dsize = strlen(email) + 1;
1466
1467 time(&now);
1468 rc = mu_dbm_fetch(db, &key, &contents);
1469 if (rc == 0) {
1470 time_t timestamp;
1471
1472 if (!(contents.mu_dsize == sizeof timestamp))
1473 #line 778
1474 (
1475 #line 778
1476 env_throw_bi(env, mfe_dbfailure, NULL, _("greylist database %s has wrong data size"),greylist_format->dbname)
1477 #line 778
1478 )
1479 #line 781
1480 ;
1481
1482 timestamp = *(time_t*) contents.mu_dptr;
1483
1484 if (now < timestamp) {
1485 time_t diff = timestamp - now;
1486 mf_c_val(*env_data_ref(env, greylist_seconds_left_loc),long) = (diff);
1487
1488
1489 #line 789
1490
1491 #line 789
1492 mu_debug(debug_handle, MU_DEBUG_TRACE6,("%s still greylisted (for %lu sec.)",
1493 email,
1494 (unsigned long) diff));
1495 #line 793
1496 rc = 1;
1497 } else if (now - timestamp >
1498 greylist_format->expire_interval) {
1499
1500 #line 796
1501
1502 #line 796
1503 mu_debug(debug_handle, MU_DEBUG_TRACE6,("greylist record for %s expired", email));
1504 #line 798
1505 mf_c_val(*env_data_ref(env, greylist_seconds_left_loc),long) = (interval);
1506 if (!readonly) {
1507 now += interval;
1508 memcpy(contents.mu_dptr, &now, sizeof now);
1509 rc = mu_dbm_store(db, &key, &contents, 1);
1510 if (rc)
1511 mu_error(_("Cannot insert datum "
1512 "`%-.*s' in greylist "
1513 "database %s: %s"),
1514 (int)key.mu_dsize,
1515 (char*)key.mu_dptr,
1516 greylist_format->dbname,
1517 rc == MU_ERR_FAILURE ?
1518 mu_dbm_strerror(db) :
1519 mu_strerror(rc));
1520 } else
1521
1522 #line 814
1523
1524 #line 814
1525 mu_debug(debug_handle, MU_DEBUG_TRACE6,("database opened in readonly mode: "
1526 "not updating"));
1527 #line 817
1528 rc = 1;
1529 } else {
1530
1531 #line 819
1532
1533 #line 819
1534 mu_debug(debug_handle, MU_DEBUG_TRACE6,("%s finished greylisting period", email));
1535 #line 821
1536 rc = 0;
1537 }
1538 mu_dbm_datum_free(&contents);
1539 } else if (!readonly) {
1540
1541 #line 825
1542
1543 #line 825
1544 mu_debug(debug_handle, MU_DEBUG_TRACE6,("greylisting %s", email));
1545 mf_c_val(*env_data_ref(env, greylist_seconds_left_loc),long) = (interval);
1546 now += interval;
1547 contents.mu_dptr = (void*)&now;
1548 contents.mu_dsize = sizeof now;
1549 rc = mu_dbm_store(db, &key, &contents, 1);
1550 if (rc)
1551 mu_error(_("Cannot insert datum `%-.*s' in greylist "
1552 "database %s: %s"),
1553 (int)key.mu_dsize, (char*)key.mu_dptr,
1554 greylist_format->dbname,
1555 rc == MU_ERR_FAILURE ?
1556 mu_dbm_strerror(db) : mu_strerror(rc));
1557 rc = 1;
1558 } else
1559 rc = 0;
1560
1561 mu_dbm_destroy(&db);
1562
1563 return rc;
1564 }
1565
1566 /* The `is_greylisted' predicate for new databases */
1567 static int
is_greylisted_ct(eval_environ_t env,char * email)1568 is_greylisted_ct(eval_environ_t env, char *email)
1569 {
1570 int rc;
1571 mu_dbm_file_t db;
1572 struct mu_dbm_datum key;
1573 struct mu_dbm_datum contents;
1574 time_t now;
1575
1576 rc = _open_dbm(&db, greylist_format->dbname, MU_STREAM_RDWR, 0600,
1577 NULL);
1578 if (rc)
1579 rc = _open_dbm(&db, greylist_format->dbname,
1580 MU_STREAM_READ, 0600, NULL);
1581 if (!(rc == 0))
1582 #line 862
1583 (
1584 #line 862
1585 env_throw_bi(env, mfe_dbfailure, NULL, _("mf_dbm_open(%s) failed: %s"),greylist_format->dbname,mu_strerror(rc))
1586 #line 862
1587 )
1588 ;
1589
1590 memset(&key, 0, sizeof key);
1591 memset(&contents, 0, sizeof contents);
1592 key.mu_dptr = email;
1593 key.mu_dsize = strlen(email) + 1;
1594
1595 time(&now);
1596 rc = mu_dbm_fetch(db, &key, &contents);
1597 if (rc == 0) {
1598 time_t timestamp;
1599
1600 if (!(contents.mu_dsize == sizeof timestamp))
1601 #line 875
1602 (
1603 #line 875
1604 env_throw_bi(env, mfe_dbfailure, NULL, _("greylist database %s has wrong data size"),greylist_format->dbname)
1605 #line 875
1606 )
1607 #line 878
1608 ;
1609
1610 timestamp = *(time_t*) contents.mu_dptr;
1611
1612 rc = timestamp > now;
1613 if (rc)
1614 mf_c_val(*env_data_ref(env, greylist_seconds_left_loc),long) = (timestamp - now);
1615
1616 mu_dbm_datum_free(&contents);
1617 } else
1618 rc = 0;
1619
1620 mu_dbm_destroy(&db);
1621
1622 return rc;
1623 }
1624
1625 struct greylist_class {
1626 int (*gl_fun)(eval_environ_t, char *, long);
1627 int (*gl_pred)(eval_environ_t, char *);
1628 };
1629
1630 struct greylist_class greylist_class[] = {
1631 { do_greylist_traditional, is_greylisted_traditional },
1632 { do_greylist_ct, is_greylisted_ct }
1633 };
1634
1635 /* greylist(key, interval)
1636
1637 Returns true if the key is greylisted, false if it's OK to
1638 deliver mail.
1639 */
1640 void
1641 #line 910
bi_greylist(eval_environ_t env)1642 bi_greylist(eval_environ_t env)
1643 #line 910
1644
1645 #line 910
1646
1647 #line 910 "db.bi"
1648 {
1649 #line 910
1650
1651 #line 910
1652
1653 #line 910
1654
1655 #line 910
1656 char * email;
1657 #line 910
1658 long interval;
1659 #line 910
1660
1661 #line 910
1662 get_string_arg(env, 0, &email);
1663 #line 910
1664 get_numeric_arg(env, 1, &interval);
1665 #line 910
1666
1667 #line 910
1668
1669 #line 910
1670 adjust_stack(env, 2);
1671 #line 910
1672
1673 #line 910
1674
1675 #line 910
1676 if (builtin_module_trace(BUILTIN_IDX_db))
1677 #line 910
1678 prog_trace(env, "greylist %s %lu",email, interval);;
1679 #line 910
1680
1681 {
1682
1683 #line 912
1684 do {
1685 #line 912
1686 push(env, (STKVAL)(mft_number)(greylist_class[greylist_semantics].gl_fun(env, email,
1687 #line 912
1688 interval)));
1689 #line 912
1690 goto endlab;
1691 #line 912
1692 } while (0);
1693 #line 914
1694 }
1695 endlab:
1696 #line 915
1697 env_function_cleanup_flush(env, NULL);
1698 #line 915
1699 return;
1700 #line 915
1701 }
1702
1703 /* is_greylisted(key)
1704
1705 Returns true if the key is greylisted, otherwise false
1706
1707 */
1708 void
1709 #line 922
bi_is_greylisted(eval_environ_t env)1710 bi_is_greylisted(eval_environ_t env)
1711 #line 922
1712
1713 #line 922
1714
1715 #line 922 "db.bi"
1716 {
1717 #line 922
1718
1719 #line 922
1720
1721 #line 922
1722
1723 #line 922
1724 char * email;
1725 #line 922
1726
1727 #line 922
1728 get_string_arg(env, 0, &email);
1729 #line 922
1730
1731 #line 922
1732
1733 #line 922
1734 adjust_stack(env, 1);
1735 #line 922
1736
1737 #line 922
1738
1739 #line 922
1740 if (builtin_module_trace(BUILTIN_IDX_db))
1741 #line 922
1742 prog_trace(env, "is_greylisted %s",email);;
1743 #line 922
1744
1745 {
1746
1747 #line 924
1748 do {
1749 #line 924
1750 push(env, (STKVAL)(mft_number)(greylist_class[greylist_semantics].gl_pred(env, email)));
1751 #line 924
1752 goto endlab;
1753 #line 924
1754 } while (0);
1755 }
1756 endlab:
1757 #line 926
1758 env_function_cleanup_flush(env, NULL);
1759 #line 926
1760 return;
1761 #line 926
1762 }
1763
1764 void
1765 #line 928
bi_db_name(eval_environ_t env)1766 bi_db_name(eval_environ_t env)
1767 #line 928
1768
1769 #line 928
1770
1771 #line 928 "db.bi"
1772 {
1773 #line 928
1774
1775 #line 928
1776
1777 #line 928
1778
1779 #line 928
1780 char * MFL_DATASEG fmtid;
1781 #line 928
1782
1783 #line 928
1784 get_string_arg(env, 0, &fmtid);
1785 #line 928
1786
1787 #line 928
1788
1789 #line 928
1790 adjust_stack(env, 1);
1791 #line 928
1792
1793 #line 928
1794
1795 #line 928
1796 if (builtin_module_trace(BUILTIN_IDX_db))
1797 #line 928
1798 prog_trace(env, "db_name %s",fmtid);;
1799 #line 928
1800
1801 {
1802 struct db_format *fmt = db_format_lookup(fmtid);
1803 if (!(fmt != NULL))
1804 #line 931
1805 (
1806 #line 931
1807 env_throw_bi(env, mfe_not_found, "db_name", _("no such db format: %s"),fmtid)
1808 #line 931
1809 )
1810 #line 933
1811 ;
1812
1813 #line 934
1814 do {
1815 #line 934
1816 pushs(env, fmt->dbname);
1817 #line 934
1818 goto endlab;
1819 #line 934
1820 } while (0);
1821 }
1822 endlab:
1823 #line 936
1824 env_function_cleanup_flush(env, NULL);
1825 #line 936
1826 return;
1827 #line 936
1828 }
1829
1830 void
1831 #line 938
bi_db_get_active(eval_environ_t env)1832 bi_db_get_active(eval_environ_t env)
1833 #line 938
1834
1835 #line 938
1836
1837 #line 938 "db.bi"
1838 {
1839 #line 938
1840
1841 #line 938
1842
1843 #line 938
1844
1845 #line 938
1846 char * fmtid;
1847 #line 938
1848
1849 #line 938
1850 get_string_arg(env, 0, &fmtid);
1851 #line 938
1852
1853 #line 938
1854
1855 #line 938
1856 adjust_stack(env, 1);
1857 #line 938
1858
1859 #line 938
1860
1861 #line 938
1862 if (builtin_module_trace(BUILTIN_IDX_db))
1863 #line 938
1864 prog_trace(env, "db_get_active %s",fmtid);;
1865 #line 938
1866
1867 {
1868 struct db_format *fmt = db_format_lookup(fmtid);
1869 if (!(fmt != NULL))
1870 #line 941
1871 (
1872 #line 941
1873 env_throw_bi(env, mfe_not_found, "db_get_active", _("no such db format: %s"),fmtid)
1874 #line 941
1875 )
1876 #line 943
1877 ;
1878
1879 #line 944
1880 do {
1881 #line 944
1882 push(env, (STKVAL)(mft_number)(fmt->enabled));
1883 #line 944
1884 goto endlab;
1885 #line 944
1886 } while (0);
1887 }
1888 endlab:
1889 #line 946
1890 env_function_cleanup_flush(env, NULL);
1891 #line 946
1892 return;
1893 #line 946
1894 }
1895
1896 void
1897 #line 948
bi_db_set_active(eval_environ_t env)1898 bi_db_set_active(eval_environ_t env)
1899 #line 948
1900
1901 #line 948
1902
1903 #line 948 "db.bi"
1904 {
1905 #line 948
1906
1907 #line 948
1908
1909 #line 948
1910
1911 #line 948
1912 char * fmtid;
1913 #line 948
1914 long active;
1915 #line 948
1916
1917 #line 948
1918 get_string_arg(env, 0, &fmtid);
1919 #line 948
1920 get_numeric_arg(env, 1, &active);
1921 #line 948
1922
1923 #line 948
1924
1925 #line 948
1926 adjust_stack(env, 2);
1927 #line 948
1928
1929 #line 948
1930
1931 #line 948
1932 if (builtin_module_trace(BUILTIN_IDX_db))
1933 #line 948
1934 prog_trace(env, "db_set_active %s %lu",fmtid, active);;
1935 #line 948
1936
1937 {
1938 struct db_format *fmt = db_format_lookup(fmtid);
1939 if (!(fmt != NULL))
1940 #line 951
1941 (
1942 #line 951
1943 env_throw_bi(env, mfe_not_found, "db_set_active", _("no such db format: %s"),fmtid)
1944 #line 951
1945 )
1946 #line 953
1947 ;
1948 fmt->enabled = active;
1949 }
1950
1951 #line 956
1952 env_function_cleanup_flush(env, NULL);
1953 #line 956
1954 return;
1955 #line 956
1956 }
1957
1958 void
1959 #line 958
bi_db_expire_interval(eval_environ_t env)1960 bi_db_expire_interval(eval_environ_t env)
1961 #line 958
1962
1963 #line 958
1964
1965 #line 958 "db.bi"
1966 {
1967 #line 958
1968
1969 #line 958
1970
1971 #line 958
1972
1973 #line 958
1974 char * fmtid;
1975 #line 958
1976
1977 #line 958
1978 get_string_arg(env, 0, &fmtid);
1979 #line 958
1980
1981 #line 958
1982
1983 #line 958
1984 adjust_stack(env, 1);
1985 #line 958
1986
1987 #line 958
1988
1989 #line 958
1990 if (builtin_module_trace(BUILTIN_IDX_db))
1991 #line 958
1992 prog_trace(env, "db_expire_interval %s",fmtid);;
1993 #line 958
1994
1995 {
1996 struct db_format *fmt = db_format_lookup(fmtid);
1997 if (!(fmt != NULL))
1998 #line 961
1999 (
2000 #line 961
2001 env_throw_bi(env, mfe_not_found, "db_expire_interval", _("no such db format: %s"),fmtid)
2002 #line 961
2003 )
2004 #line 963
2005 ;
2006
2007 #line 964
2008 do {
2009 #line 964
2010 push(env, (STKVAL)(mft_number)(fmt->expire_interval));
2011 #line 964
2012 goto endlab;
2013 #line 964
2014 } while (0);
2015 }
2016 endlab:
2017 #line 966
2018 env_function_cleanup_flush(env, NULL);
2019 #line 966
2020 return;
2021 #line 966
2022 }
2023
2024 #line 982 "../../src/builtin/snarf.m4"
2025
2026 #line 982
2027
2028 #line 982
2029
2030 #line 982
2031 void
2032 #line 982
db_init_builtin(void)2033 db_init_builtin(void)
2034 #line 982
2035 {
2036 #line 982
2037 debug_handle = mu_debug_register_category("bi_db");
2038 #line 982
2039
2040 #line 982
2041 #line 82 "db.bi"
2042
2043 #line 82
2044 install_pragma("dbprop", 3, 5, _pragma_dbprop);
2045 #line 272 "db.bi"
2046 va_builtin_install_ex("dbmap", bi_dbmap, 0, dtype_number, 3, 1, 0|0, dtype_string, dtype_string, dtype_number);
2047 #line 283 "db.bi"
2048 va_builtin_install_ex("dbget", bi_dbget, 0, dtype_string, 4, 2, 0|0, dtype_string, dtype_string, dtype_string, dtype_number);
2049 #line 295 "db.bi"
2050 va_builtin_install_ex("dbput", bi_dbput, 0, dtype_unspecified, 5, 2, 0|0, dtype_string, dtype_string, dtype_string, dtype_number, dtype_number);
2051 #line 338 "db.bi"
2052 va_builtin_install_ex("dbinsert", bi_dbinsert, 0, dtype_unspecified, 6, 3, 0|0, dtype_string, dtype_string, dtype_string, dtype_number, dtype_number, dtype_number);
2053 #line 384 "db.bi"
2054 va_builtin_install_ex("dbdel", bi_dbdel, 0, dtype_unspecified, 4, 2, 0|0, dtype_string, dtype_string, dtype_number, dtype_number);
2055 #line 452 "db.bi"
2056 DBTAB_id = builtin_priv_register(alloc_db_tab, destroy_db_tab,
2057 #line 452
2058 NULL);
2059 #line 468 "db.bi"
2060 va_builtin_install_ex("dbfirst", bi_dbfirst, 0, dtype_number, 1, 0, 0|0, dtype_string);
2061 #line 509 "db.bi"
2062 va_builtin_install_ex("dbnext", bi_dbnext, 0, dtype_number, 1, 0, 0|0, dtype_number);
2063 #line 534 "db.bi"
2064 va_builtin_install_ex("dbkey", bi_dbkey, 0, dtype_string, 1, 0, 0|0, dtype_number);
2065 #line 552 "db.bi"
2066 va_builtin_install_ex("dbvalue", bi_dbvalue, 0, dtype_string, 1, 0, 0|0, dtype_number);
2067 #line 591 "db.bi"
2068
2069 #line 591
2070 install_pragma("greylist", 2, 2, _pragma_greylist);
2071 #line 617 "db.bi"
2072 builtin_variable_install("greylist_seconds_left", dtype_number, SYM_VOLATILE, &greylist_seconds_left_loc);
2073 #line 910 "db.bi"
2074 va_builtin_install_ex("greylist", bi_greylist, 0, dtype_number, 2, 0, 0|0, dtype_string, dtype_number);
2075 #line 922 "db.bi"
2076 va_builtin_install_ex("is_greylisted", bi_is_greylisted, 0, dtype_number, 1, 0, 0|0, dtype_string);
2077 #line 928 "db.bi"
2078 va_builtin_install_ex("db_name", bi_db_name, 0, dtype_string, 1, 0, 0|0, dtype_string);
2079 #line 938 "db.bi"
2080 va_builtin_install_ex("db_get_active", bi_db_get_active, 0, dtype_number, 1, 0, 0|0, dtype_string);
2081 #line 948 "db.bi"
2082 va_builtin_install_ex("db_set_active", bi_db_set_active, 0, dtype_unspecified, 2, 0, 0|0, dtype_string, dtype_number);
2083 #line 958 "db.bi"
2084 va_builtin_install_ex("db_expire_interval", bi_db_expire_interval, 0, dtype_number, 1, 0, 0|0, dtype_string);
2085
2086 #line 982 "../../src/builtin/snarf.m4"
2087
2088 #line 982
2089 }
2090 #line 982 "../../src/builtin/snarf.m4"
2091
2092