plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

common.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 }