diff --git a/src/sbbs3/msgtoqwk.cpp b/src/sbbs3/msgtoqwk.cpp index 7c7dcaddbe4b6931db895187cfb9bb6db388b1d5..81c58c9154789f79939e6c5d43c924e1614fe753 100644 --- a/src/sbbs3/msgtoqwk.cpp +++ b/src/sbbs3/msgtoqwk.cpp @@ -8,7 +8,7 @@ * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * * - * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html * + * Copyright 2008 Rob Swindell - http://www.synchro.net/copyright.html * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * @@ -45,17 +45,105 @@ /* mode determines how to handle Ctrl-A codes */ /****************************************************************************/ ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, int subnum - , int conf) + , int conf, FILE* hdrs) { char str[512],from[512],to[512],ch=0,tear=0,tearwatch=0,*buf,*p; char tmp[512]; long l,size=0,offset; int i; + ushort hfield_type; struct tm tm; smbmsg_t remsg; time_t tt; offset=ftell(qwk_fp); + if(hdrs!=NULL) { + fprintf(hdrs,"[%x]\n",offset); + + /* Message-IDs */ + fprintf(hdrs,"Message-ID: %s\n",get_msgid(&cfg,subnum,msg)); + 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 + ); + + /* 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); + + /* 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); + + /* 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",msg->hfield_dat[i]); + + /* Blank line: */ + fprintf(hdrs,"\n"); + } memset(str,' ',QWK_BLOCK_LEN); fwrite(str,QWK_BLOCK_LEN,1,qwk_fp); /* Init header to space */ @@ -70,14 +158,15 @@ ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, int subnum else sprintf(from,"%.128s@%.128s",msg->from,(char*)msg->from_net.addr); if(strlen(from)>25) { - sprintf(str,"From: %.128s%c%c",from,QWK_NEWLINE,QWK_NEWLINE); - fwrite(str,strlen(str),1,qwk_fp); - size+=strlen(str); - sprintf(from,"%.128s",msg->from); } } + size+=fprintf(qwk_fp,"From: %.128s%c%c",from,QWK_NEWLINE,QWK_NEWLINE); + sprintf(from,"%.128s",msg->from); + } + } else { sprintf(from,"%.128s",msg->from); if(msg->hdr.attr&MSG_ANONYMOUS && !SYSOP) /* from user */ - strcpy(from,text[Anonymous]); } + SAFECOPY(from,text[Anonymous]); + } if(msg->to_net.addr && (uint)subnum==INVALID_SUB) { if(msg->to_net.type==NET_FIDO) @@ -89,10 +178,9 @@ ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, int subnum p=strchr((char *)msg->to_net.addr,'/'); if(p) { /* Another hop */ p++; - strcpy(to,"NETMAIL"); - sprintf(str,"%.128s@%.128s%c",msg->to,p,QWK_NEWLINE); - fwrite(str,strlen(str),1,qwk_fp); - size+=strlen(str); } + SAFECOPY(to,"NETMAIL"); + size+=fprintf(qwk_fp,"%.128s@%.128s%c",msg->to,p,QWK_NEWLINE); + } else sprintf(to,"%.128s",msg->to); } else @@ -100,73 +188,56 @@ ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, int subnum else sprintf(to,"%.128s@%.128s",msg->to,(char*)msg->to_net.addr); if(strlen(to)>25) { - sprintf(str,"To: %.128s%c%c",to,QWK_NEWLINE,QWK_NEWLINE); - fwrite(str,strlen(str),1,qwk_fp); - size+=strlen(str); + size+=fprintf(qwk_fp,"To: %.128s%c%c",to,QWK_NEWLINE,QWK_NEWLINE); if(msg->to_net.type==NET_QWK) - strcpy(to,"NETMAIL"); + SAFECOPY(to,"NETMAIL"); else - sprintf(to,"%.128s",msg->to); } } + sprintf(to,"%.128s",msg->to); + } + } else sprintf(to,"%.128s",msg->to); - if(msg->from_net.type==NET_QWK && mode&QM_VIA && !msg->forwarded) { - sprintf(str,"@VIA: %.*s%c" - ,(int)(sizeof(str)-12),(char*)msg->from_net.addr,QWK_NEWLINE); - fwrite(str,strlen(str),1,qwk_fp); - size+=strlen(str); } + 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) { - sprintf(str,"@MSGID: %.*s%c" - ,(int)(sizeof(str)-12),get_msgid(&cfg,subnum,msg),QWK_NEWLINE); - fwrite(str,strlen(str),1,qwk_fp); - size+=strlen(str); + size+=fprintf(qwk_fp,"@MSGID: %s%c" + ,get_msgid(&cfg,subnum,msg),QWK_NEWLINE); - str[0]=0; if(msg->reply_id) { SAFECOPY(tmp,msg->reply_id); truncstr(tmp," "); - sprintf(str,"@REPLY: %.*s%c" - ,(int)(sizeof(str)-12),tmp,QWK_NEWLINE); + 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)) - sprintf(str,"@REPLY: <%s>%c",smb.last_error,QWK_NEWLINE); + size+=fprintf(qwk_fp,"@REPLY: <%s>%c",smb.last_error,QWK_NEWLINE); else - sprintf(str,"@REPLY: %s%c" + size+=fprintf(qwk_fp,"@REPLY: %s%c" ,get_msgid(&cfg,subnum,&remsg) ,QWK_NEWLINE); } - if(str[0]) { - fwrite(str,strlen(str),1,qwk_fp); - size+=strlen(str); - } } - if(msg->hdr.when_written.zone && mode&QM_TZ) { - sprintf(str,"@TZ: %04x%c",msg->hdr.when_written.zone,QWK_NEWLINE); - fwrite(str,strlen(str),1,qwk_fp); - size+=strlen(str); - } + if(msg->hdr.when_written.zone && mode&QM_TZ) + size+=fprintf(qwk_fp,"@TZ: %04x%c",msg->hdr.when_written.zone,QWK_NEWLINE); - if(msg->replyto!=NULL && mode&QM_REPLYTO) { - sprintf(str,"@REPLYTO: %.*s%c" - ,(int)(sizeof(str)-12),msg->replyto,QWK_NEWLINE); - fwrite(str,strlen(str),1,qwk_fp); - size+=strlen(str); - } + 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) { - sprintf(str,"Forwarded from %s on %s%c",p + size+=fprintf(qwk_fp,"Forwarded from %s on %s%c",p ,timestr(*(time32_t *)msg->hfield_dat[i]) ,QWK_NEWLINE); - fwrite(str,strlen(str),1,qwk_fp); - size+=strlen(str); } } @@ -228,70 +299,68 @@ ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, int subnum str[0]=0; switch(toupper(ch)) { /* non-color codes */ case 'L': - strcpy(str,"\x1b[2J\x1b[H"); + SAFECOPY(str,"\x1b[2J\x1b[H"); break; case 'W': - strcpy(str,ansi(LIGHTGRAY)); + SAFECOPY(str,ansi(LIGHTGRAY)); break; case 'K': - strcpy(str,ansi(BLACK)); + SAFECOPY(str,ansi(BLACK)); break; case 'H': - strcpy(str,ansi(HIGH)); + SAFECOPY(str,ansi(HIGH)); break; case 'I': - strcpy(str,ansi(BLINK)); + SAFECOPY(str,ansi(BLINK)); break; case 'N': /* Normal */ - strcpy(str,ansi(ANSI_NORMAL)); + SAFECOPY(str,ansi(ANSI_NORMAL)); break; case 'R': /* Color codes */ - strcpy(str,ansi(RED)); + SAFECOPY(str,ansi(RED)); break; case 'G': - strcpy(str,ansi(GREEN)); + SAFECOPY(str,ansi(GREEN)); break; case 'B': - strcpy(str,ansi(BLUE)); + SAFECOPY(str,ansi(BLUE)); break; case 'C': - strcpy(str,ansi(CYAN)); + SAFECOPY(str,ansi(CYAN)); break; case 'M': - strcpy(str,ansi(MAGENTA)); + SAFECOPY(str,ansi(MAGENTA)); break; case 'Y': /* Yellow */ - strcpy(str,ansi(BROWN)); + SAFECOPY(str,ansi(BROWN)); break; case '0': - strcpy(str,ansi(BG_BLACK)); + SAFECOPY(str,ansi(BG_BLACK)); break; case '1': - strcpy(str,ansi(BG_RED)); + SAFECOPY(str,ansi(BG_RED)); break; case '2': - strcpy(str,ansi(BG_GREEN)); + SAFECOPY(str,ansi(BG_GREEN)); break; case '3': - strcpy(str,ansi(BG_BROWN)); + SAFECOPY(str,ansi(BG_BROWN)); break; case '4': - strcpy(str,ansi(BG_BLUE)); + SAFECOPY(str,ansi(BG_BLUE)); break; case '5': - strcpy(str,ansi(BG_MAGENTA)); + SAFECOPY(str,ansi(BG_MAGENTA)); break; case '6': - strcpy(str,ansi(BG_CYAN)); + SAFECOPY(str,ansi(BG_CYAN)); break; case '7': - strcpy(str,ansi(BG_LIGHTGRAY)); + SAFECOPY(str,ansi(BG_LIGHTGRAY)); break; } - if(str[0]) { - fwrite(str,strlen(str),1,qwk_fp); - size+=strlen(str); - } + if(str[0]) + size+=fwrite(str,sizeof(char),strlen(str),qwk_fp); continue; } /* End Expand */ @@ -314,18 +383,18 @@ ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, int subnum if(mode&QM_TAGLINE && !(cfg.sub[subnum]->misc&SUB_NOTAG)) { if(!tear) /* no tear line */ - sprintf(str,"\1n---%c",QWK_NEWLINE); /* so add one */ + SAFEPRINTF(str,"\1n---%c",QWK_NEWLINE); /* so add one */ else - strcpy(str,"\1n"); + SAFECOPY(str,"\1n"); if(cfg.sub[subnum]->misc&SUB_ASCII) ch='*'; else ch='�'; - sprintf(tmp," %c \1g%.10s\1n %c %.127s%c" + 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,NULL); - fwrite(str,strlen(str),1,qwk_fp); - size+=strlen(str); } + size+=fwrite(str,sizeof(char),strlen(str),qwk_fp); + } while(size%QWK_BLOCK_LEN) { /* Pad with spaces */ size++; @@ -335,7 +404,7 @@ ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, int subnum if(localtime_r(&tt,&tm)==NULL) memset(&tm,0,sizeof(tm)); - sprintf(tmp,"%02u-%02u-%02u%02u:%02u" + 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); @@ -351,7 +420,7 @@ ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, int subnum ch=' '; /* public, unread */ } - sprintf(str,"%c%-7lu%-13.13s%-25.25s" + 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 */ diff --git a/src/sbbs3/pack_qwk.cpp b/src/sbbs3/pack_qwk.cpp index f3105b5b35c41455e104689afcb03af80747ca58..92269a09c27906612f053524a6e5180d6077d7fe 100644 --- a/src/sbbs3/pack_qwk.cpp +++ b/src/sbbs3/pack_qwk.cpp @@ -8,7 +8,7 @@ * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * * - * Copyright 2007 Rob Swindell - http://www.synchro.net/copyright.html * + * Copyright 2008 Rob Swindell - http://www.synchro.net/copyright.html * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * @@ -63,6 +63,7 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) post_t *post; glob_t g; FILE *stream,*qwk,*personal,*ndx; + FILE* hdrs=NULL; DIR* dir; DIRENT* dirent; struct tm tm; @@ -73,7 +74,7 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) ex|=EX_OFFLINE; delfiles(cfg.temp_dir,ALLFILES); - sprintf(str,"%sfile/%04u.qwk",cfg.data_dir,useron.number); + SAFEPRINTF2(str,"%sfile/%04u.qwk",cfg.data_dir,useron.number); if(fexistcase(str)) { for(k=0;k<cfg.total_fextrs;k++) if(!stricmp(cfg.fextr[k]->ext,useron.tmpext) @@ -108,7 +109,7 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) /***************************/ /* Create CONTROL.DAT file */ /***************************/ - sprintf(str,"%sCONTROL.DAT",cfg.temp_dir); + SAFEPRINTF(str,"%sCONTROL.DAT",cfg.temp_dir); if((stream=fopen(str,"wb"))==NULL) { errormsg(WHERE,ERR_OPEN,str,0); return(false); @@ -137,11 +138,11 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) for(i=0;i<usrgrps;i++) for(j=0;j<usrsubs[i];j++) { if(useron.qwk&QWK_EXT) /* 255 char max */ - sprintf(confname,"%s %s" + SAFEPRINTF2(confname,"%s %s" ,cfg.grp[cfg.sub[usrsub[i][j]]->grp]->sname ,cfg.sub[usrsub[i][j]]->lname); else /* 10 char max */ - strcpy(confname,cfg.sub[usrsub[i][j]]->qwkname); + SAFECOPY(confname,cfg.sub[usrsub[i][j]]->qwkname); fprintf(stream,"%u\r\n%s\r\n" ,cfg.sub[usrsub[i][j]]->qwkconf ? cfg.sub[usrsub[i][j]]->qwkconf : ((i+1)*1000)+j+1,confname); @@ -151,7 +152,7 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) /***********************/ /* Create DOOR.ID File */ /***********************/ - sprintf(str,"%sDOOR.ID",cfg.temp_dir); + SAFEPRINTF(str,"%sDOOR.ID",cfg.temp_dir); if((stream=fopen(str,"wb"))==NULL) { errormsg(WHERE,ERR_OPEN,str,0); return(false); @@ -190,7 +191,7 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) /***********************/ /* Create NETFLAGS.DAT */ /***********************/ - sprintf(str,"%sNETFLAGS.DAT",cfg.temp_dir); + SAFEPRINTF(str,"%sNETFLAGS.DAT",cfg.temp_dir); if((stream=fopen(str,"wb"))==NULL) { errormsg(WHERE,ERR_CREATE,str,0); return(false); @@ -206,7 +207,7 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) /****************************************************/ /* Create MESSAGES.DAT, write header and leave open */ /****************************************************/ - sprintf(str,"%sMESSAGES.DAT",cfg.temp_dir); + SAFEPRINTF(str,"%sMESSAGES.DAT",cfg.temp_dir); if(fexistcase(str)) fmode="r+b"; else @@ -215,6 +216,14 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) errormsg(WHERE,ERR_OPEN,str,0); return(false); } + if(useron.qwk&QWK_HEADERS) { + SAFEPRINTF(str,"%sHEADERS.DAT",cfg.temp_dir); + if((hdrs=fopen(str,"a"))==NULL) { + fclose(qwk); + errormsg(WHERE,ERR_OPEN,str,0); + return(false); + } + } l=filelength(fileno(qwk)); if(l<1) { fprintf(qwk,"%-128.128s","Produced by " VERSION_NOTICE " " COPYRIGHT_NOTICE); @@ -223,7 +232,7 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) msgndx=l/QWK_BLOCK_LEN; fseek(qwk,0,SEEK_END); } - sprintf(str,"%sNEWFILES.DAT",cfg.temp_dir); + SAFEPRINTF(str,"%sNEWFILES.DAT",cfg.temp_dir); remove(str); if(!(useron.rest&FLAG('T')) && useron.qwk&QWK_FILES) files=create_filelist("NEWFILES.DAT",FL_ULTIME); @@ -236,9 +245,11 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) useron.qwk|=(QWK_EMAIL|QWK_ALLMAIL|QWK_DELMAIL); if(!(useron.qwk&QWK_NOINDEX)) { - sprintf(str,"%sPERSONAL.NDX",cfg.temp_dir); + SAFEPRINTF(str,"%sPERSONAL.NDX",cfg.temp_dir); if((personal=fopen(str,"ab"))==NULL) { fclose(qwk); + if(hdrs!=NULL) + fclose(hdrs); errormsg(WHERE,ERR_OPEN,str,0); return(false); } @@ -247,11 +258,13 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) personal=NULL; if(useron.qwk&(QWK_EMAIL|QWK_ALLMAIL) /* && !prepack */) { - sprintf(smb.file,"%smail",cfg.data_dir); + 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(qwk); + if(hdrs!=NULL) + fclose(hdrs); if(personal) fclose(personal); errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); @@ -267,9 +280,11 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) if(mailmsgs && !(sys_status&SS_ABORT)) { bputs(text[QWKPackingEmail]); if(!(useron.qwk&QWK_NOINDEX)) { - sprintf(str,"%s000.NDX",cfg.temp_dir); + SAFEPRINTF(str,"%s000.NDX",cfg.temp_dir); if((ndx=fopen(str,"ab"))==NULL) { fclose(qwk); + if(hdrs!=NULL) + fclose(hdrs); if(personal) fclose(personal); smb_close(&smb); @@ -298,14 +313,14 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) continue; if(msg.hdr.auxattr&MSG_FILEATTACH && useron.qwk&QWK_ATTACH) { - sprintf(str,"%sfile/%04u.in/%s" + SAFEPRINTF3(str,"%sfile/%04u.in/%s" ,cfg.data_dir,useron.number,msg.subj); - sprintf(tmp,"%s%s",cfg.temp_dir,msg.subj); + SAFEPRINTF2(tmp,"%s%s",cfg.temp_dir,msg.subj); if(fexistcase(str) && !fexistcase(tmp)) mv(str,tmp,1); } - size=msgtoqwk(&msg,qwk,mode,INVALID_SUB,0); + size=msgtoqwk(&msg,qwk,mode,INVALID_SUB,0,hdrs); smb_unlockmsghdr(&smb,&msg); smb_freemsgmem(&msg); if(ndx) { @@ -359,7 +374,7 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) continue; } - sprintf(smb.file,"%s%s" + SAFEPRINTF2(smb.file,"%s%s" ,cfg.sub[usrsub[i][j]]->data_dir,cfg.sub[usrsub[i][j]]->code); smb.retry_time=cfg.smb_retry_time; smb.subnum=usrsub[i][j]; @@ -389,9 +404,11 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) conf=((i+1)*1000)+j+1; if(!(useron.qwk&QWK_NOINDEX)) { - sprintf(str,"%s%u.NDX",cfg.temp_dir,conf); + SAFEPRINTF2(str,"%s%u.NDX",cfg.temp_dir,conf); if((ndx=fopen(str,"ab"))==NULL) { fclose(qwk); + if(hdrs!=NULL) + fclose(hdrs); if(personal) fclose(personal); smb_close(&smb); @@ -435,7 +452,7 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) else mode&=~(QM_TAGLINE|QM_TO_QNET); - size=msgtoqwk(&msg,qwk,mode,usrsub[i][j],conf); + size=msgtoqwk(&msg,qwk,mode,usrsub[i][j],conf,hdrs); smb_unlockmsghdr(&smb,&msg); if(ndx) { @@ -468,7 +485,7 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) bprintf(text[QWKPackedSubboard],submsgs,(*msgcnt)); if(ndx) { fclose(ndx); - sprintf(str,"%s%u.NDX",cfg.temp_dir,conf); + SAFEPRINTF2(str,"%s%u.NDX",cfg.temp_dir,conf); if(!flength(str)) remove(str); } @@ -497,7 +514,7 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) ,ftell(qwk) ,time(NULL)-start ,((*msgcnt)+mailmsgs)/(time(NULL)-start)); - sprintf(str,"Packed %lu messages (%lu bytes) in %lu seconds (%lu msgs/sec)" + SAFEPRINTF4(str,"Packed %lu messages (%lu bytes) in %lu seconds (%lu msgs/sec)" ,(*msgcnt)+mailmsgs ,ftell(qwk) ,(ulong)(time(NULL)-start) @@ -509,9 +526,11 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) } fclose(qwk); /* close MESSAGE.DAT */ + if(hdrs!=NULL) + fclose(hdrs); /* close HEADERS.DAT */ if(personal) { fclose(personal); /* close PERSONAL.NDX */ - sprintf(str,"%sPERSONAL.NDX",cfg.temp_dir); + SAFEPRINTF(str,"%sPERSONAL.NDX",cfg.temp_dir); if(!flength(str)) remove(str); } @@ -521,13 +540,13 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) return(false); if(/*!prepack && */ useron.rest&FLAG('Q')) { /* If QWK Net node, check for files */ - sprintf(str,"%sqnet/%s.out/",cfg.data_dir,useron.alias); + SAFEPRINTF2(str,"%sqnet/%s.out/",cfg.data_dir,useron.alias); dir=opendir(str); while(dir!=NULL && (dirent=readdir(dir))!=NULL) { /* Move files into temp dir */ - sprintf(str,"%sqnet/%s.out/%s",cfg.data_dir,useron.alias,dirent->d_name); + SAFEPRINTF3(str,"%sqnet/%s.out/%s",cfg.data_dir,useron.alias,dirent->d_name); if(isdir(str)) continue; - sprintf(tmp2,"%s%s",cfg.temp_dir,dirent->d_name); + SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,dirent->d_name); lncntr=0; /* Default pause */ if(online==ON_LOCAL) eprintf(LOG_INFO,"Including %s in packet",str); @@ -562,11 +581,11 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) for(i=0;i<batdn_total;i++) { lncntr=0; unpadfname(batdn_name[i],tmp); - sprintf(tmp2,"%s%s",cfg.temp_dir,tmp); + SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,tmp); if(!fexistcase(tmp2)) { seqwait(cfg.dir[batdn_dir[i]]->seqdev); bprintf(text[RetrievingFile],tmp); - sprintf(str,"%s%s" + SAFEPRINTF2(str,"%s%s" ,batdn_alt[i]>0 && batdn_alt[i]<=cfg.altpaths ? cfg.altpath[batdn_alt[i]-1] : cfg.dir[batdn_dir[i]]->path @@ -592,29 +611,29 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) /***********************/ /* packets */ /* Copy QWK Text files */ /***********************/ - sprintf(str,"%sQWK/HELLO",cfg.text_dir); + SAFEPRINTF(str,"%sQWK/HELLO",cfg.text_dir); if(fexistcase(str)) { - sprintf(tmp2,"%sHELLO",cfg.temp_dir); + SAFEPRINTF(tmp2,"%sHELLO",cfg.temp_dir); mv(str,tmp2,1); } - sprintf(str,"%sQWK/BBSNEWS",cfg.text_dir); + SAFEPRINTF(str,"%sQWK/BBSNEWS",cfg.text_dir); if(fexistcase(str)) { - sprintf(tmp2,"%sBBSNEWS",cfg.temp_dir); + SAFEPRINTF(tmp2,"%sBBSNEWS",cfg.temp_dir); mv(str,tmp2,1); } - sprintf(str,"%sQWK/GOODBYE",cfg.text_dir); + SAFEPRINTF(str,"%sQWK/GOODBYE",cfg.text_dir); if(fexistcase(str)) { - sprintf(tmp2,"%sGOODBYE",cfg.temp_dir); + SAFEPRINTF(tmp2,"%sGOODBYE",cfg.temp_dir); mv(str,tmp2,1); } - sprintf(str,"%sQWK/BLT-*",cfg.text_dir); + SAFEPRINTF(str,"%sQWK/BLT-*",cfg.text_dir); glob(str,0,NULL,&g); for(i=0;i<(uint)g.gl_pathc;i++) { /* Copy BLT-*.* files */ fname=getfname(g.gl_pathv[i]); padfname(fname,str); if(isdigit(str[4]) && isdigit(str[9])) { - sprintf(str,"%sQWK/%s",cfg.text_dir,fname); - sprintf(tmp2,"%s%s",cfg.temp_dir,fname); + SAFEPRINTF2(str,"%sQWK/%s",cfg.text_dir,fname); + SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,fname); mv(str,tmp2,1); } } @@ -635,7 +654,7 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) /*******************/ /* Compress Packet */ /*******************/ - sprintf(tmp2,"%s%s",cfg.temp_dir,ALLFILES); + SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,ALLFILES); i=external(cmdstr(temp_cmd(),packet,tmp2,NULL) ,ex|EX_WILDCARD); if(!fexist(packet)) { @@ -651,8 +670,7 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) return(true); l=flength(packet); - sprintf(str,"%s.qwk",cfg.sys_id); - bprintf(text[FiFilename],str); + bprintf(text[FiFilename],getfname(packet)); bprintf(text[FiFileSize],ultoac(l,tmp)); if(l>0L && cur_cps) i=l/(ulong)cur_cps; @@ -666,12 +684,11 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack) } if(useron.rest&FLAG('Q')) { - sprintf(str,"%s.qwk",cfg.sys_id); dir=opendir(cfg.temp_dir); while(dir!=NULL && (dirent=readdir(dir))!=NULL) { - if(!stricmp(str,dirent->d_name)) /* QWK packet */ + if(!stricmp(getfname(packet),dirent->d_name)) /* QWK packet */ continue; - sprintf(tmp,"%s%s",cfg.temp_dir,dirent->d_name); + SAFEPRINTF2(tmp,"%s%s",cfg.temp_dir,dirent->d_name); if(!isdir(tmp)) remove(tmp); } diff --git a/src/sbbs3/pack_rep.cpp b/src/sbbs3/pack_rep.cpp index 5fa16ccfcd462e12d54e7048b055f0652d9ff490..2f8dd0aed3224298a2f3378d2e1021c9a5206525 100644 --- a/src/sbbs3/pack_rep.cpp +++ b/src/sbbs3/pack_rep.cpp @@ -8,7 +8,7 @@ * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * * - * Copyright 2005 Rob Swindell - http://www.synchro.net/copyright.html * + * Copyright 2008 Rob Swindell - http://www.synchro.net/copyright.html * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * @@ -44,26 +44,35 @@ /****************************************************************************/ bool sbbs_t::pack_rep(uint hubnum) { - char str[MAX_PATH+1]; - char tmp[MAX_PATH+1],tmp2[MAX_PATH+1]; - int file,mode; - uint i,j,k; - long l,msgcnt,submsgs,packedmail,netfiles=0,deleted; - int32_t posts; - int32_t mailmsgs; - ulong msgs; + 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 l,msgcnt,submsgs,packedmail,netfiles=0,deleted; + int32_t posts; + int32_t mailmsgs; + ulong msgs; uint32_t last; - post_t *post; - mail_t *mail; - FILE* rep; - DIR* dir; - DIRENT* dirent; - smbmsg_t msg; + 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); - sprintf(str,"%s%s.rep",cfg.data_dir,cfg.qhub[hubnum]->id); - if(fexist(str)) { + + 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 @@ -71,26 +80,39 @@ bool sbbs_t::pack_rep(uint hubnum) /*************************************************/ /* Create SYSID.MSG, write header and leave open */ /*************************************************/ - sprintf(str,"%s%s.msg",cfg.temp_dir,cfg.qhub[hubnum]->id); + 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); } + return(false); + } if(filelength(file)<1) { /* New REP packet */ - sprintf(str,"%-*s" - ,QWK_BLOCK_LEN,cfg.qhub[hubnum]->id); /* So write header */ + 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 */ /*********************/ - sprintf(smb.file,"%smail",cfg.data_dir); + 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); } + return(false); + } /***********************/ /* Pack E-mail, if any */ @@ -110,15 +132,16 @@ bool sbbs_t::pack_rep(uint hubnum) if(!loadmsg(&msg,mail[l].number)) continue; - sprintf(str,"%s/",cfg.qhub[hubnum]->id); + 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; } + continue; + } - msgtoqwk(&msg,rep,QM_TO_QNET|QM_REP|A_LEAVE,INVALID_SUB,0); + msgtoqwk(&msg,rep,QM_TO_QNET|QM_REP|A_LEAVE,INVALID_SUB,0,hdrs); packedmail++; smb_unlockmsghdr(&smb,&msg); smb_freemsgmem(&msg); @@ -137,19 +160,22 @@ bool sbbs_t::pack_rep(uint hubnum) if(!msgs || last<=subscan[j].ptr) { if(subscan[j].ptr>last) { subscan[j].ptr=last; - subscan[j].last=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; } + continue; + } - sprintf(smb.file,"%s%s" + 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; } + continue; + } post=loadposts(&posts,j,subscan[j].ptr,LP_BYSELF|LP_OTHERS|LP_PRIVATE|LP_REP); eprintf(LOG_INFO,remove_ctrl_a(text[NScanStatusFmt],tmp) @@ -157,7 +183,8 @@ bool sbbs_t::pack_rep(uint hubnum) ,cfg.sub[j]->lname,posts,msgs); if(!posts) { /* no new messages */ smb_close(&smb); - continue; } + continue; + } subscan[j].ptr=last; /* set pointer */ eprintf(LOG_INFO,"%s",remove_ctrl_a(text[QWKPackingSubboard],tmp)); /* ptr to last msg */ @@ -174,20 +201,22 @@ bool sbbs_t::pack_rep(uint hubnum) !(cfg.sub[j]->misc&SUB_GATE)) { smb_freemsgmem(&msg); smb_unlockmsghdr(&smb,&msg); - continue; } + 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; } + 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]); + msgtoqwk(&msg,rep,mode,j,cfg.qhub[hubnum]->conf[i],hdrs); smb_freemsgmem(&msg); smb_unlockmsghdr(&smb,&msg); @@ -202,18 +231,18 @@ bool sbbs_t::pack_rep(uint hubnum) YIELD(); /* yield */ } + if(hdrs!=NULL) + fclose(hdrs); fclose(rep); /* close HUB_ID.MSG */ CRLF; /* Look for extra files to send out */ - sprintf(str,"%sqnet/%s.out",cfg.data_dir,cfg.qhub[hubnum]->id); - strlwr(str); + SAFEPRINTF2(str,"%sqnet/%s.out",cfg.data_dir,hubid_lower); dir=opendir(str); while(dir!=NULL && (dirent=readdir(dir))!=NULL) { - sprintf(str,"%sqnet/%s.out/%s",cfg.data_dir,cfg.qhub[hubnum]->id,dirent->d_name); - strlwr(str); + SAFEPRINTF3(str,"%sqnet/%s.out/%s",cfg.data_dir,hubid_lower,dirent->d_name); if(isdir(str)) continue; - sprintf(tmp2,"%s%s",cfg.temp_dir,dirent->d_name); + SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,dirent->d_name); eprintf(LOG_INFO,remove_ctrl_a(text[RetrievingFile],tmp),str); if(!mv(str,tmp2,1)) netfiles++; @@ -231,28 +260,29 @@ bool sbbs_t::pack_rep(uint hubnum) /*******************/ /* Compress Packet */ /*******************/ - sprintf(str,"%s%s.rep",cfg.data_dir,cfg.qhub[hubnum]->id); - sprintf(tmp2,"%s%s",cfg.temp_dir,ALLFILES); + 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(!fexist(str)) { + 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 errorlog("Couldn't compress REP packet"); - return(false); } - sprintf(str,"%sqnet/%s.out/",cfg.data_dir,cfg.qhub[hubnum]->id); - strlwr(str); + return(false); + } + SAFEPRINTF2(str,"%sqnet/%s.out/",cfg.data_dir,hubid_lower); delfiles(str,ALLFILES); if(packedmail) { /* Delete NetMail */ - sprintf(smb.file,"%smail",cfg.data_dir); + 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); } + return(true); + } mail=loadmail(&smb,&mailmsgs,0,MAIL_YOUR,0); @@ -261,14 +291,16 @@ bool sbbs_t::pack_rep(uint hubnum) free(mail); smb_close(&smb); errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error); /* messes with the index */ - return(true); } + 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); } + return(true); + } deleted=0; /* Mark as READ and DELETE */ @@ -280,13 +312,14 @@ bool sbbs_t::pack_rep(uint hubnum) if(!loadmsg(&msg,mail[l].number)) continue; - sprintf(str,"%s/",cfg.qhub[hubnum]->id); + 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; } + continue; + } msg.hdr.attr|=MSG_DELETE; msg.idx.attr=msg.hdr.attr; diff --git a/src/sbbs3/qwk.cpp b/src/sbbs3/qwk.cpp index 341b8a4ba056a085843340dead4926d8b52bb6ad..d29de6d447f0e752bfd6c5d12686d30842d806be 100644 --- a/src/sbbs3/qwk.cpp +++ b/src/sbbs3/qwk.cpp @@ -8,7 +8,7 @@ * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * * - * Copyright 2005 Rob Swindell - http://www.synchro.net/copyright.html * + * Copyright 2008 Rob Swindell - http://www.synchro.net/copyright.html * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * @@ -475,6 +475,9 @@ void sbbs_t::qwk_sec() bprintf("\1hC\1n) %-30s: \1h%s\r\n" ,"Include Control Files" ,useron.qwk&QWK_NOCTRL ? text[No]:text[Yes]); + bprintf("\1hH\1n) %-30s: \1h%s\r\n" + ,"Include HEADERS.DAT" + ,useron.qwk&QWK_HEADERS ? text[Yes]:text[No]); bprintf("\1hY\1n) %-30s: \1h%s\r\n" ,"Include Messages from You" ,useron.qwk&QWK_BYSELF ? text[Yes]:text[No]); @@ -491,7 +494,7 @@ void sbbs_t::qwk_sec() ,"Extended (QWKE) Packet Format" ,useron.qwk&QWK_EXT ? text[Yes]:text[No]); bputs(text[UserDefaultsWhich]); - ch=(char)getkeys("AEDFIOQTYMNCXZV",0); + ch=(char)getkeys("AEDFHIOQTYMNCXZV",0); if(sys_status&SS_ABORT || !ch || ch=='Q' || !online) break; switch(ch) { @@ -521,6 +524,9 @@ void sbbs_t::qwk_sec() else useron.qwk&=~(QWK_EMAIL|QWK_ALLMAIL); break; + case 'H': + useron.qwk^=QWK_HEADERS; + break; case 'I': useron.qwk^=QWK_ATTACH; break; diff --git a/src/sbbs3/readmsgs.cpp b/src/sbbs3/readmsgs.cpp index 5a61d1ac84e31fc3cc5b9c769b3baa1134ec4b51..e07b30badda2bd23b3943342f62ca4107e16f886 100644 --- a/src/sbbs3/readmsgs.cpp +++ b/src/sbbs3/readmsgs.cpp @@ -99,6 +99,10 @@ char *binstr(uchar *buf, ushort length, char* str) for(i=0;i<length;i++) { sprintf(tmp,"%02X ",buf[i]); strcat(str,tmp); + if(i >= 100) { + strcat(str,"..."); + break; + } } return(str); } @@ -118,9 +122,11 @@ void sbbs_t::msghdr(smbmsg_t* msg) ,binstr((uchar *)msg->hfield_dat[i],msg->hfield[i].length,str)); /* fixed fields */ - bprintf("%-16.16s %s %s\r\n","when_written" + bprintf("%-16.16s %08lX %04hX %s %s\r\n","when_written" + ,msg->hdr.when_written.time, msg->hdr.when_written.zone ,timestr(msg->hdr.when_written.time), smb_zonestr(msg->hdr.when_written.zone,NULL)); - bprintf("%-16.16s %s %s\r\n","when_imported" + bprintf("%-16.16s %08lX %04hX %s %s\r\n","when_imported" + ,msg->hdr.when_imported.time, msg->hdr.when_imported.zone ,timestr(msg->hdr.when_imported.time), smb_zonestr(msg->hdr.when_imported.zone,NULL)); bprintf("%-16.16s %04Xh\r\n","type" ,msg->hdr.type); bprintf("%-16.16s %04Xh\r\n","version" ,msg->hdr.version); diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index f7442078f5682bb0a3efc8ae3ccfb0e18cd56bd2..f5359ea3cc45de8d1bf13eb9e748e0d4f861bebf 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -8,7 +8,7 @@ * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * * - * Copyright 2007 Rob Swindell - http://www.synchro.net/copyright.html * + * Copyright 2008 Rob Swindell - http://www.synchro.net/copyright.html * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * @@ -132,9 +132,11 @@ extern int thread_suid_broken; /* NPTL is no longer broken */ #include "semfile.h" #include "dirwrap.h" #include "filewrap.h" +#include "datewrap.h" #include "sockwrap.h" #include "link_list.h" #include "msg_queue.h" +#include "xpdatetime.h" #include "smblib.h" #include "ars_defs.h" @@ -730,7 +732,7 @@ public: bool unpack_rep(char* repfile=NULL); /* msgtoqwk.cpp */ - ulong msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, int subnum, int conf); + ulong msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, int subnum, int conf, FILE* hdrs_dat); /* qwktomsg.cpp */ bool qwktomsg(FILE *qwk_fp, char *hdrblk, char fromhub, uint subnum diff --git a/src/sbbs3/sbbsdefs.h b/src/sbbs3/sbbsdefs.h index d1c2d5d87f61d102c2b63408394c399db99e272b..44ee0ed041140a19d2bbc092c05e3e498d0018df 100644 --- a/src/sbbs3/sbbsdefs.h +++ b/src/sbbs3/sbbsdefs.h @@ -407,6 +407,7 @@ typedef enum { /* Values for xtrn_t.event */ #define QWK_NOCTRL (1L<<12) /* No extraneous control files */ #define QWK_EXT (1L<<13) /* QWK Extended (QWKE) format */ #define QWK_MSGID (1L<<14) /* Include "@MSGID" in msgs */ +#define QWK_HEADERS (1L<<16) /* Include HEADERS.DAT file */ #define QWK_DEFAULT (QWK_FILES|QWK_ATTACH|QWK_EMAIL|QWK_DELMAIL) diff --git a/src/sbbs3/un_rep.cpp b/src/sbbs3/un_rep.cpp index 133e9d72860f648d69684b42dbe88d4663e7754f..160f51b001fa2d329bf771772afaf4e1efc64c0a 100644 --- a/src/sbbs3/un_rep.cpp +++ b/src/sbbs3/un_rep.cpp @@ -8,7 +8,7 @@ * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * * - * Copyright 2007 Rob Swindell - http://www.synchro.net/copyright.html * + * Copyright 2008 Rob Swindell - http://www.synchro.net/copyright.html * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * @@ -45,6 +45,9 @@ bool sbbs_t::unpack_rep(char* repfile) { char str[MAX_PATH+1],fname[MAX_PATH+1] ,*AttemptedToUploadREPpacket="Attempted to upload REP packet"; + char rep_fname[MAX_PATH+1]; + char msg_fname[MAX_PATH+1]; + char hdrs_fname[MAX_PATH+1]; char tmp[512]; char from[26]; char to[26]; @@ -57,18 +60,19 @@ bool sbbs_t::unpack_rep(char* repfile) ulong ex; node_t node; FILE* rep; + FILE* hdrs=NULL; DIR* dir; DIRENT* dirent; BOOL twit_list; - sprintf(fname,"%stwitlist.cfg",cfg.ctrl_dir); + SAFEPRINTF(fname,"%stwitlist.cfg",cfg.ctrl_dir); twit_list=fexist(fname); if(repfile!=NULL) - strcpy(str,repfile); + SAFECOPY(rep_fname,repfile); else - sprintf(str,"%s%s.rep",cfg.temp_dir,cfg.sys_id); - if(!fexistcase(str)) { + SAFEPRINTF2(rep_fname,"%s%s.rep",cfg.temp_dir,cfg.sys_id); + if(!fexistcase(rep_fname)) { bputs(text[QWKReplyNotReceived]); logline("U!",AttemptedToUploadREPpacket); logline(nulstr,"REP file not received"); @@ -82,27 +86,40 @@ bool sbbs_t::unpack_rep(char* repfile) ex=EX_OUTL|EX_OUTR; if(online!=ON_REMOTE) ex|=EX_OFFLINE; - i=external(cmdstr(cfg.fextr[k]->cmd,str,ALLFILES,NULL),ex); + i=external(cmdstr(cfg.fextr[k]->cmd,rep_fname,ALLFILES,NULL),ex); if(i) { bputs(text[QWKExtractionFailed]); logline("U!",AttemptedToUploadREPpacket); logline(nulstr,"Extraction failed"); return(false); } - sprintf(str,"%s%s.msg",cfg.temp_dir,cfg.sys_id); - if(!fexistcase(str)) { + SAFEPRINTF(hdrs_fname,"%sHEADERS.DAT",cfg.temp_dir); + if(fexistcase(hdrs_fname)) { + /* If we receive a headers.dat from a QWKnet node, we know the hubs supports it */ + /* So turn on headers.dat in subsequent .QWK files */ + if(!(useron.qwk&QWK_HEADERS)) { + useron.qwk|=QWK_HEADERS; + putuserrec(&cfg,useron.number,U_QWK,8,ultoa(useron.qwk,str,16)); + } + if((hdrs=fopen(hdrs_fname,"r")) == NULL) + errormsg(WHERE,ERR_OPEN,hdrs_fname,0); + } + SAFEPRINTF2(msg_fname,"%s%s.msg",cfg.temp_dir,cfg.sys_id); + if(!fexistcase(msg_fname)) { bputs(text[QWKReplyNotReceived]); logline("U!",AttemptedToUploadREPpacket); logline(nulstr,"MSG file not received"); return(false); } - if((rep=fnopen(&file,str,O_RDONLY))==NULL) { - errormsg(WHERE,ERR_OPEN,str,O_RDONLY); + if((rep=fnopen(&file,msg_fname,O_RDONLY))==NULL) { + errormsg(WHERE,ERR_OPEN,msg_fname,O_RDONLY); return(false); } size=filelength(file); fread(block,QWK_BLOCK_LEN,1,rep); if(strnicmp((char *)block,cfg.sys_id,strlen(cfg.sys_id))) { + if(hdrs!=NULL) + fclose(hdrs); fclose(rep); bputs(text[QWKReplyNotReceived]); logline("U!",AttemptedToUploadREPpacket); @@ -123,19 +140,17 @@ bool sbbs_t::unpack_rep(char* repfile) lncntr=0; /* defeat pause */ if(fseek(rep,l,SEEK_SET)!=0) { - sprintf(str,"%s.msg", cfg.sys_id); - errormsg(WHERE,ERR_SEEK,str,l); + errormsg(WHERE,ERR_SEEK,msg_fname,l); break; } if(fread(block,1,QWK_BLOCK_LEN,rep)!=QWK_BLOCK_LEN) { - sprintf(str,"%s.msg", cfg.sys_id); - errormsg(WHERE,ERR_READ,str,ftell(rep)); + errormsg(WHERE,ERR_READ,msg_fname,ftell(rep)); break; } sprintf(tmp,"%.6s",block+116); i=atoi(tmp); /* i = number of blocks */ if(i<2) { - sprintf(str,"%s.msg blocks (read '%s' at offset %ld)", cfg.sys_id, tmp, l); + SAFEPRINTF3(str,"%s blocks (read '%s' at offset %ld)", msg_fname, tmp, l); errormsg(WHERE,ERR_CHK,str,i); i=1; continue; @@ -188,7 +203,7 @@ bool sbbs_t::unpack_rep(char* repfile) continue; } - sprintf(smb.file,"%smail",cfg.data_dir); + SAFEPRINTF(smb.file,"%smail",cfg.data_dir); smb.retry_time=cfg.smb_retry_time; if(lastsub!=INVALID_SUB) { @@ -250,7 +265,7 @@ bool sbbs_t::unpack_rep(char* repfile) putuserrec(&cfg,useron.number,U_ETODAY,5 ,ultoa(useron.etoday,tmp,10)); bprintf(text[Emailed],username(&cfg,j,tmp),j); - sprintf(str,"%s sent e-mail to %s #%d" + SAFEPRINTF3(str,"%s sent e-mail to %s #%d" ,useron.alias,username(&cfg,j,tmp),j); logline("E+",str); if(useron.rest&FLAG('Q')) { @@ -258,20 +273,20 @@ bool sbbs_t::unpack_rep(char* repfile) truncsp(tmp); } else - strcpy(tmp,useron.alias); + SAFECOPY(tmp,useron.alias); for(k=1;k<=cfg.sys_nodes;k++) { /* Tell user, if online */ getnodedat(k,&node,0); if(node.useron==j && !(node.misc&NODE_POFF) && (node.status==NODE_INUSE || node.status==NODE_QUIET)) { - sprintf(str,text[EmailNodeMsg] + SAFEPRINTF2(str,text[EmailNodeMsg] ,cfg.node_num,tmp); putnmsg(&cfg,k,str); break; } } if(k>cfg.sys_nodes) { - sprintf(str,text[UserSentYouMail],tmp); + SAFEPRINTF(str,text[UserSentYouMail],tmp); putsmsg(&cfg,j,str); } } /* end of email */ @@ -301,7 +316,7 @@ bool sbbs_t::unpack_rep(char* repfile) k--; /* k is sub */ if(j>=usrgrps || k>=usrsubs[j] || cfg.sub[usrsub[j][k]]->qwkconf) { bprintf(text[QWKInvalidConferenceN],n); - sprintf(str,"%s: Invalid conference number %lu",useron.alias,n); + SAFEPRINTF2(str,"%s: Invalid conference number %lu",useron.alias,n); logline("P!",str); continue; } @@ -387,14 +402,14 @@ bool sbbs_t::unpack_rep(char* repfile) /* TWIT FILTER */ if(twit_list) { - sprintf(fname,"%stwitlist.cfg",cfg.ctrl_dir); + SAFEPRINTF(fname,"%stwitlist.cfg",cfg.ctrl_dir); sprintf(from,"%25.25s",block+46); /* From user */ truncsp(from); sprintf(to,"%25.25s",block+21); /* To user */ truncsp(to); if(findstr(from,fname) || findstr(to,fname)) { - sprintf(str,"Filtering post from %s to %s on %s %s" + SAFEPRINTF4(str,"Filtering post from %s to %s on %s %s" ,from ,to ,cfg.grp[cfg.sub[n]->grp]->sname,cfg.sub[n]->lname); @@ -407,7 +422,7 @@ bool sbbs_t::unpack_rep(char* repfile) if(lastsub!=INVALID_SUB) smb_close(&smb); lastsub=INVALID_SUB; - sprintf(smb.file,"%s%s",cfg.sub[n]->data_dir,cfg.sub[n]->code); + SAFEPRINTF2(smb.file,"%s%s",cfg.sub[n]->data_dir,cfg.sub[n]->code); smb.retry_time=cfg.smb_retry_time; smb.subnum=n; if((j=smb_open(&smb))!=0) { @@ -451,7 +466,7 @@ bool sbbs_t::unpack_rep(char* repfile) user_posted_msg(&cfg, &useron, 1); bprintf(text[Posted],cfg.grp[cfg.sub[n]->grp]->sname ,cfg.sub[n]->lname); - sprintf(str,"%s posted on %s %s" + SAFEPRINTF3(str,"%s posted on %s %s" ,useron.alias,cfg.grp[cfg.sub[n]->grp]->sname,cfg.sub[n]->lname); signal_sub_sem(&cfg,n); logline("P+",str); @@ -464,39 +479,41 @@ bool sbbs_t::unpack_rep(char* repfile) if(lastsub!=INVALID_SUB) smb_close(&smb); + if(hdrs!=NULL) + fclose(hdrs); fclose(rep); if(useron.rest&FLAG('Q')) { /* QWK Net Node */ - sprintf(str,"%s%s.msg",cfg.temp_dir,cfg.sys_id); - if(fexistcase(str)) - remove(str); - sprintf(str,"%s%s.rep",cfg.temp_dir,cfg.sys_id); - if(fexistcase(str)) - remove(str); - sprintf(str,"%sATTXREF.DAT",cfg.temp_dir); - if(fexistcase(str)) - remove(str); + if(fexistcase(msg_fname)) + remove(msg_fname); + if(fexistcase(rep_fname)) + remove(rep_fname); + if(fexistcase(hdrs_fname)) + remove(hdrs_fname); + SAFEPRINTF(fname,"%sATTXREF.DAT",cfg.temp_dir); + if(fexistcase(fname)) + remove(fname); dir=opendir(cfg.temp_dir); while(dir!=NULL && (dirent=readdir(dir))!=NULL) { /* Extra files */ // Move files - sprintf(str,"%s%s",cfg.temp_dir,dirent->d_name); + SAFEPRINTF2(str,"%s%s",cfg.temp_dir,dirent->d_name); if(isdir(str)) continue; // Create directory if necessary - sprintf(inbox,"%sqnet/%s.in",cfg.data_dir,useron.alias); + SAFEPRINTF2(inbox,"%sqnet/%s.in",cfg.data_dir,useron.alias); MKDIR(inbox); - sprintf(fname,"%s/%s",inbox,dirent->d_name); + SAFEPRINTF2(fname,"%s/%s",inbox,dirent->d_name); mv(str,fname,1); - sprintf(str,text[ReceivedFileViaQWK],dirent->d_name,useron.alias); + SAFEPRINTF2(str,text[ReceivedFileViaQWK],dirent->d_name,useron.alias); putsmsg(&cfg,1,str); } if(dir!=NULL) closedir(dir); - sprintf(str,"%sqnet-rep.now",cfg.data_dir); - ftouch(str); + SAFEPRINTF(fname,"%sqnet-rep.now",cfg.data_dir); + ftouch(fname); } bputs(text[QWKUnpacked]);