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