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