|
|
1.1 ! root 1: /* msgtoqwk.cpp */ ! 2: ! 3: /* Synchronet message to QWK format conversion routine */ ! 4: ! 5: /* $Id: msgtoqwk.cpp,v 1.24 2005/09/20 03:39:52 deuce 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 2004 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=0,tear=0,tearwatch=0,*buf,*p; ! 51: char tmp[512]; ! 52: long l,size=0,offset; ! 53: int i; ! 54: struct tm tm; ! 55: smbmsg_t remsg; ! 56: ! 57: offset=ftell(qwk_fp); ! 58: memset(str,' ',QWK_BLOCK_LEN); ! 59: fwrite(str,QWK_BLOCK_LEN,1,qwk_fp); /* Init header to space */ ! 60: ! 61: if(msg->from_net.addr && (uint)subnum==INVALID_SUB) { ! 62: if(mode&QM_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,smb_faddrtoa((faddr_t *)msg->from_net.addr,tmp)); ! 67: else if(msg->from_net.type==NET_INTERNET) ! 68: sprintf(from,"%.128s",(char*)msg->from_net.addr); ! 69: else ! 70: sprintf(from,"%.128s@%.128s",msg->from,(char*)msg->from_net.addr); ! 71: if(strlen(from)>25) { ! 72: sprintf(str,"From: %.128s%c%c",from,QWK_NEWLINE,QWK_NEWLINE); ! 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,smb_faddrtoa((faddr_t *)msg->to_net.addr,tmp)); ! 84: else if(msg->to_net.type==NET_INTERNET) ! 85: sprintf(to,"%.128s",(char*)msg->to_net.addr); ! 86: else if(msg->to_net.type==NET_QWK) { ! 87: if(mode&QM_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%c",msg->to,p,QWK_NEWLINE); ! 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,(char*)msg->to_net.addr); } ! 99: else ! 100: sprintf(to,"%.128s@%.128s",msg->to,(char*)msg->to_net.addr); ! 101: if(strlen(to)>25) { ! 102: sprintf(str,"To: %.128s%c%c",to,QWK_NEWLINE,QWK_NEWLINE); ! 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&QM_VIA && !msg->forwarded) { ! 113: sprintf(str,"@VIA: %.*s%c" ! 114: ,(int)(sizeof(str)-12),(char*)msg->from_net.addr,QWK_NEWLINE); ! 115: fwrite(str,strlen(str),1,qwk_fp); ! 116: size+=strlen(str); } ! 117: ! 118: if(mode&QM_MSGID && (uint)subnum!=INVALID_SUB) { ! 119: sprintf(str,"@MSGID: %.*s%c" ! 120: ,(int)(sizeof(str)-12),get_msgid(&cfg,subnum,msg),QWK_NEWLINE); ! 121: fwrite(str,strlen(str),1,qwk_fp); ! 122: size+=strlen(str); ! 123: ! 124: str[0]=0; ! 125: if(msg->reply_id) { ! 126: SAFECOPY(tmp,msg->reply_id); ! 127: truncstr(tmp," "); ! 128: sprintf(str,"@REPLY: %.*s%c" ! 129: ,(int)(sizeof(str)-12),tmp,QWK_NEWLINE); ! 130: } else if(msg->hdr.thread_back) { ! 131: memset(&remsg,0,sizeof(remsg)); ! 132: remsg.hdr.number=msg->hdr.thread_back; ! 133: if(smb_getmsgidx(&smb, &remsg)) ! 134: sprintf(str,"@REPLY: <%s>%c",smb.last_error,QWK_NEWLINE); ! 135: else ! 136: sprintf(str,"@REPLY: %s%c" ! 137: ,get_msgid(&cfg,subnum,&remsg) ! 138: ,QWK_NEWLINE); ! 139: } ! 140: if(str[0]) { ! 141: fwrite(str,strlen(str),1,qwk_fp); ! 142: size+=strlen(str); ! 143: } ! 144: } ! 145: ! 146: if(msg->hdr.when_written.zone && mode&QM_TZ) { ! 147: sprintf(str,"@TZ: %04x%c",msg->hdr.when_written.zone,QWK_NEWLINE); ! 148: fwrite(str,strlen(str),1,qwk_fp); ! 149: size+=strlen(str); ! 150: } ! 151: ! 152: if(msg->replyto!=NULL && mode&QM_REPLYTO) { ! 153: sprintf(str,"@REPLYTO: %.*s%c" ! 154: ,(int)(sizeof(str)-12),msg->replyto,QWK_NEWLINE); ! 155: fwrite(str,strlen(str),1,qwk_fp); ! 156: size+=strlen(str); ! 157: } ! 158: ! 159: p=0; ! 160: for(i=0;i<msg->total_hfields;i++) { ! 161: if(msg->hfield[i].type==SENDER) ! 162: p=(char *)msg->hfield_dat[i]; ! 163: if(msg->hfield[i].type==FORWARDED && p) { ! 164: sprintf(str,"Forwarded from %s on %s%c",p ! 165: ,timestr((time_t *)msg->hfield_dat[i]) ! 166: ,QWK_NEWLINE); ! 167: fwrite(str,strlen(str),1,qwk_fp); ! 168: size+=strlen(str); ! 169: } ! 170: } ! 171: ! 172: buf=smb_getmsgtxt(&smb,msg,GETMSGTXT_ALL); ! 173: if(!buf) ! 174: return(0); ! 175: ! 176: for(l=0;buf[l];l++) { ! 177: ch=buf[l]; ! 178: ! 179: if(ch==LF) { ! 180: if(tear) ! 181: tear++; /* Count LFs after tearline */ ! 182: if(tear>3) /* more than two LFs after the tear */ ! 183: tear=0; ! 184: if(tearwatch==4) { /* watch for LF---LF */ ! 185: tear=1; ! 186: tearwatch=0; } ! 187: else if(!tearwatch) ! 188: tearwatch=1; ! 189: else ! 190: tearwatch=0; ! 191: ch=QWK_NEWLINE; ! 192: fputc(ch,qwk_fp); /* Replace LF with funky char */ ! 193: size++; ! 194: continue; } ! 195: ! 196: if(ch==CR) { /* Ignore CRs */ ! 197: if(tearwatch<4) /* LF---CRLF is okay */ ! 198: tearwatch=0; /* LF-CR- is not okay */ ! 199: continue; } ! 200: ! 201: if(ch==' ' && tearwatch==4) { /* watch for "LF--- " */ ! 202: tear=1; ! 203: tearwatch=0; } ! 204: ! 205: if(ch=='-') { /* watch for "LF---" */ ! 206: if(l==0 || (tearwatch && tearwatch<4)) ! 207: tearwatch++; ! 208: else ! 209: tearwatch=0; } ! 210: else ! 211: tearwatch=0; ! 212: ! 213: if((uint)subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_ASCII) { ! 214: if(ch<' ' && ch!=1) ! 215: ch='.'; ! 216: else if((uchar)ch>0x7f) ! 217: ch='*'; } ! 218: ! 219: if(ch==QWK_NEWLINE) /* funky char */ ! 220: ch='*'; ! 221: ! 222: if(ch==CTRL_A) { ! 223: ch=buf[++l]; ! 224: if(!ch) ! 225: break; ! 226: if(mode&A_EXPAND) { ! 227: str[0]=0; ! 228: switch(toupper(ch)) { /* non-color codes */ ! 229: case 'L': ! 230: strcpy(str,"\x1b[2J\x1b[H"); ! 231: break; ! 232: case 'W': ! 233: strcpy(str,ansi(LIGHTGRAY)); ! 234: break; ! 235: case 'K': ! 236: strcpy(str,ansi(BLACK)); ! 237: break; ! 238: case 'H': ! 239: strcpy(str,ansi(HIGH)); ! 240: break; ! 241: case 'I': ! 242: strcpy(str,ansi(BLINK)); ! 243: break; ! 244: case 'N': /* Normal */ ! 245: strcpy(str,ansi(ANSI_NORMAL)); ! 246: break; ! 247: case 'R': /* Color codes */ ! 248: strcpy(str,ansi(RED)); ! 249: break; ! 250: case 'G': ! 251: strcpy(str,ansi(GREEN)); ! 252: break; ! 253: case 'B': ! 254: strcpy(str,ansi(BLUE)); ! 255: break; ! 256: case 'C': ! 257: strcpy(str,ansi(CYAN)); ! 258: break; ! 259: case 'M': ! 260: strcpy(str,ansi(MAGENTA)); ! 261: break; ! 262: case 'Y': /* Yellow */ ! 263: strcpy(str,ansi(BROWN)); ! 264: break; ! 265: case '0': ! 266: strcpy(str,ansi(BG_BLACK)); ! 267: break; ! 268: case '1': ! 269: strcpy(str,ansi(BG_RED)); ! 270: break; ! 271: case '2': ! 272: strcpy(str,ansi(BG_GREEN)); ! 273: break; ! 274: case '3': ! 275: strcpy(str,ansi(BG_BROWN)); ! 276: break; ! 277: case '4': ! 278: strcpy(str,ansi(BG_BLUE)); ! 279: break; ! 280: case '5': ! 281: strcpy(str,ansi(BG_MAGENTA)); ! 282: break; ! 283: case '6': ! 284: strcpy(str,ansi(BG_CYAN)); ! 285: break; ! 286: case '7': ! 287: strcpy(str,ansi(BG_LIGHTGRAY)); ! 288: break; ! 289: } ! 290: if(str[0]) { ! 291: fwrite(str,strlen(str),1,qwk_fp); ! 292: size+=strlen(str); ! 293: } ! 294: continue; ! 295: } /* End Expand */ ! 296: ! 297: if(mode&A_LEAVE) { ! 298: fputc(1,qwk_fp); ! 299: fputc(ch,qwk_fp); ! 300: size+=2L; } ! 301: else /* Strip */ ! 302: if(toupper(ch)=='L') { ! 303: fputc(FF,qwk_fp); ! 304: size++; } ! 305: continue; } /* End of Ctrl-A shit */ ! 306: fputc(ch,qwk_fp); ! 307: size++; } ! 308: ! 309: free(buf); ! 310: if(ch!=QWK_NEWLINE) { ! 311: fputc(QWK_NEWLINE,qwk_fp); /* make sure it ends in CRLF */ ! 312: size++; } ! 313: ! 314: if(mode&QM_TAGLINE && !(cfg.sub[subnum]->misc&SUB_NOTAG)) { ! 315: if(!tear) /* no tear line */ ! 316: sprintf(str,"\1n---%c",QWK_NEWLINE); /* so add one */ ! 317: else ! 318: strcpy(str,"\1n"); ! 319: if(cfg.sub[subnum]->misc&SUB_ASCII) ch='*'; ! 320: else ch='�'; ! 321: sprintf(tmp," %c \1g%.10s\1n %c %.127s%c" ! 322: ,ch,VERSION_NOTICE,ch,cfg.sub[subnum]->tagline,QWK_NEWLINE); ! 323: strcat(str,tmp); ! 324: if(!(mode&A_LEAVE)) ! 325: remove_ctrl_a(str,NULL); ! 326: fwrite(str,strlen(str),1,qwk_fp); ! 327: size+=strlen(str); } ! 328: ! 329: while(size%QWK_BLOCK_LEN) { /* Pad with spaces */ ! 330: size++; ! 331: fputc(' ',qwk_fp); } ! 332: ! 333: if(localtime_r((time_t *)&msg->hdr.when_written.time,&tm)==NULL) ! 334: memset(&tm,0,sizeof(tm)); ! 335: ! 336: sprintf(tmp,"%02u-%02u-%02u%02u:%02u" ! 337: ,tm.tm_mon+1,tm.tm_mday,TM_YEAR(tm.tm_year) ! 338: ,tm.tm_hour,tm.tm_min); ! 339: ! 340: if(msg->hdr.attr&MSG_PRIVATE) { ! 341: if(msg->hdr.attr&MSG_READ) ! 342: ch='*'; /* private, read */ ! 343: else ! 344: ch='+'; /* private, unread */ } ! 345: else { ! 346: if(msg->hdr.attr&MSG_READ) ! 347: ch='-'; /* public, read */ ! 348: else ! 349: ch=' '; /* public, unread */ } ! 350: ! 351: ! 352: sprintf(str,"%c%-7lu%-13.13s%-25.25s" ! 353: "%-25.25s%-25.25s%12s%-8lu%-6lu\xe1%c%c%c%c%c" ! 354: ,ch /* message status flag */ ! 355: ,mode&QM_REP ? (ulong)conf /* conference or */ ! 356: : msg->hdr.number&MAX_MSGNUM /* message number */ ! 357: ,tmp /* date and time */ ! 358: ,to /* To: */ ! 359: ,from /* From: */ ! 360: ,msg->subj /* Subject */ ! 361: ,nulstr /* Password */ ! 362: ,msg->hdr.thread_back&MAX_MSGNUM /* Message Re: Number */ ! 363: ,(size/QWK_BLOCK_LEN)+1 /* Number of blocks */ ! 364: ,(char)conf&0xff /* Conference number lo byte */ ! 365: ,(ushort)conf>>8 /* hi byte */ ! 366: ,' ' /* not used */ ! 367: ,' ' /* not used */ ! 368: ,useron.rest&FLAG('Q') ? '*' : ' ' /* Net tag line */ ! 369: ); ! 370: ! 371: fseek(qwk_fp,offset,SEEK_SET); ! 372: fwrite(str,QWK_BLOCK_LEN,1,qwk_fp); ! 373: fseek(qwk_fp,size,SEEK_CUR); ! 374: ! 375: return(size); ! 376: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.