bind.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #include "common.h"
  2. #include "send.h"
  3. static int forward_loop(char *, char *);
  4. /* bind the destinations to the commands to be executed */
  5. extern dest *
  6. up_bind(dest *destp, message *mp, int checkforward)
  7. {
  8. dest *list[2]; /* lists of unbound destinations */
  9. int li; /* index into list[2] */
  10. dest *bound=0; /* bound destinations */
  11. dest *dp;
  12. int i;
  13. list[0] = destp;
  14. list[1] = 0;
  15. /*
  16. * loop once to check for:
  17. * - forwarding rights
  18. * - addressing loops
  19. * - illegal characters
  20. * - characters that need escaping
  21. */
  22. for (dp = d_rm(&list[0]); dp != 0; dp = d_rm(&list[0])) {
  23. if (!checkforward)
  24. dp->authorized = 1;
  25. dp->addr = escapespecial(dp->addr);
  26. if (forward_loop(s_to_c(dp->addr), thissys)) {
  27. dp->status = d_eloop;
  28. d_same_insert(&bound, dp);
  29. } else if(forward_loop(s_to_c(mp->sender), thissys)) {
  30. dp->status = d_eloop;
  31. d_same_insert(&bound, dp);
  32. } else if(shellchars(s_to_c(dp->addr))) {
  33. dp->status = d_syntax;
  34. d_same_insert(&bound, dp);
  35. } else
  36. d_insert(&list[1], dp);
  37. }
  38. li = 1;
  39. /* Loop until all addresses are bound or address loop detected */
  40. for (i=0; list[li]!=0 && i<32; ++i, li ^= 1) {
  41. /* Traverse the current list. Bound items are put on the
  42. * `bound' list. Unbound items are put on the next list to
  43. * traverse, `list[li^1]'.
  44. */
  45. for (dp = d_rm(&list[li]); dp != 0; dp = d_rm(&list[li])){
  46. dest *newlist;
  47. rewrite(dp, mp);
  48. if(debug)
  49. fprint(2, "%s -> %s\n", s_to_c(dp->addr),
  50. dp->repl1 ? s_to_c(dp->repl1):"");
  51. switch (dp->status) {
  52. case d_auth:
  53. /* authorize address if not already authorized */
  54. if(!dp->authorized){
  55. authorize(dp);
  56. if(dp->status==d_auth)
  57. d_insert(&list[li^1], dp);
  58. else
  59. d_insert(&bound, dp);
  60. }
  61. break;
  62. case d_cat:
  63. /* address -> local */
  64. newlist = expand_local(dp);
  65. if (newlist == 0) {
  66. /* append to mailbox (or error) */
  67. d_same_insert(&bound, dp);
  68. } else if (newlist->status == d_undefined) {
  69. /* Forward to ... */
  70. d_insert(&list[li^1], newlist);
  71. } else {
  72. /* Pipe to ... */
  73. d_same_insert(&bound, newlist);
  74. }
  75. break;
  76. case d_pipe:
  77. /* address -> command */
  78. d_same_insert(&bound, dp);
  79. break;
  80. case d_alias:
  81. /* address -> rewritten address */
  82. newlist = s_to_dest(dp->repl1, dp);
  83. if(newlist != 0)
  84. d_insert(&list[li^1], newlist);
  85. else
  86. d_same_insert(&bound, dp);
  87. break;
  88. case d_translate:
  89. /* pipe to a translator */
  90. newlist = translate(dp);
  91. if (newlist != 0)
  92. d_insert(&list[li^1], newlist);
  93. else
  94. d_same_insert(&bound, dp);
  95. break;
  96. default:
  97. /* error */
  98. d_same_insert(&bound, dp);
  99. break;
  100. }
  101. }
  102. }
  103. /* mark remaining comands as "forwarding loops" */
  104. for (dp = d_rm(&list[li]); dp != 0; dp = d_rm(&list[li])) {
  105. dp->status = d_loop;
  106. d_same_insert(&bound, dp);
  107. }
  108. return bound;
  109. }
  110. /* Return TRUE if a forwarding loop exists, i.e., the String `system'
  111. * is found more than 4 times in the return address.
  112. */
  113. static int
  114. forward_loop(char *addr, char *system)
  115. {
  116. int len = strlen(system), found = 0;
  117. while (addr = strchr(addr, '!'))
  118. if (!strncmp(++addr, system, len)
  119. && addr[len] == '!' && ++found == 4)
  120. return 1;
  121. return 0;
  122. }