|
|
1.1 root 1: /* msgtoqwk.cpp */
2:
3: /* Synchronet message to QWK format conversion routine */
4:
5: /* $Id: msgtoqwk.cpp,v 1.2 2000/12/11 23:21:12 rswindell Exp $ */
6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
11: * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html *
12: * *
13: * This program is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU General Public License for more details: gpl.txt or *
18: * http://www.fsf.org/copyleft/gpl.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: #include "sbbs.h"
39: #include "qwk.h"
40:
41: #define MAX_MSGNUM 0x7FFFFFUL // only 7 (decimal) digits allowed for msg num
42:
43: /****************************************************************************/
44: /* Converts message 'msg' to QWK format, writing to file 'qwk_fp'. */
45: /* mode determines how to handle Ctrl-A codes */
46: /****************************************************************************/
47: ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, int subnum
48: , int conf)
49: {
50: char str[512],from[512],to[512],ch,tear=0,tearwatch=0,HUGE16 *buf,*p;
51: char tmp[512];
52: long l,size=0,offset;
53: int i;
54: struct tm tm;
55: struct tm* tm_p;
56:
57: offset=ftell(qwk_fp);
58: memset(str,SP,128);
59: fwrite(str,128,1,qwk_fp); /* Init header to space */
60:
61: if(msg->from_net.addr && (uint)subnum==INVALID_SUB) {
62: if(mode&TO_QNET)
63: sprintf(from,"%.128s",msg->from);
64: else if(msg->from_net.type==NET_FIDO)
65: sprintf(from,"%.128s@%.128s"
66: ,msg->from,faddrtoa(*(faddr_t *)msg->from_net.addr));
67: else if(msg->from_net.type==NET_INTERNET)
68: sprintf(from,"%.128s",msg->from_net.addr);
69: else
70: sprintf(from,"%.128s@%.128s",msg->from,msg->from_net.addr);
71: if(strlen(from)>25) {
72: sprintf(str,"From: %.128s\xe3\xe3",from);
73: fwrite(str,strlen(str),1,qwk_fp);
74: size+=strlen(str);
75: sprintf(from,"%.128s",msg->from); } }
76: else {
77: sprintf(from,"%.128s",msg->from);
78: if(msg->hdr.attr&MSG_ANONYMOUS && !SYSOP) /* from user */
79: strcpy(from,text[Anonymous]); }
80:
81: if(msg->to_net.addr && (uint)subnum==INVALID_SUB) {
82: if(msg->to_net.type==NET_FIDO)
83: sprintf(to,"%.128s@%s",msg->to,faddrtoa(*(faddr_t *)msg->to_net.addr));
84: else if(msg->to_net.type==NET_INTERNET)
85: sprintf(to,"%.128s",msg->to_net.addr);
86: else if(msg->to_net.type==NET_QWK) {
87: if(mode&TO_QNET) {
88: p=strchr((char *)msg->to_net.addr,'/');
89: if(p) { /* Another hop */
90: p++;
91: strcpy(to,"NETMAIL");
92: sprintf(str,"%.128s@%.128s\xe3",msg->to,p);
93: fwrite(str,strlen(str),1,qwk_fp);
94: size+=strlen(str); }
95: else
96: sprintf(to,"%.128s",msg->to); }
97: else
98: sprintf(to,"%.128s@%.128s",msg->to,msg->to_net.addr); }
99: else
100: sprintf(to,"%.128s@%.128s",msg->to,msg->to_net.addr);
101: if(strlen(to)>25) {
102: sprintf(str,"To: %.128s\xe3\xe3",to);
103: fwrite(str,strlen(str),1,qwk_fp);
104: size+=strlen(str);
105: if(msg->to_net.type==NET_QWK)
106: strcpy(to,"NETMAIL");
107: else
108: sprintf(to,"%.128s",msg->to); } }
109: else
110: sprintf(to,"%.128s",msg->to);
111:
112: if(msg->from_net.type==NET_QWK && mode&VIA && !msg->forwarded) {
113: sprintf(str,"@VIA:%.128s\xe3",msg->from_net.addr);
114: fwrite(str,strlen(str),1,qwk_fp);
115: size+=strlen(str); }
116:
117: if(msg->hdr.when_written.zone && mode&TZ) {
118: sprintf(str,"@TZ:%04x\xe3",msg->hdr.when_written.zone);
119: fwrite(str,strlen(str),1,qwk_fp);
120: size+=strlen(str); }
121:
122: p=0;
123: for(i=0;i<msg->total_hfields;i++) {
124: if(msg->hfield[i].type==SENDER)
125: p=(char *)msg->hfield_dat[i];
126: if(msg->hfield[i].type==FORWARDED && p) {
127: sprintf(str,"Forwarded from %s on %s\xe3",p
128: ,timestr((time_t *)msg->hfield_dat[i]));
129: fwrite(str,strlen(str),1,qwk_fp);
130: size+=strlen(str); } }
131:
132: buf=smb_getmsgtxt(&smb,msg,1);
133: if(!buf)
134: return(0);
135:
136: for(l=0;buf[l];l++) {
137: ch=buf[l];
138:
139: if(ch==LF) {
140: if(tear)
141: tear++; /* Count LFs after tearline */
142: if(tear>3) /* more than two LFs after the tear */
143: tear=0;
144: if(tearwatch==4) { /* watch for LF---LF */
145: tear=1;
146: tearwatch=0; }
147: else if(!tearwatch)
148: tearwatch=1;
149: else
150: tearwatch=0;
151: ch='\xe3';
152: fputc(ch,qwk_fp); /* Replace LF with funky char */
153: size++;
154: continue; }
155:
156: if(ch==CR) { /* Ignore CRs */
157: if(tearwatch<4) /* LF---CRLF is okay */
158: tearwatch=0; /* LF-CR- is not okay */
159: continue; }
160:
161: if(ch==SP && tearwatch==4) { /* watch for "LF--- " */
162: tear=1;
163: tearwatch=0; }
164:
165: if(ch=='-') { /* watch for "LF---" */
166: if(l==0 || (tearwatch && tearwatch<4))
167: tearwatch++;
168: else
169: tearwatch=0; }
170: else
171: tearwatch=0;
172:
173: if((uint)subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_ASCII) {
174: if(ch<SP && ch!=1)
175: ch='.';
176: else if((uchar)ch>0x7f)
177: ch='*'; }
178:
179: if((uchar)ch==0xE3) /* funky char */
180: ch='*';
181:
182: if(ch==1) { /* ctrl-a */
183: ch=buf[++l];
184: if(!ch)
185: break;
186: if(mode&A_EXPAND) {
187: str[0]=0;
188: switch(toupper(ch)) { /* non-color codes */
189: case 'L':
190: strcpy(str,"\x1b[2J\x1b[H");
191: break;
192: case 'W':
193: strcpy(str,ansi(LIGHTGRAY));
194: break;
195: case 'K':
196: strcpy(str,ansi(BLACK));
197: break;
198: case 'H':
199: strcpy(str,ansi(HIGH));
200: break;
201: case 'I':
202: strcpy(str,ansi(BLINK));
203: break;
204: case 'N': /* Normal */
205: strcpy(str,"\x1b[0m");
206: break;
207: case '0':
208: strcpy(str,"\x1b[40m");
209: break;
210: case '7':
211: strcpy(str,ansi(LIGHTGRAY<<4));
212: break;
213: case 'R': /* Color codes */
214: strcpy(str,ansi(RED));
215: break;
216: case 'G':
217: strcpy(str,ansi(GREEN));
218: break;
219: case 'B':
220: strcpy(str,ansi(BLUE));
221: break;
222: case 'C':
223: strcpy(str,ansi(CYAN));
224: break;
225: case 'M':
226: strcpy(str,ansi(MAGENTA));
227: break;
228: case 'Y': /* Yellow */
229: strcpy(str,ansi(BROWN));
230: break;
231: case '1':
232: strcpy(str,ansi(RED<<4));
233: break;
234: case '2':
235: strcpy(str,ansi(GREEN<<4));
236: break;
237: case '3':
238: strcpy(str,ansi(BROWN<<4));
239: break;
240: case '4':
241: strcpy(str,ansi(BLUE<<4));
242: break;
243: case '5':
244: strcpy(str,ansi(MAGENTA<<4));
245: break;
246: case '6':
247: strcpy(str,ansi(CYAN<<4));
248: break; }
249: if(str[0]) {
250: fwrite(str,strlen(str),1,qwk_fp);
251: size+=strlen(str); }
252: continue; } /* End Expand */
253:
254: if(mode&A_LEAVE) {
255: fputc(1,qwk_fp);
256: fputc(ch,qwk_fp);
257: size+=2L; }
258: else /* Strip */
259: if(toupper(ch)=='L') {
260: fputc(FF,qwk_fp);
261: size++; }
262: continue; } /* End of Ctrl-A shit */
263: fputc(ch,qwk_fp);
264: size++; }
265:
266: LFREE(buf);
267: if((uchar)ch!=0xE3) {
268: fputc(0xE3,qwk_fp); /* make sure it ends in CRLF */
269: size++; }
270:
271: if(mode&TAGLINE && !(cfg.sub[subnum]->misc&SUB_NOTAG)) {
272: if(!tear) /* no tear line */
273: strcpy(str,"\1n---\xe3"); /* so add one */
274: else
275: strcpy(str,"\1n");
276: if(cfg.sub[subnum]->misc&SUB_ASCII) ch='*';
277: else ch='�';
278: sprintf(tmp," %c \1g%s\1n %c %.127s\xe3"
279: ,ch,"Synchronet",ch,cfg.sub[subnum]->tagline);
280: strcat(str,tmp);
281: if(!(mode&A_LEAVE))
282: remove_ctrl_a(str);
283: fwrite(str,strlen(str),1,qwk_fp);
284: size+=strlen(str); }
285:
286: while(size%128L) { /* Pad with spaces */
287: size++;
288: fputc(SP,qwk_fp); }
289:
290: tm_p=gmtime((time_t *)&msg->hdr.when_written.time);
291: if(tm_p)
292: tm=*tm_p;
293: else
294: memset(&tm,0,sizeof(tm));
295:
296: sprintf(tmp,"%02u-%02u-%02u%02u:%02u"
297: ,tm.tm_mon+1,tm.tm_mday,TM_YEAR(tm.tm_year)
298: ,tm.tm_hour,tm.tm_min);
299:
300: if(msg->hdr.attr&MSG_PRIVATE) {
301: if(msg->hdr.attr&MSG_READ)
302: ch='*'; /* private, read */
303: else
304: ch='+'; /* private, unread */ }
305: else {
306: if(msg->hdr.attr&MSG_READ)
307: ch='-'; /* public, read */
308: else
309: ch=' '; /* public, unread */ }
310:
311:
312: sprintf(str,"%c%-7lu%-13.13s%-25.25s"
313: "%-25.25s%-25.25s%12s%-8lu%-6lu\xe1%c%c%c%c%c"
314: ,ch /* message status flag */
315: ,mode&REP ? (ulong)conf /* conference or */
316: : msg->hdr.number&MAX_MSGNUM /* message number */
317: ,tmp /* date and time */
318: ,to /* To: */
319: ,from /* From: */
320: ,msg->subj /* Subject */
321: ,nulstr /* Password */
322: ,msg->hdr.thread_orig&MAX_MSGNUM /* Message Re: Number */
323: ,(size/128L)+1 /* Number of 128byte blocks */
324: ,(char)conf&0xff /* Conference number lo byte */
325: ,(ushort)conf>>8 /* hi byte */
326: ,SP /* not used */
327: ,SP /* not used */
328: ,useron.rest&FLAG('Q') ? '*' : SP /* Net tag line */
329: );
330:
331: fseek(qwk_fp,offset,SEEK_SET);
332: fwrite(str,128,1,qwk_fp);
333: fseek(qwk_fp,size,SEEK_CUR);
334:
335: return(size);
336: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.