282cce16c1dcb3149ec79af7498f3838066ed3eb
[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  *
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 <syslog.h>
17 #include "citadel.h"
18
19 void LoadInternetConfig();
20 void get_config();
21 struct config config;
22
23 char temp[20];
24
25 char ALIASES[128];
26 char CIT86NET[128];
27 char SENDMAIL[128];
28 char FALLBACK[128];
29 char GW_DOMAIN[128];
30 char TABLEFILE[128];
31 int RUN_NETPROC = 1;
32
33 int haschar(st,ch)
34 char st[];
35 int ch; {
36         int a,b;
37         b=0;
38         for (a=0; a<strlen(st); ++a) if (st[a]==ch) ++b;
39         return(b);
40         }
41
42
43
44 void fpgetfield(fp,string)
45 FILE *fp;
46 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(msgfile,mfout,sbuf,rbuf,nbuf,pbuf,mid_buf,rmname,subj)
68 char *msgfile;
69 FILE *mfout;
70 char *sbuf;             /* sender */
71 char *rbuf;             /* recipient (in this case, an Internet address) */
72 char *nbuf;             /* source node */
73 char *pbuf;             /* path */
74 long *mid_buf;          /* message ID */
75 char *rmname;           /* room name */
76 char *subj;             /* subject */
77         {
78         int a,b,c,e,old,mtype,aflag;
79         int real = 0;
80         char aaa[128],bbb[128];
81         FILE *fp;
82         int width;
83         int generate_subject = 1;
84
85         strcpy(subj, "");
86         strcpy(pbuf, "");       
87         strcpy(nbuf, NODENAME); 
88         strcpy(rmname,"");
89         time(mid_buf);
90         width=80;
91         fp=fopen(msgfile, "rb");
92         if (fp==NULL) {
93                 fprintf(stderr, "netmailer: can't open message file\n");
94                 return;
95                 }
96         strcpy(aaa,""); 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); aflag=getc(fp);
104         goto BONFGM;
105 A:      if (aflag==1) goto AFLAG;
106         old=real; a=getc(fp); real=a;
107         if (a==0) goto END;
108         if (a<0) goto END;
109
110         /* generate subject... */
111         if ( (generate_subject == 1) && (strlen(subj) < 60)) {
112                 subj[strlen(subj)+1] = 0;
113                 subj[strlen(subj)] = (((a>31)&&(a<127)) ? a : 32);
114                 }
115         
116         if ( ((a==13)||(a==10)) && (old!=13) && (old!=10) ) a=32;
117         if ( ((old==13)||(old==10)) && ((real==32)||(real==13)||(real==10))) {
118                                                 fprintf(mfout,"\n"); c=1; }
119
120         if (a!=32) {
121         if ( ((strlen(aaa)+c)>(width-5)) && (strlen(aaa)>(width-5)) )
122                 { fprintf(mfout,"\n%s",aaa); c=strlen(aaa); aaa[0]=0; }
123          b=strlen(aaa); aaa[b]=a; aaa[b+1]=0; }
124         if (a==32) {    if ((strlen(aaa)+c)>(width-5)) { 
125                                                         fprintf(mfout,"\n");
126                                                         c=1;
127                                                         }
128                         fprintf(mfout,"%s ",aaa); ++c; c=c+strlen(aaa);
129                         strcpy(aaa,""); goto A; }
130         if ((a==13)||(a==10)) {
131                                 fprintf(mfout,"%s\n",aaa); c=1;
132                                 strcpy(aaa,""); goto A; }
133         goto A;
134
135 AFLAG:  a=getc(fp);
136         if (a==0) goto END;
137         if (a==13) {
138                 putc(10, mfout);
139                 }
140         else {
141                 putc(a, mfout);
142                 }
143         goto AFLAG;
144
145 END:    fclose(fp);
146         return;
147
148 BONFGM: b=getc(fp); if (b<0) goto END;
149         if (b=='M') goto A;
150         fpgetfield(fp, bbb);
151         if (b=='A') strcpy(sbuf, bbb);
152         if (b=='R') strcpy(rbuf, bbb);
153         if (b=='N') strcpy(nbuf, bbb);
154         if (b=='P') strcpy(pbuf, bbb);
155         if (b=='I') *mid_buf = atol(bbb);
156         if (b=='O') strcpy(rmname, bbb);
157         if (b=='U') {
158                 strcpy(subj, bbb);
159                 generate_subject = 0; /* have a real subj so don't gen one */
160                 }
161         goto BONFGM;
162         }
163
164 void main(argc,argv)
165 int argc;
166 char *argv[]; {
167         int a;
168         FILE *fp,*rmail;
169         char sbuf[200],rbuf[200],cstr[100],fstr[128];
170         char nbuf[64],pbuf[128],rmname[128],buf[128];
171         char subject[200];
172         long mid_buf;
173         long now;
174         int mlist = 0;
175
176         fprintf(stderr, "netmailer: started...  sending mail to %s\n", argv[1]);
177         openlog("netmailer", LOG_PID, LOG_USER);
178         get_config();   
179         LoadInternetConfig();
180         sprintf(temp, "/tmp/netmailer.%d", getpid()); /* temp file name */
181
182         if ( (argc < 2) || (argc > 3) ) {
183                 fprintf(stderr, "netmailer: usage: netmailer recipient@node.dom [mlist]\n");
184                 exit(1);
185                 }
186
187         /*
188          * If we are running in mailing list mode, the room is being two-way
189          * gatewayed to an Internet mailing list.  Since many listprocs only
190          * accept postings from subscribed addresses, we must always use the
191          * room's address as the originating user.
192          */
193         if ( (argc == 3) && (!strcasecmp(argv[2], "mlist")) ) {
194                 mlist = 1;
195                 }
196
197         /* convert to ASCII & get info */
198         fp=fopen(temp,"w");
199         msgform(argv[1], fp, sbuf, rbuf, nbuf, pbuf, &mid_buf, rmname, subject);
200         fclose(fp);
201
202         strcpy(buf, rmname);
203         strcpy(rmname, "room_");
204         strcat(rmname, buf);
205         for (a=0; a<strlen(rmname); ++a) {
206                 if (rmname[a] == ' ') rmname[a] = '_';
207                 rmname[a] = tolower(rmname[a]);
208                 }
209
210         sprintf(cstr, SENDMAIL, rbuf);
211         rmail=(FILE *)popen(cstr,"w");
212
213         strcpy(fstr,sbuf);
214         for (a=0; a<strlen(sbuf); ++a) if (sbuf[a]==32) sbuf[a]='_';
215         for (a=0; a<strlen(rbuf); ++a) if (rbuf[a]==32) rbuf[a]='_';
216
217         /*
218          * This logic attempts to compose From and From: lines that are
219          * as RFC822-compliant as possible.  The return addresses are correct
220          * if you're using Citadel's 'citmail' delivery agent to allow BBS
221          * users to receive Internet mail.
222          */
223         fprintf(rmail,"From ");
224         if (strcasecmp(nbuf,NODENAME)) fprintf(rmail,"%s!",nbuf);
225
226         if (!strcasecmp(nbuf,NODENAME)) strcpy(nbuf, FQDN);
227         
228         if (mlist) {
229                 fprintf(rmail,"%s\n", rmname);
230                 fprintf(rmail,"From: %s@%s (%s)\n", rmname, FQDN, fstr);
231                 }
232         else {
233
234                 if (!strcasecmp(nbuf, NODENAME)) {              /* from this system */
235                         fprintf(rmail,"%s\n",pbuf);
236                         fprintf(rmail,"From: %s@%s (%s)\n",
237                                 sbuf, FQDN, fstr);
238                         }
239                 else if (haschar(nbuf, '.')) {          /* from an FQDN */
240                         fprintf(rmail,"%s\n",sbuf);
241                         fprintf(rmail,"From: %s@%s (%s)\n",
242                                 sbuf, nbuf, fstr);
243                         }
244                 else {                                  /* from another Cit */
245                         fprintf(rmail,"%s\n",sbuf);
246                         fprintf(rmail,"From: %s@%s.%s (%s)\n",
247                                 sbuf, nbuf, GW_DOMAIN, fstr);
248                         }
249
250                 }
251
252         /*
253          * Everything else is pretty straightforward.
254          */
255         fprintf(rmail,"To: %s\n", rbuf);
256         time(&now);
257         fprintf(rmail,"Date: %s", asctime(localtime(&now)));
258         fprintf(rmail,"Message-Id: <%ld@%s>\n", mid_buf, nbuf);
259         fprintf(rmail,"X-Mailer: %s\n", CITADEL);
260         fprintf(rmail,"Subject: %s\n", subject);
261         fprintf(rmail,"\n");
262         fp=fopen(temp,"r");
263         if (fp!=NULL) {
264                 do {
265                         a=getc(fp);
266                         if (a>=0) putc(a,rmail);
267                         } while(a>=0);
268                 fclose(fp);
269                 }
270         fprintf(rmail,"\n");
271         pclose(rmail);
272   
273         unlink(temp);           /* get rid of the ASCII file */
274         exit(0);                /* go back to the main program */
275         }