bool sbbs_t::pack_rep(uint hubnum) { char str[MAX_PATH+1]; char tmp[MAX_PATH+1],tmp2[MAX_PATH+1]; char hubid_upper[LEN_QWKID+1]; char hubid_lower[LEN_QWKID+1]; int file,mode; uint i,j,k; long msgcnt,submsgs,packedmail,netfiles=0,deleted; uint32_t u; uint32_t posts; uint32_t mailmsgs; ulong msgs; uint32_t last; post_t* post; mail_t* mail; FILE* rep; FILE* hdrs=NULL; DIR* dir; DIRENT* dirent; smbmsg_t msg; msgcnt=0L; delfiles(cfg.temp_dir,ALLFILES); SAFECOPY(hubid_upper,cfg.qhub[hubnum]->id); strupr(hubid_upper); SAFECOPY(hubid_lower,cfg.qhub[hubnum]->id); strlwr(hubid_lower); SAFEPRINTF2(str,"%s%s.REP",cfg.data_dir,hubid_upper); if(fexistcase(str)) { eprintf(LOG_INFO,"Updating %s", str); external(cmdstr(cfg.qhub[hubnum]->unpack,str,ALLFILES,NULL),EX_OFFLINE); } else eprintf(LOG_INFO,"Creating %s", str); /*************************************************/ /* Create SYSID.MSG, write header and leave open */ /*************************************************/ SAFEPRINTF2(str,"%s%s.MSG",cfg.temp_dir,hubid_upper); fexistcase(str); if((rep=fnopen(&file,str,O_CREAT|O_WRONLY|O_TRUNC))==NULL) { errormsg(WHERE,ERR_CREATE,str,O_CREAT|O_WRONLY|O_TRUNC); return(false); } if(filelength(file)<1) { /* New REP packet */ SAFEPRINTF2(str,"%-*s" ,QWK_BLOCK_LEN,hubid_upper); /* So write header */ fwrite(str,QWK_BLOCK_LEN,1,rep); } fseek(rep,0L,SEEK_END); /* Always includes HEADERS.DAT in .REP packets which are only for QWKnet hubs */ /* And *usually* a Synchronet system */ SAFEPRINTF(str,"%sHEADERS.DAT",cfg.temp_dir); fexistcase(str); if((hdrs=fopen(str,"a"))==NULL) errormsg(WHERE,ERR_CREATE,str,0); /*********************/ /* Pack new messages */ /*********************/ SAFEPRINTF(smb.file,"%smail",cfg.data_dir); smb.retry_time=cfg.smb_retry_time; smb.subnum=INVALID_SUB; if((i=smb_open(&smb))!=0) { fclose(rep); if(hdrs!=NULL) fclose(hdrs); errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); return(false); } /***********************/ /* Pack E-mail, if any */ /***********************/ qwkmail_last=0; mail=loadmail(&smb,&mailmsgs,0,MAIL_YOUR,0); packedmail=0; if(mailmsgs) { eprintf(LOG_INFO,"Packing NetMail for %s", cfg.qhub[hubnum]->id); for(u=0;u<mailmsgs;u++) { // bprintf("\b\b\b\b\b%-5lu",u+1); memset(&msg,0,sizeof(msg)); msg.idx=mail[u]; if(msg.idx.number>qwkmail_last) qwkmail_last=msg.idx.number; if(!loadmsg(&msg,mail[u].number)) continue; SAFEPRINTF(str,"%s/",cfg.qhub[hubnum]->id); if(msg.to_net.type!=NET_QWK || (strcmp((char *)msg.to_net.addr,cfg.qhub[hubnum]->id) && strncmp((char *)msg.to_net.addr,str,strlen(str)))) { smb_unlockmsghdr(&smb,&msg); smb_freemsgmem(&msg); continue; } msgtoqwk(&msg,rep,QM_TO_QNET|QM_REP|A_LEAVE,INVALID_SUB,0,hdrs); packedmail++; smb_unlockmsghdr(&smb,&msg); smb_freemsgmem(&msg); YIELD(); /* yield */ } eprintf(LOG_INFO,"Packed %d NetMail messages",packedmail); } smb_close(&smb); /* Close the e-mail */ if(mailmsgs) free(mail); for(i=0;i<cfg.qhub[hubnum]->subs;i++) { j=cfg.qhub[hubnum]->sub[i]; /* j now equals the real sub num */ msgs=getlastmsg(j,&last,0); lncntr=0; /* defeat pause */ if(!msgs || last<=subscan[j].ptr) { if(subscan[j].ptr>last) { subscan[j].ptr=last; subscan[j].last=last; } eprintf(LOG_INFO,remove_ctrl_a(text[NScanStatusFmt],tmp) ,cfg.grp[cfg.sub[j]->grp]->sname ,cfg.sub[j]->lname,0L,msgs); continue; } SAFEPRINTF2(smb.file,"%s%s" ,cfg.sub[j]->data_dir,cfg.sub[j]->code); smb.retry_time=cfg.smb_retry_time; smb.subnum=j; if((k=smb_open(&smb))!=0) { errormsg(WHERE,ERR_OPEN,smb.file,k,smb.last_error); continue; } post=loadposts(&posts,j,subscan[j].ptr,LP_BYSELF|LP_OTHERS|LP_PRIVATE|LP_REP,NULL); eprintf(LOG_INFO,remove_ctrl_a(text[NScanStatusFmt],tmp) ,cfg.grp[cfg.sub[j]->grp]->sname ,cfg.sub[j]->lname,posts,msgs); if(!posts) { /* no new messages */ smb_close(&smb); continue; } subscan[j].ptr=last; /* set pointer */ eprintf(LOG_INFO,"%s",remove_ctrl_a(text[QWKPackingSubboard],tmp)); /* ptr to last msg */ submsgs=0; for(u=0;u<posts;u++) { // bprintf("\b\b\b\b\b%-5lu",u+1); memset(&msg,0,sizeof(msg)); msg.idx=post[u]; if(!loadmsg(&msg,post[u].number)) continue; if(msg.from_net.type && msg.from_net.type!=NET_QWK && !(cfg.sub[j]->misc&SUB_GATE)) { smb_freemsgmem(&msg); smb_unlockmsghdr(&smb,&msg); continue; } if(!strnicmp(msg.subj,"NE:",3) || (msg.from_net.type==NET_QWK && route_circ((char *)msg.from_net.addr,cfg.qhub[hubnum]->id))) { smb_freemsgmem(&msg); smb_unlockmsghdr(&smb,&msg); continue; } mode=cfg.qhub[hubnum]->mode[i]|QM_TO_QNET|QM_REP; if(mode&A_LEAVE) mode|=(QM_VIA|QM_TZ|QM_MSGID); if(msg.from_net.type!=NET_QWK) mode|=QM_TAGLINE; msgtoqwk(&msg,rep,mode,j,cfg.qhub[hubnum]->conf[i],hdrs); smb_freemsgmem(&msg); smb_unlockmsghdr(&smb,&msg); msgcnt++; submsgs++; if(!(u%50)) YIELD(); /* yield */ } eprintf(LOG_INFO,remove_ctrl_a(text[QWKPackedSubboard],tmp),submsgs,msgcnt); free(post); smb_close(&smb); YIELD(); /* yield */ } if(hdrs!=NULL) fclose(hdrs); fclose(rep); /* close HUB_ID.MSG */ CRLF; /* Look for extra files to send out */ SAFEPRINTF2(str,"%sqnet/%s.out",cfg.data_dir,hubid_lower); dir=opendir(str); while(dir!=NULL && (dirent=readdir(dir))!=NULL) { SAFEPRINTF3(str,"%sqnet/%s.out/%s",cfg.data_dir,hubid_lower,dirent->d_name); if(isdir(str)) continue; SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,dirent->d_name); eprintf(LOG_INFO,remove_ctrl_a(text[RetrievingFile],tmp),str); if(!mv(str,tmp2,/* copy: */TRUE)) netfiles++; } if(dir!=NULL) closedir(dir); if(netfiles) CRLF; if(!msgcnt && !netfiles && !packedmail) { eprintf(LOG_INFO,remove_ctrl_a(text[QWKNoNewMessages],tmp)); return(true); // Changed from false Mar-11-2005 (needs to be true to save updated ptrs) } /*******************/ /* Compress Packet */ /*******************/ SAFEPRINTF2(str,"%s%s.REP",cfg.data_dir,hubid_upper); SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,ALLFILES); i=external(cmdstr(cfg.qhub[hubnum]->pack,str,tmp2,NULL) ,EX_OFFLINE|EX_WILDCARD); if(!fexistcase(str)) { eprintf(LOG_WARNING,"%s",remove_ctrl_a(text[QWKCompressionFailed],tmp)); if(i) errormsg(WHERE,ERR_EXEC,cmdstr(cfg.qhub[hubnum]->pack,str,tmp2,NULL),i); else lprintf(LOG_ERR, "Couldn't compress REP packet"); return(false); } SAFEPRINTF2(str,"%sqnet/%s.out/",cfg.data_dir,hubid_lower); delfiles(str,ALLFILES); if(packedmail) { /* Delete NetMail */ SAFEPRINTF(smb.file,"%smail",cfg.data_dir); smb.retry_time=cfg.smb_retry_time; smb.subnum=INVALID_SUB; if((i=smb_open(&smb))!=0) { errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); return(true); } mail=loadmail(&smb,&mailmsgs,0,MAIL_YOUR,0); if((i=smb_locksmbhdr(&smb))!=0) { /* Lock the base, so nobody */ if(mailmsgs) free(mail); smb_close(&smb); errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error); /* messes with the index */ return(true); } if((i=smb_getstatus(&smb))!=0) { if(mailmsgs) free(mail); smb_close(&smb); errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error); return(true); } deleted=0; /* Mark as READ and DELETE */ for(u=0;u<mailmsgs;u++) { if(mail[u].number>qwkmail_last) continue; memset(&msg,0,sizeof(msg)); /* !IMPORTANT: search by number (do not initialize msg.idx.offset) */ if(!loadmsg(&msg,mail[u].number)) continue; SAFEPRINTF(str,"%s/",cfg.qhub[hubnum]->id); if(msg.to_net.type!=NET_QWK || (strcmp((char *)msg.to_net.addr,cfg.qhub[hubnum]->id) && strncmp((char *)msg.to_net.addr,str,strlen(str)))) { smb_unlockmsghdr(&smb,&msg); smb_freemsgmem(&msg); continue; } msg.hdr.attr|=MSG_DELETE; msg.idx.attr=msg.hdr.attr; if((i=smb_putmsg(&smb,&msg))!=0) errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); else deleted++; smb_unlockmsghdr(&smb,&msg); smb_freemsgmem(&msg); } if(deleted && cfg.sys_misc&SM_DELEMAIL) delmail(0,MAIL_YOUR); smb_close(&smb); if(mailmsgs) free(mail); eprintf(LOG_INFO,"Deleted %d sent NetMail messages",deleted); } return(true); }
ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, uint subnum , int conf, FILE* hdrs) { char str[512],from[512],to[512],ch=0,tear=0,tearwatch=0,*buf,*p; char asc; char msgid[256]; char tmp[512]; long l,size=0,offset; int i; ushort hfield_type; struct tm tm; smbmsg_t remsg; time_t tt; offset=(long)ftell(qwk_fp); if(hdrs!=NULL) { fprintf(hdrs,"[%lx]\n",offset); /* Message-IDs */ fprintf(hdrs,"Message-ID: %s\n",get_msgid(&cfg,subnum,msg,msgid,sizeof(msgid))); if(msg->reply_id!=NULL) fprintf(hdrs,"In-Reply-To: %s\n",msg->reply_id); /* Time/Date/Zone info */ fprintf(hdrs,"WhenWritten: %-20s %04hx\n" ,xpDateTime_to_isoDateTimeStr( time_to_xpDateTime(msg->hdr.when_written.time,smb_tzutc(msg->hdr.when_written.zone)) ,/* separators: */"","","", /* precision: */0 ,str,sizeof(str)) ,msg->hdr.when_written.zone ); fprintf(hdrs,"WhenImported: %-20s %04hx\n" ,xpDateTime_to_isoDateTimeStr( time_to_xpDateTime(msg->hdr.when_imported.time,smb_tzutc(msg->hdr.when_imported.zone)) ,/* separators: */"","","", /* precision: */0 ,str,sizeof(str)) ,msg->hdr.when_imported.zone ); fprintf(hdrs,"WhenExported: %-20s %04hx\n" ,xpDateTime_to_isoDateTimeStr( xpDateTime_now() ,/* separators: */"","","", /* precision: */0 ,str,sizeof(str)) ,sys_timezone(&cfg) ); fprintf(hdrs,"ExportedFrom: %s %s %"PRIu32"\n" ,cfg.sys_id ,subnum==INVALID_SUB ? "mail":cfg.sub[subnum]->code ,msg->hdr.number ); /* SENDER */ fprintf(hdrs,"%s: %s\n",smb_hfieldtype(SENDER),msg->from); if(msg->from_net.type) fprintf(hdrs,"%s: %s\n",smb_hfieldtype(SENDERNETADDR),smb_netaddrstr(&msg->from_net,tmp)); if((p=(char*)smb_get_hfield(msg,hfield_type=SENDERIPADDR,NULL))!=NULL) fprintf(hdrs,"%s: %s\n",smb_hfieldtype(hfield_type),p); if((p=(char*)smb_get_hfield(msg,hfield_type=SENDERHOSTNAME,NULL))!=NULL) fprintf(hdrs,"%s: %s\n",smb_hfieldtype(hfield_type),p); if((p=(char*)smb_get_hfield(msg,hfield_type=SENDERPROTOCOL,NULL))!=NULL) fprintf(hdrs,"%s: %s\n",smb_hfieldtype(hfield_type),p); if(msg->from_org!=NULL) fprintf(hdrs,"Organization: %s\n",msg->from_org); else if(msg->from_net.type==NET_NONE) fprintf(hdrs,"Organization: %s\n",cfg.sys_name); /* Reply-To */ if((p=(char*)smb_get_hfield(msg,RFC822REPLYTO,NULL))==NULL) { if(msg->replyto_net.type==NET_INTERNET) p=(char*)msg->replyto_net.addr; else if(msg->replyto!=NULL) p=msg->replyto; } if(p!=NULL) fprintf(hdrs,"Reply-To: %s\n",p); /* use original RFC822 header field */ /* SUBJECT */ fprintf(hdrs,"%s: %s\n",smb_hfieldtype(SUBJECT),msg->subj); /* RECIPIENT */ fprintf(hdrs,"%s: %s\n",smb_hfieldtype(RECIPIENT),msg->to); if(msg->to_net.type) fprintf(hdrs,"%s: %s\n",smb_hfieldtype(RECIPIENTNETADDR),smb_netaddrstr(&msg->to_net,tmp)); /* FidoNet */ if((p=(char*)smb_get_hfield(msg,hfield_type=FIDOAREA,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); if((p=(char*)smb_get_hfield(msg,hfield_type=FIDOSEENBY,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); if((p=(char*)smb_get_hfield(msg,hfield_type=FIDOPATH,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); if((p=(char*)smb_get_hfield(msg,hfield_type=FIDOMSGID,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); if((p=(char*)smb_get_hfield(msg,hfield_type=FIDOREPLYID,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); if((p=(char*)smb_get_hfield(msg,hfield_type=FIDOPID,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); if((p=(char*)smb_get_hfield(msg,hfield_type=FIDOFLAGS,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); if((p=(char*)smb_get_hfield(msg,hfield_type=FIDOTID,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); /* Synchronet */ if((p=(char*)smb_get_hfield(msg,hfield_type=SMB_EDITOR,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); /* USENET */ if((p=(char*)smb_get_hfield(msg,hfield_type=USENETPATH,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); if((p=(char*)smb_get_hfield(msg,hfield_type=USENETNEWSGROUPS,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); /* RFC822 header fields: */ for(i=0;i<msg->total_hfields;i++) if(msg->hfield[i].type==RFC822HEADER) fprintf(hdrs,"%s\n",truncsp_lines((char*)msg->hfield_dat[i])); /* Blank line: */ fprintf(hdrs,"\n"); } fprintf(qwk_fp,"%*s",QWK_BLOCK_LEN,""); /* Init header to space */ /* QWKE compatible kludges */ SAFECOPY(from,msg->from); if(msg->from_net.addr && (uint)subnum==INVALID_SUB && !(mode&QM_TO_QNET)) { if(msg->from_net.type==NET_FIDO) sprintf(from,"%.128s@%.128s" ,msg->from,smb_faddrtoa((faddr_t *)msg->from_net.addr,tmp)); else if(msg->from_net.type==NET_INTERNET || strchr((char*)msg->from_net.addr,'@')!=NULL) sprintf(from,"%.128s",(char*)msg->from_net.addr); else sprintf(from,"%.128s@%.128s",msg->from,(char*)msg->from_net.addr); } if(msg->hdr.attr&MSG_ANONYMOUS && !SYSOP) SAFECOPY(from,text[Anonymous]); else if((subnum==INVALID_SUB || (useron.qwk&QWK_EXT)) && strlen(from) > QWK_HFIELD_LEN) { size+=fprintf(qwk_fp,"From: %.128s%c", from, QWK_NEWLINE); SAFECOPY(from,msg->from); } SAFECOPY(to,msg->to); if(msg->to_net.addr && (uint)subnum==INVALID_SUB) { if(msg->to_net.type==NET_FIDO) sprintf(to,"%.128s@%s",msg->to,smb_faddrtoa((faddr_t *)msg->to_net.addr,tmp)); else if(msg->to_net.type==NET_INTERNET) sprintf(to,"%.128s",(char*)msg->to_net.addr); else if(msg->to_net.type==NET_QWK) { if(mode&QM_TO_QNET) { p=strchr((char *)msg->to_net.addr,'/'); if(p) { /* Another hop */ p++; SAFECOPY(to,"NETMAIL"); size+=fprintf(qwk_fp,"%.128s@%.128s%c",msg->to,p,QWK_NEWLINE); } else sprintf(to,"%.128s",msg->to); } else sprintf(to,"%.128s@%.128s",msg->to,(char*)msg->to_net.addr); } else sprintf(to,"%.128s@%.128s",msg->to,(char*)msg->to_net.addr); } if((subnum==INVALID_SUB || (useron.qwk&QWK_EXT)) && strlen(to) > QWK_HFIELD_LEN) { size+=fprintf(qwk_fp,"To: %.128s%c", to, QWK_NEWLINE); if(msg->to_net.type==NET_QWK) SAFECOPY(to,"NETMAIL"); else SAFECOPY(to,msg->to); } if((useron.qwk&QWK_EXT) && strlen(msg->subj) > QWK_HFIELD_LEN) size+=fprintf(qwk_fp,"Subject: %.128s%c", msg->subj, QWK_NEWLINE); if(msg->from_net.type==NET_QWK && mode&QM_VIA && !msg->forwarded) size+=fprintf(qwk_fp,"@VIA: %s%c" ,(char*)msg->from_net.addr,QWK_NEWLINE); if(mode&QM_MSGID && (uint)subnum!=INVALID_SUB) { size+=fprintf(qwk_fp,"@MSGID: %s%c" ,get_msgid(&cfg,subnum,msg,msgid,sizeof(msgid)),QWK_NEWLINE); if(msg->reply_id) { SAFECOPY(tmp,msg->reply_id); truncstr(tmp," "); size+=fprintf(qwk_fp,"@REPLY: %s%c" ,tmp,QWK_NEWLINE); } else if(msg->hdr.thread_back) { memset(&remsg,0,sizeof(remsg)); remsg.hdr.number=msg->hdr.thread_back; if(smb_getmsgidx(&smb, &remsg)) size+=fprintf(qwk_fp,"@REPLY: <%s>%c",smb.last_error,QWK_NEWLINE); else size+=fprintf(qwk_fp,"@REPLY: %s%c" ,get_msgid(&cfg,subnum,&remsg,msgid,sizeof(msgid)) ,QWK_NEWLINE); } } if(msg->hdr.when_written.zone && mode&QM_TZ) size+=fprintf(qwk_fp,"@TZ: %04hx%c",msg->hdr.when_written.zone,QWK_NEWLINE); if(msg->replyto!=NULL && mode&QM_REPLYTO) size+=fprintf(qwk_fp,"@REPLYTO: %s%c" ,msg->replyto,QWK_NEWLINE); p=0; for(i=0;i<msg->total_hfields;i++) { if(msg->hfield[i].type==SENDER) p=(char *)msg->hfield_dat[i]; if(msg->hfield[i].type==FORWARDED && p) { size+=fprintf(qwk_fp,"Forwarded from %s on %s%c",p ,timestr(*(time32_t *)msg->hfield_dat[i]) ,QWK_NEWLINE); } } buf=smb_getmsgtxt(&smb,msg,GETMSGTXT_ALL); if(!buf) return(0); for(l=0;buf[l];l++) { ch=buf[l]; if(ch=='\n') { if(tear) tear++; /* Count LFs after tearline */ if(tear>3) /* more than two LFs after the tear */ tear=0; if(tearwatch==4) { /* watch for LF---LF */ tear=1; tearwatch=0; } else if(!tearwatch) tearwatch=1; else tearwatch=0; if(l && buf[l-1]=='\r') /* Replace CRLF with funky char */ ch=QWK_NEWLINE; /* but leave sole LF (soft-NL) alone */ fputc(ch,qwk_fp); size++; continue; } if(ch=='\r') { /* Ignore CRs */ if(tearwatch<4) /* LF---CRLF is okay */ tearwatch=0; /* LF-CR- is not okay */ continue; } if(ch==' ' && tearwatch==4) { /* watch for "LF--- " */ tear=1; tearwatch=0; } if(ch=='-') { /* watch for "LF---" */ if(l==0 || (tearwatch && tearwatch<4)) tearwatch++; else tearwatch=0; } else tearwatch=0; if((uint)subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_ASCII) { if(ch<' ' && ch!=1) ch='.'; else if((uchar)ch>0x7f) ch=exascii_to_ascii_char(ch); } if(ch==QWK_NEWLINE) /* funky char */ ch='*'; if(ch==CTRL_A) { ch=buf[++l]; if(ch==0 || toupper(ch)=='Z') /* EOF */ break; if((asc=ctrl_a_to_ascii_char(ch)) != 0) { fputc(asc,qwk_fp); size++; continue; } if(mode&A_EXPAND) { str[0]=0; switch(toupper(ch)) { case 'W': SAFECOPY(str,ansi(LIGHTGRAY)); break; case 'K': SAFECOPY(str,ansi(BLACK)); break; case 'H': SAFECOPY(str,ansi(HIGH)); break; case 'I': SAFECOPY(str,ansi(BLINK)); break; case '-': case '_': case 'N': /* Normal */ SAFECOPY(str,ansi(ANSI_NORMAL)); break; case 'R': SAFECOPY(str,ansi(RED)); break; case 'G': SAFECOPY(str,ansi(GREEN)); break; case 'B': SAFECOPY(str,ansi(BLUE)); break; case 'C': SAFECOPY(str,ansi(CYAN)); break; case 'M': SAFECOPY(str,ansi(MAGENTA)); break; case 'Y': /* Yellow */ SAFECOPY(str,ansi(BROWN)); break; case '0': SAFECOPY(str,ansi(BG_BLACK)); break; case '1': SAFECOPY(str,ansi(BG_RED)); break; case '2': SAFECOPY(str,ansi(BG_GREEN)); break; case '3': SAFECOPY(str,ansi(BG_BROWN)); break; case '4': SAFECOPY(str,ansi(BG_BLUE)); break; case '5': SAFECOPY(str,ansi(BG_MAGENTA)); break; case '6': SAFECOPY(str,ansi(BG_CYAN)); break; case '7': SAFECOPY(str,ansi(BG_LIGHTGRAY)); break; } if(str[0]) size+=fwrite(str,sizeof(char),strlen(str),qwk_fp); continue; } /* End Expand */ if(mode&A_LEAVE && valid_ctrl_a_code(ch)) { fputc(CTRL_A,qwk_fp); fputc(ch,qwk_fp); size+=2L; } continue; } /* End of Ctrl-A shit */ fputc(ch,qwk_fp); size++; } free(buf); if(ch!=QWK_NEWLINE) { fputc(QWK_NEWLINE,qwk_fp); /* make sure it ends in CRLF */ size++; } if(mode&QM_TAGLINE && !(cfg.sub[subnum]->misc&SUB_NOTAG)) { if(!tear) /* no tear line */ SAFEPRINTF(str,"\1n---%c",QWK_NEWLINE); /* so add one */ else SAFECOPY(str,"\1n"); if(cfg.sub[subnum]->misc&SUB_ASCII) ch='*'; else ch='รพ'; safe_snprintf(tmp,sizeof(tmp)," %c \1g%.10s\1n %c %.127s%c" ,ch,VERSION_NOTICE,ch,cfg.sub[subnum]->tagline,QWK_NEWLINE); strcat(str,tmp); if(!(mode&A_LEAVE)) remove_ctrl_a(str,str); size+=fwrite(str,sizeof(char),strlen(str),qwk_fp); } while(size%QWK_BLOCK_LEN) { /* Pad with spaces */ size++; fputc(' ',qwk_fp); } tt=msg->hdr.when_written.time; if(localtime_r(&tt,&tm)==NULL) memset(&tm,0,sizeof(tm)); safe_snprintf(tmp,sizeof(tmp),"%02u-%02u-%02u%02u:%02u" ,tm.tm_mon+1,tm.tm_mday,TM_YEAR(tm.tm_year) ,tm.tm_hour,tm.tm_min); if(msg->hdr.attr&MSG_PRIVATE) { if(msg->hdr.attr&MSG_READ) ch='*'; /* private, read */ else ch='+'; /* private, unread */ } else { if(msg->hdr.attr&MSG_READ) ch='-'; /* public, read */ else ch=' '; /* public, unread */ } safe_snprintf(str,sizeof(str),"%c%-7lu%-13.13s%-25.25s" "%-25.25s%-25.25s%12s%-8lu%-6lu\xe1%c%c%c%c%c" ,ch /* message status flag */ ,mode&QM_REP ? (ulong)conf /* conference or */ : msg->hdr.number&MAX_MSGNUM /* message number */ ,tmp /* date and time */ ,to /* To: */ ,from /* From: */ ,msg->subj /* Subject */ ,nulstr /* Password */ ,msg->hdr.thread_back&MAX_MSGNUM /* Message Re: Number */ ,(size/QWK_BLOCK_LEN)+1 /* Number of blocks */ ,(char)conf&0xff /* Conference number lo byte */ ,(ushort)conf>>8 /* hi byte */ ,' ' /* not used */ ,' ' /* not used */ ,useron.rest&FLAG('Q') ? '*' : ' ' /* Net tag line */ ); fseek(qwk_fp,offset,SEEK_SET); fwrite(str,QWK_BLOCK_LEN,1,qwk_fp); fseek(qwk_fp,size,SEEK_CUR); return(size); }