--- sbbs/src/sbbs3/writemsg.cpp 2018/04/24 16:41:23 1.1.1.1 +++ sbbs/src/sbbs3/writemsg.cpp 2018/04/24 16:43:11 1.1.1.2 @@ -2,13 +2,13 @@ /* Synchronet message creation routines */ -/* $Id: writemsg.cpp,v 1.1.1.1 2018/04/24 16:41:23 root Exp $ */ +/* $Id: writemsg.cpp,v 1.1.1.2 2018/04/24 16:43:11 root Exp $ */ /**************************************************************************** * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * * - * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html * + * Copyright 2011 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 * @@ -36,27 +36,149 @@ ****************************************************************************/ #include "sbbs.h" +#include "wordwrap.h" #define MAX_LINE_LEN 82L -const char *qstr=" > %.76s\r\n"; +const char *quote_fmt=" > %.*s\r\n"; void quotestr(char *str); /****************************************************************************/ /* Returns temporary message text filename (for message/text editors) */ /****************************************************************************/ -char* sbbs_t::msg_tmp_fname(int xedit, char* fname, size_t len) +char* sbbs_t::msg_tmp_fname(int xedit, char* path, size_t len) { - safe_snprintf(fname, len, "%sINPUT.MSG", cfg.temp_dir); + safe_snprintf(path, len, "%sINPUT.MSG", cfg.temp_dir); if(xedit) { if(cfg.xedit[xedit-1]->misc&QUICKBBS) - safe_snprintf(fname, len, "%sMSGTMP", cfg.node_dir); /* QuickBBS editors are dumb */ + safe_snprintf(path, len, "%sMSGTMP", cfg.node_dir); /* QuickBBS editors are dumb */ if(cfg.xedit[xedit-1]->misc&XTRN_LWRCASE) - strlwr(fname); + strlwr(getfname(path)); } - return(fname); + return path; +} + +/****************************************************************************/ +/****************************************************************************/ +char* sbbs_t::quotes_fname(int xedit, char *path, size_t len) +{ + safe_snprintf(path, len, "%sQUOTES.TXT", cfg.node_dir); + if(xedit && cfg.xedit[xedit-1]->misc&XTRN_LWRCASE) + strlwr(getfname(path)); + return path; +} + +/****************************************************************************/ +/****************************************************************************/ +void sbbs_t::quotemsg(smbmsg_t* msg, int tails) +{ + char fname[MAX_PATH+1]; + char* buf; + char* wrapped=NULL; + FILE* fp; + + quotes_fname(useron.xedit,fname,sizeof(fname)); + removecase(fname); + + if((fp=fopen(fname,"w"))==NULL) { + errormsg(WHERE,ERR_OPEN,fname,0); + return; + } + + if((buf=smb_getmsgtxt(&smb,msg,tails)) != NULL) { + strip_invalid_attr(buf); + if(useron.xedit && (cfg.xedit[useron.xedit-1]->misc"EWRAP)) + wrapped=::wordwrap(buf, cols-4, cols-1, /* handle_quotes */TRUE); + if(wrapped!=NULL) { + fputs(wrapped,fp); + free(wrapped); + } else + fputs(buf,fp); + smb_freemsgtxt(buf); + } else if(smb_getmsgdatlen(msg)>2) + errormsg(WHERE,ERR_READ,smb.file,smb_getmsgdatlen(msg)); + fclose(fp); +} + +/****************************************************************************/ +/****************************************************************************/ +int sbbs_t::process_edited_text(char* buf, FILE* stream, long mode, unsigned* lines) +{ + int i,l; + int len=0; + + for(l=i=0;buf[l] && imisc&QUICKBBS) { + len+=fwrite(crlf,1,2,stream); + i++; + continue; + } + /* Expand LF to CRLF? */ + if(buf[l]==LF && (!l || buf[l-1]!=CR) && useron.xedit + && cfg.xedit[useron.xedit-1]->misc&EXPANDLF) { + len+=fwrite(crlf,1,2,stream); + i++; + continue; + } + /* Strip FidoNet Kludge Lines? */ + if(buf[l]==CTRL_A && useron.xedit + && cfg.xedit[useron.xedit-1]->misc&STRIPKLUDGE) { + while(buf[l] && buf[l]!=LF) + l++; + if(buf[l]==0) + break; + continue; + } + if(!(mode&(WM_EMAIL|WM_NETMAIL)) + && (!l || buf[l-1]==LF) + && buf[l]=='-' && buf[l+1]=='-' && buf[l+2]=='-' + && (buf[l+3]==' ' || buf[l+3]==TAB || buf[l+3]==CR)) + buf[l+1]='+'; + if(buf[l]==LF) + i++; + fputc(buf[l],stream); + len++; + } + + if(buf[l]) + bputs(text[NoMoreLines]); + + if(lines!=NULL) + *lines=i; + return len; +} + +/****************************************************************************/ +/****************************************************************************/ +int sbbs_t::process_edited_file(const char* src, const char* dest, long mode, unsigned* lines) +{ + char* buf; + long len; + FILE* fp; + + if((len=(long)flength(src))<1) + return -1; + + if((buf=(char*)malloc(len+1))==NULL) + return -2; + + if((fp=fopen(src,"rb"))==NULL) + return -3; + + memset(buf,0,len+1); + fread(buf,len,sizeof(char),fp); + fclose(fp); + + if((fp=fopen(dest,"wb"))!=NULL) { + len=process_edited_text(buf, fp, mode, lines); + fclose(fp); + } + free(buf); + + return len; } /****************************************************************************/ @@ -65,8 +187,8 @@ char* sbbs_t::msg_tmp_fname(int xedit, c /* message and 'title' is the title (70chars max) for the message. */ /* 'dest' contains a text description of where the message is going. */ /****************************************************************************/ -bool sbbs_t::writemsg(char *fname, char *top, char *title, long mode, int subnum - ,char *dest) +bool sbbs_t::writemsg(const char *fname, const char *top, char *title, long mode, int subnum + ,const char *dest, char** editor) { char str[256],quote[128],c,*buf,*p,*tp ,useron_level; @@ -78,9 +200,13 @@ bool sbbs_t::writemsg(char *fname, char ulong l; FILE* stream; FILE* fp; + unsigned lines; useron_level=useron.level; + if(editor!=NULL) + *editor=NULL; + if((buf=(char*)malloc(cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)) ==NULL) { errormsg(WHERE,ERR_ALLOC,fname @@ -102,10 +228,7 @@ bool sbbs_t::writemsg(char *fname, char /* Quote entire message to MSGTMP or INPUT.MSG */ if(useron.xedit && cfg.xedit[useron.xedit-1]->misc"EALL) { - strcpy(tmp,"QUOTES.TXT"); - if(cfg.xedit[useron.xedit-1]->misc&XTRN_LWRCASE) - strlwr(tmp); - sprintf(str,"%s%s",cfg.node_dir,tmp); + quotes_fname(useron.xedit, str, sizeof(str)); if((stream=fnopen(NULL,str,O_RDONLY))==NULL) { errormsg(WHERE,ERR_OPEN,str,O_RDONLY); free(buf); @@ -120,10 +243,10 @@ bool sbbs_t::writemsg(char *fname, char } while(!feof(stream) && !ferror(stream)) { - if(!fgets(str,255,stream)) + if(!fgets(str,sizeof(str),stream)) break; quotestr(str); - sprintf(tmp,qstr,str); + SAFEPRINTF2(tmp,quote_fmt,cols-4,str); write(file,tmp,strlen(tmp)); linesquoted++; } @@ -137,10 +260,7 @@ bool sbbs_t::writemsg(char *fname, char ; else if(yesno(text[QuoteMessageQ])) { - strcpy(tmp,"QUOTES.TXT"); - if(useron.xedit && cfg.xedit[useron.xedit-1]->misc&XTRN_LWRCASE) - strlwr(tmp); - sprintf(str,"%s%s",cfg.node_dir,tmp); + quotes_fname(useron.xedit, str, sizeof(str)); if((stream=fnopen(&file,str,O_RDONLY))==NULL) { errormsg(WHERE,ERR_OPEN,str,O_RDONLY); free(buf); @@ -154,10 +274,10 @@ bool sbbs_t::writemsg(char *fname, char return(false); } - l=ftell(stream); /* l now points to start of message */ + l=(long)ftell(stream); /* l now points to start of message */ while(online) { - sprintf(str,text[QuoteLinesPrompt],linesquoted ? "Done":"All"); + SAFEPRINTF(str,text[QuoteLinesPrompt],linesquoted ? "Done":"All"); mnemonics(str); i=getstr(quote,10,K_UPPER); if(sys_status&SS_ABORT) { @@ -171,10 +291,10 @@ bool sbbs_t::writemsg(char *fname, char if(!i || quote[0]=='A') { /* Quote all */ fseek(stream,l,SEEK_SET); while(!feof(stream) && !ferror(stream)) { - if(!fgets(str,255,stream)) + if(!fgets(str,sizeof(str),stream)) break; quotestr(str); - sprintf(tmp,qstr,str); + SAFEPRINTF2(tmp,quote_fmt,cols-4,str); write(file,tmp,strlen(tmp)); linesquoted++; } @@ -186,7 +306,7 @@ bool sbbs_t::writemsg(char *fname, char CRLF; attr(LIGHTGRAY); while(!feof(stream) && !ferror(stream) && !msgabort()) { - if(!fgets(str,255,stream)) + if(!fgets(str,sizeof(str),stream)) break; quotestr(str); bprintf("%3d: %.74s\r\n",i,str); @@ -207,7 +327,7 @@ bool sbbs_t::writemsg(char *fname, char fseek(stream,l,SEEK_SET); j=1; while(!feof(stream) && !ferror(stream) && jmisc&XTRN_LWRCASE) - strlwr(tmp); - sprintf(str,"%s%s",cfg.node_dir,tmp); + quotes_fname(useron.xedit, str, sizeof(str)); removecase(str); } @@ -256,16 +373,20 @@ bool sbbs_t::writemsg(char *fname, char if(!(mode&(WM_EXTDESC|WM_SUBJ_RO))) { if(mode&WM_FILE) { +#if 0 max_title_len=12; /* ToDo: implied 8.3 filename limit! */ +#endif CRLF; bputs(text[Filename]); } else { +#if 0 max_title_len=LEN_TITLE; if(mode&WM_QWKNET || (subnum!=INVALID_SUB && (cfg.sub[subnum]->misc&(SUB_QNET|SUB_INET|SUB_FIDO))==SUB_QNET)) max_title_len=25; +#endif bputs(text[SubjectPrompt]); } if(!getstr(title,max_title_len,mode&WM_FILE ? K_LINE : K_LINE|K_EDIT|K_AUTODEL) @@ -320,6 +441,9 @@ bool sbbs_t::writemsg(char *fname, char else if(useron.xedit) { + if(editor!=NULL) + *editor=cfg.xedit[useron.xedit-1]->name; + editor_inf(useron.xedit,dest,title,mode,subnum); if(cfg.xedit[useron.xedit-1]->type) { gettimeleft(); @@ -327,8 +451,8 @@ bool sbbs_t::writemsg(char *fname, char ,timeleft,cfg.xedit[useron.xedit-1]->misc); } - if(cfg.xedit[useron.xedit-1]->misc&IO_INTS) { - ex_mode|=(EX_OUTR|EX_INR); + if(cfg.xedit[useron.xedit-1]->misc&XTRN_STDIO) { + ex_mode|=EX_STDIO; if(cfg.xedit[useron.xedit-1]->misc&WWIVCOLOR) ex_mode|=EX_WWIV; } @@ -340,7 +464,7 @@ bool sbbs_t::writemsg(char *fname, char if(!linesquoted) removecase(msgtmp); else { - qlen=flength(msgtmp); + qlen=(long)flength(msgtmp); qtime=fdate(msgtmp); } @@ -363,7 +487,7 @@ bool sbbs_t::writemsg(char *fname, char fgets(str,sizeof(str),fp); fgets(str,sizeof(str),fp); truncsp(str); - sprintf(title,"%.*s",max_title_len,str); + safe_snprintf(title,max_title_len,"%s",str); fclose(fp); } } @@ -376,7 +500,7 @@ bool sbbs_t::writemsg(char *fname, char free(buf); return(false); } - length=filelength(file); + length=(long)filelength(file); l=strlen((char *)buf); /* reserve space for top and terminating null */ /* truncate if too big */ if(length>(long)((cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)-(l+1))) { @@ -392,7 +516,7 @@ bool sbbs_t::writemsg(char *fname, char buf[0]=0; if(linesquoted) { if((file=nopen(msgtmp,O_RDONLY))!=-1) { - length=filelength(file); + length=(long)filelength(file); l=length>(cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)-1 ? (cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)-1 : length; lread(file,buf,l); @@ -409,50 +533,17 @@ bool sbbs_t::writemsg(char *fname, char now=time(NULL); bputs(text[Saving]); - if((stream=fnopen(&file,fname,O_WRONLY|O_CREAT|O_TRUNC))==NULL) { + if((stream=fnopen(NULL,fname,O_WRONLY|O_CREAT|O_TRUNC))==NULL) { errormsg(WHERE,ERR_OPEN,fname,O_WRONLY|O_CREAT|O_TRUNC); free(buf); return(false); } - for(l=i=0;buf[l] && imisc&QUICKBBS) { - fwrite(crlf,2,1,stream); - i++; - continue; - } - /* Expand LF to CRLF? */ - if(buf[l]==LF && (!l || buf[l-1]!=CR) && useron.xedit - && cfg.xedit[useron.xedit-1]->misc&EXPANDLF) { - fwrite(crlf,2,1,stream); - i++; - continue; - } - /* Strip FidoNet Kludge Lines? */ - if(buf[l]==1 && useron.xedit - && cfg.xedit[useron.xedit-1]->misc&STRIPKLUDGE) { - while(buf[l] && buf[l]!=LF) - l++; - if(buf[l]==0) - break; - continue; - } - if(!(mode&(WM_EMAIL|WM_NETMAIL)) - && (!l || buf[l-1]==LF) - && buf[l]=='-' && buf[l+1]=='-' && buf[l+2]=='-' - && (buf[l+3]==' ' || buf[l+3]==TAB || buf[l+3]==CR)) - buf[l+1]='+'; - if(buf[l]==LF) - i++; - fputc(buf[l],stream); - } - - if(buf[l]) - bputs(text[NoMoreLines]); + l=process_edited_text(buf,stream,mode,&lines); /* Signature file */ - if(subnum==INVALID_SUB || !(cfg.sub[subnum]->misc&SUB_NOUSERSIG)) { - sprintf(str,"%suser/%04u.sig",cfg.data_dir,useron.number); + if((subnum==INVALID_SUB && cfg.msg_misc&MM_EMAILSIG) + || (subnum!=INVALID_SUB && !(cfg.sub[subnum]->misc&SUB_NOUSERSIG))) { + SAFEPRINTF2(str,"%suser/%04u.sig",cfg.data_dir,useron.number); FILE* sig; if(fexist(str) && (sig=fopen(str,"rb"))!=NULL) { while(!feof(sig)) { @@ -460,7 +551,7 @@ bool sbbs_t::writemsg(char *fname, char break; fputs(str,stream); l+=strlen(str); /* byte counter */ - i++; /* line counter */ + lines++; /* line counter */ } fclose(sig); } @@ -468,7 +559,7 @@ bool sbbs_t::writemsg(char *fname, char fclose(stream); free((char *)buf); - bprintf(text[SavedNBytes],l,i); + bprintf(text[SavedNBytes],l,lines); return(true); } @@ -477,15 +568,13 @@ bool sbbs_t::writemsg(char *fname, char /****************************************************************************/ void quotestr(char *str) { - int j; - - j=strlen(str); - while(j && (str[j-1]==' ' || str[j-1]==LF || str[j-1]==CR)) j--; - str[j]=0; - remove_ctrl_a(str,NULL); + truncsp(str); + remove_ctrl_a(str,str); } -void sbbs_t::editor_inf(int xeditnum,char *dest, char *title, long mode +/****************************************************************************/ +/****************************************************************************/ +void sbbs_t::editor_inf(int xeditnum, const char *dest, const char *title, long mode ,uint subnum) { char str[MAX_PATH+1]; @@ -498,12 +587,12 @@ void sbbs_t::editor_inf(int xeditnum,cha strcpy(tmp,"MSGINF"); if(cfg.xedit[xeditnum]->misc&XTRN_LWRCASE) strlwr(tmp); - sprintf(str,"%s%s",cfg.node_dir,tmp); + SAFEPRINTF2(str,"%s%s",cfg.node_dir,tmp); if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) { errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC); return; } - sprintf(str,"%s\r\n%s\r\n%s\r\n%u\r\n%s\r\n%s\r\n" + safe_snprintf(str,sizeof(str),"%s\r\n%s\r\n%s\r\n%u\r\n%s\r\n%s\r\n" ,(subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_NAME) ? useron.name : useron.alias ,dest,title,1 @@ -521,12 +610,12 @@ void sbbs_t::editor_inf(int xeditnum,cha strcpy(tmp,"EDITOR.INF"); if(cfg.xedit[xeditnum]->misc&XTRN_LWRCASE) strlwr(tmp); - sprintf(str,"%s%s",cfg.node_dir,tmp); + SAFEPRINTF2(str,"%s%s",cfg.node_dir,tmp); if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) { errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC); return; } - sprintf(str,"%s\r\n%s\r\n%u\r\n%s\r\n%s\r\n%u\r\n" + safe_snprintf(str,sizeof(str),"%s\r\n%s\r\n%u\r\n%s\r\n%s\r\n%u\r\n" ,title,dest,useron.number ,(subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_NAME) ? useron.name : useron.alias @@ -554,7 +643,7 @@ void sbbs_t::removeline(char *str, char errormsg(WHERE,ERR_OPEN,str,O_RDONLY); return; } - flen=filelength(file); + flen=(long)filelength(file); slen=strlen(str2); if((buf=(char *)malloc(flen))==NULL) { close(file); @@ -601,7 +690,7 @@ void sbbs_t::removeline(char *str, char /* The Synchronet editor. */ /* Returns the number of lines edited. */ /*****************************************************************************/ -ulong sbbs_t::msgeditor(char *buf, char *top, char *title) +ulong sbbs_t::msgeditor(char *buf, const char *top, char *title) { int i,j,line,lines=0,maxlines; char strin[256],**str,done=0; @@ -659,7 +748,7 @@ ulong sbbs_t::msgeditor(char *buf, char bprintf("\r\nMessage editor: Read in %d lines\r\n",lines); bprintf(text[EnterMsgNow],maxlines); - sprintf(path,"%smenu/msgtabs.*", cfg.text_dir); + SAFEPRINTF(path,"%smenu/msgtabs.*", cfg.text_dir); if(fexist(path)) menu("msgtabs"); else { @@ -802,7 +891,7 @@ ulong sbbs_t::msgeditor(char *buf, char else if(toupper(strin[1])=='L') { /* list message */ if(line==lines) free(str[line]); - if(lines) + if(lines && text[WithLineNumbersQ][0]) i=!noyes(text[WithLineNumbersQ]); else i=0; @@ -816,7 +905,7 @@ ulong sbbs_t::msgeditor(char *buf, char if(j) j--; /* start from line j */ while(jmisc&XTRN_SH) mode|=EX_SH; - if(cfg.xedit[useron.xedit-1]->misc&IO_INTS) { - mode|=(EX_OUTR|EX_INR); + if(cfg.xedit[useron.xedit-1]->misc&XTRN_STDIO) { + mode|=EX_STDIO; if(cfg.xedit[useron.xedit-1]->misc&WWIVCOLOR) mode|=EX_WWIV; } CLS; rioctl(IOCM|PAUSE|ABORT); - external(cmdstr(cfg.xedit[useron.xedit-1]->rcmd,msgtmp,nulstr,NULL),mode,cfg.node_dir); - if(stricmp(msgtmp,path) && !fcompare(msgtmp, path)) /* file changed */ - fcopy(msgtmp, path); + if(external(cmdstr(cfg.xedit[useron.xedit-1]->rcmd,msgtmp,nulstr,NULL),mode,cfg.node_dir)!=0) + return false; + l=process_edited_file(msgtmp, path, /* mode: */0, &lines); + if(l>0) { + SAFEPRINTF4(str,"%s created or edited file: %s (%u bytes, %u lines)" + ,useron.alias, path, l, lines); + logline(LOG_NOTICE,nulstr,str); + } rioctl(IOSM|PAUSE|ABORT); - return; + return true; } if((buf=(char *)malloc(maxlines*MAX_LINE_LEN))==NULL) { errormsg(WHERE,ERR_ALLOC,nulstr,maxlines*MAX_LINE_LEN); - return; + return false; } if((file=nopen(fname,O_RDONLY))!=-1) { - length=filelength(file); + length=(long)filelength(file); if(length>(long)maxlines*MAX_LINE_LEN) { close(file); free(buf); attr(cfg.color[clr_err]); bprintf("\7\r\nFile size (%lu bytes) is larger than %lu (maxlines: %lu).\r\n" ,length, (ulong)maxlines*MAX_LINE_LEN, maxlines); - return; + return false; } if(read(file,buf,length)!=length) { close(file); free(buf); errormsg(WHERE,ERR_READ,fname,length); - return; + return false; } buf[length]=0; close(file); @@ -962,27 +1059,22 @@ void sbbs_t::editfile(char *fname) } if(!msgeditor(buf,nulstr,nulstr)) { free(buf); - return; + return false; } bputs(text[Saving]); - if((file=nopen(fname,O_CREAT|O_WRONLY|O_TRUNC))==-1) { + if((stream=fnopen(NULL,fname,O_CREAT|O_WRONLY|O_TRUNC))==NULL) { errormsg(WHERE,ERR_OPEN,fname,O_CREAT|O_WRONLY|O_TRUNC); free(buf); - return; - } - if((size_t)write(file,buf,strlen(buf))!=strlen(buf)) { - close(file); - errormsg(WHERE,ERR_WRITE,fname,strlen(buf)); - free(buf); - return; + return false; } - for(l=lines=0;buf[l];l++) - if(buf[l]==LF) - lines++; + l=process_edited_text(buf,stream,/* mode: */0,&lines); bprintf(text[SavedNBytes],l,lines); - close(file); + fclose(stream); free(buf); - return; + SAFEPRINTF4(str,"%s created or edited file: %s (%u bytes, %u lines)" + ,useron.alias, fname, l, lines); + logline(nulstr,str); + return true; } /*************************/ @@ -1000,9 +1092,9 @@ void sbbs_t::copyfattach(uint to, uint f sp=strrchr(tp,'/'); /* sp is slash pointer */ if(!sp) sp=strrchr(tp,'\\'); if(sp) tp=sp+1; - sprintf(str2,"%sfile/%04u.in/%s" /* str2 is path/fname */ + SAFEPRINTF3(str2,"%sfile/%04u.in/%s" /* str2 is path/fname */ ,cfg.data_dir,to,tp); - sprintf(str3,"%sfile/%04u.in/%s" /* str2 is path/fname */ + SAFEPRINTF3(str3,"%sfile/%04u.in/%s" /* str2 is path/fname */ ,cfg.data_dir,from,tp); if(strcmp(str2,str3)) mv(str3,str2,1); @@ -1025,8 +1117,9 @@ void sbbs_t::forwardmail(smbmsg_t *msg, node_t node; msghdr_t hdr=msg->hdr; idxrec_t idx=msg->idx; + time32_t now32; - if(useron.etoday>=cfg.level_emailperday[useron.level] && !SYSOP) { + if(useron.etoday>=cfg.level_emailperday[useron.level] && !SYSOP && !(useron.exempt&FLAG('M'))) { bputs(text[TooManyEmailsToday]); return; } @@ -1048,17 +1141,21 @@ void sbbs_t::forwardmail(smbmsg_t *msg, smb_hfield_str(msg,SENDER,useron.alias); - sprintf(str,"%u",useron.number); + SAFEPRINTF(str,"%u",useron.number); smb_hfield_str(msg,SENDEREXT,str); + /* Security logging */ + msg_client_hfields(msg,&client); + smb_hfield_str(msg,SENDERSERVER,startup->host_name); + username(&cfg,usernumber,touser); smb_hfield_str(msg,RECIPIENT,touser); - sprintf(str,"%u",usernumber); - smb_hfield(msg,RECIPIENTEXT,sizeof(str),str); + SAFEPRINTF(str,"%u",usernumber); + smb_hfield_str(msg,RECIPIENTEXT,str); msg->idx.to=usernumber; - now=time(NULL); - smb_hfield(msg,FORWARDED,sizeof(time_t),&now); + now32=time(NULL); + smb_hfield(msg,FORWARDED,sizeof(time32_t),&now32); if((i=smb_open_da(&smb))!=SMB_SUCCESS) { @@ -1073,7 +1170,7 @@ void sbbs_t::forwardmail(smbmsg_t *msg, if((i=smb_addmsghdr(&smb,msg,SMB_SELFPACK))!=SMB_SUCCESS) { - errormsg(WHERE,ERR_WRITE,smb.file,i); + errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); smb_freemsg_dfields(&smb,msg,1); return; } @@ -1082,7 +1179,7 @@ void sbbs_t::forwardmail(smbmsg_t *msg, copyfattach(usernumber,useron.number,msg->subj); bprintf(text[Forwarded],username(&cfg,usernumber,str),usernumber); - sprintf(str,"%s forwarded mail to %s #%d" + SAFEPRINTF3(str,"%s forwarded mail to %s #%d" ,useron.alias ,username(&cfg,usernumber,tmp) ,usernumber); @@ -1108,13 +1205,13 @@ void sbbs_t::forwardmail(smbmsg_t *msg, getnodedat(i,&node,0); if(node.useron==usernumber && !(node.misc&NODE_POFF) && (node.status==NODE_INUSE || node.status==NODE_QUIET)) { - sprintf(str,text[EmailNodeMsg],cfg.node_num,useron.alias); + SAFEPRINTF2(str,text[EmailNodeMsg],cfg.node_num,useron.alias); putnmsg(&cfg,i,str); break; } } if(i>cfg.sys_nodes) { /* User wasn't online, so leave short msg */ - sprintf(str,text[UserSentYouMail],useron.alias); + SAFEPRINTF(str,text[UserSentYouMail],useron.alias); putsmsg(&cfg,usernumber,str); } } @@ -1130,7 +1227,7 @@ void sbbs_t::automsg() int file; time_t now=time(NULL); - sprintf(automsg,"%smsgs/auto.msg",cfg.data_dir); + SAFEPRINTF(automsg,"%smsgs/auto.msg",cfg.data_dir); while(online) { SYNC; mnemonics(text[AutoMsg]); @@ -1166,10 +1263,10 @@ void sbbs_t::automsg() return; } if(anon) - sprintf(tmp,"%.80s",text[Anonymous]); + SAFEPRINTF(tmp,"%.80s",text[Anonymous]); else - sprintf(tmp,"%s #%d",useron.alias,useron.number); - sprintf(str,text[AutoMsgBy],tmp,timestr(&now)); + SAFEPRINTF2(tmp,"%s #%d",useron.alias,useron.number); + SAFEPRINTF2(str,text[AutoMsgBy],tmp,timestr(now)); strcat(str," "); write(file,str,strlen(str)); write(file,buf,strlen(buf)); @@ -1189,7 +1286,7 @@ void sbbs_t::editmsg(smbmsg_t *msg, uint { char buf[SDT_BLOCK_LEN]; char msgtmp[MAX_PATH+1]; - ushort xlat; + uint16_t xlat; int file,i,j,x; long length,offset; FILE *instream; @@ -1200,20 +1297,21 @@ void sbbs_t::editmsg(smbmsg_t *msg, uint msg_tmp_fname(useron.xedit, msgtmp, sizeof(msgtmp)); removecase(msgtmp); msgtotxt(msg,msgtmp,0,1); - editfile(msgtmp); - length=flength(msgtmp); + if(!editfile(msgtmp)) + return; + length=(long)flength(msgtmp); if(length<1L) return; length+=2; /* +2 for translation string */ if((i=smb_locksmbhdr(&smb))!=SMB_SUCCESS) { - errormsg(WHERE,ERR_LOCK,smb.file,i); + errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error); return; } if((i=smb_getstatus(&smb))!=SMB_SUCCESS) { - errormsg(WHERE,ERR_READ,smb.file,i); + errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error); return; } @@ -1277,7 +1375,7 @@ void sbbs_t::editmsg(smbmsg_t *msg, uint smb_unlocksmbhdr(&smb); msg->hdr.length=(ushort)smb_getmsghdrlen(msg); if((i=smb_putmsghdr(&smb,msg))!=SMB_SUCCESS) - errormsg(WHERE,ERR_WRITE,smb.file,i); + errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); } /****************************************************************************/ @@ -1312,7 +1410,7 @@ bool sbbs_t::movemsg(smbmsg_t* msg, uint fseek(smb.sdt_fp,msg->hdr.offset,SEEK_SET); fread(buf,length,1,smb.sdt_fp); - sprintf(newsmb.file,"%s%s",cfg.sub[newsub]->data_dir,cfg.sub[newsub]->code); + SAFEPRINTF2(newsmb.file,"%s%s",cfg.sub[newsub]->data_dir,cfg.sub[newsub]->code); newsmb.retry_time=cfg.smb_retry_time; newsmb.subnum=newsub; if((i=smb_open(&newsmb))!=SMB_SUCCESS) { @@ -1389,7 +1487,7 @@ bool sbbs_t::movemsg(smbmsg_t* msg, uint bprintf("\r\nMoved to %s %s\r\n\r\n" ,cfg.grp[usrgrp[newgrp]]->sname,cfg.sub[newsub]->lname); - sprintf(str,"%s moved message from %s %s to %s %s" + safe_snprintf(str,sizeof(str),"%s moved message from %s %s to %s %s" ,useron.alias ,cfg.grp[newgrp]->sname,cfg.sub[newsub]->sname ,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->sname);