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