Blob


1 #include "common.h"
2 #include "send.h"
4 static int forward_loop(char *, char *);
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;
16 list[0] = destp;
17 list[1] = 0;
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;
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;
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;
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);
116 return bound;
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)
125 int len = strlen(system), found = 0;
127 while (addr = strchr(addr, '!'))
128 if (!strncmp(++addr, system, len)
129 && addr[len] == '!' && ++found == 4)
130 return 1;
131 return 0;