URI:
       tbind.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tbind.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 }