common.c 3.3 KB

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