13e12c5d1SDavid du Colombier #include "common.h"
23e12c5d1SDavid du Colombier #include "send.h"
33e12c5d1SDavid du Colombier
43e12c5d1SDavid du Colombier static int forward_loop(char *, char *);
53e12c5d1SDavid du Colombier
63e12c5d1SDavid du Colombier /* bind the destinations to the commands to be executed */
73e12c5d1SDavid du Colombier extern dest *
up_bind(dest * destp,message * mp,int checkforward)83e12c5d1SDavid du Colombier up_bind(dest *destp, message *mp, int checkforward)
93e12c5d1SDavid du Colombier {
103e12c5d1SDavid du Colombier dest *list[2]; /* lists of unbound destinations */
113e12c5d1SDavid du Colombier int li; /* index into list[2] */
123e12c5d1SDavid du Colombier dest *bound=0; /* bound destinations */
133e12c5d1SDavid du Colombier dest *dp;
143e12c5d1SDavid du Colombier int i;
153e12c5d1SDavid du Colombier
163e12c5d1SDavid du Colombier list[0] = destp;
173e12c5d1SDavid du Colombier list[1] = 0;
183e12c5d1SDavid du Colombier
193e12c5d1SDavid du Colombier /*
203e12c5d1SDavid du Colombier * loop once to check for:
213e12c5d1SDavid du Colombier * - forwarding rights
223e12c5d1SDavid du Colombier * - addressing loops
233e12c5d1SDavid du Colombier * - illegal characters
24*7dd7cddfSDavid du Colombier * - characters that need escaping
253e12c5d1SDavid du Colombier */
263e12c5d1SDavid du Colombier for (dp = d_rm(&list[0]); dp != 0; dp = d_rm(&list[0])) {
273e12c5d1SDavid du Colombier if (!checkforward)
283e12c5d1SDavid du Colombier dp->authorized = 1;
29*7dd7cddfSDavid du Colombier dp->addr = escapespecial(dp->addr);
303e12c5d1SDavid du Colombier if (forward_loop(s_to_c(dp->addr), thissys)) {
313e12c5d1SDavid du Colombier dp->status = d_eloop;
323e12c5d1SDavid du Colombier d_same_insert(&bound, dp);
333e12c5d1SDavid du Colombier } else if(forward_loop(s_to_c(mp->sender), thissys)) {
343e12c5d1SDavid du Colombier dp->status = d_eloop;
353e12c5d1SDavid du Colombier d_same_insert(&bound, dp);
363e12c5d1SDavid du Colombier } else if(shellchars(s_to_c(dp->addr))) {
373e12c5d1SDavid du Colombier dp->status = d_syntax;
383e12c5d1SDavid du Colombier d_same_insert(&bound, dp);
393e12c5d1SDavid du Colombier } else
403e12c5d1SDavid du Colombier d_insert(&list[1], dp);
413e12c5d1SDavid du Colombier }
423e12c5d1SDavid du Colombier li = 1;
433e12c5d1SDavid du Colombier
443e12c5d1SDavid du Colombier /* Loop until all addresses are bound or address loop detected */
453e12c5d1SDavid du Colombier for (i=0; list[li]!=0 && i<32; ++i, li ^= 1) {
463e12c5d1SDavid du Colombier /* Traverse the current list. Bound items are put on the
473e12c5d1SDavid du Colombier * `bound' list. Unbound items are put on the next list to
483e12c5d1SDavid du Colombier * traverse, `list[li^1]'.
493e12c5d1SDavid du Colombier */
503e12c5d1SDavid du Colombier for (dp = d_rm(&list[li]); dp != 0; dp = d_rm(&list[li])){
513e12c5d1SDavid du Colombier dest *newlist;
523e12c5d1SDavid du Colombier
53*7dd7cddfSDavid du Colombier rewrite(dp, mp);
543e12c5d1SDavid du Colombier if(debug)
553e12c5d1SDavid du Colombier fprint(2, "%s -> %s\n", s_to_c(dp->addr),
563e12c5d1SDavid du Colombier dp->repl1 ? s_to_c(dp->repl1):"");
573e12c5d1SDavid du Colombier switch (dp->status) {
583e12c5d1SDavid du Colombier case d_auth:
593e12c5d1SDavid du Colombier /* authorize address if not already authorized */
603e12c5d1SDavid du Colombier if(!dp->authorized){
613e12c5d1SDavid du Colombier authorize(dp);
623e12c5d1SDavid du Colombier if(dp->status==d_auth)
633e12c5d1SDavid du Colombier d_insert(&list[li^1], dp);
643e12c5d1SDavid du Colombier else
653e12c5d1SDavid du Colombier d_insert(&bound, dp);
663e12c5d1SDavid du Colombier }
673e12c5d1SDavid du Colombier break;
683e12c5d1SDavid du Colombier case d_cat:
693e12c5d1SDavid du Colombier /* address -> local */
703e12c5d1SDavid du Colombier newlist = expand_local(dp);
713e12c5d1SDavid du Colombier if (newlist == 0) {
723e12c5d1SDavid du Colombier /* append to mailbox (or error) */
733e12c5d1SDavid du Colombier d_same_insert(&bound, dp);
743e12c5d1SDavid du Colombier } else if (newlist->status == d_undefined) {
753e12c5d1SDavid du Colombier /* Forward to ... */
763e12c5d1SDavid du Colombier d_insert(&list[li^1], newlist);
773e12c5d1SDavid du Colombier } else {
783e12c5d1SDavid du Colombier /* Pipe to ... */
793e12c5d1SDavid du Colombier d_same_insert(&bound, newlist);
803e12c5d1SDavid du Colombier }
813e12c5d1SDavid du Colombier break;
823e12c5d1SDavid du Colombier case d_pipe:
833e12c5d1SDavid du Colombier /* address -> command */
843e12c5d1SDavid du Colombier d_same_insert(&bound, dp);
853e12c5d1SDavid du Colombier break;
863e12c5d1SDavid du Colombier case d_alias:
873e12c5d1SDavid du Colombier /* address -> rewritten address */
883e12c5d1SDavid du Colombier newlist = s_to_dest(dp->repl1, dp);
893e12c5d1SDavid du Colombier if(newlist != 0)
903e12c5d1SDavid du Colombier d_insert(&list[li^1], newlist);
913e12c5d1SDavid du Colombier else
923e12c5d1SDavid du Colombier d_same_insert(&bound, dp);
933e12c5d1SDavid du Colombier break;
943e12c5d1SDavid du Colombier case d_translate:
953e12c5d1SDavid du Colombier /* pipe to a translator */
963e12c5d1SDavid du Colombier newlist = translate(dp);
973e12c5d1SDavid du Colombier if (newlist != 0)
983e12c5d1SDavid du Colombier d_insert(&list[li^1], newlist);
993e12c5d1SDavid du Colombier else
1003e12c5d1SDavid du Colombier d_same_insert(&bound, dp);
1013e12c5d1SDavid du Colombier break;
1023e12c5d1SDavid du Colombier default:
1033e12c5d1SDavid du Colombier /* error */
1043e12c5d1SDavid du Colombier d_same_insert(&bound, dp);
1053e12c5d1SDavid du Colombier break;
1063e12c5d1SDavid du Colombier }
1073e12c5d1SDavid du Colombier }
1083e12c5d1SDavid du Colombier }
1093e12c5d1SDavid du Colombier
1103e12c5d1SDavid du Colombier /* mark remaining comands as "forwarding loops" */
1113e12c5d1SDavid du Colombier for (dp = d_rm(&list[li]); dp != 0; dp = d_rm(&list[li])) {
1123e12c5d1SDavid du Colombier dp->status = d_loop;
1133e12c5d1SDavid du Colombier d_same_insert(&bound, dp);
1143e12c5d1SDavid du Colombier }
1153e12c5d1SDavid du Colombier
1163e12c5d1SDavid du Colombier return bound;
1173e12c5d1SDavid du Colombier }
1183e12c5d1SDavid du Colombier
1193e12c5d1SDavid du Colombier /* Return TRUE if a forwarding loop exists, i.e., the String `system'
1203e12c5d1SDavid du Colombier * is found more than 4 times in the return address.
1213e12c5d1SDavid du Colombier */
1223e12c5d1SDavid du Colombier static int
forward_loop(char * addr,char * system)1233e12c5d1SDavid du Colombier forward_loop(char *addr, char *system)
1243e12c5d1SDavid du Colombier {
1253e12c5d1SDavid du Colombier int len = strlen(system), found = 0;
1263e12c5d1SDavid du Colombier
1273e12c5d1SDavid du Colombier while (addr = strchr(addr, '!'))
1283e12c5d1SDavid du Colombier if (!strncmp(++addr, system, len)
1293e12c5d1SDavid du Colombier && addr[len] == '!' && ++found == 4)
1303e12c5d1SDavid du Colombier return 1;
1313e12c5d1SDavid du Colombier return 0;
1323e12c5d1SDavid du Colombier }
1333e12c5d1SDavid du Colombier
134