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