Initial revision
[citadel.git] / citadel / cux2ascii.c
1 /*
2  * cux2ascii v2.3
3  * see copyright.doc for copyright information
4  *
5  * This program is a filter which converts Citadel/UX binary message format
6  * to standard UseNet news format.  Useful for Citadel<->News gateways.
7  */
8
9 #include <fcntl.h>
10 #include <stdio.h>
11 #include <ctype.h>
12 #include <time.h>
13 #include "citadel.h"
14
15 long finduser();
16
17 void get_config();      struct config config;
18
19 int struncmp(lstr,rstr,len)
20 char lstr[],rstr[];
21 int len; {
22         int pos = 0;
23         char lc,rc;
24         while (pos<len) {
25                 lc=tolower(lstr[pos]);
26                 rc=tolower(rstr[pos]);
27                 if ((lc==0)&&(rc==0)) return(0);
28                 if (lc<rc) return(-1);
29                 if (lc>rc) return(1);
30                 pos=pos+1;
31                 }
32         return(0);
33         }
34
35 main(argc,argv)
36 int argc;
37 char *argv[]; {
38         struct tm *tm;
39         int a,b,e,mtype,aflag;
40         char bbb[100],ngn[100];
41         long tmid;
42         char tsid[64];
43         char tuid[64];
44         FILE *fp,*tfp;
45         long now,msglen;
46         char tflnm[16];
47
48         int cuunbatch = 0;
49
50         /* experimental cuunbatch header generation */
51         for (a=0; a<argc; ++a) {
52                 if (!strcmp(argv[a],"-c")) cuunbatch = 1;
53                 }
54
55         get_config();
56
57         sprintf(tflnm,"/tmp/c2a%d",getpid());
58
59         fp=stdin;
60    while (1) {
61         do {
62                 e=getc(fp);
63                 if (e<0) exit(0);
64                 } while(e!=255);
65         mtype=getc(fp); aflag=getc(fp);
66
67         tmid = 0L;
68         strcpy(tsid,FQDN);
69         strcpy(tuid,"postmaster");
70
71         tfp=fopen(tflnm,"w");
72    do {
73         b=getc(fp);
74         if (b=='M') {
75                 fprintf(tfp,"Message-ID: <%ld@%s>\n",tmid,tsid);
76                 fprintf(tfp,"\n");
77                 if (aflag!=1) fmout(80,fp,tfp);
78                    else while(a=getc(fp), a>0) {
79                         putc(a,tfp); if (a==13) putc(10,tfp);
80                         }
81                 }
82         if ((b!='M')&&(b>0)) fpgetfield(fp,bbb);
83         if (b=='I') tmid=atol(bbb);
84         if (b=='N') {
85                 strcpy(tsid,bbb);
86                 if (!strcmp(tsid,NODENAME)) strcpy(tsid,FQDN);
87                 for (a=0; a<strlen(tuid); ++a) if (tuid[a]==' ') tuid[a]='_';
88                 fprintf(tfp,"From: %s@%s ",tuid,tsid);
89                 for (a=0; a<strlen(tuid); ++a) if (tuid[a]=='_') tuid[a]=' ';
90                 fprintf(tfp,"(%s)\n",tuid);
91                 }
92         if (b=='P') fprintf(tfp,"Path: %s\n",bbb);
93         if (b=='A') strcpy(tuid,bbb);
94         if (b=='O') {
95                 xref(bbb,ngn);
96                 fprintf(tfp,"Newsgroups: %s\n",ngn);
97                 }
98         if (b=='R') fprintf(tfp,"To: %s\n",bbb);
99         if (b=='U') fprintf(tfp,"Subject: %s\n",bbb);
100         if (b=='T') {
101                 now=atol(bbb);
102                 tm=(struct tm *)localtime(&now);
103                 fprintf(tfp,"Date: %s",asctime(tm));
104                 }
105            } while ((b!='M')&&(b>0));
106         msglen=ftell(tfp);
107         fclose(tfp);
108
109         if (cuunbatch) {
110                 printf("#! cuunbatch %ld\n",msglen);
111                 }
112         else {
113                 printf("#! rnews %ld\n",msglen);
114                 }
115
116         tfp=fopen(tflnm,"r");
117         while(msglen--) putc(getc(tfp),stdout);
118         fclose(tfp);
119         unlink(tflnm);
120    }
121 exit(0);
122 }
123
124 fpgetfield(fp,string)   /* level-2 break out next null-terminated string */
125 FILE *fp;
126 char string[];
127 {
128 int a,b;
129 strcpy(string,"");
130 a=0;
131         do {
132                 b=getc(fp);
133                 if (b<1) { string[a]=0; return(0); }
134                 string[a]=b;
135                 ++a;
136                 } while(b!=0);
137         return(0);
138 }
139
140 fmout(width,fp,mout)
141 int width;
142 FILE *fp,*mout;
143         {
144         int a,b,c,real,old;
145         char aaa[140];
146         
147         strcpy(aaa,""); old=255;
148         c=1; /* c is the current pos */
149 FMTA:   old=real; a=getc(fp); real=a;
150         if (a<=0) goto FMTEND;
151         
152         if ( ((a==13)||(a==10)) && (old!=13) && (old!=10) ) a=32;
153         if ( ((old==13)||(old==10)) && (isspace(real)) ) {
154                                                 fprintf(mout,"\n"); c=1; }
155         if (a>126) goto FMTA;
156
157         if (a>32) {
158         if ( ((strlen(aaa)+c)>(width-1)) && (strlen(aaa)>(width-1)) )
159                 { fprintf(mout,"\n%s",aaa); c=strlen(aaa); aaa[0]=0; }
160          b=strlen(aaa); aaa[b]=a; aaa[b+1]=0; }
161         if (a==32) {    if ((strlen(aaa)+c)>(width-1)) { 
162                                                         fprintf(mout,"\n");
163                                                         c=1;
164                                                         }
165                         fprintf(mout,"%s ",aaa); ++c; c=c+strlen(aaa);
166                         strcpy(aaa,""); goto FMTA; }
167         if ((a==13)||(a==10)) {
168                                 fprintf(mout,"%s\n",aaa); c=1;
169                                 strcpy(aaa,""); goto FMTA; }
170         goto FMTA;
171
172 FMTEND: fprintf(mout,"\n");
173         return(0);
174 }
175
176 xref(roomname,newsgroup)
177 char *roomname,*newsgroup; {
178         char tbuf[128];
179         FILE *fp;
180         int commapos,a;
181
182         strcpy(newsgroup,roomname);
183         fp=fopen("./network/rnews.xref","r");
184         if (fp==NULL) return(1);
185         while (fgets(tbuf,128,fp)!=NULL) {
186                 tbuf[strlen(tbuf)-1]=0;         /* strip off the newline */
187                 a=strlen(tbuf);
188                 while (a--) if (tbuf[a]==',') commapos=a;
189                 tbuf[commapos]=0;
190                 if (!strucmp(&tbuf[commapos+1],roomname))
191                         strcpy(newsgroup,tbuf);
192                 }
193         fclose(fp);
194         return(0);
195         }