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