|
|
1.1 ! root 1: /* postmsg.cpp */ ! 2: ! 3: /* Synchronet user create/post public message routine */ ! 4: ! 5: /* $Id: postmsg.cpp,v 1.3 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: /****************************************************************************/ ! 41: /* Posts a message on subboard number sub, with 'top' as top of message. */ ! 42: /* Returns 1 if posted, 0 if not. */ ! 43: /****************************************************************************/ ! 44: bool sbbs_t::postmsg(uint subnum, smbmsg_t *remsg, long wm_mode) ! 45: { ! 46: char str[256],touser[256],title[LEN_TITLE+1],buf[SDT_BLOCK_LEN] ! 47: ,top[256]; ! 48: ushort xlat,msgattr; ! 49: int i,j,x,file,storage; ! 50: ulong l,length,offset,crc=0xffffffff; ! 51: FILE *instream; ! 52: smbmsg_t msg,tmpmsg; ! 53: ! 54: if(remsg) { ! 55: sprintf(title,"%.*s",LEN_TITLE,remsg->subj); ! 56: if(cfg.sub[subnum]->misc&SUB_INET) // All Internet posts to "All" 05/20/97 ! 57: touser[0]=0; ! 58: else if(remsg->hdr.attr&MSG_ANONYMOUS) ! 59: strcpy(touser,text[Anonymous]); ! 60: else ! 61: strcpy(touser,remsg->from); ! 62: msgattr=(ushort)(remsg->hdr.attr&MSG_PRIVATE); ! 63: sprintf(top,text[RegardingByToOn],title,touser,remsg->to ! 64: ,timestr((time_t *)&remsg->hdr.when_written.time) ! 65: ,zonestr(remsg->hdr.when_written.zone)); } ! 66: else { ! 67: title[0]=0; ! 68: touser[0]=0; ! 69: top[0]=0; ! 70: msgattr=0; } ! 71: ! 72: if(useron.rest&FLAG('P')) { ! 73: bputs(text[R_Post]); ! 74: return(false); } ! 75: ! 76: if((cfg.sub[subnum]->misc&(SUB_QNET|SUB_FIDO|SUB_PNET|SUB_INET)) ! 77: && (useron.rest&FLAG('N'))) { ! 78: bputs(text[CantPostOnSub]); ! 79: return(false); } ! 80: ! 81: if(useron.ptoday>=cfg.level_postsperday[useron.level]) { ! 82: bputs(text[TooManyPostsToday]); ! 83: return(false); } ! 84: ! 85: bprintf(text[Posting],cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname); ! 86: action=NODE_PMSG; ! 87: nodesync(); ! 88: ! 89: if(!(msgattr&MSG_PRIVATE) && (cfg.sub[subnum]->misc&SUB_PONLY ! 90: || (cfg.sub[subnum]->misc&SUB_PRIV && !noyes(text[PrivatePostQ])))) ! 91: msgattr|=MSG_PRIVATE; ! 92: ! 93: if(sys_status&SS_ABORT) ! 94: return(false); ! 95: ! 96: if(!(cfg.sub[subnum]->misc&SUB_INET) // Prompt for TO: user ! 97: && (cfg.sub[subnum]->misc&SUB_TOUSER || msgattr&MSG_PRIVATE || touser[0])) { ! 98: if(!touser[0] && !(msgattr&MSG_PRIVATE)) ! 99: strcpy(touser,"All"); ! 100: bputs(text[PostTo]); ! 101: i=LEN_ALIAS; ! 102: if(cfg.sub[subnum]->misc&(SUB_PNET|SUB_INET)) ! 103: i=60; ! 104: if(cfg.sub[subnum]->misc&SUB_FIDO) ! 105: i=35; ! 106: if(cfg.sub[subnum]->misc&SUB_QNET) ! 107: i=25; ! 108: getstr(touser,i,K_UPRLWR|K_LINE|K_EDIT|K_AUTODEL); ! 109: if(stricmp(touser,"ALL") ! 110: && !(cfg.sub[subnum]->misc&(SUB_PNET|SUB_FIDO|SUB_QNET|SUB_INET|SUB_ANON))) { ! 111: if(cfg.sub[subnum]->misc&SUB_NAME) { ! 112: if(!userdatdupe(useron.number,U_NAME,LEN_NAME,touser,0)) { ! 113: bputs(text[UnknownUser]); ! 114: return(false); } } ! 115: else { ! 116: if((i=finduser(touser))==0) ! 117: return(false); ! 118: username(&cfg,i,touser); } } ! 119: if(sys_status&SS_ABORT) ! 120: return(false); } ! 121: ! 122: if(!touser[0]) ! 123: strcpy(touser,"All"); // Default to ALL ! 124: ! 125: if(!stricmp(touser,"SYSOP") && !SYSOP) // Change SYSOP to user #1 ! 126: username(&cfg,1,touser); ! 127: ! 128: if(msgattr&MSG_PRIVATE && !stricmp(touser,"ALL")) { ! 129: bputs(text[NoToUser]); ! 130: return(false); } ! 131: if(msgattr&MSG_PRIVATE) ! 132: wm_mode|=WM_PRIVATE; ! 133: ! 134: if(cfg.sub[subnum]->misc&SUB_AONLY ! 135: || (cfg.sub[subnum]->misc&SUB_ANON && useron.exempt&FLAG('A') ! 136: && !noyes(text[AnonymousQ]))) ! 137: msgattr|=MSG_ANONYMOUS; ! 138: ! 139: if(cfg.sub[subnum]->mod_ar[0] && chk_ar(cfg.sub[subnum]->mod_ar,&useron)) ! 140: msgattr|=MSG_MODERATED; ! 141: ! 142: if(cfg.sub[subnum]->misc&SUB_SYSPERM && sub_op(subnum)) ! 143: msgattr|=MSG_PERMANENT; ! 144: ! 145: if(msgattr&MSG_PRIVATE) ! 146: bputs(text[PostingPrivately]); ! 147: ! 148: if(msgattr&MSG_ANONYMOUS) ! 149: bputs(text[PostingAnonymously]); ! 150: ! 151: if(cfg.sub[subnum]->misc&SUB_NAME) ! 152: bputs(text[UsingRealName]); ! 153: ! 154: sprintf(str,"%sINPUT.MSG",cfg.node_dir); ! 155: if(!writemsg(str,top,title,wm_mode,subnum,touser)) { ! 156: bputs(text[Aborted]); ! 157: return(false); } ! 158: ! 159: bputs(text[WritingIndx]); ! 160: ! 161: if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) { ! 162: errormsg(WHERE,ERR_OPEN,cfg.sub[subnum]->code,i); ! 163: return(false); } ! 164: ! 165: sprintf(smb.file,"%s%s",cfg.sub[subnum]->data_dir,cfg.sub[subnum]->code); ! 166: smb.retry_time=cfg.smb_retry_time; ! 167: if((i=smb_open(&smb))!=0) { ! 168: smb_stack(&smb,SMB_STACK_POP); ! 169: errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); ! 170: return(false); } ! 171: ! 172: if(filelength(fileno(smb.shd_fp))<1) { /* Create it if it doesn't exist */ ! 173: smb.status.max_crcs=cfg.sub[subnum]->maxcrcs; ! 174: smb.status.max_msgs=cfg.sub[subnum]->maxmsgs; ! 175: smb.status.max_age=cfg.sub[subnum]->maxage; ! 176: smb.status.attr=cfg.sub[subnum]->misc&SUB_HYPER ? SMB_HYPERALLOC : 0; ! 177: if((i=smb_create(&smb))!=0) { ! 178: smb_close(&smb); ! 179: smb_stack(&smb,SMB_STACK_POP); ! 180: errormsg(WHERE,ERR_CREATE,smb.file,i,smb.last_error); ! 181: return(false); } } ! 182: ! 183: if((i=smb_locksmbhdr(&smb))!=0) { ! 184: smb_close(&smb); ! 185: smb_stack(&smb,SMB_STACK_POP); ! 186: errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error); ! 187: return(false); } ! 188: ! 189: if((i=smb_getstatus(&smb))!=0) { ! 190: smb_close(&smb); ! 191: smb_stack(&smb,SMB_STACK_POP); ! 192: errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error); ! 193: return(false); } ! 194: ! 195: length=flength(str)+2; /* +2 for translation string */ ! 196: ! 197: if(length&0xfff00000UL) { ! 198: smb_close(&smb); ! 199: smb_stack(&smb,SMB_STACK_POP); ! 200: errormsg(WHERE,ERR_LEN,str,length); ! 201: return(false); } ! 202: ! 203: if(smb.status.attr&SMB_HYPERALLOC) { ! 204: offset=smb_hallocdat(&smb); ! 205: storage=SMB_HYPERALLOC; } ! 206: else { ! 207: if((i=smb_open_da(&smb))!=0) { ! 208: smb_unlocksmbhdr(&smb); ! 209: smb_close(&smb); ! 210: smb_stack(&smb,SMB_STACK_POP); ! 211: errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); ! 212: return(false); } ! 213: if(cfg.sub[subnum]->misc&SUB_FAST) { ! 214: offset=smb_fallocdat(&smb,length,1); ! 215: storage=SMB_FASTALLOC; } ! 216: else { ! 217: offset=smb_allocdat(&smb,length,1); ! 218: storage=SMB_SELFPACK; } ! 219: smb_close_da(&smb); } ! 220: ! 221: if((file=open(str,O_RDONLY|O_BINARY))==-1 ! 222: || (instream=fdopen(file,"rb"))==NULL) { ! 223: smb_freemsgdat(&smb,offset,length,1); ! 224: smb_unlocksmbhdr(&smb); ! 225: smb_close(&smb); ! 226: smb_stack(&smb,SMB_STACK_POP); ! 227: errormsg(WHERE,ERR_OPEN,str,O_RDONLY|O_BINARY); ! 228: return(false); } ! 229: ! 230: setvbuf(instream,NULL,_IOFBF,2*1024); ! 231: fseek(smb.sdt_fp,offset,SEEK_SET); ! 232: xlat=XLAT_NONE; ! 233: fwrite(&xlat,2,1,smb.sdt_fp); ! 234: x=SDT_BLOCK_LEN-2; /* Don't read/write more than 255 */ ! 235: while(!feof(instream)) { ! 236: memset(buf,0,x); ! 237: j=fread(buf,1,x,instream); ! 238: if((j!=x || feof(instream)) && buf[j-1]==LF && buf[j-2]==CR) ! 239: buf[j-1]=buf[j-2]=0; /* Convert to NULL */ ! 240: if(cfg.sub[subnum]->maxcrcs) { ! 241: for(i=0;i<j;i++) ! 242: crc=ucrc32(buf[i],crc); } ! 243: fwrite(buf,j,1,smb.sdt_fp); ! 244: x=SDT_BLOCK_LEN; } ! 245: fflush(smb.sdt_fp); ! 246: fclose(instream); ! 247: crc=~crc; ! 248: ! 249: memset(&msg,0,sizeof(smbmsg_t)); ! 250: memcpy(msg.hdr.id,"SHD\x1a",4); ! 251: msg.hdr.version=smb_ver(); ! 252: msg.hdr.attr=msg.idx.attr=msgattr; ! 253: msg.hdr.when_written.time=msg.hdr.when_imported.time=time(NULL); ! 254: msg.hdr.when_written.zone=msg.hdr.when_imported.zone=cfg.sys_timezone; ! 255: if(remsg) { ! 256: msg.hdr.thread_orig=remsg->hdr.number; ! 257: if(!remsg->hdr.thread_first) { ! 258: remsg->hdr.thread_first=smb.status.last_msg+1; ! 259: if((i=smb_lockmsghdr(&smb,remsg))!=0) ! 260: errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error); ! 261: else { ! 262: i=smb_putmsghdr(&smb,remsg); ! 263: smb_unlockmsghdr(&smb,remsg); ! 264: if(i) ! 265: errormsg(WHERE,ERR_WRITE,smb.file,i); } } ! 266: else { ! 267: l=remsg->hdr.thread_first; ! 268: while(1) { ! 269: tmpmsg.idx.offset=0; ! 270: if(!loadmsg(&tmpmsg,l)) ! 271: break; ! 272: if(tmpmsg.hdr.thread_next && tmpmsg.hdr.thread_next!=l) { ! 273: l=tmpmsg.hdr.thread_next; ! 274: smb_unlockmsghdr(&smb,&tmpmsg); ! 275: smb_freemsgmem(&tmpmsg); ! 276: continue; } ! 277: tmpmsg.hdr.thread_next=smb.status.last_msg+1; ! 278: if((i=smb_putmsghdr(&smb,&tmpmsg))!=0) ! 279: errormsg(WHERE,ERR_WRITE,smb.file,i); ! 280: smb_unlockmsghdr(&smb,&tmpmsg); ! 281: smb_freemsgmem(&tmpmsg); ! 282: break; } } } ! 283: ! 284: ! 285: if(cfg.sub[subnum]->maxcrcs) { ! 286: i=smb_addcrc(&smb,crc); ! 287: if(i) { ! 288: smb_freemsgdat(&smb,offset,length,1); ! 289: smb_unlocksmbhdr(&smb); ! 290: smb_close(&smb); ! 291: smb_stack(&smb,SMB_STACK_POP); ! 292: bputs("\1r\1h\1iDuplicate message!\r\n"); ! 293: return(false); } } ! 294: ! 295: msg.hdr.offset=offset; ! 296: ! 297: smb_hfield(&msg,RECIPIENT,strlen(touser),touser); ! 298: strlwr(touser); ! 299: msg.idx.to=crc16(touser); ! 300: ! 301: strcpy(str,cfg.sub[subnum]->misc&SUB_NAME ? useron.name : useron.alias); ! 302: smb_hfield(&msg,SENDER,strlen(str),str); ! 303: strlwr(str); ! 304: msg.idx.from=crc16(str); ! 305: ! 306: sprintf(str,"%u",useron.number); ! 307: smb_hfield(&msg,SENDEREXT,strlen(str),str); ! 308: ! 309: smb_hfield(&msg,SUBJECT,strlen(title),title); ! 310: strcpy(str,title); ! 311: strlwr(str); ! 312: remove_re(str); ! 313: msg.idx.subj=crc16(str); ! 314: ! 315: smb_dfield(&msg,TEXT_BODY,length); ! 316: ! 317: smb_unlocksmbhdr(&smb); ! 318: i=smb_addmsghdr(&smb,&msg,storage); ! 319: smb_close(&smb); ! 320: smb_stack(&smb,SMB_STACK_POP); ! 321: ! 322: smb_freemsgmem(&msg); ! 323: if(i) { ! 324: smb_freemsgdat(&smb,offset,length,1); ! 325: errormsg(WHERE,ERR_WRITE,smb.file,i); ! 326: return(false); } ! 327: ! 328: useron.ptoday++; ! 329: useron.posts++; ! 330: logon_posts++; ! 331: putuserrec(&cfg,useron.number,U_POSTS,5,ultoa(useron.posts,str,10)); ! 332: putuserrec(&cfg,useron.number,U_PTODAY,5,ultoa(useron.ptoday,str,10)); ! 333: bprintf(text[Posted],cfg.grp[cfg.sub[subnum]->grp]->sname ! 334: ,cfg.sub[subnum]->lname); ! 335: sprintf(str,"Posted on %s %s",cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname); ! 336: logline("P+",str); ! 337: if(cfg.sub[subnum]->misc&SUB_FIDO && cfg.sub[subnum]->echomail_sem[0]) /* semaphore */ ! 338: if((file=nopen(cmdstr(cfg.sub[subnum]->echomail_sem,nulstr,nulstr,NULL) ! 339: ,O_WRONLY|O_CREAT|O_TRUNC))!=-1) ! 340: close(file); ! 341: return(true); ! 342: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.