Initial revision
[citadel.git] / citadel / mailinglist.c
1 /*
2  * mailinglist.c
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 "citadel.h"
26
27 void LoadInternetConfig();
28 void get_config();
29 struct config config;
30
31 char ALIASES[128];
32 char CIT86NET[128];
33 char SENDMAIL[128];
34 char FALLBACK[128];
35 char GW_DOMAIN[128];
36 char TABLEFILE[128];
37 char OUTGOING_FQDN[128];
38 int RUN_NETPROC = 1;
39
40 int struncmp(lstr,rstr,len)
41 char lstr[],rstr[];
42 int len; {
43         int pos = 0;
44         char lc,rc;
45         while (pos<len) {
46                 lc=tolower(lstr[pos]);
47                 rc=tolower(rstr[pos]);
48                 if ((lc==0)&&(rc==0)) return(0);
49                 if (lc<rc) return(-1);
50                 if (lc>rc) return(1);
51                 pos=pos+1;
52                 }
53         return(0);
54         }
55
56 /* 
57  * Consult the mailinglists table to find out where we should send the
58  * mailing list postings to.
59  */
60 void xref(room,listaddr)                /* xref table */
61 char room[]; 
62 char listaddr[]; {
63         FILE *fp;
64         int a;
65         char buf[128];
66         
67         strcpy(listaddr, "");
68         fp=fopen(TABLEFILE, "r");
69         while (fgets(buf,128,fp)!=NULL) {
70                 buf[strlen(buf)-1]=0;
71                 for (a=0; a<strlen(buf); ++a) {
72                         if ( (buf[a]==',') && (!strucmp(&buf[a+1],room)) ) {
73                                 strcpy(listaddr,buf);
74                                 listaddr[a] = 0;
75                                 }
76                         }
77                 }
78         fclose(fp);
79         return;
80         }
81
82
83 /*
84  * The main loop.  We don't need any command-line parameters to this program.
85  */
86 void main() {
87
88         char header[3];
89         char fields[32][1024];
90         int num_fields;
91         int ch, p, a;
92         int in_header;
93         int is_good;
94         char listaddr[512];
95         char mailcmd[256];
96         FILE *nm;
97         char tempfile[64];
98
99         get_config();
100         LoadInternetConfig();
101         sprintf(tempfile, "/tmp/mlist.%d", getpid() );
102
103         while(1) {
104
105                 /* seek to the next message */
106                 is_good = 0;
107                 do {
108                         if (feof(stdin)) {
109                                 unlink(tempfile);
110                                 exit(0);
111                                 }
112                         } while (getc(stdin) != 255);
113
114                 header[0] = 255;
115                 header[1] = getc(stdin);
116                 header[2] = getc(stdin);
117                 in_header = 1;
118                 num_fields = 0;
119
120                 do {
121                         fields[num_fields][0] = getc(stdin);
122                         if (fields[num_fields][0] != 'M') {
123                                 p = 1;
124                                 do {
125                                         ch = getc(stdin);
126                                         fields[num_fields][p++] = ch;
127                                         } while ((ch!=0) && (!feof(stdin)));
128                                 if (fields[num_fields][0] == 'N') {
129                                         if (!strcmp(&fields[num_fields][1],
130                                                 NODENAME)) {
131                                                         is_good = 1;
132                                                         }
133                                         }
134                                 if (fields[num_fields][0] == 'O') {
135                                         xref(&fields[num_fields][1], listaddr);
136                                         }
137                                 if (fields[num_fields][0]!='R') ++num_fields;
138                                 }
139                         else {
140                                 /* flush the message out to the next program */
141
142                                 nm =  fopen(tempfile, "wb");
143                                 fprintf(nm, "%c%c%c",
144                                         header[0], header[1], header[2]);
145                                 for (a=0; a<num_fields; ++a) {
146                                         fprintf(nm, "%s%c", &fields[a][0], 0);
147                                         }
148                                 fprintf(nm, "R%s%c", listaddr, 0);
149                         
150                                 putc('M', nm);
151                                 do {
152                                         ch = getc(stdin);
153                                         putc(ch, nm);
154                                         } while ((ch!=0) && (!feof(stdin)));
155                                 in_header = 0;
156                                 fclose(nm);
157                                 if (is_good) {
158                                         sprintf(mailcmd, "exec netmailer %s mlist", tempfile);
159                                         system(mailcmd);
160                                         is_good = 0;
161                                         }
162                                 }
163                         } while (in_header);
164                 }
165         }