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