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