|  | #include "common.h" | 
|  | #include "send.h" | 
|  |  | 
|  | static int forward_loop(char *, char *); | 
|  |  | 
|  | /* bind the destinations to the commands to be executed */ | 
|  | extern dest * | 
|  | up_bind(dest *destp, message *mp, int checkforward) | 
|  | { | 
|  | dest *list[2];		/* lists of unbound destinations */ | 
|  | int li;			/* index into list[2] */ | 
|  | dest *bound=0;	/* bound destinations */ | 
|  | dest *dp; | 
|  | int i; | 
|  |  | 
|  | list[0] = destp; | 
|  | list[1] = 0; | 
|  |  | 
|  | /* | 
|  | *  loop once to check for: | 
|  | *	- forwarding rights | 
|  | *	- addressing loops | 
|  | *	- illegal characters | 
|  | *	- characters that need escaping | 
|  | */ | 
|  | for (dp = d_rm(&list[0]); dp != 0; dp = d_rm(&list[0])) { | 
|  | if (!checkforward) | 
|  | dp->authorized = 1; | 
|  | dp->addr = escapespecial(dp->addr); | 
|  | if (forward_loop(s_to_c(dp->addr), thissys)) { | 
|  | dp->status = d_eloop; | 
|  | d_same_insert(&bound, dp); | 
|  | } else if(forward_loop(s_to_c(mp->sender), thissys)) { | 
|  | dp->status = d_eloop; | 
|  | d_same_insert(&bound, dp); | 
|  | } else if(shellchars(s_to_c(dp->addr))) { | 
|  | dp->status = d_syntax; | 
|  | d_same_insert(&bound, dp); | 
|  | } else | 
|  | d_insert(&list[1], dp); | 
|  | } | 
|  | li = 1; | 
|  |  | 
|  | /* Loop until all addresses are bound or address loop detected */ | 
|  | for (i=0; list[li]!=0 && i<32; ++i, li ^= 1) { | 
|  | /* Traverse the current list.  Bound items are put on the | 
|  | * `bound' list.  Unbound items are put on the next list to | 
|  | * traverse, `list[li^1]'. | 
|  | */ | 
|  | for (dp = d_rm(&list[li]); dp != 0; dp = d_rm(&list[li])){ | 
|  | dest *newlist; | 
|  |  | 
|  | rewrite(dp, mp); | 
|  | if(debug) | 
|  | fprint(2, "%s -> %s\n", s_to_c(dp->addr), | 
|  | dp->repl1 ? s_to_c(dp->repl1):""); | 
|  | switch (dp->status) { | 
|  | case d_auth: | 
|  | /* authorize address if not already authorized */ | 
|  | if(!dp->authorized){ | 
|  | authorize(dp); | 
|  | if(dp->status==d_auth) | 
|  | d_insert(&list[li^1], dp); | 
|  | else | 
|  | d_insert(&bound, dp); | 
|  | } | 
|  | break; | 
|  | case d_cat: | 
|  | /* address -> local */ | 
|  | newlist = expand_local(dp); | 
|  | if (newlist == 0) { | 
|  | /* append to mailbox (or error) */ | 
|  | d_same_insert(&bound, dp); | 
|  | } else if (newlist->status == d_undefined) { | 
|  | /* Forward to ... */ | 
|  | d_insert(&list[li^1], newlist); | 
|  | } else { | 
|  | /* Pipe to ... */ | 
|  | d_same_insert(&bound, newlist); | 
|  | } | 
|  | break; | 
|  | case d_pipe: | 
|  | /* address -> command */ | 
|  | d_same_insert(&bound, dp); | 
|  | break; | 
|  | case d_alias: | 
|  | /* address -> rewritten address */ | 
|  | newlist = s_to_dest(dp->repl1, dp); | 
|  | if(newlist != 0) | 
|  | d_insert(&list[li^1], newlist); | 
|  | else | 
|  | d_same_insert(&bound, dp); | 
|  | break; | 
|  | case d_translate: | 
|  | /* pipe to a translator */ | 
|  | newlist = translate(dp); | 
|  | if (newlist != 0) | 
|  | d_insert(&list[li^1], newlist); | 
|  | else | 
|  | d_same_insert(&bound, dp); | 
|  | break; | 
|  | default: | 
|  | /* error */ | 
|  | d_same_insert(&bound, dp); | 
|  | break; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /* mark remaining comands as "forwarding loops" */ | 
|  | for (dp = d_rm(&list[li]); dp != 0; dp = d_rm(&list[li])) { | 
|  | dp->status = d_loop; | 
|  | d_same_insert(&bound, dp); | 
|  | } | 
|  |  | 
|  | return bound; | 
|  | } | 
|  |  | 
|  | /* Return TRUE if a forwarding loop exists, i.e., the String `system' | 
|  | * is found more than 4 times in the return address. | 
|  | */ | 
|  | static int | 
|  | forward_loop(char *addr, char *system) | 
|  | { | 
|  | int len = strlen(system), found = 0; | 
|  |  | 
|  | while (addr = strchr(addr, '!')) | 
|  | if (!strncmp(++addr, system, len) | 
|  | && addr[len] == '!' && ++found == 4) | 
|  | return 1; | 
|  | return 0; | 
|  | } | 
|  |  |