|
|
1.1 ! root 1: /* writemsg.cpp */ ! 2: ! 3: /* Synchronet message creation routines */ ! 4: ! 5: /* $Id: writemsg.cpp,v 1.68 2006/09/15 01:36:33 rswindell Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2006 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: ! 40: #define MAX_LINE_LEN 82L ! 41: ! 42: const char *qstr=" > %.76s\r\n"; ! 43: void quotestr(char *str); ! 44: ! 45: /****************************************************************************/ ! 46: /* Returns temporary message text filename (for message/text editors) */ ! 47: /****************************************************************************/ ! 48: char* sbbs_t::msg_tmp_fname(int xedit, char* fname, size_t len) ! 49: { ! 50: safe_snprintf(fname, len, "%sINPUT.MSG", cfg.temp_dir); ! 51: ! 52: if(xedit) { ! 53: if(cfg.xedit[xedit-1]->misc&QUICKBBS) ! 54: safe_snprintf(fname, len, "%sMSGTMP", cfg.node_dir); /* QuickBBS editors are dumb */ ! 55: if(cfg.xedit[xedit-1]->misc&XTRN_LWRCASE) ! 56: strlwr(fname); ! 57: } ! 58: ! 59: return(fname); ! 60: } ! 61: ! 62: /****************************************************************************/ ! 63: /* Creates a message (post or mail) using standard line editor. 'fname' is */ ! 64: /* is name of file to create, 'top' is a buffer to place at beginning of */ ! 65: /* message and 'title' is the title (70chars max) for the message. */ ! 66: /* 'dest' contains a text description of where the message is going. */ ! 67: /****************************************************************************/ ! 68: bool sbbs_t::writemsg(char *fname, char *top, char *title, long mode, int subnum ! 69: ,char *dest) ! 70: { ! 71: char str[256],quote[128],c,*buf,*p,*tp ! 72: ,useron_level; ! 73: char msgtmp[MAX_PATH+1]; ! 74: char tmp[512]; ! 75: int i,j,file,linesquoted=0; ! 76: long length,qlen=0,qtime=0,ex_mode=0; ! 77: int max_title_len=LEN_TITLE; ! 78: ulong l; ! 79: FILE* stream; ! 80: FILE* fp; ! 81: ! 82: useron_level=useron.level; ! 83: ! 84: if((buf=(char*)malloc(cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)) ! 85: ==NULL) { ! 86: errormsg(WHERE,ERR_ALLOC,fname ! 87: ,cfg.level_linespermsg[useron_level]*MAX_LINE_LEN); ! 88: return(false); ! 89: } ! 90: ! 91: if(mode&WM_NETMAIL || ! 92: (!(mode&(WM_EMAIL|WM_NETMAIL)) && cfg.sub[subnum]->misc&SUB_PNET)) ! 93: mode|=WM_NOTOP; ! 94: ! 95: msg_tmp_fname(useron.xedit, msgtmp, sizeof(msgtmp)); ! 96: ! 97: if(mode&WM_QUOTE && !(useron.rest&FLAG('J')) ! 98: && ((mode&(WM_EMAIL|WM_NETMAIL) && cfg.sys_misc&SM_QUOTE_EM) ! 99: || (!(mode&(WM_EMAIL|WM_NETMAIL)) && (uint)subnum!=INVALID_SUB ! 100: && cfg.sub[subnum]->misc&SUB_QUOTE))) { ! 101: ! 102: /* Quote entire message to MSGTMP or INPUT.MSG */ ! 103: ! 104: if(useron.xedit && cfg.xedit[useron.xedit-1]->misc"EALL) { ! 105: strcpy(tmp,"QUOTES.TXT"); ! 106: if(cfg.xedit[useron.xedit-1]->misc&XTRN_LWRCASE) ! 107: strlwr(tmp); ! 108: sprintf(str,"%s%s",cfg.node_dir,tmp); ! 109: if((stream=fnopen(NULL,str,O_RDONLY))==NULL) { ! 110: errormsg(WHERE,ERR_OPEN,str,O_RDONLY); ! 111: free(buf); ! 112: return(false); ! 113: } ! 114: ! 115: if((file=nopen(msgtmp,O_WRONLY|O_CREAT|O_TRUNC))==-1) { ! 116: errormsg(WHERE,ERR_OPEN,msgtmp,O_WRONLY|O_CREAT|O_TRUNC); ! 117: free(buf); ! 118: fclose(stream); ! 119: return(false); ! 120: } ! 121: ! 122: while(!feof(stream) && !ferror(stream)) { ! 123: if(!fgets(str,255,stream)) ! 124: break; ! 125: quotestr(str); ! 126: sprintf(tmp,qstr,str); ! 127: write(file,tmp,strlen(tmp)); ! 128: linesquoted++; ! 129: } ! 130: fclose(stream); ! 131: close(file); ! 132: } ! 133: ! 134: /* Quote nothing to MSGTMP or INPUT.MSG automatically */ ! 135: ! 136: else if(useron.xedit && cfg.xedit[useron.xedit-1]->misc"ENONE) ! 137: ; ! 138: ! 139: else if(yesno(text[QuoteMessageQ])) { ! 140: strcpy(tmp,"QUOTES.TXT"); ! 141: if(useron.xedit && cfg.xedit[useron.xedit-1]->misc&XTRN_LWRCASE) ! 142: strlwr(tmp); ! 143: sprintf(str,"%s%s",cfg.node_dir,tmp); ! 144: if((stream=fnopen(&file,str,O_RDONLY))==NULL) { ! 145: errormsg(WHERE,ERR_OPEN,str,O_RDONLY); ! 146: free(buf); ! 147: return(false); ! 148: } ! 149: ! 150: if((file=nopen(msgtmp,O_WRONLY|O_CREAT|O_TRUNC))==-1) { ! 151: errormsg(WHERE,ERR_OPEN,msgtmp,O_WRONLY|O_CREAT|O_TRUNC); ! 152: free(buf); ! 153: fclose(stream); ! 154: return(false); ! 155: } ! 156: ! 157: l=ftell(stream); /* l now points to start of message */ ! 158: ! 159: while(online) { ! 160: sprintf(str,text[QuoteLinesPrompt],linesquoted ? "Done":"All"); ! 161: mnemonics(str); ! 162: i=getstr(quote,10,K_UPPER); ! 163: if(sys_status&SS_ABORT) { ! 164: fclose(stream); ! 165: close(file); ! 166: free(buf); ! 167: return(false); ! 168: } ! 169: if(!i && linesquoted) ! 170: break; ! 171: if(!i || quote[0]=='A') { /* Quote all */ ! 172: fseek(stream,l,SEEK_SET); ! 173: while(!feof(stream) && !ferror(stream)) { ! 174: if(!fgets(str,255,stream)) ! 175: break; ! 176: quotestr(str); ! 177: sprintf(tmp,qstr,str); ! 178: write(file,tmp,strlen(tmp)); ! 179: linesquoted++; ! 180: } ! 181: break; ! 182: } ! 183: if(quote[0]=='L') { ! 184: fseek(stream,l,SEEK_SET); ! 185: i=1; ! 186: CRLF; ! 187: attr(LIGHTGRAY); ! 188: while(!feof(stream) && !ferror(stream) && !msgabort()) { ! 189: if(!fgets(str,255,stream)) ! 190: break; ! 191: quotestr(str); ! 192: bprintf("%3d: %.74s\r\n",i,str); ! 193: i++; ! 194: } ! 195: continue; ! 196: } ! 197: ! 198: if(!isdigit(quote[0])) ! 199: break; ! 200: p=quote; ! 201: while(p) { ! 202: if(*p==',' || *p==' ') ! 203: p++; ! 204: i=atoi(p); ! 205: if(!i) ! 206: break; ! 207: fseek(stream,l,SEEK_SET); ! 208: j=1; ! 209: while(!feof(stream) && !ferror(stream) && j<i) { ! 210: if(!fgets(tmp,255,stream)) ! 211: break; ! 212: j++; /* skip beginning */ ! 213: } ! 214: tp=strchr(p,'-'); /* tp for temp pointer */ ! 215: if(tp) { /* range */ ! 216: i=atoi(tp+1); ! 217: while(!feof(stream) && !ferror(stream) && j<=i) { ! 218: if(!fgets(str,255,stream)) ! 219: break; ! 220: quotestr(str); ! 221: sprintf(tmp,qstr,str); ! 222: write(file,tmp,strlen(tmp)); ! 223: linesquoted++; ! 224: j++; ! 225: } ! 226: } ! 227: else { /* one line */ ! 228: if(fgets(str,255,stream)) { ! 229: quotestr(str); ! 230: sprintf(tmp,qstr,str); ! 231: write(file,tmp,strlen(tmp)); ! 232: linesquoted++; ! 233: } ! 234: } ! 235: p=strchr(p,','); ! 236: // if(!p) p=strchr(p,' '); 02/05/96 huh? ! 237: } ! 238: } ! 239: ! 240: fclose(stream); ! 241: close(file); ! 242: } ! 243: } ! 244: else { ! 245: strcpy(tmp,"QUOTES.TXT"); ! 246: if(useron.xedit && cfg.xedit[useron.xedit-1]->misc&XTRN_LWRCASE) ! 247: strlwr(tmp); ! 248: sprintf(str,"%s%s",cfg.node_dir,tmp); ! 249: removecase(str); ! 250: } ! 251: ! 252: if(!online || sys_status&SS_ABORT) { ! 253: free(buf); ! 254: return(false); ! 255: } ! 256: ! 257: if(!(mode&(WM_EXTDESC|WM_SUBJ_RO))) { ! 258: if(mode&WM_FILE) { ! 259: max_title_len=12; /* ToDo: implied 8.3 filename limit! */ ! 260: CRLF; ! 261: bputs(text[Filename]); ! 262: } ! 263: else { ! 264: max_title_len=LEN_TITLE; ! 265: if(mode&WM_QWKNET ! 266: || (subnum!=INVALID_SUB ! 267: && (cfg.sub[subnum]->misc&(SUB_QNET|SUB_INET|SUB_FIDO))==SUB_QNET)) ! 268: max_title_len=25; ! 269: bputs(text[SubjectPrompt]); ! 270: } ! 271: if(!getstr(title,max_title_len,mode&WM_FILE ? K_LINE : K_LINE|K_EDIT|K_AUTODEL) ! 272: && useron_level && useron.logons) { ! 273: free(buf); ! 274: return(false); ! 275: } ! 276: if(!(mode&(WM_EMAIL|WM_NETMAIL)) && cfg.sub[subnum]->misc&SUB_QNET ! 277: && !SYSOP ! 278: && (!stricmp(title,"DROP") || !stricmp(title,"ADD") ! 279: || !strnicmp(dest,"SBBS",4))) { ! 280: free(buf); /* Users can't post DROP or ADD in QWK netted subs */ ! 281: return(false); /* or messages to "SBBS" */ ! 282: } ! 283: } ! 284: ! 285: if(!online || sys_status&SS_ABORT) { ! 286: free(buf); ! 287: return(false); ! 288: } ! 289: ! 290: if(console&CON_RAW_IN) { ! 291: bprintf(text[EnterMsgNowRaw] ! 292: ,(ulong)cfg.level_linespermsg[useron_level]*MAX_LINE_LEN); ! 293: if(top[0] && !(mode&WM_NOTOP)) { ! 294: strcpy((char *)buf,top); ! 295: strcat((char *)buf,crlf); ! 296: l=strlen((char *)buf); ! 297: } ! 298: else ! 299: l=0; ! 300: while(l<(ulong)(cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)) { ! 301: c=getkey(0); ! 302: if(sys_status&SS_ABORT) { /* Ctrl-C */ ! 303: free(buf); ! 304: return(false); ! 305: } ! 306: if((c==ESC || c==CTRL_A) && useron.rest&FLAG('A')) /* ANSI restriction */ ! 307: continue; ! 308: if(c==BEL && useron.rest&FLAG('B')) /* Beep restriction */ ! 309: continue; ! 310: if(!(console&CON_RAW_IN)) /* Ctrl-Z was hit */ ! 311: break; ! 312: outchar(c); ! 313: buf[l++]=c; ! 314: } ! 315: buf[l]=0; ! 316: if(l==(ulong)cfg.level_linespermsg[useron_level]*MAX_LINE_LEN) ! 317: bputs(text[OutOfBytes]); ! 318: } ! 319: ! 320: ! 321: else if(useron.xedit) { ! 322: ! 323: editor_inf(useron.xedit,dest,title,mode,subnum); ! 324: if(cfg.xedit[useron.xedit-1]->type) { ! 325: gettimeleft(); ! 326: xtrndat(useron.alias,cfg.node_dir,cfg.xedit[useron.xedit-1]->type ! 327: ,timeleft,cfg.xedit[useron.xedit-1]->misc); ! 328: } ! 329: ! 330: if(cfg.xedit[useron.xedit-1]->misc&IO_INTS) { ! 331: ex_mode|=(EX_OUTR|EX_INR); ! 332: if(cfg.xedit[useron.xedit-1]->misc&WWIVCOLOR) ! 333: ex_mode|=EX_WWIV; ! 334: } ! 335: if(cfg.xedit[useron.xedit-1]->misc&XTRN_NATIVE) ! 336: ex_mode|=EX_NATIVE; ! 337: if(cfg.xedit[useron.xedit-1]->misc&XTRN_SH) ! 338: ex_mode|=EX_SH; ! 339: ! 340: if(!linesquoted) ! 341: removecase(msgtmp); ! 342: else { ! 343: qlen=flength(msgtmp); ! 344: qtime=fdate(msgtmp); ! 345: } ! 346: ! 347: CLS; ! 348: rioctl(IOCM|PAUSE|ABORT); ! 349: external(cmdstr(cfg.xedit[useron.xedit-1]->rcmd,msgtmp,nulstr,NULL),ex_mode,cfg.node_dir); ! 350: rioctl(IOSM|PAUSE|ABORT); ! 351: ! 352: checkline(); ! 353: if(!fexistcase(msgtmp) || !online ! 354: || (linesquoted && qlen==flength(msgtmp) && qtime==fdate(msgtmp))) { ! 355: free(buf); ! 356: return(false); ! 357: } ! 358: SAFEPRINTF(str,"%sRESULT.ED",cfg.node_dir); ! 359: if(!(mode&(WM_EXTDESC|WM_FILE|WM_SUBJ_RO)) ! 360: && !(cfg.xedit[useron.xedit-1]->misc&QUICKBBS) ! 361: && fexistcase(str)) { ! 362: if((fp=fopen(str,"r")) != NULL) { ! 363: fgets(str,sizeof(str),fp); ! 364: fgets(str,sizeof(str),fp); ! 365: truncsp(str); ! 366: sprintf(title,"%.*s",max_title_len,str); ! 367: fclose(fp); ! 368: } ! 369: } ! 370: ! 371: buf[0]=0; ! 372: if(!(mode&WM_NOTOP)) ! 373: strcpy((char *)buf,top); ! 374: if((file=nopen(msgtmp,O_RDONLY))==-1) { ! 375: errormsg(WHERE,ERR_OPEN,msgtmp,O_RDONLY); ! 376: free(buf); ! 377: return(false); ! 378: } ! 379: length=filelength(file); ! 380: l=strlen((char *)buf); /* reserve space for top and terminating null */ ! 381: /* truncate if too big */ ! 382: if(length>(long)((cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)-(l+1))) { ! 383: length=(cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)-(l+1); ! 384: bputs(text[OutOfBytes]); ! 385: } ! 386: lread(file,buf+l,length); ! 387: close(file); ! 388: // remove(msgtmp); /* no need to save the temp input file */ ! 389: buf[l+length]=0; ! 390: } ! 391: else { ! 392: buf[0]=0; ! 393: if(linesquoted) { ! 394: if((file=nopen(msgtmp,O_RDONLY))!=-1) { ! 395: length=filelength(file); ! 396: l=length>(cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)-1 ! 397: ? (cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)-1 : length; ! 398: lread(file,buf,l); ! 399: buf[l]=0; ! 400: close(file); ! 401: // remove(msgtmp); ! 402: } ! 403: } ! 404: if(!(msgeditor((char *)buf,mode&WM_NOTOP ? nulstr : top,title))) { ! 405: free(buf); /* Assertion here Dec-17-2003, think I fixed in block above (rev 1.52) */ ! 406: return(false); ! 407: } ! 408: } ! 409: ! 410: now=time(NULL); ! 411: bputs(text[Saving]); ! 412: if((stream=fnopen(&file,fname,O_WRONLY|O_CREAT|O_TRUNC))==NULL) { ! 413: errormsg(WHERE,ERR_OPEN,fname,O_WRONLY|O_CREAT|O_TRUNC); ! 414: free(buf); ! 415: return(false); ! 416: } ! 417: for(l=i=0;buf[l] && i<cfg.level_linespermsg[useron_level];l++) { ! 418: if((uchar)buf[l]==141 && useron.xedit ! 419: && cfg.xedit[useron.xedit-1]->misc&QUICKBBS) { ! 420: fwrite(crlf,2,1,stream); ! 421: i++; ! 422: continue; ! 423: } ! 424: /* Expand LF to CRLF? */ ! 425: if(buf[l]==LF && (!l || buf[l-1]!=CR) && useron.xedit ! 426: && cfg.xedit[useron.xedit-1]->misc&EXPANDLF) { ! 427: fwrite(crlf,2,1,stream); ! 428: i++; ! 429: continue; ! 430: } ! 431: /* Strip FidoNet Kludge Lines? */ ! 432: if(buf[l]==1 && useron.xedit ! 433: && cfg.xedit[useron.xedit-1]->misc&STRIPKLUDGE) { ! 434: while(buf[l] && buf[l]!=LF) ! 435: l++; ! 436: if(buf[l]==0) ! 437: break; ! 438: continue; ! 439: } ! 440: if(!(mode&(WM_EMAIL|WM_NETMAIL)) ! 441: && (!l || buf[l-1]==LF) ! 442: && buf[l]=='-' && buf[l+1]=='-' && buf[l+2]=='-' ! 443: && (buf[l+3]==' ' || buf[l+3]==TAB || buf[l+3]==CR)) ! 444: buf[l+1]='+'; ! 445: if(buf[l]==LF) ! 446: i++; ! 447: fputc(buf[l],stream); ! 448: } ! 449: ! 450: if(buf[l]) ! 451: bputs(text[NoMoreLines]); ! 452: ! 453: /* Signature file */ ! 454: if(subnum==INVALID_SUB || !(cfg.sub[subnum]->misc&SUB_NOUSERSIG)) { ! 455: sprintf(str,"%suser/%04u.sig",cfg.data_dir,useron.number); ! 456: FILE* sig; ! 457: if(fexist(str) && (sig=fopen(str,"rb"))!=NULL) { ! 458: while(!feof(sig)) { ! 459: if(!fgets(str,sizeof(str),sig)) ! 460: break; ! 461: fputs(str,stream); ! 462: l+=strlen(str); /* byte counter */ ! 463: i++; /* line counter */ ! 464: } ! 465: fclose(sig); ! 466: } ! 467: } ! 468: ! 469: fclose(stream); ! 470: free((char *)buf); ! 471: bprintf(text[SavedNBytes],l,i); ! 472: return(true); ! 473: } ! 474: ! 475: /****************************************************************************/ ! 476: /* Modify 'str' to for quoted format. Remove ^A codes, etc. */ ! 477: /****************************************************************************/ ! 478: void quotestr(char *str) ! 479: { ! 480: int j; ! 481: ! 482: j=strlen(str); ! 483: while(j && (str[j-1]==' ' || str[j-1]==LF || str[j-1]==CR)) j--; ! 484: str[j]=0; ! 485: remove_ctrl_a(str,NULL); ! 486: } ! 487: ! 488: void sbbs_t::editor_inf(int xeditnum,char *dest, char *title, long mode ! 489: ,uint subnum) ! 490: { ! 491: char str[MAX_PATH+1]; ! 492: char tmp[32]; ! 493: int file; ! 494: ! 495: xeditnum--; ! 496: ! 497: if(cfg.xedit[xeditnum]->misc&QUICKBBS) { ! 498: strcpy(tmp,"MSGINF"); ! 499: if(cfg.xedit[xeditnum]->misc&XTRN_LWRCASE) ! 500: strlwr(tmp); ! 501: sprintf(str,"%s%s",cfg.node_dir,tmp); ! 502: if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) { ! 503: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC); ! 504: return; ! 505: } ! 506: sprintf(str,"%s\r\n%s\r\n%s\r\n%u\r\n%s\r\n%s\r\n" ! 507: ,(subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_NAME) ? useron.name ! 508: : useron.alias ! 509: ,dest,title,1 ! 510: ,mode&WM_NETMAIL ? "NetMail" ! 511: :mode&WM_EMAIL ? "Electronic Mail" ! 512: :subnum==INVALID_SUB ? nulstr ! 513: :cfg.sub[subnum]->sname ! 514: ,mode&WM_PRIVATE ? "YES":"NO"); ! 515: write(file,str,strlen(str)); ! 516: close(file); ! 517: } ! 518: else { ! 519: SAFEPRINTF(str,"%sRESULT.ED",cfg.node_dir); ! 520: removecase(str); ! 521: strcpy(tmp,"EDITOR.INF"); ! 522: if(cfg.xedit[xeditnum]->misc&XTRN_LWRCASE) ! 523: strlwr(tmp); ! 524: sprintf(str,"%s%s",cfg.node_dir,tmp); ! 525: if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) { ! 526: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC); ! 527: return; ! 528: } ! 529: sprintf(str,"%s\r\n%s\r\n%u\r\n%s\r\n%s\r\n%u\r\n" ! 530: ,title,dest,useron.number ! 531: ,(subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_NAME) ? useron.name ! 532: : useron.alias ! 533: ,useron.name,useron.level); ! 534: write(file,str,strlen(str)); ! 535: close(file); ! 536: } ! 537: } ! 538: ! 539: ! 540: ! 541: /****************************************************************************/ ! 542: /* Removes from file 'str' every LF terminated line that starts with 'str2' */ ! 543: /* That is divisable by num. Function skips first 'skip' number of lines */ ! 544: /****************************************************************************/ ! 545: void sbbs_t::removeline(char *str, char *str2, char num, char skip) ! 546: { ! 547: char* buf; ! 548: char slen; ! 549: int i,file; ! 550: long l=0,flen; ! 551: FILE *stream; ! 552: ! 553: if((file=nopen(str,O_RDONLY))==-1) { ! 554: errormsg(WHERE,ERR_OPEN,str,O_RDONLY); ! 555: return; ! 556: } ! 557: flen=filelength(file); ! 558: slen=strlen(str2); ! 559: if((buf=(char *)malloc(flen))==NULL) { ! 560: close(file); ! 561: errormsg(WHERE,ERR_ALLOC,str,flen); ! 562: return; ! 563: } ! 564: if(lread(file,buf,flen)!=flen) { ! 565: close(file); ! 566: errormsg(WHERE,ERR_READ,str,flen); ! 567: free(buf); ! 568: return; ! 569: } ! 570: close(file); ! 571: if((stream=fnopen(&file,str,O_WRONLY|O_TRUNC))==NULL) { ! 572: close(file); ! 573: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_TRUNC); ! 574: free(buf); ! 575: return; ! 576: } ! 577: for(i=0;l<flen && i<skip;l++) { ! 578: fputc(buf[l],stream); ! 579: if(buf[l]==LF) ! 580: i++; ! 581: } ! 582: while(l<flen) { ! 583: if(!strncmp((char *)buf+l,str2,slen)) { ! 584: for(i=0;i<num && l<flen;i++) { ! 585: while(l<flen && buf[l]!=LF) l++; ! 586: l++; ! 587: } ! 588: } ! 589: else { ! 590: for(i=0;i<num && l<flen;i++) { ! 591: while(l<flen && buf[l]!=LF) fputc(buf[l++],stream); ! 592: fputc(buf[l++],stream); ! 593: } ! 594: } ! 595: } ! 596: fclose(stream); ! 597: free((char *)buf); ! 598: } ! 599: ! 600: /*****************************************************************************/ ! 601: /* The Synchronet editor. */ ! 602: /* Returns the number of lines edited. */ ! 603: /*****************************************************************************/ ! 604: ulong sbbs_t::msgeditor(char *buf, char *top, char *title) ! 605: { ! 606: int i,j,line,lines=0,maxlines; ! 607: char strin[256],**str,done=0; ! 608: char tmp[512]; ! 609: char path[MAX_PATH+1]; ! 610: ulong l,m; ! 611: ! 612: rioctl(IOCM|ABORT); ! 613: rioctl(IOCS|ABORT); ! 614: ! 615: maxlines=cfg.level_linespermsg[useron.level]; ! 616: ! 617: if((str=(char **)malloc(sizeof(char *)*(maxlines+1)))==NULL) { ! 618: errormsg(WHERE,ERR_ALLOC,"msgeditor",sizeof(char *)*(maxlines+1)); ! 619: return(0); ! 620: } ! 621: m=strlen(buf); ! 622: l=0; ! 623: while(l<m && lines<maxlines) { ! 624: msgabort(); /* to allow pausing */ ! 625: if((str[lines]=(char *)malloc(MAX_LINE_LEN))==NULL) { ! 626: errormsg(WHERE,ERR_ALLOC,nulstr,MAX_LINE_LEN); ! 627: for(i=0;i<lines;i++) ! 628: free(str[i]); ! 629: free(str); ! 630: rioctl(IOSM|ABORT); ! 631: return(0); ! 632: } ! 633: for(i=0;i<79 && l<m;i++,l++) { ! 634: if(buf[l]==CR) { ! 635: l+=2; ! 636: break; ! 637: } ! 638: if(buf[l]==TAB) { ! 639: if(!(i%8)) /* hard-coded tabstop of 8 */ ! 640: str[lines][i++]=' '; /* for expansion */ ! 641: while(i%8 && i<79) ! 642: str[lines][i++]=' '; ! 643: i--; ! 644: /*** ! 645: bprintf("\r\nMessage editor: Expanded tab on line #%d",lines+1); ! 646: ***/ } ! 647: else str[lines][i]=buf[l]; ! 648: } ! 649: if(i==79) { ! 650: if(buf[l]==CR) ! 651: l+=2; ! 652: else ! 653: bprintf("\r\nMessage editor: Split line #%d",lines+1); ! 654: } ! 655: str[lines][i]=0; ! 656: lines++; ! 657: } ! 658: if(lines) ! 659: bprintf("\r\nMessage editor: Read in %d lines\r\n",lines); ! 660: bprintf(text[EnterMsgNow],maxlines); ! 661: ! 662: sprintf(path,"%smenu/msgtabs.*", cfg.text_dir); ! 663: if(fexist(path)) ! 664: menu("msgtabs"); ! 665: else { ! 666: for(i=0;i<79;i++) { ! 667: if(i%EDIT_TABSIZE || !i) ! 668: outchar('-'); ! 669: else ! 670: outchar('+'); ! 671: } ! 672: CRLF; ! 673: } ! 674: putmsg(top,P_SAVEATR|P_NOATCODES); ! 675: for(line=0;line<lines && !msgabort();line++) { /* display lines in buf */ ! 676: putmsg(str[line],P_SAVEATR|P_NOATCODES); ! 677: cleartoeol(); /* delete to end of line */ ! 678: CRLF; ! 679: } ! 680: SYNC; ! 681: rioctl(IOSM|ABORT); ! 682: while(online && !done) { ! 683: checkline(); ! 684: if(line==lines) { ! 685: if((str[line]=(char *)malloc(MAX_LINE_LEN))==NULL) { ! 686: errormsg(WHERE,ERR_ALLOC,nulstr,MAX_LINE_LEN); ! 687: for(i=0;i<lines;i++) ! 688: free(str[i]); ! 689: free(str); ! 690: return(0); ! 691: } ! 692: str[line][0]=0; ! 693: } ! 694: if(line>(maxlines-10)) { ! 695: if(line==maxlines) ! 696: bputs(text[NoMoreLines]); ! 697: else ! 698: bprintf(text[OnlyNLinesLeft],maxlines-line); ! 699: } ! 700: strcpy(strin,str[line]); ! 701: do { ! 702: if(!line) ! 703: outchar(CR); ! 704: getstr(strin,79,K_WRAP|K_MSG|K_EDIT); ! 705: } while(console&CON_UPARROW && !line); ! 706: ! 707: if(sys_status&SS_ABORT) { ! 708: if(line==lines) ! 709: free(str[line]); ! 710: continue; ! 711: } ! 712: if(strin[0]=='/' && strlen(strin)<8) { ! 713: if(!stricmp(strin,"/DEBUG") && SYSOP) { ! 714: if(line==lines) ! 715: free(str[line]); ! 716: bprintf("\r\nline=%d lines=%d rows=%d\r\n",line,lines,rows); ! 717: continue; ! 718: } ! 719: else if(!stricmp(strin,"/ABT")) { ! 720: if(line==lines) /* delete a line */ ! 721: free(str[line]); ! 722: for(i=0;i<lines;i++) ! 723: free(str[i]); ! 724: free(str); ! 725: return(0); ! 726: } ! 727: else if(toupper(strin[1])=='D') { ! 728: if(line==lines) /* delete a line */ ! 729: free(str[line]); ! 730: if(!lines) ! 731: continue; ! 732: i=atoi(strin+2)-1; ! 733: if(i==-1) /* /D means delete last line */ ! 734: i=lines-1; ! 735: if(i>=lines || i<0) ! 736: bputs(text[InvalidLineNumber]); ! 737: else { ! 738: free(str[i]); ! 739: lines--; ! 740: while(i<lines) { ! 741: str[i]=str[i+1]; ! 742: i++; ! 743: } ! 744: if(line>lines) ! 745: line=lines; ! 746: } ! 747: continue; ! 748: } ! 749: else if(toupper(strin[1])=='I') { ! 750: if(line==lines) /* insert a line before number x */ ! 751: free(str[line]); ! 752: if(line==maxlines || !lines) ! 753: continue; ! 754: i=atoi(strin+2)-1; ! 755: if(i==-1) ! 756: i=lines-1; ! 757: if(i>=lines || i<0) ! 758: bputs(text[InvalidLineNumber]); ! 759: else { ! 760: for(line=lines;line>i;line--) /* move the pointers */ ! 761: str[line]=str[line-1]; ! 762: if((str[i]=(char *)malloc(MAX_LINE_LEN))==NULL) { ! 763: errormsg(WHERE,ERR_ALLOC,nulstr,MAX_LINE_LEN); ! 764: for(i=0;i<lines;i++) ! 765: free(str[i]); ! 766: free(str); ! 767: return(0); ! 768: } ! 769: str[i][0]=0; ! 770: line=++lines; ! 771: } ! 772: continue; ! 773: } ! 774: else if(toupper(strin[1])=='E') { ! 775: if(line==lines) /* edit a line */ ! 776: free(str[line]); ! 777: if(!lines) ! 778: continue; ! 779: i=atoi(strin+2)-1; ! 780: j=K_MSG|K_EDIT; /* use j for the getstr mode */ ! 781: if(i==-1) { /* /E means edit last line */ ! 782: i=lines-1; ! 783: j|=K_WRAP; /* wrap when editing last line */ ! 784: } ! 785: if(i>=lines || i<0) ! 786: bputs(text[InvalidLineNumber]); ! 787: else ! 788: getstr(str[i],79,j); ! 789: continue; ! 790: } ! 791: else if(!stricmp(strin,"/CLR")) { ! 792: bputs(text[MsgCleared]); ! 793: if(line!=lines) ! 794: lines--; ! 795: for(i=0;i<=lines;i++) ! 796: free(str[i]); ! 797: line=0; ! 798: lines=0; ! 799: putmsg(top,P_SAVEATR|P_NOATCODES); ! 800: continue; ! 801: } ! 802: else if(toupper(strin[1])=='L') { /* list message */ ! 803: if(line==lines) ! 804: free(str[line]); ! 805: if(lines) ! 806: i=!noyes(text[WithLineNumbersQ]); ! 807: else ! 808: i=0; ! 809: CRLF; ! 810: attr(LIGHTGRAY); ! 811: putmsg(top,P_SAVEATR|P_NOATCODES); ! 812: if(!lines) { ! 813: continue; ! 814: } ! 815: j=atoi(strin+2); ! 816: if(j) j--; /* start from line j */ ! 817: while(j<lines && !msgabort()) { ! 818: if(i) { /* line numbers */ ! 819: sprintf(tmp,"%3d: %-.74s",j+1,str[j]); ! 820: putmsg(tmp,P_SAVEATR|P_NOATCODES); ! 821: } ! 822: else ! 823: putmsg(str[j],P_SAVEATR|P_NOATCODES); ! 824: cleartoeol(); /* delete to end of line */ ! 825: CRLF; ! 826: j++; ! 827: } ! 828: SYNC; ! 829: continue; ! 830: } ! 831: else if(!stricmp(strin,"/S")) { /* Save */ ! 832: if(line==lines) ! 833: free(str[line]); ! 834: done=1; ! 835: continue;} ! 836: else if(!stricmp(strin,"/T")) { /* Edit title/subject */ ! 837: if(line==lines) ! 838: free(str[line]); ! 839: if(title[0]) { ! 840: bputs(text[SubjectPrompt]); ! 841: getstr(title,LEN_TITLE,K_LINE|K_EDIT|K_AUTODEL); ! 842: SYNC; ! 843: CRLF; ! 844: } ! 845: continue; ! 846: } ! 847: else if(!stricmp(strin,"/?")) { ! 848: if(line==lines) ! 849: free(str[line]); ! 850: menu("editor"); /* User Editor Commands */ ! 851: SYNC; ! 852: continue; ! 853: } ! 854: else if(!stricmp(strin,"/ATTR")) { ! 855: if(line==lines) ! 856: free(str[line]); ! 857: menu("attr"); /* User ANSI Commands */ ! 858: SYNC; ! 859: continue; ! 860: } ! 861: } ! 862: strcpy(str[line],strin); ! 863: if(line<maxlines) ! 864: line++; ! 865: else ! 866: free(str[line]); ! 867: if(line>lines) ! 868: lines++; ! 869: if(console&CON_UPARROW) { ! 870: outchar(CR); ! 871: cursor_up(); ! 872: cleartoeol(); ! 873: line-=2; ! 874: } ! 875: } ! 876: if(!online) { ! 877: for(i=0;i<lines;i++) ! 878: free(str[i]); ! 879: free(str); ! 880: return(0); ! 881: } ! 882: strcpy(buf,top); ! 883: for(i=0;i<lines;i++) { ! 884: strcat(buf,str[i]); ! 885: strcat(buf,crlf); ! 886: free(str[i]); ! 887: } ! 888: free(str); ! 889: return(lines); ! 890: } ! 891: ! 892: ! 893: /****************************************************************************/ ! 894: /* Edits an existing file or creates a new one in MSG format */ ! 895: /****************************************************************************/ ! 896: void sbbs_t::editfile(char *fname) ! 897: { ! 898: char *buf,path[MAX_PATH+1]; ! 899: char msgtmp[MAX_PATH+1]; ! 900: int file; ! 901: long length,maxlines,lines,l,mode=0; ! 902: ! 903: maxlines=cfg.level_linespermsg[useron.level]; ! 904: sprintf(path,"%sQUOTES.TXT",cfg.node_dir); ! 905: removecase(path); ! 906: ! 907: if(useron.xedit) { ! 908: ! 909: SAFECOPY(path,fname); ! 910: ! 911: msg_tmp_fname(useron.xedit, msgtmp, sizeof(msgtmp)); ! 912: if(stricmp(msgtmp,path)) { ! 913: removecase(msgtmp); ! 914: if(fexistcase(path)) ! 915: fcopy(path, msgtmp); ! 916: } ! 917: ! 918: editor_inf(useron.xedit,fname,nulstr,0,INVALID_SUB); ! 919: if(cfg.xedit[useron.xedit-1]->misc&XTRN_NATIVE) ! 920: mode|=EX_NATIVE; ! 921: if(cfg.xedit[useron.xedit-1]->misc&XTRN_SH) ! 922: mode|=EX_SH; ! 923: if(cfg.xedit[useron.xedit-1]->misc&IO_INTS) { ! 924: mode|=(EX_OUTR|EX_INR); ! 925: if(cfg.xedit[useron.xedit-1]->misc&WWIVCOLOR) ! 926: mode|=EX_WWIV; ! 927: } ! 928: CLS; ! 929: rioctl(IOCM|PAUSE|ABORT); ! 930: external(cmdstr(cfg.xedit[useron.xedit-1]->rcmd,msgtmp,nulstr,NULL),mode,cfg.node_dir); ! 931: if(stricmp(msgtmp,path) && !fcompare(msgtmp, path)) /* file changed */ ! 932: fcopy(msgtmp, path); ! 933: rioctl(IOSM|PAUSE|ABORT); ! 934: return; ! 935: } ! 936: if((buf=(char *)malloc(maxlines*MAX_LINE_LEN))==NULL) { ! 937: errormsg(WHERE,ERR_ALLOC,nulstr,maxlines*MAX_LINE_LEN); ! 938: return; ! 939: } ! 940: if((file=nopen(fname,O_RDONLY))!=-1) { ! 941: length=filelength(file); ! 942: if(length>(long)maxlines*MAX_LINE_LEN) { ! 943: close(file); ! 944: free(buf); ! 945: attr(cfg.color[clr_err]); ! 946: bprintf("\7\r\nFile size (%lu bytes) is larger than %lu (maxlines: %lu).\r\n" ! 947: ,length, (ulong)maxlines*MAX_LINE_LEN, maxlines); ! 948: return; ! 949: } ! 950: if(read(file,buf,length)!=length) { ! 951: close(file); ! 952: free(buf); ! 953: errormsg(WHERE,ERR_READ,fname,length); ! 954: return; ! 955: } ! 956: buf[length]=0; ! 957: close(file); ! 958: } ! 959: else { ! 960: buf[0]=0; ! 961: bputs(text[NewFile]); ! 962: } ! 963: if(!msgeditor(buf,nulstr,nulstr)) { ! 964: free(buf); ! 965: return; ! 966: } ! 967: bputs(text[Saving]); ! 968: if((file=nopen(fname,O_CREAT|O_WRONLY|O_TRUNC))==-1) { ! 969: errormsg(WHERE,ERR_OPEN,fname,O_CREAT|O_WRONLY|O_TRUNC); ! 970: free(buf); ! 971: return; ! 972: } ! 973: if((size_t)write(file,buf,strlen(buf))!=strlen(buf)) { ! 974: close(file); ! 975: errormsg(WHERE,ERR_WRITE,fname,strlen(buf)); ! 976: free(buf); ! 977: return; ! 978: } ! 979: for(l=lines=0;buf[l];l++) ! 980: if(buf[l]==LF) ! 981: lines++; ! 982: bprintf(text[SavedNBytes],l,lines); ! 983: close(file); ! 984: free(buf); ! 985: return; ! 986: } ! 987: ! 988: /*************************/ ! 989: /* Copy file attachments */ ! 990: /*************************/ ! 991: void sbbs_t::copyfattach(uint to, uint from, char *title) ! 992: { ! 993: char str[128],str2[128],str3[128],*tp,*sp,*p; ! 994: ! 995: strcpy(str,title); ! 996: tp=str; ! 997: while(1) { ! 998: p=strchr(tp,' '); ! 999: if(p) *p=0; ! 1000: sp=strrchr(tp,'/'); /* sp is slash pointer */ ! 1001: if(!sp) sp=strrchr(tp,'\\'); ! 1002: if(sp) tp=sp+1; ! 1003: sprintf(str2,"%sfile/%04u.in/%s" /* str2 is path/fname */ ! 1004: ,cfg.data_dir,to,tp); ! 1005: sprintf(str3,"%sfile/%04u.in/%s" /* str2 is path/fname */ ! 1006: ,cfg.data_dir,from,tp); ! 1007: if(strcmp(str2,str3)) ! 1008: mv(str3,str2,1); ! 1009: if(!p) ! 1010: break; ! 1011: tp=p+1; ! 1012: } ! 1013: } ! 1014: ! 1015: ! 1016: /****************************************************************************/ ! 1017: /* Forwards mail (fname) to usernumber */ ! 1018: /* Called from function readmail */ ! 1019: /****************************************************************************/ ! 1020: void sbbs_t::forwardmail(smbmsg_t *msg, int usernumber) ! 1021: { ! 1022: char str[256],touser[128]; ! 1023: char tmp[512]; ! 1024: int i; ! 1025: node_t node; ! 1026: msghdr_t hdr=msg->hdr; ! 1027: idxrec_t idx=msg->idx; ! 1028: ! 1029: if(useron.etoday>=cfg.level_emailperday[useron.level] && !SYSOP) { ! 1030: bputs(text[TooManyEmailsToday]); ! 1031: return; ! 1032: } ! 1033: if(useron.rest&FLAG('F')) { ! 1034: bputs(text[R_Forward]); ! 1035: return; ! 1036: } ! 1037: if(usernumber==1 && useron.rest&FLAG('S')) { ! 1038: bprintf(text[R_Feedback],cfg.sys_op); ! 1039: return; ! 1040: } ! 1041: if(usernumber!=1 && useron.rest&FLAG('E')) { ! 1042: bputs(text[R_Email]); ! 1043: return; ! 1044: } ! 1045: ! 1046: msg->idx.attr&=~(MSG_READ|MSG_DELETE); ! 1047: msg->hdr.attr=msg->idx.attr; ! 1048: ! 1049: ! 1050: smb_hfield_str(msg,SENDER,useron.alias); ! 1051: sprintf(str,"%u",useron.number); ! 1052: smb_hfield_str(msg,SENDEREXT,str); ! 1053: ! 1054: username(&cfg,usernumber,touser); ! 1055: smb_hfield_str(msg,RECIPIENT,touser); ! 1056: sprintf(str,"%u",usernumber); ! 1057: smb_hfield(msg,RECIPIENTEXT,sizeof(str),str); ! 1058: msg->idx.to=usernumber; ! 1059: ! 1060: now=time(NULL); ! 1061: smb_hfield(msg,FORWARDED,sizeof(time_t),&now); ! 1062: ! 1063: ! 1064: if((i=smb_open_da(&smb))!=SMB_SUCCESS) { ! 1065: errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); ! 1066: return; ! 1067: } ! 1068: if((i=smb_incmsg_dfields(&smb,msg,1))!=SMB_SUCCESS) { ! 1069: errormsg(WHERE,ERR_WRITE,smb.file,i); ! 1070: return; ! 1071: } ! 1072: smb_close_da(&smb); ! 1073: ! 1074: ! 1075: if((i=smb_addmsghdr(&smb,msg,SMB_SELFPACK))!=SMB_SUCCESS) { ! 1076: errormsg(WHERE,ERR_WRITE,smb.file,i); ! 1077: smb_freemsg_dfields(&smb,msg,1); ! 1078: return; ! 1079: } ! 1080: ! 1081: if(msg->hdr.auxattr&MSG_FILEATTACH) ! 1082: copyfattach(usernumber,useron.number,msg->subj); ! 1083: ! 1084: bprintf(text[Forwarded],username(&cfg,usernumber,str),usernumber); ! 1085: sprintf(str,"%s forwarded mail to %s #%d" ! 1086: ,useron.alias ! 1087: ,username(&cfg,usernumber,tmp) ! 1088: ,usernumber); ! 1089: logline("E",str); ! 1090: msg->idx=idx; ! 1091: msg->hdr=hdr; ! 1092: ! 1093: ! 1094: if(usernumber==1) { ! 1095: useron.fbacks++; ! 1096: logon_fbacks++; ! 1097: putuserrec(&cfg,useron.number,U_FBACKS,5,ultoa(useron.fbacks,tmp,10)); ! 1098: } ! 1099: else { ! 1100: useron.emails++; ! 1101: logon_emails++; ! 1102: putuserrec(&cfg,useron.number,U_EMAILS,5,ultoa(useron.emails,tmp,10)); ! 1103: } ! 1104: useron.etoday++; ! 1105: putuserrec(&cfg,useron.number,U_ETODAY,5,ultoa(useron.etoday,tmp,10)); ! 1106: ! 1107: for(i=1;i<=cfg.sys_nodes;i++) { /* Tell user, if online */ ! 1108: getnodedat(i,&node,0); ! 1109: if(node.useron==usernumber && !(node.misc&NODE_POFF) ! 1110: && (node.status==NODE_INUSE || node.status==NODE_QUIET)) { ! 1111: sprintf(str,text[EmailNodeMsg],cfg.node_num,useron.alias); ! 1112: putnmsg(&cfg,i,str); ! 1113: break; ! 1114: } ! 1115: } ! 1116: if(i>cfg.sys_nodes) { /* User wasn't online, so leave short msg */ ! 1117: sprintf(str,text[UserSentYouMail],useron.alias); ! 1118: putsmsg(&cfg,usernumber,str); ! 1119: } ! 1120: } ! 1121: ! 1122: /****************************************************************************/ ! 1123: /* Auto-Message Routine ('A' from the main menu) */ ! 1124: /****************************************************************************/ ! 1125: void sbbs_t::automsg() ! 1126: { ! 1127: char str[256],buf[300],anon=0; ! 1128: char tmp[512]; ! 1129: char automsg[MAX_PATH+1]; ! 1130: int file; ! 1131: time_t now=time(NULL); ! 1132: ! 1133: sprintf(automsg,"%smsgs/auto.msg",cfg.data_dir); ! 1134: while(online) { ! 1135: SYNC; ! 1136: mnemonics(text[AutoMsg]); ! 1137: switch(getkeys("RWQ",0)) { ! 1138: case 'R': ! 1139: printfile(automsg,P_NOABORT|P_NOATCODES); ! 1140: break; ! 1141: case 'W': ! 1142: if(useron.rest&FLAG('W')) { ! 1143: bputs(text[R_AutoMsg]); ! 1144: break; ! 1145: } ! 1146: action=NODE_AMSG; ! 1147: SYNC; ! 1148: bputs("\r\n3 lines:\r\n"); ! 1149: if(!getstr(str,68,K_WRAP|K_MSG)) ! 1150: break; ! 1151: strcpy(buf,str); ! 1152: strcat(buf,"\r\n "); ! 1153: getstr(str,68,K_WRAP|K_MSG); ! 1154: strcat(buf,str); ! 1155: strcat(buf,"\r\n "); ! 1156: getstr(str,68,K_MSG); ! 1157: strcat(str,crlf); ! 1158: strcat(buf,str); ! 1159: if(yesno(text[OK])) { ! 1160: if(useron.exempt&FLAG('A')) { ! 1161: if(!noyes(text[AnonymousQ])) ! 1162: anon=1; ! 1163: } ! 1164: if((file=nopen(automsg,O_WRONLY|O_CREAT|O_TRUNC))==-1) { ! 1165: errormsg(WHERE,ERR_OPEN,automsg,O_WRONLY|O_CREAT|O_TRUNC); ! 1166: return; ! 1167: } ! 1168: if(anon) ! 1169: sprintf(tmp,"%.80s",text[Anonymous]); ! 1170: else ! 1171: sprintf(tmp,"%s #%d",useron.alias,useron.number); ! 1172: sprintf(str,text[AutoMsgBy],tmp,timestr(&now)); ! 1173: strcat(str," "); ! 1174: write(file,str,strlen(str)); ! 1175: write(file,buf,strlen(buf)); ! 1176: close(file); ! 1177: } ! 1178: break; ! 1179: case 'Q': ! 1180: return; ! 1181: } ! 1182: } ! 1183: } ! 1184: ! 1185: /****************************************************************************/ ! 1186: /* Edits messages */ ! 1187: /****************************************************************************/ ! 1188: void sbbs_t::editmsg(smbmsg_t *msg, uint subnum) ! 1189: { ! 1190: char buf[SDT_BLOCK_LEN]; ! 1191: char msgtmp[MAX_PATH+1]; ! 1192: ushort xlat; ! 1193: int file,i,j,x; ! 1194: long length,offset; ! 1195: FILE *instream; ! 1196: ! 1197: if(!msg->hdr.total_dfields) ! 1198: return; ! 1199: ! 1200: msg_tmp_fname(useron.xedit, msgtmp, sizeof(msgtmp)); ! 1201: removecase(msgtmp); ! 1202: msgtotxt(msg,msgtmp,0,1); ! 1203: editfile(msgtmp); ! 1204: length=flength(msgtmp); ! 1205: if(length<1L) ! 1206: return; ! 1207: ! 1208: length+=2; /* +2 for translation string */ ! 1209: ! 1210: if((i=smb_locksmbhdr(&smb))!=SMB_SUCCESS) { ! 1211: errormsg(WHERE,ERR_LOCK,smb.file,i); ! 1212: return; ! 1213: } ! 1214: ! 1215: if((i=smb_getstatus(&smb))!=SMB_SUCCESS) { ! 1216: errormsg(WHERE,ERR_READ,smb.file,i); ! 1217: return; ! 1218: } ! 1219: ! 1220: if(!(smb.status.attr&SMB_HYPERALLOC)) { ! 1221: if((i=smb_open_da(&smb))!=SMB_SUCCESS) { ! 1222: errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); ! 1223: return; ! 1224: } ! 1225: if((i=smb_freemsg_dfields(&smb,msg,1))!=SMB_SUCCESS) ! 1226: errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); ! 1227: } ! 1228: ! 1229: msg->dfield[0].type=TEXT_BODY; /* Make one single data field */ ! 1230: msg->dfield[0].length=length; ! 1231: msg->dfield[0].offset=0; ! 1232: for(x=1;x<msg->hdr.total_dfields;x++) { /* Clear the other data fields */ ! 1233: msg->dfield[x].type=UNUSED; /* so we leave the header length */ ! 1234: msg->dfield[x].length=0; /* unchanged */ ! 1235: msg->dfield[x].offset=0; ! 1236: } ! 1237: ! 1238: ! 1239: if(smb.status.attr&SMB_HYPERALLOC) ! 1240: offset=smb_hallocdat(&smb); ! 1241: else { ! 1242: if((subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_FAST) ! 1243: || (subnum==INVALID_SUB && cfg.sys_misc&SM_FASTMAIL)) ! 1244: offset=smb_fallocdat(&smb,length,1); ! 1245: else ! 1246: offset=smb_allocdat(&smb,length,1); ! 1247: smb_close_da(&smb); ! 1248: } ! 1249: ! 1250: msg->hdr.offset=offset; ! 1251: if((file=open(msgtmp,O_RDONLY|O_BINARY))==-1 ! 1252: || (instream=fdopen(file,"rb"))==NULL) { ! 1253: smb_unlocksmbhdr(&smb); ! 1254: smb_freemsgdat(&smb,offset,length,1); ! 1255: errormsg(WHERE,ERR_OPEN,msgtmp,O_RDONLY|O_BINARY); ! 1256: return; ! 1257: } ! 1258: ! 1259: setvbuf(instream,NULL,_IOFBF,2*1024); ! 1260: fseek(smb.sdt_fp,offset,SEEK_SET); ! 1261: xlat=XLAT_NONE; ! 1262: fwrite(&xlat,2,1,smb.sdt_fp); ! 1263: x=SDT_BLOCK_LEN-2; /* Don't read/write more than 255 */ ! 1264: while(!feof(instream)) { ! 1265: memset(buf,0,x); ! 1266: j=fread(buf,1,x,instream); ! 1267: if(j<1) ! 1268: break; ! 1269: if(j>1 && (j!=x || feof(instream)) && buf[j-1]==LF && buf[j-2]==CR) ! 1270: buf[j-1]=buf[j-2]=0; /* Convert to NULL */ ! 1271: fwrite(buf,j,1,smb.sdt_fp); ! 1272: x=SDT_BLOCK_LEN; ! 1273: } ! 1274: fflush(smb.sdt_fp); ! 1275: fclose(instream); ! 1276: ! 1277: smb_unlocksmbhdr(&smb); ! 1278: msg->hdr.length=(ushort)smb_getmsghdrlen(msg); ! 1279: if((i=smb_putmsghdr(&smb,msg))!=SMB_SUCCESS) ! 1280: errormsg(WHERE,ERR_WRITE,smb.file,i); ! 1281: } ! 1282: ! 1283: /****************************************************************************/ ! 1284: /* Moves a message from one message base to another */ ! 1285: /****************************************************************************/ ! 1286: bool sbbs_t::movemsg(smbmsg_t* msg, uint subnum) ! 1287: { ! 1288: char str[256],*buf; ! 1289: uint i; ! 1290: int newgrp,newsub,storage; ! 1291: ulong offset,length; ! 1292: smbmsg_t newmsg=*msg; ! 1293: smb_t newsmb; ! 1294: ! 1295: for(i=0;i<usrgrps;i++) /* Select New Group */ ! 1296: uselect(1,i,"Message Group",cfg.grp[usrgrp[i]]->lname,0); ! 1297: if((newgrp=uselect(0,0,0,0,0))<0) ! 1298: return(false); ! 1299: ! 1300: for(i=0;i<usrsubs[newgrp];i++) /* Select New Sub-Board */ ! 1301: uselect(1,i,"Sub-Board",cfg.sub[usrsub[newgrp][i]]->lname,0); ! 1302: if((newsub=uselect(0,0,0,0,0))<0) ! 1303: return(false); ! 1304: newsub=usrsub[newgrp][newsub]; ! 1305: ! 1306: length=smb_getmsgdatlen(msg); ! 1307: if((buf=(char *)malloc(length))==NULL) { ! 1308: errormsg(WHERE,ERR_ALLOC,smb.file,length); ! 1309: return(false); ! 1310: } ! 1311: ! 1312: fseek(smb.sdt_fp,msg->hdr.offset,SEEK_SET); ! 1313: fread(buf,length,1,smb.sdt_fp); ! 1314: ! 1315: sprintf(newsmb.file,"%s%s",cfg.sub[newsub]->data_dir,cfg.sub[newsub]->code); ! 1316: newsmb.retry_time=cfg.smb_retry_time; ! 1317: newsmb.subnum=newsub; ! 1318: if((i=smb_open(&newsmb))!=SMB_SUCCESS) { ! 1319: free(buf); ! 1320: errormsg(WHERE,ERR_OPEN,newsmb.file,i,newsmb.last_error); ! 1321: return(false); ! 1322: } ! 1323: ! 1324: if(filelength(fileno(newsmb.shd_fp))<1) { /* Create it if it doesn't exist */ ! 1325: newsmb.status.max_crcs=cfg.sub[newsub]->maxcrcs; ! 1326: newsmb.status.max_msgs=cfg.sub[newsub]->maxmsgs; ! 1327: newsmb.status.max_age=cfg.sub[newsub]->maxage; ! 1328: newsmb.status.attr=cfg.sub[newsub]->misc&SUB_HYPER ? SMB_HYPERALLOC :0; ! 1329: if((i=smb_create(&newsmb))!=SMB_SUCCESS) { ! 1330: free(buf); ! 1331: smb_close(&newsmb); ! 1332: errormsg(WHERE,ERR_CREATE,newsmb.file,i,newsmb.last_error); ! 1333: return(false); ! 1334: } ! 1335: } ! 1336: ! 1337: if((i=smb_locksmbhdr(&newsmb))!=SMB_SUCCESS) { ! 1338: free(buf); ! 1339: smb_close(&newsmb); ! 1340: errormsg(WHERE,ERR_LOCK,newsmb.file,i,newsmb.last_error); ! 1341: return(false); ! 1342: } ! 1343: ! 1344: if((i=smb_getstatus(&newsmb))!=SMB_SUCCESS) { ! 1345: free(buf); ! 1346: smb_close(&newsmb); ! 1347: errormsg(WHERE,ERR_READ,newsmb.file,i,newsmb.last_error); ! 1348: return(false); ! 1349: } ! 1350: ! 1351: if(newsmb.status.attr&SMB_HYPERALLOC) { ! 1352: offset=smb_hallocdat(&newsmb); ! 1353: storage=SMB_HYPERALLOC; ! 1354: } ! 1355: else { ! 1356: if((i=smb_open_da(&newsmb))!=SMB_SUCCESS) { ! 1357: free(buf); ! 1358: smb_close(&newsmb); ! 1359: errormsg(WHERE,ERR_OPEN,newsmb.file,i,newsmb.last_error); ! 1360: return(false); ! 1361: } ! 1362: if(cfg.sub[newsub]->misc&SUB_FAST) { ! 1363: offset=smb_fallocdat(&newsmb,length,1); ! 1364: storage=SMB_FASTALLOC; ! 1365: } ! 1366: else { ! 1367: offset=smb_allocdat(&newsmb,length,1); ! 1368: storage=SMB_SELFPACK; ! 1369: } ! 1370: smb_close_da(&newsmb); ! 1371: } ! 1372: ! 1373: newmsg.hdr.offset=offset; ! 1374: newmsg.hdr.version=smb_ver(); ! 1375: ! 1376: fseek(newsmb.sdt_fp,offset,SEEK_SET); ! 1377: fwrite(buf,length,1,newsmb.sdt_fp); ! 1378: fflush(newsmb.sdt_fp); ! 1379: free(buf); ! 1380: ! 1381: i=smb_addmsghdr(&newsmb,&newmsg,storage); // calls smb_unlocksmbhdr() ! 1382: smb_close(&newsmb); ! 1383: ! 1384: if(i) { ! 1385: errormsg(WHERE,ERR_WRITE,newsmb.file,i,newsmb.last_error); ! 1386: smb_freemsg_dfields(&newsmb,&newmsg,1); ! 1387: return(false); ! 1388: } ! 1389: ! 1390: bprintf("\r\nMoved to %s %s\r\n\r\n" ! 1391: ,cfg.grp[usrgrp[newgrp]]->sname,cfg.sub[newsub]->lname); ! 1392: sprintf(str,"%s moved message from %s %s to %s %s" ! 1393: ,useron.alias ! 1394: ,cfg.grp[newgrp]->sname,cfg.sub[newsub]->sname ! 1395: ,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->sname); ! 1396: logline("M+",str); ! 1397: signal_sub_sem(&cfg,newsub); ! 1398: ! 1399: return(true); ! 1400: } ! 1401: ! 1402: ushort sbbs_t::chmsgattr(ushort attr) ! 1403: { ! 1404: int ch; ! 1405: ! 1406: while(online && !(sys_status&SS_ABORT)) { ! 1407: CRLF; ! 1408: show_msgattr(attr); ! 1409: menu("msgattr"); ! 1410: ch=getkey(K_UPPER); ! 1411: if(ch) ! 1412: bprintf("%c\r\n",ch); ! 1413: switch(ch) { ! 1414: case 'P': ! 1415: attr^=MSG_PRIVATE; ! 1416: break; ! 1417: case 'R': ! 1418: attr^=MSG_READ; ! 1419: break; ! 1420: case 'K': ! 1421: attr^=MSG_KILLREAD; ! 1422: break; ! 1423: case 'A': ! 1424: attr^=MSG_ANONYMOUS; ! 1425: break; ! 1426: case 'N': /* Non-purgeable */ ! 1427: attr^=MSG_PERMANENT; ! 1428: break; ! 1429: case 'M': ! 1430: attr^=MSG_MODERATED; ! 1431: break; ! 1432: case 'V': ! 1433: attr^=MSG_VALIDATED; ! 1434: break; ! 1435: case 'D': ! 1436: attr^=MSG_DELETE; ! 1437: break; ! 1438: case 'L': ! 1439: attr^=MSG_LOCKED; ! 1440: break; ! 1441: default: ! 1442: return(attr); ! 1443: } ! 1444: } ! 1445: return(attr); ! 1446: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.