comparison src/context.cpp @ 214:82886d4dd71f stable-6-0-19

Fixes to compile on Fedora 9 and for const correctness.
author Carl Byington <carl@five-ten-sg.com>
date Tue, 10 Jun 2008 08:58:42 -0700
parents 4db1457cd11a
children 5c3e9bf45bb5
comparison
equal deleted inserted replaced
213:44ffef730bc4 214:82886d4dd71f
16 #include <sys/ioctl.h> 16 #include <sys/ioctl.h>
17 #include <sys/socket.h> 17 #include <sys/socket.h>
18 #include <sys/stat.h> 18 #include <sys/stat.h>
19 #include <sys/un.h> 19 #include <sys/un.h>
20 #include <unistd.h> 20 #include <unistd.h>
21 21 #include <climits>
22 char *token_autowhite; 22
23 char *token_black; 23 const char *token_autowhite;
24 char *token_cctld; 24 const char *token_black;
25 char *token_content; 25 const char *token_cctld;
26 char *token_context; 26 const char *token_content;
27 char *token_dccbulk; 27 const char *token_context;
28 char *token_dccfrom; 28 const char *token_dccbulk;
29 char *token_dccgrey; 29 const char *token_dccfrom;
30 char *token_dccto; 30 const char *token_dccgrey;
31 char *token_default; 31 const char *token_dccto;
32 char *token_dnsbl; 32 const char *token_default;
33 char *token_dnsbll; 33 const char *token_dnsbl;
34 char *token_envfrom; 34 const char *token_dnsbll;
35 char *token_envto; 35 const char *token_envfrom;
36 char *token_filter; 36 const char *token_envto;
37 char *token_generic; 37 const char *token_filter;
38 char *token_host_limit; 38 const char *token_generic;
39 char *token_html_limit; 39 const char *token_host_limit;
40 char *token_html_tags; 40 const char *token_html_limit;
41 char *token_ignore; 41 const char *token_html_tags;
42 char *token_include; 42 const char *token_ignore;
43 char *token_inherit; 43 const char *token_include;
44 char *token_lbrace; 44 const char *token_inherit;
45 char *token_mailhost; 45 const char *token_lbrace;
46 char *token_many; 46 const char *token_mailhost;
47 char *token_no; 47 const char *token_many;
48 char *token_off; 48 const char *token_no;
49 char *token_ok; 49 const char *token_off;
50 char *token_ok2; 50 const char *token_ok;
51 char *token_on; 51 const char *token_ok2;
52 char *token_rate; 52 const char *token_on;
53 char *token_rbrace; 53 const char *token_rate;
54 char *token_require; 54 const char *token_rbrace;
55 char *token_semi; 55 const char *token_require;
56 char *token_soft; 56 const char *token_semi;
57 char *token_spamassassin; 57 const char *token_soft;
58 char *token_substitute; 58 const char *token_spamassassin;
59 char *token_tld; 59 const char *token_substitute;
60 char *token_unknown; 60 const char *token_tld;
61 char *token_uribl; 61 const char *token_unknown;
62 char *token_verify; 62 const char *token_uribl;
63 char *token_white; 63 const char *token_verify;
64 char *token_yes; 64 const char *token_white;
65 65 const char *token_yes;
66 char *token_myhostname; 66
67 const char *token_myhostname;
67 #ifndef HOST_NAME_MAX 68 #ifndef HOST_NAME_MAX
68 #define HOST_NAME_MAX 255 69 #define HOST_NAME_MAX 255
69 #endif 70 #endif
70 char myhostname[HOST_NAME_MAX+1]; 71 char myhostname[HOST_NAME_MAX+1];
71 72
172 } 173 }
173 return 0; 174 return 0;
174 } 175 }
175 176
176 177
177 int SMTP::cmd(char *c) { 178 int SMTP::cmd(const char *c) {
178 if (c) { 179 if (c) {
179 init(); 180 init();
180 append(c); 181 append(c);
181 } 182 }
182 append("\r\n"); 183 append("\r\n");
199 efrom[0] = '\0'; 200 efrom[0] = '\0';
200 return rc; 201 return rc;
201 } 202 }
202 203
203 204
204 int SMTP::from(char *f) { 205 int SMTP::from(const char *f) {
205 // the mail from address was originally passed in from sendmail enclosed in 206 // the mail from address was originally passed in from sendmail enclosed in
206 // <>. to_lower_string() removed the <> and converted the rest to lowercase, 207 // <>. to_lower_string() removed the <> and converted the rest to lowercase,
207 // except in the case of an empty return path, which was left as the two 208 // except in the case of an empty return path, which was left as the two
208 // character string <>. 209 // character string <>.
209 if (strncmp(efrom, f, maxlen)) { 210 if (strncmp(efrom, f, maxlen)) {
217 } 218 }
218 return 250; // pretend it worked 219 return 250; // pretend it worked
219 } 220 }
220 221
221 222
222 int SMTP::rcpt(char *t) { 223 int SMTP::rcpt(const char *t) {
223 init(); 224 init();
224 append("RCPT TO:<"); 225 append("RCPT TO:<");
225 append(t); 226 append(t);
226 append(">"); 227 append(">");
227 return cmd(NULL); 228 return cmd(NULL);
238 close(fd); 239 close(fd);
239 } 240 }
240 241
241 242
242 #ifdef VERIFY_DEBUG 243 #ifdef VERIFY_DEBUG
243 void SMTP::log(char *m, int v) { 244 void SMTP::log(const char *m, int v) {
244 char buf[maxlen]; 245 char buf[maxlen];
245 snprintf(buf, maxlen, m, v); 246 snprintf(buf, maxlen, m, v);
246 my_syslog(buf); 247 my_syslog(buf);
247 } 248 }
248 249
249 250
250 void SMTP::log(char *m, char *v) { 251 void SMTP::log(const char *m, const char *v) {
251 char buf[maxlen]; 252 char buf[maxlen];
252 snprintf(buf, maxlen, m, v); 253 snprintf(buf, maxlen, m, v);
253 my_syslog(buf); 254 my_syslog(buf);
254 } 255 }
255 #endif 256 #endif
256 257
257 258
258 //////////////////////////////////////////////// 259 ////////////////////////////////////////////////
259 // smtp verifier so backup mx machines can see the valid users 260 // smtp verifier so backup mx machines can see the valid users
260 // 261 //
261 VERIFY::VERIFY(char *h) { 262 VERIFY::VERIFY(const char *h) {
262 host = h; 263 host = h;
263 last_err = 0; 264 last_err = 0;
264 pthread_mutex_init(&mutex, 0); 265 pthread_mutex_init(&mutex, 0);
265 } 266 }
266 267
362 pthread_mutex_unlock(&mutex); 363 pthread_mutex_unlock(&mutex);
363 } 364 }
364 } 365 }
365 366
366 367
367 bool VERIFY::ok(char *from, char *to) { 368 bool VERIFY::ok(const char *from, const char *to) {
368 if (host == token_myhostname) return true; 369 if (host == token_myhostname) return true;
369 SMTP *conn = get_connection(); 370 SMTP *conn = get_connection();
370 if (!conn) return true; // cannot verify right now, we have socket errors 371 if (!conn) return true; // cannot verify right now, we have socket errors
371 int rc; 372 int rc;
372 rc = conn->from(from); 373 rc = conn->from(from);
388 389
389 390
390 //////////////////////////////////////////////// 391 ////////////////////////////////////////////////
391 // setup a new smtp verify host 392 // setup a new smtp verify host
392 // 393 //
393 VERIFYP add_verify_host(char *host); 394 VERIFYP add_verify_host(const char *host);
394 VERIFYP add_verify_host(char *host) { 395 VERIFYP add_verify_host(const char *host) {
395 VERIFYP rc = NULL; 396 VERIFYP rc = NULL;
396 pthread_mutex_lock(&verifier_mutex); 397 pthread_mutex_lock(&verifier_mutex);
397 verify_map::iterator i = verifiers.find(host); 398 verify_map::iterator i = verifiers.find(host);
398 if (i == verifiers.end()) { 399 if (i == verifiers.end()) {
399 rc = new VERIFY(host); 400 rc = new VERIFY(host);
423 424
424 425
425 //////////////////////////////////////////////// 426 ////////////////////////////////////////////////
426 // automatic whitelister 427 // automatic whitelister
427 // 428 //
428 WHITELISTER::WHITELISTER(char *f, int d) { 429 WHITELISTER::WHITELISTER(const char *f, int d) {
429 fn = f; 430 fn = f;
430 days = d; 431 days = d;
431 pthread_mutex_init(&mutex, 0); 432 pthread_mutex_init(&mutex, 0);
432 need = false; 433 need = false;
433 loaded = time(NULL); 434 loaded = time(NULL);
480 481
481 // purge old entries 482 // purge old entries
482 for (autowhite_sent::iterator i=rcpts.begin(); i!=rcpts.end();) { 483 for (autowhite_sent::iterator i=rcpts.begin(); i!=rcpts.end();) {
483 time_t when = (*i).second; 484 time_t when = (*i).second;
484 if (when < limit) { 485 if (when < limit) {
485 char *who = (*i).first; 486 const char *who = (*i).first;
486 free(who); 487 free((void*)who);
487 rcpts.erase(i++); 488 rcpts.erase(i++);
488 need = true; 489 need = true;
489 } 490 }
490 else i++; 491 else i++;
491 } 492 }
494 // dump the file 495 // dump the file
495 ofstream ofs; 496 ofstream ofs;
496 ofs.open(fn); 497 ofs.open(fn);
497 if (!ofs.fail()) { 498 if (!ofs.fail()) {
498 for (autowhite_sent::iterator i=rcpts.begin(); i!=rcpts.end(); i++) { 499 for (autowhite_sent::iterator i=rcpts.begin(); i!=rcpts.end(); i++) {
499 char *who = (*i).first; 500 const char *who = (*i).first;
500 int when = (*i).second; 501 int when = (*i).second;
501 if (!strchr(who, ' ')) { 502 if (!strchr(who, ' ')) {
502 ofs << who << " " << when << endl; 503 ofs << who << " " << when << endl;
503 } 504 }
504 } 505 }
509 } 510 }
510 pthread_mutex_unlock(&mutex); 511 pthread_mutex_unlock(&mutex);
511 } 512 }
512 513
513 514
514 void WHITELISTER::sent(char *to) { 515 void WHITELISTER::sent(const char *to) {
515 // we take ownership of the string 516 // we take ownership of the string
516 pthread_mutex_lock(&mutex); 517 pthread_mutex_lock(&mutex);
517 need = true; 518 need = true;
518 autowhite_sent::iterator i = rcpts.find(to); 519 autowhite_sent::iterator i = rcpts.find(to);
519 if (i == rcpts.end()) { 520 if (i == rcpts.end()) {
520 rcpts[to] = time(NULL); 521 rcpts[to] = time(NULL);
521 } 522 }
522 else { 523 else {
523 (*i).second = time(NULL); 524 (*i).second = time(NULL);
524 free(to); 525 free((void*)to);
525 } 526 }
526 pthread_mutex_unlock(&mutex); 527 pthread_mutex_unlock(&mutex);
527 } 528 }
528 529
529 530
530 bool WHITELISTER::is_white(char *from) { 531 bool WHITELISTER::is_white(const char *from) {
531 pthread_mutex_lock(&mutex); 532 pthread_mutex_lock(&mutex);
532 autowhite_sent::iterator i = rcpts.find(from); 533 autowhite_sent::iterator i = rcpts.find(from);
533 bool rc = (i != rcpts.end()); 534 bool rc = (i != rcpts.end());
534 pthread_mutex_unlock(&mutex); 535 pthread_mutex_unlock(&mutex);
535 return rc; 536 return rc;
537 538
538 539
539 //////////////////////////////////////////////// 540 ////////////////////////////////////////////////
540 // setup a new auto whitelister file 541 // setup a new auto whitelister file
541 // 542 //
542 WHITELISTERP add_whitelister_file(char *fn, int days); 543 WHITELISTERP add_whitelister_file(const char *fn, int days);
543 WHITELISTERP add_whitelister_file(char *fn, int days) { 544 WHITELISTERP add_whitelister_file(const char *fn, int days) {
544 WHITELISTERP rc = NULL; 545 WHITELISTERP rc = NULL;
545 pthread_mutex_lock(&whitelister_mutex); 546 pthread_mutex_lock(&whitelister_mutex);
546 whitelister_map::iterator i = whitelisters.find(fn); 547 whitelister_map::iterator i = whitelisters.find(fn);
547 if (i == whitelisters.end()) { 548 if (i == whitelisters.end()) {
548 rc = new WHITELISTER(fn, days); 549 rc = new WHITELISTER(fn, days);
572 } 573 }
573 return NULL; 574 return NULL;
574 } 575 }
575 576
576 577
577 DELAYWHITE::DELAYWHITE(char *loto_, WHITELISTERP w_, CONTEXTP con_) { 578 DELAYWHITE::DELAYWHITE(const char *loto_, WHITELISTERP w_, CONTEXTP con_) {
578 loto = loto_; 579 loto = loto_;
579 w = w_; 580 w = w_;
580 con = con_; 581 con = con_;
581 } 582 }
582 583
583 584
584 DNSBL::DNSBL(char *n, char *s, char *m) { 585 DNSBL::DNSBL(const char *n, const char *s, const char *m) {
585 name = n; 586 name = n;
586 suffix = s; 587 suffix = s;
587 message = m; 588 message = m;
588 } 589 }
589 590
623 default_context = con; 624 default_context = con;
624 } 625 }
625 } 626 }
626 627
627 628
628 void CONFIG::add_to(char *to, CONTEXTP con) { 629 void CONFIG::add_to(const char *to, CONTEXTP con) {
629 context_map::iterator i = env_to.find(to); 630 context_map::iterator i = env_to.find(to);
630 if (i != env_to.end()) { 631 if (i != env_to.end()) {
631 CONTEXTP c = (*i).second; 632 CONTEXTP c = (*i).second;
632 if ((c != con) && (c != con->get_parent())) { 633 if ((c != con) && (c != con->get_parent())) {
633 if (debug_syslog) { 634 if (debug_syslog) {
634 char oldname[maxlen]; 635 char oldname[maxlen];
635 char newname[maxlen]; 636 char newname[maxlen];
636 char *oldn = c->get_full_name(oldname, maxlen); 637 const char *oldn = c->get_full_name(oldname, maxlen);
637 char *newn = con->get_full_name(newname, maxlen); 638 const char *newn = con->get_full_name(newname, maxlen);
638 char buf[maxlen*3]; 639 char buf[maxlen*3];
639 snprintf(buf, maxlen*3, "both %s and %s claim envelope to %s, the second one wins", oldn, newn, to); 640 snprintf(buf, maxlen*3, "both %s and %s claim envelope to %s, the second one wins", oldn, newn, to);
640 my_syslog(buf); 641 my_syslog(buf);
641 } 642 }
642 } 643 }
643 } 644 }
644 env_to[to] = con; 645 env_to[to] = con;
645 } 646 }
646 647
647 648
648 CONTEXTP CONFIG::find_context(char *to) { 649 CONTEXTP CONFIG::find_context(const char *to) {
649 context_map::iterator i = env_to.find(to); 650 context_map::iterator i = env_to.find(to);
650 if (i != env_to.end()) return (*i).second; // found user@domain key 651 if (i != env_to.end()) return (*i).second; // found user@domain key
651 char *x = strchr(to, '@'); 652 const char *x = strchr(to, '@');
652 if (x) { 653 if (x) {
653 x++; 654 x++;
654 i = env_to.find(x); 655 i = env_to.find(x);
655 if (i != env_to.end()) return (*i).second; // found domain key 656 if (i != env_to.end()) return (*i).second; // found domain key
656 char y = *x; 657 size_t len = x - to;
657 *x = '\0'; 658 char user[len+1];
658 i = env_to.find(to); 659 memcpy(user, to, len);
659 *x = y; 660 user[len] = '\0';
661 i = env_to.find(user);
660 if (i != env_to.end()) return (*i).second; // found user@ key 662 if (i != env_to.end()) return (*i).second; // found user@ key
661 } 663 }
662 return default_context; 664 return default_context;
663 } 665 }
664 666
671 CONTEXTP p = c->get_parent(); 673 CONTEXTP p = c->get_parent();
672 if (!p && (c != default_context)) c->dump(false, spamass); 674 if (!p && (c != default_context)) c->dump(false, spamass);
673 } 675 }
674 char buf[maxlen]; 676 char buf[maxlen];
675 for (context_map::iterator i=env_to.begin(); i!=env_to.end(); i++) { 677 for (context_map::iterator i=env_to.begin(); i!=env_to.end(); i++) {
676 char *to = (*i).first; 678 const char *to = (*i).first;
677 CONTEXTP con = (*i).second; 679 CONTEXTP con = (*i).second;
678 printf("// envelope to %s \t-> context %s \n", to, con->get_full_name(buf,maxlen)); 680 printf("// envelope to %s \t-> context %s \n", to, con->get_full_name(buf,maxlen));
679 } 681 }
680 if (spamass && (spamc == spamc_empty)) { 682 if (spamass && (spamc == spamc_empty)) {
681 printf("// *** warning - spamassassin filtering requested, but spamc not found by autoconf.\n"); 683 printf("// *** warning - spamassassin filtering requested, but spamc not found by autoconf.\n");
682 } 684 }
683 } 685 }
684 686
685 687
686 CONTEXT::CONTEXT(CONTEXTP parent_, char *name_) { 688 CONTEXT::CONTEXT(CONTEXTP parent_, const char *name_) {
687 parent = parent_; 689 parent = parent_;
688 name = name_; 690 name = name_;
689 verify_host = NULL; 691 verify_host = NULL;
690 verifier = NULL; 692 verifier = NULL;
691 generic_regx = NULL; 693 generic_regx = NULL;
726 if (!parent) return false; 728 if (!parent) return false;
727 return parent->is_parent(p); 729 return parent->is_parent(p);
728 } 730 }
729 731
730 732
731 char *CONTEXT::get_full_name(char *buffer, int size) { 733 const char *CONTEXT::get_full_name(char *buffer, int size) {
732 if (!parent) return name; 734 if (!parent) return name;
733 char buf[maxlen]; 735 char buf[maxlen];
734 snprintf(buffer, size, "%s.%s", parent->get_full_name(buf, maxlen), name); 736 snprintf(buffer, size, "%s.%s", parent->get_full_name(buf, maxlen), name);
735 return buffer; 737 return buffer;
736 } 738 }
737 739
738 740
739 bool CONTEXT::set_generic(char *regx, char *msg) 741 bool CONTEXT::set_generic(const char *regx, const char *msg)
740 { 742 {
741 int rc = 0; 743 int rc = 0;
742 if (generic_regx) regfree(&generic_pattern); 744 if (generic_regx) regfree(&generic_pattern);
743 generic_regx = regx; 745 generic_regx = regx;
744 generic_message = msg; 746 generic_message = msg;
747 } 749 }
748 return rc; // true iff bad pattern 750 return rc; // true iff bad pattern
749 } 751 }
750 752
751 753
752 char *CONTEXT::generic_match(char *client) 754 const char *CONTEXT::generic_match(const char *client)
753 { 755 {
754 if (!client) return NULL; // allow missing _ macro, which will disable generic checking 756 if (!client) return NULL; // allow missing _ macro, which will disable generic checking
755 if (parent && !generic_regx) return parent->generic_match(client); 757 if (parent && !generic_regx) return parent->generic_match(client);
756 if (!generic_regx) return NULL; 758 if (!generic_regx) return NULL;
757 if (0 == regexec(&generic_pattern, client, 0, NULL, 0)) { 759 if (0 == regexec(&generic_pattern, client, 0, NULL, 0)) {
759 } 761 }
760 return NULL; 762 return NULL;
761 } 763 }
762 764
763 765
764 bool CONTEXT::cover_env_to(char *to) { 766 bool CONTEXT::cover_env_to(const char *to) {
765 char buffer[maxlen]; 767 const char *x = strchr(to, '@');
766 char *x = strchr(to, '@');
767 if (x) x++; 768 if (x) x++;
768 else x = to; 769 else x = to;
769 if (*x == '\0') return true; // always allow covering addresses with no domain name, eg abuse@ 770 if (*x == '\0') return true; // always allow covering addresses with no domain name, eg abuse@
770 if (!parent && env_to.empty()) return true; // empty env_to at global level covers everything 771 if (!parent && env_to.empty()) return true; // empty env_to at global level covers everything
771 string_set::iterator i = env_to.find(x); 772 string_set::iterator i = env_to.find(x);
776 } 777 }
777 return false; 778 return false;
778 } 779 }
779 780
780 781
781 VERIFYP CONTEXT::find_verify(char *to) { 782 VERIFYP CONTEXT::find_verify(const char *to) {
782 if (verifier && (verify_host != token_myhostname) && cover_env_to(to)) 783 if (verifier && (verify_host != token_myhostname) && cover_env_to(to))
783 return verifier; 784 return verifier;
784 else if (parent) 785 else if (parent)
785 return parent->find_verify(to); 786 return parent->find_verify(to);
786 else 787 else
787 return NULL; 788 return NULL;
788 } 789 }
789 790
790 791
791 WHITELISTERP CONTEXT::find_autowhite(char *from, char *to) { 792 WHITELISTERP CONTEXT::find_autowhite(const char *from, const char *to) {
792 if (whitelister && cover_env_to(to) && !cover_env_to(from)) 793 if (whitelister && cover_env_to(to) && !cover_env_to(from))
793 return whitelister; 794 return whitelister;
794 else if (parent) 795 else if (parent)
795 return parent->find_autowhite(from, to); 796 return parent->find_autowhite(from, to);
796 else 797 else
797 return NULL; 798 return NULL;
798 } 799 }
799 800
800 801
801 int CONTEXT::find_rate(char *user) { 802 int CONTEXT::find_rate(const char *user) {
802 if (rcpt_per_hour.empty()) return default_rcpt_rate; 803 if (rcpt_per_hour.empty()) return default_rcpt_rate;
803 rcpt_rates::iterator i = rcpt_per_hour.find(user); 804 rcpt_rates::iterator i = rcpt_per_hour.find(user);
804 return (i == rcpt_per_hour.end()) ? default_rcpt_rate : (*i).second; 805 return (i == rcpt_per_hour.end()) ? default_rcpt_rate : (*i).second;
805 } 806 }
806 807
807 808
808 char *CONTEXT::find_from(char *from, bool update_white) { 809 const char *CONTEXT::find_from(const char *from, bool update_white) {
809 WHITELISTERP w = whitelister; 810 WHITELISTERP w = whitelister;
810 CONTEXTP p = parent; 811 CONTEXTP p = parent;
811 while (!w && p) { 812 while (!w && p) {
812 w = p->whitelister; 813 w = p->whitelister;
813 p = p->parent; 814 p = p->parent;
823 } 824 }
824 w->sent(strdup(from)); 825 w->sent(strdup(from));
825 } 826 }
826 return token_white; 827 return token_white;
827 } 828 }
828 char *rc = env_from_default; 829 const char *rc = env_from_default;
829 string_map::iterator i = env_from.find(from); 830 string_map::iterator i = env_from.find(from);
830 if (i != env_from.end()) rc = (*i).second; // found user@domain key 831 if (i != env_from.end()) rc = (*i).second; // found user@domain key
831 else { 832 else {
832 char *x = strchr(from, '@'); 833 char *x = strchr(from, '@');
833 if (x) { 834 if (x) {
846 if ((rc == token_inherit) && parent) return parent->find_from(from); 847 if ((rc == token_inherit) && parent) return parent->find_from(from);
847 return (rc == token_inherit) ? token_unknown : rc; 848 return (rc == token_inherit) ? token_unknown : rc;
848 } 849 }
849 850
850 851
851 CONTEXTP CONTEXT::find_context(char *from) { 852 CONTEXTP CONTEXT::find_context(const char *from) {
852 context_map::iterator i = env_from_context.find(from); 853 context_map::iterator i = env_from_context.find(from);
853 if (i != env_from_context.end()) return (*i).second; // found user@domain key 854 if (i != env_from_context.end()) return (*i).second; // found user@domain key
854 char *x = strchr(from, '@'); 855 char *x = strchr(from, '@');
855 if (x) { 856 if (x) {
856 x++; 857 x++;
864 } 865 }
865 return this; 866 return this;
866 } 867 }
867 868
868 869
869 CONTEXTP CONTEXT::find_from_context_name(char *name) { 870 CONTEXTP CONTEXT::find_from_context_name(const char *name) {
870 context_map::iterator i = children.find(name); 871 context_map::iterator i = children.find(name);
871 if (i != children.end()) return (*i).second; 872 if (i != children.end()) return (*i).second;
872 return NULL; 873 return NULL;
873 } 874 }
874 875
875 876
876 DNSBLP CONTEXT::find_dnsbl(char *name) { 877 DNSBLP CONTEXT::find_dnsbl(const char *name) {
877 dnsblp_map::iterator i = dnsbl_names.find(name); 878 dnsblp_map::iterator i = dnsbl_names.find(name);
878 if (i != dnsbl_names.end()) return (*i).second; 879 if (i != dnsbl_names.end()) return (*i).second;
879 if (parent) return parent->find_dnsbl(name); 880 if (parent) return parent->find_dnsbl(name);
880 return NULL; 881 return NULL;
881 } 882 }
882 883
883 884
884 char* CONTEXT::get_content_suffix() { 885 const char* CONTEXT::get_content_suffix() {
885 if (!content_suffix && parent) return parent->get_content_suffix(); 886 if (!content_suffix && parent) return parent->get_content_suffix();
886 return content_suffix; 887 return content_suffix;
887 } 888 }
888 889
889 890
890 char* CONTEXT::get_uribl_suffix() { 891 const char* CONTEXT::get_uribl_suffix() {
891 if (!uribl_suffix && parent) return parent->get_uribl_suffix(); 892 if (!uribl_suffix && parent) return parent->get_uribl_suffix();
892 return uribl_suffix; 893 return uribl_suffix;
893 } 894 }
894 895
895 896
896 char* CONTEXT::get_content_message() { 897 const char* CONTEXT::get_content_message() {
897 if (!content_message && parent) return parent->get_content_message(); 898 if (!content_message && parent) return parent->get_content_message();
898 return content_message; 899 return content_message;
899 } 900 }
900 901
901 902
902 char* CONTEXT::get_uribl_message() { 903 const char* CONTEXT::get_uribl_message() {
903 if (!uribl_message && parent) return parent->get_uribl_message(); 904 if (!uribl_message && parent) return parent->get_uribl_message();
904 return uribl_message; 905 return uribl_message;
905 } 906 }
906 907
907 908
963 char indent[maxlen]; 964 char indent[maxlen];
964 int i = min(maxlen-1, level*4); 965 int i = min(maxlen-1, level*4);
965 memset(indent, ' ', i); 966 memset(indent, ' ', i);
966 indent[i] = '\0'; 967 indent[i] = '\0';
967 char buf[maxlen]; 968 char buf[maxlen];
968 char *fullname = get_full_name(buf,maxlen); 969 const char *fullname = get_full_name(buf,maxlen);
969 printf("%s context %s { \t// %s\n", indent, name, fullname); 970 printf("%s context %s { \t// %s\n", indent, name, fullname);
970 971
971 for (dnsblp_map::iterator i=dnsbl_names.begin(); i!=dnsbl_names.end(); i++) { 972 for (dnsblp_map::iterator i=dnsbl_names.begin(); i!=dnsbl_names.end(); i++) {
972 char *n = (*i).first; 973 const char *n = (*i).first;
973 DNSBL &d = *(*i).second; 974 DNSBL &d = *(*i).second;
974 printf("%s dnsbl %s %s \"%s\"; \n", indent, n, d.suffix, d.message); 975 printf("%s dnsbl %s %s \"%s\"; \n", indent, n, d.suffix, d.message);
975 } 976 }
976 977
977 dnsblp_list dl = get_dnsbl_list(); 978 dnsblp_list dl = get_dnsbl_list();
983 } 984 }
984 printf("; \n"); 985 printf("; \n");
985 } 986 }
986 987
987 if (content_filtering) { 988 if (content_filtering) {
988 printf("%s content on { \n", indent, env_from_default); 989 printf("%s content on { \n", indent);
989 if (content_suffix) { 990 if (content_suffix) {
990 printf("%s filter %s \"%s\"; \n", indent, content_suffix, content_message); 991 printf("%s filter %s \"%s\"; \n", indent, content_suffix, content_message);
991 } 992 }
992 if (uribl_suffix) { 993 if (uribl_suffix) {
993 printf("%s uribl %s \"%s\"; \n", indent, uribl_suffix, uribl_message); 994 printf("%s uribl %s \"%s\"; \n", indent, uribl_suffix, uribl_message);
1046 else printf("%s dcc_bulk_threshold %d; \n", indent, dcc_bulk_threshold); 1047 else printf("%s dcc_bulk_threshold %d; \n", indent, dcc_bulk_threshold);
1047 printf("%s }; \n", indent); 1048 printf("%s }; \n", indent);
1048 spamass |= (spamassassin_limit != 0); 1049 spamass |= (spamassassin_limit != 0);
1049 } 1050 }
1050 else { 1051 else {
1051 printf("%s content off {}; \n", indent, env_from_default); 1052 printf("%s content off {}; \n", indent);
1052 } 1053 }
1053 1054
1054 printf("%s env_to { \t// %s\n", indent, fullname); 1055 printf("%s env_to { \t// %s\n", indent, fullname);
1055 for (string_set::iterator i=env_to.begin(); i!=env_to.end(); i++) { 1056 for (string_set::iterator i=env_to.begin(); i!=env_to.end(); i++) {
1056 printf("%s %s; \n", indent, *i); 1057 printf("%s %s; \n", indent, *i);
1077 1078
1078 printf("%s env_from %s { \t// %s\n", indent, env_from_default, fullname); 1079 printf("%s env_from %s { \t// %s\n", indent, env_from_default, fullname);
1079 if (!env_from.empty()) { 1080 if (!env_from.empty()) {
1080 printf("%s // white/black/unknown \n", indent); 1081 printf("%s // white/black/unknown \n", indent);
1081 for (string_map::iterator i=env_from.begin(); i!=env_from.end(); i++) { 1082 for (string_map::iterator i=env_from.begin(); i!=env_from.end(); i++) {
1082 char *f = (*i).first; 1083 const char *f = (*i).first;
1083 char *t = (*i).second; 1084 const char *t = (*i).second;
1084 printf("%s %s \t%s; \n", indent, f, t); 1085 printf("%s %s \t%s; \n", indent, f, t);
1085 } 1086 }
1086 } 1087 }
1087 if (!env_from_context.empty()) { 1088 if (!env_from_context.empty()) {
1088 printf("%s // child contexts \n", indent); 1089 printf("%s // child contexts \n", indent);
1089 for (context_map::iterator j=env_from_context.begin(); j!=env_from_context.end(); j++) { 1090 for (context_map::iterator j=env_from_context.begin(); j!=env_from_context.end(); j++) {
1090 char *f = (*j).first; 1091 const char *f = (*j).first;
1091 CONTEXTP t = (*j).second; 1092 CONTEXTP t = (*j).second;
1092 printf("%s %s \t%s; \n", indent, f, t->name); 1093 printf("%s %s \t%s; \n", indent, f, t->name);
1093 } 1094 }
1094 } 1095 }
1095 printf("%s }; \n", indent); 1096 printf("%s }; \n", indent);
1096 1097
1097 if (isdefault) { 1098 if (isdefault) {
1098 printf("%s rate_limit %d { \n", indent, default_rcpt_rate); 1099 printf("%s rate_limit %d { \n", indent, default_rcpt_rate);
1099 for (rcpt_rates::iterator j=rcpt_per_hour.begin(); j!=rcpt_per_hour.end(); j++) { 1100 for (rcpt_rates::iterator j=rcpt_per_hour.begin(); j!=rcpt_per_hour.end(); j++) {
1100 char *u = (*j).first; 1101 const char *u = (*j).first;
1101 int l = (*j).second; 1102 int l = (*j).second;
1102 printf("%s \"%s\" \t%d; \n", indent, u, l); 1103 printf("%s \"%s\" \t%d; \n", indent, u, l);
1103 } 1104 }
1104 printf("%s }; \n", indent); 1105 printf("%s }; \n", indent);
1105 } 1106 }
1106 1107
1111 //////////////////////////////////////////////// 1112 ////////////////////////////////////////////////
1112 // helper to discard the strings held by a string_set 1113 // helper to discard the strings held by a string_set
1113 // 1114 //
1114 void discard(string_set &s) { 1115 void discard(string_set &s) {
1115 for (string_set::iterator i=s.begin(); i!=s.end(); i++) { 1116 for (string_set::iterator i=s.begin(); i!=s.end(); i++) {
1116 free(*i); 1117 free((void*)*i);
1117 } 1118 }
1118 s.clear(); 1119 s.clear();
1119 } 1120 }
1120 1121
1121 1122
1122 //////////////////////////////////////////////// 1123 ////////////////////////////////////////////////
1123 // helper to register a string in a string set 1124 // helper to register a string in a string set
1124 // 1125 //
1125 char* register_string(string_set &s, char *name) { 1126 const char* register_string(string_set &s, const char *name) {
1126 string_set::iterator i = s.find(name); 1127 string_set::iterator i = s.find(name);
1127 if (i != s.end()) return *i; 1128 if (i != s.end()) return *i;
1128 char *x = strdup(name); 1129 char *x = strdup(name);
1129 s.insert(x); 1130 s.insert(x);
1130 return x; 1131 return x;
1132 1133
1133 1134
1134 //////////////////////////////////////////////// 1135 ////////////////////////////////////////////////
1135 // register a global string 1136 // register a global string
1136 // 1137 //
1137 char* register_string(char *name) { 1138 const char* register_string(const char *name) {
1138 return register_string(all_strings, name); 1139 return register_string(all_strings, name);
1139 } 1140 }
1140 1141
1141 1142
1142 //////////////////////////////////////////////// 1143 ////////////////////////////////////////////////
1147 } 1148 }
1148 1149
1149 1150
1150 //////////////////////////////////////////////// 1151 ////////////////////////////////////////////////
1151 // 1152 //
1152 bool tsa(TOKEN &tok, char *token); 1153 bool tsa(TOKEN &tok, const char *token);
1153 bool tsa(TOKEN &tok, char *token) { 1154 bool tsa(TOKEN &tok, const char *token) {
1154 char *have = tok.next(); 1155 const char *have = tok.next();
1155 if (have == token) return true; 1156 if (have == token) return true;
1156 tok.token_error(token, have); 1157 tok.token_error(token, have);
1157 return false; 1158 return false;
1158 } 1159 }
1159 1160
1160 1161
1161 //////////////////////////////////////////////// 1162 ////////////////////////////////////////////////
1162 // 1163 //
1163 bool parse_dnsbl(TOKEN &tok, CONFIG &dc, CONTEXT &me); 1164 bool parse_dnsbl(TOKEN &tok, CONFIG &dc, CONTEXT &me);
1164 bool parse_dnsbl(TOKEN &tok, CONFIG &dc, CONTEXT &me) { 1165 bool parse_dnsbl(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
1165 char *name = tok.next(); 1166 const char *name = tok.next();
1166 char *suf = tok.next(); 1167 const char *suf = tok.next();
1167 char *msg = tok.next(); 1168 const char *msg = tok.next();
1168 if (!tsa(tok, token_semi)) return false; 1169 if (!tsa(tok, token_semi)) return false;
1169 DNSBLP dnsnew = new DNSBL(name, suf, msg); 1170 DNSBLP dnsnew = new DNSBL(name, suf, msg);
1170 DNSBLP dnsold = me.find_dnsbl(name); 1171 DNSBLP dnsold = me.find_dnsbl(name);
1171 if (dnsold && (*dnsold == *dnsnew)) { 1172 if (dnsold && (*dnsold == *dnsnew)) {
1172 // duplicate redefinition, ignore it 1173 // duplicate redefinition, ignore it
1181 //////////////////////////////////////////////// 1182 ////////////////////////////////////////////////
1182 // 1183 //
1183 bool parse_dnsbll(TOKEN &tok, CONFIG &dc, CONTEXT &me); 1184 bool parse_dnsbll(TOKEN &tok, CONFIG &dc, CONTEXT &me);
1184 bool parse_dnsbll(TOKEN &tok, CONFIG &dc, CONTEXT &me) { 1185 bool parse_dnsbll(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
1185 while (true) { 1186 while (true) {
1186 char *have = tok.next(); 1187 const char *have = tok.next();
1187 if (!have) break; 1188 if (!have) break;
1188 if (have == token_semi) break; 1189 if (have == token_semi) break;
1189 DNSBLP dns = me.find_dnsbl(have); 1190 DNSBLP dns = me.find_dnsbl(have);
1190 if (dns) { 1191 if (dns) {
1191 me.add_dnsbl(dns); 1192 me.add_dnsbl(dns);
1201 1202
1202 //////////////////////////////////////////////// 1203 ////////////////////////////////////////////////
1203 // 1204 //
1204 bool parse_content(TOKEN &tok, CONFIG &dc, CONTEXT &me); 1205 bool parse_content(TOKEN &tok, CONFIG &dc, CONTEXT &me);
1205 bool parse_content(TOKEN &tok, CONFIG &dc, CONTEXT &me) { 1206 bool parse_content(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
1206 char *setting = tok.next(); 1207 const char *setting = tok.next();
1207 if (setting == token_on) { 1208 if (setting == token_on) {
1208 me.set_content_filtering(true); 1209 me.set_content_filtering(true);
1209 } 1210 }
1210 else if (setting == token_off) { 1211 else if (setting == token_off) {
1211 me.set_content_filtering(false); 1212 me.set_content_filtering(false);
1214 tok.token_error("on/off", setting); 1215 tok.token_error("on/off", setting);
1215 return false; 1216 return false;
1216 } 1217 }
1217 if (!tsa(tok, token_lbrace)) return false; 1218 if (!tsa(tok, token_lbrace)) return false;
1218 while (true) { 1219 while (true) {
1219 char *have = tok.next(); 1220 const char *have = tok.next();
1220 if (!have) break; 1221 if (!have) break;
1221 if (have == token_filter) { 1222 if (have == token_filter) {
1222 char *suffix = tok.next(); 1223 const char *suffix = tok.next();
1223 char *messag = tok.next(); 1224 const char *messag = tok.next();
1224 me.set_content_suffix(suffix); 1225 me.set_content_suffix(suffix);
1225 me.set_content_message(messag); 1226 me.set_content_message(messag);
1226 if (!tsa(tok, token_semi)) return false; 1227 if (!tsa(tok, token_semi)) return false;
1227 } 1228 }
1228 else if (have == token_uribl) { 1229 else if (have == token_uribl) {
1229 char *suffix = tok.next(); 1230 const char *suffix = tok.next();
1230 char *messag = tok.next(); 1231 const char *messag = tok.next();
1231 me.set_uribl_suffix(suffix); 1232 me.set_uribl_suffix(suffix);
1232 me.set_uribl_message(messag); 1233 me.set_uribl_message(messag);
1233 if (!tsa(tok, token_semi)) return false; 1234 if (!tsa(tok, token_semi)) return false;
1234 } 1235 }
1235 else if (have == token_ignore) { 1236 else if (have == token_ignore) {
1236 if (!tsa(tok, token_lbrace)) return false; 1237 if (!tsa(tok, token_lbrace)) return false;
1237 while (true) { 1238 while (true) {
1238 if (!have) break; 1239 if (!have) break;
1239 char *have = tok.next(); 1240 const char *have = tok.next();
1240 if (have == token_rbrace) break; // done 1241 if (have == token_rbrace) break; // done
1241 me.add_ignore(have); 1242 me.add_ignore(have);
1242 } 1243 }
1243 if (!tsa(tok, token_semi)) return false; 1244 if (!tsa(tok, token_semi)) return false;
1244 } 1245 }
1245 else if (have == token_tld) { 1246 else if (have == token_tld) {
1246 if (!tsa(tok, token_lbrace)) return false; 1247 if (!tsa(tok, token_lbrace)) return false;
1247 while (true) { 1248 while (true) {
1248 char *have = tok.next(); 1249 const char *have = tok.next();
1249 if (!have) break; 1250 if (!have) break;
1250 if (have == token_rbrace) break; // done 1251 if (have == token_rbrace) break; // done
1251 me.add_tld(have); 1252 me.add_tld(have);
1252 } 1253 }
1253 if (!tsa(tok, token_semi)) return false; 1254 if (!tsa(tok, token_semi)) return false;
1254 } 1255 }
1255 else if (have == token_cctld) { 1256 else if (have == token_cctld) {
1256 if (!tsa(tok, token_lbrace)) return false; 1257 if (!tsa(tok, token_lbrace)) return false;
1257 while (true) { 1258 while (true) {
1258 char *have = tok.next(); 1259 const char *have = tok.next();
1259 if (!have) break; 1260 if (!have) break;
1260 if (have == token_rbrace) break; // done 1261 if (have == token_rbrace) break; // done
1261 me.add_cctld(have); 1262 me.add_cctld(have);
1262 } 1263 }
1263 if (!tsa(tok, token_semi)) return false; 1264 if (!tsa(tok, token_semi)) return false;
1264 } 1265 }
1265 else if (have == token_html_tags) { 1266 else if (have == token_html_tags) {
1266 if (!tsa(tok, token_lbrace)) return false; 1267 if (!tsa(tok, token_lbrace)) return false;
1267 while (true) { 1268 while (true) {
1268 char *have = tok.next(); 1269 const char *have = tok.next();
1269 if (!have) break; 1270 if (!have) break;
1270 if (have == token_rbrace) { 1271 if (have == token_rbrace) {
1271 break; // done 1272 break; // done
1272 } 1273 }
1273 else { 1274 else {
1375 // 1376 //
1376 bool parse_envto(TOKEN &tok, CONFIG &dc, CONTEXT &me); 1377 bool parse_envto(TOKEN &tok, CONFIG &dc, CONTEXT &me);
1377 bool parse_envto(TOKEN &tok, CONFIG &dc, CONTEXT &me) { 1378 bool parse_envto(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
1378 if (!tsa(tok, token_lbrace)) return false; 1379 if (!tsa(tok, token_lbrace)) return false;
1379 while (true) { 1380 while (true) {
1380 char *have = tok.next(); 1381 const char *have = tok.next();
1381 if (!have) break; 1382 if (!have) break;
1382 if (have == token_rbrace) break; 1383 if (have == token_rbrace) break;
1383 if (have == token_semi) { 1384 if (have == token_semi) {
1384 // optional separators 1385 // optional separators
1385 } 1386 }
1386 else if (have == token_dccto) { 1387 else if (have == token_dccto) {
1387 char *flavor = tok.next(); 1388 const char *flavor = tok.next();
1388 if (!tsa(tok, token_lbrace)) return false; 1389 if (!tsa(tok, token_lbrace)) return false;
1389 bool keeping = false; 1390 bool keeping = false;
1390 while (true) { 1391 while (true) {
1391 char *have = tok.next(); 1392 const char *have = tok.next();
1392 if (!have) break; 1393 if (!have) break;
1393 if (have == token_rbrace) break; 1394 if (have == token_rbrace) break;
1394 if (have == flavor) { 1395 if (have == flavor) {
1395 keeping = true; 1396 keeping = true;
1396 continue; 1397 continue;
1437 1438
1438 //////////////////////////////////////////////// 1439 ////////////////////////////////////////////////
1439 // 1440 //
1440 bool parse_verify(TOKEN &tok, CONFIG &dc, CONTEXT &me); 1441 bool parse_verify(TOKEN &tok, CONFIG &dc, CONTEXT &me);
1441 bool parse_verify(TOKEN &tok, CONFIG &dc, CONTEXT &me) { 1442 bool parse_verify(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
1442 char *host = tok.next(); 1443 const char *host = tok.next();
1443 if (!tsa(tok, token_semi)) return false; 1444 if (!tsa(tok, token_semi)) return false;
1444 me.set_verify(host); 1445 me.set_verify(host);
1445 me.set_verifier(add_verify_host(host)); 1446 me.set_verifier(add_verify_host(host));
1446 return true; 1447 return true;
1447 } 1448 }
1449 1450
1450 //////////////////////////////////////////////// 1451 ////////////////////////////////////////////////
1451 // 1452 //
1452 bool parse_generic(TOKEN &tok, CONFIG &dc, CONTEXT &me); 1453 bool parse_generic(TOKEN &tok, CONFIG &dc, CONTEXT &me);
1453 bool parse_generic(TOKEN &tok, CONFIG &dc, CONTEXT &me) { 1454 bool parse_generic(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
1454 char *regx = tok.next(); 1455 const char *regx = tok.next();
1455 char *msg = tok.next(); 1456 const char *msg = tok.next();
1456 if (!tsa(tok, token_semi)) return false; 1457 if (!tsa(tok, token_semi)) return false;
1457 if (me.set_generic(regx, msg)) { 1458 if (me.set_generic(regx, msg)) {
1458 tok.token_error("invalid regular expression %s", regx, regx); 1459 tok.token_error("invalid regular expression %s", regx, regx);
1459 return false; 1460 return false;
1460 } 1461 }
1465 //////////////////////////////////////////////// 1466 ////////////////////////////////////////////////
1466 // 1467 //
1467 bool parse_autowhite(TOKEN &tok, CONFIG &dc, CONTEXT &me); 1468 bool parse_autowhite(TOKEN &tok, CONFIG &dc, CONTEXT &me);
1468 bool parse_autowhite(TOKEN &tok, CONFIG &dc, CONTEXT &me) { 1469 bool parse_autowhite(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
1469 int days = tok.nextint(); 1470 int days = tok.nextint();
1470 char *fn = tok.next(); 1471 const char *fn = tok.next();
1471 if (!tsa(tok, token_semi)) return false; 1472 if (!tsa(tok, token_semi)) return false;
1472 me.set_autowhite(fn); 1473 me.set_autowhite(fn);
1473 me.set_whitelister(add_whitelister_file(fn, days)); 1474 me.set_whitelister(add_whitelister_file(fn, days));
1474 return true; 1475 return true;
1475 } 1476 }
1477 1478
1478 //////////////////////////////////////////////// 1479 ////////////////////////////////////////////////
1479 // 1480 //
1480 bool parse_envfrom(TOKEN &tok, CONFIG &dc, CONTEXT &me); 1481 bool parse_envfrom(TOKEN &tok, CONFIG &dc, CONTEXT &me);
1481 bool parse_envfrom(TOKEN &tok, CONFIG &dc, CONTEXT &me) { 1482 bool parse_envfrom(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
1482 char *st = tok.next(); 1483 const char *st = tok.next();
1483 if ((st == token_black) || (st == token_white) || (st == token_unknown) || (st == token_inherit)) { 1484 if ((st == token_black) || (st == token_white) || (st == token_unknown) || (st == token_inherit)) {
1484 me.set_from_default(st); 1485 me.set_from_default(st);
1485 } 1486 }
1486 else { 1487 else {
1487 tok.push(st); 1488 tok.push(st);
1488 } 1489 }
1489 if (!tsa(tok, token_lbrace)) return false; 1490 if (!tsa(tok, token_lbrace)) return false;
1490 while (true) { 1491 while (true) {
1491 char *have = tok.next(); 1492 const char *have = tok.next();
1492 if (!have) break; 1493 if (!have) break;
1493 if (have == token_rbrace) break; 1494 if (have == token_rbrace) break;
1494 if (have == token_semi) { 1495 if (have == token_semi) {
1495 // optional separators 1496 // optional separators
1496 } 1497 }
1497 else if (have == token_dccfrom) { 1498 else if (have == token_dccfrom) {
1498 if (!tsa(tok, token_lbrace)) return false; 1499 if (!tsa(tok, token_lbrace)) return false;
1499 bool keeping = false; 1500 bool keeping = false;
1500 bool many = false; 1501 bool many = false;
1501 while (true) { 1502 while (true) {
1502 char *have = tok.next(); 1503 const char *have = tok.next();
1503 if (!have) break; 1504 if (!have) break;
1504 if (have == token_rbrace) break; 1505 if (have == token_rbrace) break;
1505 if (have == token_ok) { 1506 if (have == token_ok) {
1506 keeping = true; 1507 keeping = true;
1507 many = false; 1508 many = false;
1531 tok.skipeol(); 1532 tok.skipeol();
1532 } 1533 }
1533 } 1534 }
1534 else { 1535 else {
1535 // may be a valid email address or domain name 1536 // may be a valid email address or domain name
1536 char *st = tok.next(); 1537 const char *st = tok.next();
1537 if ((st == token_white) || (st == token_black) || (st == token_unknown) || (st == token_inherit)) { 1538 if ((st == token_white) || (st == token_black) || (st == token_unknown) || (st == token_inherit)) {
1538 me.add_from(have, st); 1539 me.add_from(have, st);
1539 } 1540 }
1540 else { 1541 else {
1541 CONTEXTP con = me.find_from_context_name(st); 1542 CONTEXTP con = me.find_from_context_name(st);
1555 1556
1556 //////////////////////////////////////////////// 1557 ////////////////////////////////////////////////
1557 // 1558 //
1558 bool parse_rate(TOKEN &tok, CONFIG &dc, CONTEXT &me); 1559 bool parse_rate(TOKEN &tok, CONFIG &dc, CONTEXT &me);
1559 bool parse_rate(TOKEN &tok, CONFIG &dc, CONTEXT &me) { 1560 bool parse_rate(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
1560 char *def = tok.next(); 1561 const char *def = tok.next();
1561 tok.push(def); 1562 tok.push(def);
1562 if (def != token_lbrace) me.set_default_rate(tok.nextint()); 1563 if (def != token_lbrace) me.set_default_rate(tok.nextint());
1563 if (!tsa(tok, token_lbrace)) return false; 1564 if (!tsa(tok, token_lbrace)) return false;
1564 while (true) { 1565 while (true) {
1565 char *have = tok.next(); 1566 const char *have = tok.next();
1566 if (!have) break; 1567 if (!have) break;
1567 if (have == token_rbrace) break; 1568 if (have == token_rbrace) break;
1568 if (have == token_semi) { 1569 if (have == token_semi) {
1569 // optional separators 1570 // optional separators
1570 } 1571 }
1578 1579
1579 //////////////////////////////////////////////// 1580 ////////////////////////////////////////////////
1580 // 1581 //
1581 bool parse_context(TOKEN &tok, CONFIG &dc, CONTEXTP parent); 1582 bool parse_context(TOKEN &tok, CONFIG &dc, CONTEXTP parent);
1582 bool parse_context(TOKEN &tok, CONFIG &dc, CONTEXTP parent) { 1583 bool parse_context(TOKEN &tok, CONFIG &dc, CONTEXTP parent) {
1583 char *name = tok.next(); 1584 const char *name = tok.next();
1584 if (!tsa(tok, token_lbrace)) return false; 1585 if (!tsa(tok, token_lbrace)) return false;
1585 CONTEXTP con = new CONTEXT(parent, name); 1586 CONTEXTP con = new CONTEXT(parent, name);
1586 1587
1587 while (true) { 1588 while (true) {
1588 char *have = tok.next(); 1589 const char *have = tok.next();
1589 if (!have) break; 1590 if (!have) break;
1590 if (have == token_rbrace) break; // done 1591 if (have == token_rbrace) break; // done
1591 if (have == token_dnsbl) { 1592 if (have == token_dnsbl) {
1592 if (!parse_dnsbl(tok, dc, *con)) return false; 1593 if (!parse_dnsbl(tok, dc, *con)) return false;
1593 } 1594 }
1636 1637
1637 1638
1638 //////////////////////////////////////////////// 1639 ////////////////////////////////////////////////
1639 // parse a config file 1640 // parse a config file
1640 // 1641 //
1641 bool load_conf(CONFIG &dc, char *fn) { 1642 bool load_conf(CONFIG &dc, const char *fn) {
1642 int count = 0; 1643 int count = 0;
1643 TOKEN tok(fn, &dc.config_files); 1644 TOKEN tok(fn, &dc.config_files);
1644 while (true) { 1645 while (true) {
1645 char *have = tok.next(); 1646 const char *have = tok.next();
1646 if (!have) break; 1647 if (!have) break;
1647 if (have == token_context) { 1648 if (have == token_context) {
1648 if (!parse_context(tok, dc, NULL)) { 1649 if (!parse_context(tok, dc, NULL)) {
1649 tok.token_error("load_conf() failed to parse context"); 1650 tok.token_error("load_conf() failed to parse context");
1650 return false; 1651 return false;