]> code.citadel.org Git - citadel.git/blob - citadel/netmailer.c
90a8bb83edae3c14a964ab44f368b04367cee843
[citadel.git] / citadel / netmailer.c
1 /*
2  * netmailer for Citadel/UX
3  * see copyright.doc for copyright information
4  *
5  * netproc calls this to export Citadel mail to RFC822-compliant mailers.
6  * $Id$
7  */
8
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <stdio.h>
12 #include <fcntl.h>
13 #include <time.h>
14 #include <string.h>
15 #include <ctype.h>
16 #include <limits.h>
17 #include <syslog.h>
18 #include "citadel.h"
19
20 void LoadInternetConfig(void);
21 void get_config(void);
22 struct config config;
23
24 char temp[PATH_MAX];
25
26 char ALIASES[128];
27 char CIT86NET[128];
28 char SENDMAIL[128];
29 char FALLBACK[128];
30 char GW_DOMAIN[128];
31 char TABLEFILE[128];
32 int RUN_NETPROC = 1;
33
34 int haschar(char *st, int ch)
35 {
36         int a, b;
37         b = 0;
38         for (a = 0; a < strlen(st); ++a)
39                 if (st[a] == ch)
40                         ++b;
41         return (b);
42 }
43
44
45
46 void fpgetfield(FILE * fp, char *string)
47 {
48         int a, b;
49         strcpy(string, "");
50         a = 0;
51         do {
52                 b = getc(fp);
53                 if (b < 1) {
54                         string[a] = 0;
55                         return;
56                 }
57                 string[a] = b;
58                 ++a;
59         } while (b != 0);
60 }
61
62
63 /* This is NOT the same msgform() found in the main program. It has been
64  * modified to format 80 columns into a temporary file, and extract the
65  * sender and recipient names for use within the main() loop.
66  */
67 void msgform(char *msgfile, FILE * mfout, char *sbuf, char *rbuf, char *nbuf,
68                 char *pbuf, time_t * mid_buf, char *rmname, char *subj)
69                         /* sender */
70                         /* recipient (in this case, an Internet address) */
71                         /* source node */
72                         /* path */
73                         /* message ID */
74                         /* room name */
75                         /* subject */
76 {
77         int a, b, c, e, old, mtype, aflag;
78         int real = 0;
79         char aaa[128], bbb[128];
80         FILE *fp;
81         int width;
82         int generate_subject = 1;
83
84         strcpy(subj, "");
85         strcpy(pbuf, "");
86         strcpy(nbuf, NODENAME);
87         strcpy(rmname, "");
88         time(mid_buf);
89         width = 80;
90         fp = fopen(msgfile, "rb");
91         if (fp == NULL) {
92                 fprintf(stderr, "netmailer: can't open message file\n");
93                 return;
94         }
95         strcpy(aaa, "");
96         old = 255;
97         c = 1;                  /* c is the current pos */
98         e = getc(fp);
99         if (e != 255) {
100                 fprintf(stderr, "netmailer: This is not a Citadel message.\n");
101                 goto END;
102         }
103         mtype = getc(fp);
104         aflag = getc(fp);
105         goto BONFGM;
106
107 A:      if (aflag == 1)
108                 goto AFLAG;
109         old = real;
110         a = getc(fp);
111         real = a;
112         if (a == 0)
113                 goto END;
114         if (a < 0)
115                 goto END;
116
117         /* generate subject... */
118         if ((generate_subject == 1) && (strlen(subj) < 60)) {
119                 subj[strlen(subj) + 1] = 0;
120                 subj[strlen(subj)] = (((a > 31) && (a < 127)) ? a : 32);
121         }
122         if (((a == 13) || (a == 10)) && (old != 13) && (old != 10))
123                 a = 32;
124         if (((old == 13) || (old == 10)) && ((real == 32) || (real == 13) || (real == 10))) {
125                 fprintf(mfout, "\n");
126                 c = 1;
127         }
128         if (a != 32) {
129                 if (((strlen(aaa) + c) > (width - 5)) && (strlen(aaa) > (width - 5))) {
130                         fprintf(mfout, "\n%s", aaa);
131                         c = strlen(aaa);
132                         aaa[0] = 0;
133                 }
134                 b = strlen(aaa);
135                 aaa[b] = a;
136                 aaa[b + 1] = 0;
137         }
138         if (a == 32) {
139                 if ((strlen(aaa) + c) > (width - 5)) {
140                         fprintf(mfout, "\n");
141                         c = 1;
142                 }
143                 fprintf(mfout, "%s ", aaa);
144                 ++c;
145                 c = c + strlen(aaa);
146                 strcpy(aaa, "");
147                 goto A;
148         }
149         if ((a == 13) || (a == 10)) {
150                 fprintf(mfout, "%s\n", aaa);
151                 c = 1;
152                 strcpy(aaa, "");
153                 goto A;
154         }
155         goto A;
156
157 AFLAG:  a = getc(fp);
158         if (a == 0)
159                 goto END;
160         if (a == 13) {
161                 putc(10, mfout);
162         } else {
163                 putc(a, mfout);
164         }
165         goto AFLAG;
166
167 END:    fclose(fp);
168         return;
169
170 BONFGM: b = getc(fp);
171         if (b < 0)
172                 goto END;
173         if (b == 'M')
174                 goto A;
175         fpgetfield(fp, bbb);
176         if (b == 'A')
177                 strcpy(sbuf, bbb);
178         if (b == 'R')
179                 strcpy(rbuf, bbb);
180         if (b == 'N')
181                 strcpy(nbuf, bbb);
182         if (b == 'P')
183                 strcpy(pbuf, bbb);
184         if (b == 'I')
185                 *mid_buf = atol(bbb);
186         if (b == 'O')
187                 strcpy(rmname, bbb);
188         if (b == 'U') {
189                 strcpy(subj, bbb);
190                 generate_subject = 0;   /* have a real subj so don't gen one */
191         }
192         goto BONFGM;
193 }
194
195 int main(int argc, char **argv)
196 {
197         int a;
198         FILE *fp, *rmail;
199         char sbuf[200], rbuf[200], cstr[100], fstr[128];
200         char nbuf[64], pbuf[128], rmname[128], buf[128];
201         char subject[200];
202         time_t mid_buf;
203         time_t now;
204         int mlist = 0;
205
206         openlog("netmailer", LOG_PID, LOG_USER);
207         get_config();
208         LoadInternetConfig();
209         sprintf(temp, tmpnam(NULL));    /* temp file name */
210
211         if ((argc < 2) || (argc > 3)) {
212                 fprintf(stderr, "netmailer: usage: "
213                         "netmailer <filename> [mlist]\n");
214                 exit(1);
215         }
216         /*
217          * If we are running in mailing list mode, the room is being two-way
218          * gatewayed to an Internet mailing list.  Since many listprocs only
219          * accept postings from subscribed addresses, we must always use the
220          * room's address as the originating user.
221          */
222         if ((argc == 3) && (!strcasecmp(argv[2], "mlist"))) {
223                 mlist = 1;
224         }
225         /* convert to ASCII & get info */
226         fp = fopen(temp, "w");
227         msgform(argv[1], fp, sbuf, rbuf, nbuf, pbuf, &mid_buf, rmname, subject);
228         fclose(fp);
229
230         strcpy(buf, rmname);
231         strcpy(rmname, "room_");
232         strcat(rmname, buf);
233         for (a = 0; a < strlen(rmname); ++a) {
234                 if (rmname[a] == ' ')
235                         rmname[a] = '_';
236                 rmname[a] = tolower(rmname[a]);
237         }
238
239         sprintf(cstr, SENDMAIL, rbuf);
240         rmail = (FILE *) popen(cstr, "w");
241
242         strcpy(fstr, sbuf);
243         for (a = 0; a < strlen(sbuf); ++a)
244                 if (sbuf[a] == 32)
245                         sbuf[a] = '_';
246         for (a = 0; a < strlen(rbuf); ++a)
247                 if (rbuf[a] == 32)
248                         rbuf[a] = '_';
249
250         /*
251          * This logic attempts to compose From and From: lines that are
252          * as RFC822-compliant as possible.  The return addresses are correct
253          * if you're using Citadel's 'citmail' delivery agent to allow BBS
254          * users to receive Internet mail.
255          */
256         fprintf(rmail, "From ");
257         if (strcasecmp(nbuf, NODENAME))
258                 fprintf(rmail, "%s!", nbuf);
259
260         if (!strcasecmp(nbuf, NODENAME))
261                 strcpy(nbuf, FQDN);
262
263         if (mlist) {
264                 fprintf(rmail, "%s\n", rmname);
265                 fprintf(rmail, "From: %s@%s (%s)\n", rmname, FQDN, fstr);
266         } else {
267
268                 if (!strcasecmp(nbuf, NODENAME)) {      /* from this system */
269                         fprintf(rmail, "%s\n", pbuf);
270                         fprintf(rmail, "From: %s@%s (%s)\n",
271                                 sbuf, FQDN, fstr);
272                 } else if (haschar(nbuf, '.')) {        /* from an FQDN */
273                         fprintf(rmail, "%s\n", sbuf);
274                         fprintf(rmail, "From: %s@%s (%s)\n",
275                                 sbuf, nbuf, fstr);
276                 } else {        /* from another Cit */
277                         fprintf(rmail, "%s\n", sbuf);
278                         fprintf(rmail, "From: %s@%s.%s (%s)\n",
279                                 sbuf, nbuf, GW_DOMAIN, fstr);
280                 }
281
282         }
283
284         /*
285          * Everything else is pretty straightforward.
286          */
287         fprintf(rmail, "To: %s\n", rbuf);
288         time(&now);
289         fprintf(rmail, "Date: %s", asctime(localtime(&now)));
290         fprintf(rmail, "Message-Id: <%ld@%s>\n", (long) mid_buf, nbuf);
291         fprintf(rmail, "X-Mailer: %s\n", CITADEL);
292         fprintf(rmail, "Subject: %s\n", subject);
293         fprintf(rmail, "\n");
294         fp = fopen(temp, "r");
295         if (fp != NULL) {
296                 do {
297                         a = getc(fp);
298                         if (a >= 0)
299                                 putc(a, rmail);
300                 } while (a >= 0);
301                 fclose(fp);
302         }
303         fprintf(rmail, "\n");
304         pclose(rmail);
305
306         unlink(temp);           /* get rid of the ASCII file */
307         execlp("./netproc", "netproc", "-i", NULL);
308         exit(0);                /* go back to the main program */
309 }