URI:
       tcommon.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
       ---
       tcommon.c (3372B)
       ---
            1 #include "common.h"
            2 #include "dat.h"
            3 
            4 String*
            5 getaddr(Node *p)
            6 {
            7         for(; p; p = p->next){
            8                 if(p->s && p->addr)
            9                         return p->s;
           10         }
           11         return nil;
           12 }
           13 
           14 /* send messae adding our own reply-to and precedence */
           15 void
           16 getaddrs(void)
           17 {
           18         Field *f;
           19 
           20         for(f = firstfield; f; f = f->next){
           21                 if(f->node->c == FROM && from == nil)
           22                         from = getaddr(f->node);
           23                 if(f->node->c == SENDER && sender == nil)
           24                         sender = getaddr(f->node);
           25         }
           26 }
           27 
           28 /* write address file, should be append only */
           29 void
           30 writeaddr(char *file, char *addr, int rem, char *listname)
           31 {
           32         int fd;
           33         Dir nd;
           34 
           35         fd = open(file, OWRITE);
           36         if(fd < 0){
           37                 fd = create(file, OWRITE, DMAPPEND|0666);
           38                 if(fd < 0)
           39                         sysfatal("creating address list %s: %r", file);
           40                 nulldir(&nd);
           41                 nd.mode = DMAPPEND|0666;
           42                 dirwstat(file, &nd);
           43         } else
           44                 seek(fd, 0, 2);
           45         if(rem)
           46                 fprint(fd, "!%s\n", addr);
           47         else
           48                 fprint(fd, "%s\n", addr);
           49         close(fd);
           50 
           51         if(*addr != '#')
           52                 sendnotification(addr, listname, rem);
           53 }
           54 
           55 void
           56 remaddr(char *addr)
           57 {
           58         Addr **l;
           59         Addr *a;
           60 
           61         for(l = &al; *l; l = &(*l)->next){
           62                 a = *l;
           63                 if(strcmp(addr, a->addr) == 0){
           64                         (*l) = a->next;
           65                         free(a);
           66                         na--;
           67                         break;
           68                 }
           69         }
           70 }
           71 
           72 int
           73 addaddr(char *addr)
           74 {
           75         Addr **l;
           76         Addr *a;
           77 
           78         for(l = &al; *l; l = &(*l)->next){
           79                 if(strcmp(addr, (*l)->addr) == 0)
           80                         return 0;
           81         }
           82         na++;
           83         *l = a = malloc(sizeof(*a)+strlen(addr)+1);
           84         if(a == nil)
           85                 sysfatal("allocating: %r");
           86         a->addr = (char*)&a[1];
           87         strcpy(a->addr, addr);
           88         a->next = nil;
           89         *l = a;
           90         return 1;
           91 }
           92 
           93 /* read address file */
           94 void
           95 readaddrs(char *file)
           96 {
           97         Biobuf *b;
           98         char *p;
           99 
          100         b = Bopen(file, OREAD);
          101         if(b == nil)
          102                 return;
          103 
          104         while((p = Brdline(b, '\n')) != nil){
          105                 p[Blinelen(b)-1] = 0;
          106                 if(*p == '#')
          107                         continue;
          108                 if(*p == '!')
          109                         remaddr(p+1);
          110                 else
          111                         addaddr(p);
          112         }
          113         Bterm(b);
          114 }
          115 
          116 /* start a mailer sending to all the receivers */
          117 int
          118 startmailer(char *name)
          119 {
          120         int pfd[2];
          121         char **av;
          122         int ac;
          123         Addr *a;
          124 
          125         putenv("upasname", "/dev/null");
          126         if(pipe(pfd) < 0)
          127                 sysfatal("creating pipe: %r");
          128         switch(fork()){
          129         case -1:
          130                 sysfatal("starting mailer: %r");
          131         case 0:
          132                 close(pfd[1]);
          133                 break;
          134         default:
          135                 close(pfd[0]);
          136                 return pfd[1];
          137         }
          138 
          139         dup(pfd[0], 0);
          140         close(pfd[0]);
          141 
          142         av = malloc(sizeof(char*)*(na+2));
          143         if(av == nil)
          144                 sysfatal("starting mailer: %r");
          145         ac = 0;
          146         av[ac++] = name;
          147         for(a = al; a != nil; a = a->next)
          148                 av[ac++] = a->addr;
          149         av[ac] = 0;
          150         exec("/bin/upas/send", av);
          151         sysfatal("execing mailer: %r");
          152 
          153         /* not reached */
          154         return -1;
          155 }
          156 
          157 void
          158 sendnotification(char *addr, char *listname, int rem)
          159 {
          160         int pfd[2];
          161         Waitmsg *w;
          162 
          163         putenv("upasname", "/dev/null");
          164         if(pipe(pfd) < 0)
          165                 sysfatal("creating pipe: %r");
          166         switch(fork()){
          167         case -1:
          168                 sysfatal("starting mailer: %r");
          169         case 0:
          170                 close(pfd[1]);
          171                 dup(pfd[0], 0);
          172                 close(pfd[0]);
          173                 execl("/bin/upas/send", "mlnotify", addr, nil);
          174                 sysfatal("execing mailer: %r");
          175                 break;
          176         default:
          177                 close(pfd[0]);
          178                 fprint(pfd[1], "From: %s-owner\n\n", listname);
          179                 if(rem)
          180                         fprint(pfd[1], "You have removed from the %s mailing list\n", listname);
          181                 else{
          182                         fprint(pfd[1], "You have been added to the %s mailing list\n", listname);
          183                         fprint(pfd[1], "To be removed, send an email to %s-owner containing\n",
          184                                 listname);
          185                         fprint(pfd[1], "the word 'remove' in the subject or body.\n");
          186                 }
          187                 close(pfd[1]);
          188 
          189                 /* wait for mailer to end */
          190                 while(w = wait()){
          191                         if(w->msg != nil && w->msg[0])
          192                                 sysfatal("%s", w->msg);
          193                         free(w);
          194                 }
          195                 break;
          196         }
          197 }