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