4c5112fcd032aedaadf6d8f9507087860a526377
[citadel.git] / citadel / mailinglist.c
1 /*
2  * $Id$
3  *
4  * This program is designed to be a filter which allows two-way interaction
5  * between a traditional e-mail mailing list and a Citadel room.
6  *
7  * It only handles the outbound side.  The inbound side is handled by the
8  * Citadel e-mail gateway.  You should subscribe rooms to lists using the
9  * "room_roomname@node.dom" type address.
10  * 
11  * Since some listprocs only accept postings from subscribed addresses, the
12  * messages which this program converts will all appear to be from the room
13  * address; however, the full name of the sender is set to the Citadel user
14  * name of the real message author.
15  * 
16  * To prevent loops, this program only sends messages originating on the local
17  * system.  Therefore it is not possible to carry a two-way mailing list room
18  * on a Citadel network.
19  */
20
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <stdio.h>
24 #include <syslog.h>
25 #include <string.h>
26 #include "citadel.h"
27
28 void LoadInternetConfig(void);
29 void get_config(void);
30 struct config config;
31
32 char ALIASES[128];
33 char CIT86NET[128];
34 char SENDMAIL[128];
35 char FALLBACK[128];
36 char GW_DOMAIN[128];
37 char TABLEFILE[128];
38 char OUTGOING_FQDN[128];
39 int RUN_NETPROC = 1;
40
41 /* 
42  * Consult the mailinglists table to find out where we should send the
43  * mailing list postings to.
44  */
45 void xref(char *room, char *listaddr)
46 {                               /* xref table */
47     FILE *fp;
48     int a;
49     char buf[128];
50
51     strcpy(listaddr, "");
52     fp = fopen(TABLEFILE, "r");
53     while (fgets(buf, 128, fp) != NULL) {
54         buf[strlen(buf) - 1] = 0;
55         for (a = 0; a < strlen(buf); ++a) {
56             if ((buf[a] == ',') && (!strcasecmp(&buf[a + 1], room))) {
57                 strcpy(listaddr, buf);
58                 listaddr[a] = 0;
59             }
60         }
61     }
62     fclose(fp);
63     return;
64 }
65
66
67 /*
68  * The main loop.  We don't need any command-line parameters to this program.
69  */
70 int main(void)
71 {
72
73     char header[3];
74     char fields[32][1024];
75     int num_fields;
76     int ch, p, a, i;
77     int in_header;
78     int is_good;
79     char listaddr[512];
80     char mailcmd[256];
81     FILE *nm;
82     char tempfile[64];
83
84     get_config();
85     LoadInternetConfig();
86     strcpy(tempfile, tmpnam(NULL));
87
88     while (1) {
89
90         /* seek to the next message */
91         is_good = 0;
92         do {
93             if (feof(stdin)) {
94                 unlink(tempfile);
95                 exit(0);
96             }
97         } while (getc(stdin) != 255);
98
99         header[0] = 255;
100         header[1] = getc(stdin);
101         header[2] = getc(stdin);
102         in_header = 1;
103         num_fields = 0;
104
105         do {
106             fields[num_fields][0] = getc(stdin);
107             if (fields[num_fields][0] != 'M') {
108                 p = 1;
109                 do {
110                     ch = getc(stdin);
111                     fields[num_fields][p++] = ch;
112                 } while ((ch != 0) && (!feof(stdin)));
113
114                 /**********************************************************/
115                 /* Only send messages which originated on the Citadel net */
116                 /* (In other words, from node names with no dots in them) */
117
118                 if (fields[num_fields][0] == 'N') {
119                     is_good = 1;
120                     for (i = 1; i < strlen(&fields[num_fields][1]); ++i) {
121                         if (fields[num_fields][i] == '.') {
122                             is_good = 0;
123                         }
124                     }
125                 }
126                 /**********************************************************/
127
128                 if (fields[num_fields][0] == 'O') {
129                     xref(&fields[num_fields][1], listaddr);
130                 }
131                 if (fields[num_fields][0] != 'R')
132                     ++num_fields;
133             } else {
134                 /* flush the message out to the next program */
135
136                 nm = fopen(tempfile, "wb");
137                 fprintf(nm, "%c%c%c",
138                         header[0], header[1], header[2]);
139                 for (a = 0; a < num_fields; ++a) {
140                     fprintf(nm, "%s%c", &fields[a][0], 0);
141                 }
142                 fprintf(nm, "R%s%c", listaddr, 0);
143
144                 putc('M', nm);
145                 do {
146                     ch = getc(stdin);
147                     putc(ch, nm);
148                 } while ((ch != 0) && (!feof(stdin)));
149                 in_header = 0;
150                 fclose(nm);
151                 if (is_good) {
152                     sprintf(mailcmd, "exec ./netmailer %s mlist", tempfile);
153                     system(mailcmd);
154                     is_good = 0;
155                 }
156             }
157         } while (in_header);
158     }
159 }