void sbbs_t::delallmail(uint usernumber, int which, bool permanent) { int i; long deleted=0; uint32_t msgs,u; mail_t *mail; smbmsg_t msg; if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) { errormsg(WHERE,ERR_OPEN,"MAIL",i); return; } sprintf(smb.file,"%smail",cfg.data_dir); smb.retry_time=cfg.smb_retry_time; smb.subnum=INVALID_SUB; if((i=smb_open(&smb))!=0) { errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); smb_stack(&smb,SMB_STACK_POP); return; } mail=loadmail(&smb,&msgs,usernumber,which,0); if(!msgs) { smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); return; } if((i=smb_locksmbhdr(&smb))!=0) { /* Lock the base, so nobody */ smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); free(mail); errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error); /* messes with the index */ return; } for(u=0;u<msgs;u++) { msg.idx.offset=0; /* search by number */ if((mail[u].attr&MSG_PERMANENT) && !permanent) continue; if(loadmsg(&msg,mail[u].number)) { /* message still there */ msg.hdr.attr|=MSG_DELETE; msg.hdr.attr&=~MSG_PERMANENT; msg.idx.attr=msg.hdr.attr; if((i=smb_putmsg(&smb,&msg))!=0) errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); else deleted++; smb_freemsgmem(&msg); smb_unlockmsghdr(&smb,&msg); } } if(msgs) free(mail); if(permanent && deleted && (cfg.sys_misc&SM_DELEMAIL)) delmail(usernumber,MAIL_ANY); smb_unlocksmbhdr(&smb); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); }
bool sbbs_t::email(int usernumber, const char *top, const char *subj, long mode) { char str[256],str2[256],msgpath[256],title[LEN_TITLE+1],ch ,buf[SDT_BLOCK_LEN]; char tmp[512]; char pid[128]; char* editor=NULL; ushort msgattr=0; uint16_t xlat=XLAT_NONE; ushort nettype; int i,j,x,file; long l; long length; ulong offset; uint32_t crc=0xffffffffUL; FILE* instream; node_t node; smbmsg_t msg; SAFECOPY(title,subj); if(useron.etoday>=cfg.level_emailperday[useron.level] && !SYSOP && !(useron.exempt&FLAG('M'))) { bputs(text[TooManyEmailsToday]); return(false); } if(usernumber==1 && useron.rest&FLAG('S') && (cfg.node_valuser!=1 || useron.fbacks || useron.emails)) { /* ! val fback */ bprintf(text[R_Feedback],cfg.sys_op); return(false); } if(usernumber!=1 && useron.rest&FLAG('E') && (cfg.node_valuser!=usernumber || useron.fbacks || useron.emails)) { bputs(text[R_Email]); return(false); } if(!usernumber) { bputs(text[UnknownUser]); return(false); } getuserrec(&cfg,usernumber,U_MISC,8,str); l=ahtoul(str); if(l&(DELETED|INACTIVE)) { /* Deleted or Inactive User */ bputs(text[UnknownUser]); return(false); } if((l&NETMAIL) && (cfg.sys_misc&SM_FWDTONET)) { getuserrec(&cfg,usernumber,U_NETMAIL,LEN_NETMAIL,str); bprintf(text[UserNetMail],str); if((mode & WM_FORCEFWD) || text[ForwardMailQ][0]==0 || yesno(text[ForwardMailQ])) /* Forward to netmail address */ return(netmail(str,subj,mode)); } bprintf(text[Emailing],username(&cfg,usernumber,tmp),usernumber); action=NODE_SMAL; nodesync(); sprintf(str,"%sfeedback.*", cfg.exec_dir); if(usernumber==cfg.node_valuser && useron.fbacks && fexist(str)) { exec_bin("feedback",&main_csi); if(main_csi.logic!=LOGIC_TRUE) return(false); } if(cfg.sys_misc&SM_ANON_EM && useron.exempt&FLAG('A') && !noyes(text[AnonymousQ])) msgattr|=MSG_ANONYMOUS; if(cfg.sys_misc&SM_DELREADM) msgattr|=MSG_KILLREAD; msg_tmp_fname(useron.xedit, msgpath, sizeof(msgpath)); username(&cfg,usernumber,str2); if(!writemsg(msgpath,top,title,mode,INVALID_SUB,str2,&editor)) { bputs(text[Aborted]); return(false); } if(mode&WM_FILE && !SYSOP && !(cfg.sys_misc&SM_FILE_EM)) mode&=~WM_FILE; if(mode&WM_FILE) { sprintf(str2,"%sfile/%04u.in", cfg.data_dir,usernumber); MKDIR(str2); sprintf(str2,"%sfile/%04u.in/%s", cfg.data_dir,usernumber,title); if(fexistcase(str2)) { bputs(text[FileAlreadyThere]); remove(msgpath); return(false); } { /* Remote */ xfer_prot_menu(XFER_UPLOAD); mnemonics(text[ProtocolOrQuit]); strcpy(str,"Q"); for(x=0;x<cfg.total_prots;x++) if(cfg.prot[x]->ulcmd[0] && chk_ar(cfg.prot[x]->ar,&useron,&client)) { sprintf(tmp,"%c",cfg.prot[x]->mnemonic); strcat(str,tmp); } ch=(char)getkeys(str,0); if(ch=='Q' || sys_status&SS_ABORT) { bputs(text[Aborted]); remove(msgpath); return(false); } for(x=0;x<cfg.total_prots;x++) if(cfg.prot[x]->ulcmd[0] && cfg.prot[x]->mnemonic==ch && chk_ar(cfg.prot[x]->ar,&useron,&client)) break; if(x<cfg.total_prots) /* This should be always */ protocol(cfg.prot[x],XFER_UPLOAD,str2,nulstr,true); } safe_snprintf(tmp,sizeof(tmp),"%s%s",cfg.temp_dir,title); if(!fexistcase(str2) && fexistcase(tmp)) mv(tmp,str2,0); l=(long)flength(str2); if(l>0) bprintf(text[FileNBytesReceived],title,ultoac(l,tmp)); else { bprintf(text[FileNotReceived],title); remove(msgpath); return(false); } } bputs(text[WritingIndx]); if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) { errormsg(WHERE,ERR_OPEN,"MAIL",i); return(false); } sprintf(smb.file,"%smail", cfg.data_dir); smb.retry_time=cfg.smb_retry_time; smb.subnum=INVALID_SUB; if((i=smb_open(&smb))!=0) { smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); return(false); } if(smb_fgetlength(smb.shd_fp)<1) { /* Create it if it doesn't exist */ smb.status.max_crcs=cfg.mail_maxcrcs; smb.status.max_age=cfg.mail_maxage; smb.status.max_msgs=0; smb.status.attr=SMB_EMAIL; if((i=smb_create(&smb))!=0) { smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_CREATE,smb.file,i,smb.last_error); return(false); } } if((i=smb_locksmbhdr(&smb))!=0) { smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error); return(false); } length=(long)flength(msgpath)+2; /* +2 for translation string */ if(length&0xfff00000UL) { smb_unlocksmbhdr(&smb); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_LEN,msgpath,length); return(false); } if((i=smb_open_da(&smb))!=0) { smb_unlocksmbhdr(&smb); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); return(false); } if(cfg.sys_misc&SM_FASTMAIL) offset=smb_fallocdat(&smb,length,1); else offset=smb_allocdat(&smb,length,1); smb_close_da(&smb); if((instream=fnopen(&file,msgpath,O_RDONLY|O_BINARY))==NULL) { smb_freemsgdat(&smb,offset,length,1); smb_unlocksmbhdr(&smb); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_OPEN,msgpath,O_RDONLY|O_BINARY); return(false); } setvbuf(instream,NULL,_IOFBF,2*1024); smb_fseek(smb.sdt_fp,offset,SEEK_SET); xlat=XLAT_NONE; smb_fwrite(&smb,&xlat,2,smb.sdt_fp); x=SDT_BLOCK_LEN-2; /* Don't read/write more than 255 */ while(!feof(instream)) { memset(buf,0,x); j=fread(buf,1,x,instream); if(j<1) break; if(j>1 && (j!=x || feof(instream)) && buf[j-1]==LF && buf[j-2]==CR) buf[j-1]=buf[j-2]=0; if(cfg.mail_maxcrcs) { for(i=0;i<j;i++) crc=ucrc32(buf[i],crc); } smb_fwrite(&smb,buf,j,smb.sdt_fp); x=SDT_BLOCK_LEN; } smb_fflush(smb.sdt_fp); fclose(instream); crc=~crc; memset(&msg,0,sizeof(smbmsg_t)); msg.hdr.version=smb_ver(); msg.hdr.attr=msgattr; if(mode&WM_FILE) msg.hdr.auxattr|=MSG_FILEATTACH; msg.hdr.when_written.time=msg.hdr.when_imported.time=time32(NULL); msg.hdr.when_written.zone=msg.hdr.when_imported.zone=sys_timezone(&cfg); if(cfg.mail_maxcrcs) { i=smb_addcrc(&smb,crc); if(i) { smb_freemsgdat(&smb,offset,length,1); smb_unlocksmbhdr(&smb); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); attr(cfg.color[clr_err]); bputs(text[CantPostMsg]); return(false); } } msg.hdr.offset=offset; username(&cfg,usernumber,str); smb_hfield_str(&msg,RECIPIENT,str); sprintf(str,"%u",usernumber); smb_hfield_str(&msg,RECIPIENTEXT,str); SAFECOPY(str,useron.alias); smb_hfield_str(&msg,SENDER,str); sprintf(str,"%u",useron.number); smb_hfield_str(&msg,SENDEREXT,str); if(useron.misc&NETMAIL) { if(useron.rest&FLAG('G')) smb_hfield_str(&msg,REPLYTO,useron.name); nettype=smb_netaddr_type(useron.netmail); if(nettype!=NET_NONE && nettype!=NET_UNKNOWN) { smb_hfield(&msg,REPLYTONETTYPE,sizeof(nettype),&nettype); smb_hfield_str(&msg,REPLYTONETADDR,useron.netmail); } } /* Security logging */ msg_client_hfields(&msg,&client); smb_hfield_str(&msg,SENDERSERVER,startup->host_name); smb_hfield_str(&msg,SUBJECT,title); /* Generate FidoNet Program Identifier */ smb_hfield_str(&msg,FIDOPID,msg_program_id(pid)); if(editor!=NULL) smb_hfield_str(&msg,SMB_EDITOR,editor); smb_dfield(&msg,TEXT_BODY,length); i=smb_addmsghdr(&smb,&msg,SMB_SELFPACK); // calls smb_unlocksmbhdr() smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); smb_freemsgmem(&msg); if(i!=SMB_SUCCESS) { smb_freemsgdat(&smb,offset,length,1); errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); return(false); } if(usernumber==1) logon_fbacks++; else logon_emails++; user_sent_email(&cfg, &useron, 1, usernumber==1); bprintf(text[Emailed],username(&cfg,usernumber,tmp),usernumber); safe_snprintf(str,sizeof(str),"%s sent e-mail to %s #%d" ,useron.alias,username(&cfg,usernumber,tmp),usernumber); logline("E+",str); if(mode&WM_FILE && online==ON_REMOTE) autohangup(); if(msgattr&MSG_ANONYMOUS) /* Don't tell user if anonymous */ return(true); for(i=1;i<=cfg.sys_nodes;i++) { /* Tell user, if online */ getnodedat(i,&node,0); if(node.useron==usernumber && !(node.misc&NODE_POFF) && (node.status==NODE_INUSE || node.status==NODE_QUIET)) { safe_snprintf(str,sizeof(str),text[EmailNodeMsg],cfg.node_num,useron.alias); putnmsg(&cfg,i,str); break; } } if(i>cfg.sys_nodes) { /* User wasn't online, so leave short msg */ safe_snprintf(str,sizeof(str),text[UserSentYouMail],useron.alias); putsmsg(&cfg,usernumber,str); } return(true); }
bool sbbs_t::postmsg(uint subnum, smbmsg_t *remsg, long wm_mode) { char str[256],title[LEN_TITLE+1],top[256]; char msg_id[256]; char touser[64]; char from[64]; char pid[128]; char* editor=NULL; char* msgbuf=NULL; uint16_t xlat; ushort msgattr; int i,storage; long dupechk_hashes; long length; FILE* fp; smbmsg_t msg; uint reason; if(remsg) { sprintf(title,"%.*s",LEN_TITLE,remsg->subj); if(remsg->hdr.attr&MSG_ANONYMOUS) SAFECOPY(from,text[Anonymous]); else SAFECOPY(from,remsg->from); // If user posted this message, reply to the original recipient again if((remsg->from_ext!=NULL && atoi(remsg->from_ext)==useron.number) || stricmp(useron.alias,remsg->from)==0 || stricmp(useron.name,remsg->from)==0) SAFECOPY(touser,remsg->to); else SAFECOPY(touser,from); msgattr=(ushort)(remsg->hdr.attr&MSG_PRIVATE); sprintf(top,text[RegardingByToOn],title,from,remsg->to ,timestr(remsg->hdr.when_written.time) ,smb_zonestr(remsg->hdr.when_written.zone,NULL)); } else { title[0]=0; touser[0]=0; top[0]=0; msgattr=0; } /* Security checks */ if(!can_user_post(&cfg,subnum,&useron,&client,&reason)) { bputs(text[reason]); return false; } bprintf(text[Posting],cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname); action=NODE_PMSG; nodesync(); if(!(msgattr&MSG_PRIVATE) && (cfg.sub[subnum]->misc&SUB_PONLY || (cfg.sub[subnum]->misc&SUB_PRIV && !noyes(text[PrivatePostQ])))) msgattr|=MSG_PRIVATE; if(sys_status&SS_ABORT) return(false); if( #if 0 /* we *do* support internet posts to specific people July-11-2002 */ !(cfg.sub[subnum]->misc&SUB_INET) && // Prompt for TO: user #endif (cfg.sub[subnum]->misc&SUB_TOUSER || msgattr&MSG_PRIVATE || touser[0])) { if(!touser[0] && !(msgattr&MSG_PRIVATE)) SAFECOPY(touser,"All"); bputs(text[PostTo]); i=LEN_ALIAS; if(cfg.sub[subnum]->misc&SUB_QNET) i=25; if(cfg.sub[subnum]->misc&SUB_FIDO) i=FIDO_NAME_LEN-1; if(cfg.sub[subnum]->misc&(SUB_PNET|SUB_INET)) i=60; getstr(touser,i,K_UPRLWR|K_LINE|K_EDIT|K_AUTODEL); if(stricmp(touser,"ALL") && !(cfg.sub[subnum]->misc&(SUB_PNET|SUB_FIDO|SUB_QNET|SUB_INET|SUB_ANON))) { if(cfg.sub[subnum]->misc&SUB_NAME) { if(!userdatdupe(useron.number,U_NAME,LEN_NAME,touser)) { bputs(text[UnknownUser]); return(false); } } else { if((i=finduser(touser))==0) return(false); username(&cfg,i,touser); } } if(sys_status&SS_ABORT) return(false); } if(!touser[0]) SAFECOPY(touser,"All"); // Default to ALL if(!stricmp(touser,"SYSOP") && !SYSOP) // Change SYSOP to user #1 username(&cfg,1,touser); if(msgattr&MSG_PRIVATE && !stricmp(touser,"ALL")) { bputs(text[NoToUser]); return(false); } if(msgattr&MSG_PRIVATE) wm_mode|=WM_PRIVATE; if(cfg.sub[subnum]->misc&SUB_AONLY || (cfg.sub[subnum]->misc&SUB_ANON && useron.exempt&FLAG('A') && !noyes(text[AnonymousQ]))) msgattr|=MSG_ANONYMOUS; if(cfg.sub[subnum]->mod_ar[0] && chk_ar(cfg.sub[subnum]->mod_ar,&useron,&client)) msgattr|=MSG_MODERATED; if(cfg.sub[subnum]->misc&SUB_SYSPERM && sub_op(subnum)) msgattr|=MSG_PERMANENT; if(msgattr&MSG_PRIVATE) bputs(text[PostingPrivately]); if(msgattr&MSG_ANONYMOUS) bputs(text[PostingAnonymously]); if(cfg.sub[subnum]->misc&SUB_NAME) bputs(text[UsingRealName]); msg_tmp_fname(useron.xedit, str, sizeof(str)); if(!writemsg(str,top,title,wm_mode,subnum,touser,&editor) || (length=(long)flength(str))<1) { /* Bugfix Aug-20-2003: Reject negative length */ bputs(text[Aborted]); return(false); } bputs(text[WritingIndx]); if((i=smb_stack(&smb,SMB_STACK_PUSH))!=SMB_SUCCESS) { errormsg(WHERE,ERR_OPEN,cfg.sub[subnum]->code,i,smb.last_error); return(false); } smb.subnum=subnum; if((i=msgbase_open(&cfg,&smb,&storage,&dupechk_hashes,&xlat))!=SMB_SUCCESS) { errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); smb_stack(&smb,SMB_STACK_POP); return(false); } if((i=smb_locksmbhdr(&smb))!=SMB_SUCCESS) { smb_close(&smb); errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error); smb_stack(&smb,SMB_STACK_POP); return(false); } if((i=smb_getstatus(&smb))!=SMB_SUCCESS) { smb_close(&smb); errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error); smb_stack(&smb,SMB_STACK_POP); return(false); } if((msgbuf=(char*)calloc(length+1,sizeof(char))) == NULL) { smb_close(&smb); errormsg(WHERE,ERR_ALLOC,"msgbuf",length+1); smb_stack(&smb,SMB_STACK_POP); return(false); } if((fp=fopen(str,"rb"))==NULL) { free(msgbuf); smb_close(&smb); errormsg(WHERE,ERR_OPEN,str,O_RDONLY|O_BINARY); smb_stack(&smb,SMB_STACK_POP); return(false); } i=fread(msgbuf,1,length,fp); fclose(fp); if(i != length) { free(msgbuf); smb_close(&smb); errormsg(WHERE,ERR_READ,str,length); smb_stack(&smb,SMB_STACK_POP); return(false); } truncsp(msgbuf); /* ToDo: split body/tail */ memset(&msg,0,sizeof(msg)); msg.hdr.attr=msgattr; msg.hdr.when_written.time=msg.hdr.when_imported.time=time32(NULL); msg.hdr.when_written.zone=msg.hdr.when_imported.zone=sys_timezone(&cfg); msg.hdr.number=smb.status.last_msg+1; /* this *should* be the new message number */ if(remsg) { msg.hdr.thread_back=remsg->hdr.number; /* needed for threading backward */ if((msg.hdr.thread_id=remsg->hdr.thread_id) == 0) msg.hdr.thread_id=remsg->hdr.number; /* Add RFC-822 Reply-ID (generate if necessary) */ if(remsg->id!=NULL) smb_hfield_str(&msg,RFC822REPLYID,remsg->id); /* Add FidoNet Reply if original message has FidoNet MSGID */ if(remsg->ftn_msgid!=NULL) smb_hfield_str(&msg,FIDOREPLYID,remsg->ftn_msgid); if((i=smb_updatethread(&smb, remsg, smb.status.last_msg+1))!=SMB_SUCCESS) errormsg(WHERE,"updating thread",smb.file,i,smb.last_error); } smb_hfield_str(&msg,RECIPIENT,touser); SAFECOPY(str,cfg.sub[subnum]->misc&SUB_NAME ? useron.name : useron.alias); smb_hfield_str(&msg,SENDER,str); sprintf(str,"%u",useron.number); smb_hfield_str(&msg,SENDEREXT,str); /* Security logging */ msg_client_hfields(&msg,&client); smb_hfield_str(&msg,SENDERSERVER,startup->host_name); smb_hfield_str(&msg,SUBJECT,title); /* Generate default (RFC822) message-id (always) */ get_msgid(&cfg,subnum,&msg,msg_id,sizeof(msg_id)); smb_hfield_str(&msg,RFC822MSGID,msg_id); /* Generate FTN (FTS-9) MSGID */ if(cfg.sub[subnum]->misc&SUB_FIDO) { ftn_msgid(cfg.sub[subnum],&msg,msg_id,sizeof(msg_id)); smb_hfield_str(&msg,FIDOMSGID,msg_id); } /* Generate FidoNet Program Identifier */ smb_hfield_str(&msg,FIDOPID,msg_program_id(pid)); if(editor!=NULL) smb_hfield_str(&msg,SMB_EDITOR,editor); i=smb_addmsg(&smb,&msg,storage,dupechk_hashes,xlat,(uchar*)msgbuf,NULL); free(msgbuf); if(i==SMB_DUPE_MSG) { attr(cfg.color[clr_err]); bprintf(text[CantPostMsg], smb.last_error); } else if(i!=SMB_SUCCESS) errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); smb_freemsgmem(&msg); if(i!=SMB_SUCCESS) return(false); logon_posts++; user_posted_msg(&cfg, &useron, 1); bprintf(text[Posted],cfg.grp[cfg.sub[subnum]->grp]->sname ,cfg.sub[subnum]->lname); sprintf(str,"%s posted on %s %s" ,useron.alias,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname); logline("P+",str); signal_sub_sem(&cfg,subnum); user_event(EVENT_POST); return(true); }
void sbbs_t::readmail(uint usernumber, int which) { char str[256],str2[256],str3[256],done=0,domsg=1 ,*p,*tp,*sp,ch; char tmp[512]; int i,j; int error; int mismatches=0,act; long length,l,lm_mode; ulong last; bool replied; file_t fd; mail_t *mail; smbmsg_t msg; if(which==MAIL_SENT && useron.rest&FLAG('K')) { bputs(text[R_ReadSentMail]); return; } msg.total_hfields=0; /* init to NULL, cause not allocated yet */ fd.dir=cfg.total_dirs+1; /* temp dir for file attachments */ if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) { errormsg(WHERE,ERR_OPEN,"MAIL",i); return; } sprintf(smb.file,"%smail",cfg.data_dir); smb.retry_time=cfg.smb_retry_time; smb.subnum=INVALID_SUB; if((i=smb_open(&smb))!=0) { smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); return; } if(cfg.sys_misc&SM_SYSVDELM && (SYSOP || cfg.sys_misc&SM_USRVDELM)) lm_mode=LM_INCDEL; else lm_mode=0; mail=loadmail(&smb,&smb.msgs,usernumber,which,lm_mode); if(!smb.msgs) { if(which==MAIL_SENT) bputs(text[NoMailSent]); else if(which==MAIL_ALL) bputs(text[NoMailOnSystem]); else bputs(text[NoMailWaiting]); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); return; } last=smb.status.last_msg; if(which==MAIL_SENT) act=NODE_RSML; else if(which==MAIL_ALL) act=NODE_SYSP; else act=NODE_RMAL; action=act; if(smb.msgs>1 && which!=MAIL_ALL) { if(which==MAIL_SENT) bputs(text[MailSentLstHdr]); else bputs(text[MailWaitingLstHdr]); for(smb.curmsg=0;smb.curmsg<smb.msgs && !msgabort();smb.curmsg++) { if(msg.total_hfields) smb_freemsgmem(&msg); msg.total_hfields=0; msg.idx.offset=mail[smb.curmsg].offset; if(!loadmsg(&msg,mail[smb.curmsg].number)) continue; smb_unlockmsghdr(&smb,&msg); bprintf(text[MailWaitingLstFmt],smb.curmsg+1 ,which==MAIL_SENT ? msg.to : (msg.hdr.attr&MSG_ANONYMOUS) && !SYSOP ? text[Anonymous] : msg.from ,msg.hdr.attr&MSG_DELETE ? '-' : msg.hdr.attr&MSG_REPLIED ? 'R' : msg.hdr.attr&MSG_READ ? ' ' : msg.from_net.type || msg.to_net.type ? 'N':'*' ,msg.subj); smb_freemsgmem(&msg); msg.total_hfields=0; } ASYNC; if(!(sys_status&SS_ABORT)) { bprintf(text[StartWithN],1L); if((long)(smb.curmsg=getnum(smb.msgs))>0) smb.curmsg--; else if((long)smb.curmsg==-1) { free(mail); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); return; } } sys_status&=~SS_ABORT; } else { smb.curmsg=0; if(which==MAIL_ALL) domsg=0; } if(which==MAIL_SENT) { sprintf(str,"%s read sent mail",useron.alias); logline("E",str); } else if(which==MAIL_ALL) { sprintf(str,"%s read all mail",useron.alias); logline("S+",str); } else { sprintf(str,"%s read mail",useron.alias); logline("E",str); } if(useron.misc&RIP) { strcpy(str,which==MAIL_YOUR ? "mailread" : which==MAIL_ALL ? "allmail" : "sentmail"); menu(str); } while(online && !done) { action=act; if(msg.total_hfields) smb_freemsgmem(&msg); msg.total_hfields=0; msg.idx.offset=mail[smb.curmsg].offset; msg.idx.number=mail[smb.curmsg].number; msg.idx.to=mail[smb.curmsg].to; msg.idx.from=mail[smb.curmsg].from; msg.idx.subj=mail[smb.curmsg].subj; if((i=smb_locksmbhdr(&smb))!=0) { errormsg(WHERE,ERR_LOCK,smb.file,i); break; } if((i=smb_getstatus(&smb))!=0) { smb_unlocksmbhdr(&smb); errormsg(WHERE,ERR_READ,smb.file,i); break; } smb_unlocksmbhdr(&smb); if(smb.status.last_msg!=last) { /* New messages */ last=smb.status.last_msg; free(mail); mail=loadmail(&smb,&smb.msgs,usernumber,which,lm_mode); /* So re-load */ if(!smb.msgs) break; for(smb.curmsg=0;smb.curmsg<smb.msgs;smb.curmsg++) if(mail[smb.curmsg].number==msg.idx.number) break; if(smb.curmsg>=smb.msgs) smb.curmsg=(smb.msgs-1); continue; } if(!loadmsg(&msg,mail[smb.curmsg].number)) { /* Message header gone */ if(mismatches>5) { /* We can't do this too many times in a row */ errormsg(WHERE,ERR_CHK,"message number",mail[smb.curmsg].number); break; } free(mail); mail=loadmail(&smb,&smb.msgs,usernumber,which,lm_mode); if(!smb.msgs) break; if(smb.curmsg>(smb.msgs-1)) smb.curmsg=(smb.msgs-1); mismatches++; continue; } smb_unlockmsghdr(&smb,&msg); msg.idx.attr=msg.hdr.attr; mismatches=0; if(domsg && !(sys_status&SS_ABORT)) { show_msg(&msg ,msg.from_ext && msg.idx.from==1 && !msg.from_net.type ? 0:P_NOATCODES); if(msg.hdr.auxattr&MSG_FILEATTACH) { /* Attached file */ smb_getmsgidx(&smb,&msg); strcpy(str,msg.subj); /* filenames in title */ // strupr(str); tp=str; while(online) { p=strchr(tp,' '); if(p) *p=0; sp=strrchr(tp,'/'); /* sp is slash pointer */ if(!sp) sp=strrchr(tp,'\\'); if(sp) tp=sp+1; padfname(tp,fd.name); sprintf(str2,"%sfile/%04u.in/%s" /* str2 is path/fname */ ,cfg.data_dir,msg.idx.to,tp); length=flength(str2); if(length<1) bputs(text[FileNotFound]); else if(!(useron.exempt&FLAG('T')) && cur_cps && !SYSOP && length/(long)cur_cps>(time_t)timeleft) bputs(text[NotEnoughTimeToDl]); else { sprintf(str3,text[DownloadAttachedFileQ] ,tp,ultoac(length,tmp)); if(length>0L && yesno(str3)) { #if 0 /* no such thing as local logon */ if(online==ON_LOCAL) { bputs(text[EnterPath]); if(getstr(str3,60,K_LINE)) { backslashcolon(str3); sprintf(tmp,"%s%s",str3,tp); if(!mv(str2,tmp,which!=MAIL_YOUR)) { logon_dlb+=length; logon_dls++; useron.dls=(ushort)adjustuserrec(&cfg,useron.number ,U_DLS,5,1); useron.dlb=adjustuserrec(&cfg,useron.number ,U_DLB,10,length); bprintf(text[FileNBytesSent] ,fd.name,ultoac(length,tmp)); } } } else #endif { /* Remote User */ xfer_prot_menu(XFER_DOWNLOAD); mnemonics(text[ProtocolOrQuit]); strcpy(str3,"Q"); for(i=0;i<cfg.total_prots;i++) if(cfg.prot[i]->dlcmd[0] && chk_ar(cfg.prot[i]->ar,&useron)) { sprintf(tmp,"%c",cfg.prot[i]->mnemonic); strcat(str3,tmp); } ch=(char)getkeys(str3,0); for(i=0;i<cfg.total_prots;i++) if(cfg.prot[i]->dlcmd[0] && ch==cfg.prot[i]->mnemonic && chk_ar(cfg.prot[i]->ar,&useron)) break; if(i<cfg.total_prots) { error=protocol(cfg.prot[i],XFER_DOWNLOAD,str2,nulstr,false); if(checkprotresult(cfg.prot[i],error,&fd)) { if(which==MAIL_YOUR) remove(str2); logon_dlb+=length; /* Update stats */ logon_dls++; useron.dls=(ushort)adjustuserrec(&cfg,useron.number ,U_DLS,5,1); useron.dlb=adjustuserrec(&cfg,useron.number ,U_DLB,10,length); bprintf(text[FileNBytesSent] ,fd.name,ultoac(length,tmp)); sprintf(str3 ,"%s downloaded attached file: %s" ,useron.alias ,fd.name); logline("D-",str3); } autohangup(); } } } } if(!p) break; tp=p+1; while(*tp==' ') tp++; } sprintf(str,"%sfile/%04u.in",cfg.data_dir,usernumber); rmdir(str); } if(which==MAIL_YOUR && !(msg.hdr.attr&MSG_READ)) { mail[smb.curmsg].attr|=MSG_READ; if(thisnode.status==NODE_INUSE) telluser(&msg); if(msg.total_hfields) smb_freemsgmem(&msg); msg.total_hfields=0; msg.idx.offset=0; /* Search by number */ if(smb_locksmbhdr(&smb)==SMB_SUCCESS) { /* Lock the entire base */ if(loadmsg(&msg,msg.idx.number)) { msg.hdr.attr|=MSG_READ; msg.idx.attr=msg.hdr.attr; if((i=smb_putmsg(&smb,&msg))!=0) errormsg(WHERE,ERR_WRITE,smb.file,i); smb_unlockmsghdr(&smb,&msg); } smb_unlocksmbhdr(&smb); } if(!msg.total_hfields) { /* unsuccessful reload */ domsg=0; continue; } } } else domsg=1; if(useron.misc&WIP) { strcpy(str,which==MAIL_YOUR ? "mailread" : which==MAIL_ALL ? "allmail" : "sentmail"); menu(str); } ASYNC; if(which==MAIL_SENT) bprintf(text[ReadingSentMail],smb.curmsg+1,smb.msgs); else if(which==MAIL_ALL) bprintf(text[ReadingAllMail],smb.curmsg+1,smb.msgs); else bprintf(text[ReadingMail],smb.curmsg+1,smb.msgs); sprintf(str,"ADFLNQRT?<>[]{}-+"); if(SYSOP) strcat(str,"CUSPH"); if(which!=MAIL_YOUR) strcat(str,"E"); l=getkeys(str,smb.msgs); if(l&0x80000000L) { if(l==-1) /* ctrl-c */ break; smb.curmsg=(l&~0x80000000L)-1; continue; } switch(l) { case 'A': /* Auto-reply to last piece */ case 'R': if(l==(cfg.sys_misc&SM_RA_EMU ? 'A' : 'R')) /* re-read last message */ break; if(which==MAIL_SENT) break; if((msg.hdr.attr&MSG_ANONYMOUS) && !SYSOP) { bputs(text[CantReplyToAnonMsg]); break; } quotemsg(&msg,1); if(msg.from_net.addr==NULL) SAFECOPY(str,msg.from); else if(msg.from_net.type==NET_FIDO) /* FidoNet type */ SAFEPRINTF2(str,"%s@%s",msg.from ,smb_faddrtoa((faddr_t *)msg.from_net.addr,tmp)); else if(msg.from_net.type==NET_INTERNET) { if(msg.replyto_net.type==NET_INTERNET) SAFECOPY(str,(char *)msg.replyto_net.addr); else SAFECOPY(str,(char *)msg.from_net.addr); } else SAFEPRINTF2(str,"%s@%s",msg.from,(char*)msg.from_net.addr); SAFECOPY(str2,str); bputs(text[Email]); if(!getstr(str,64,K_EDIT|K_AUTODEL)) break; msg.hdr.number=msg.idx.number; smb_getmsgidx(&smb,&msg); if(!stricmp(str2,str)) /* Reply to sender */ sprintf(str2,text[Regarding],msg.subj); else /* Reply to other */ sprintf(str2,text[RegardingByOn],msg.subj,msg.from ,timestr((time_t *)&msg.hdr.when_written.time)); p=strrchr(str,'@'); if(p) { /* name @addr */ replied=netmail(str,msg.subj,WM_QUOTE); sprintf(str2,text[DeleteMailQ],msg.from); } else { if(!msg.from_net.type && !stricmp(str,msg.from)) replied=email(msg.idx.from,str2,msg.subj,WM_EMAIL|WM_QUOTE); else if(!stricmp(str,"SYSOP")) replied=email(1,str2,msg.subj,WM_EMAIL|WM_QUOTE); else if((i=finduser(str))!=0) replied=email(i,str2,msg.subj,WM_EMAIL|WM_QUOTE); else replied=false; sprintf(str2,text[DeleteMailQ],msg.from); } if(replied==true && !(msg.hdr.attr&MSG_REPLIED)) { if(msg.total_hfields) smb_freemsgmem(&msg); msg.total_hfields=0; msg.idx.offset=0; if(smb_locksmbhdr(&smb)==SMB_SUCCESS) { /* Lock the entire base */ if(loadmsg(&msg,msg.idx.number)) { msg.hdr.attr|=MSG_REPLIED; msg.idx.attr=msg.hdr.attr; if((i=smb_putmsg(&smb,&msg))!=0) errormsg(WHERE,ERR_WRITE,smb.file,i); smb_unlockmsghdr(&smb,&msg); } smb_unlocksmbhdr(&smb); } } if(msg.hdr.attr&MSG_DELETE || !yesno(str2)) { if(smb.curmsg<smb.msgs-1) smb.curmsg++; else done=1; break; } /* Case 'D': must follow! */ case 'D': /* Delete last piece (toggle) */ if(msg.hdr.attr&MSG_PERMANENT) { bputs("\r\nPermanent message.\r\n"); domsg=0; break; } if(msg.total_hfields) smb_freemsgmem(&msg); msg.total_hfields=0; msg.idx.offset=0; if(smb_locksmbhdr(&smb)==SMB_SUCCESS) { /* Lock the entire base */ if(loadmsg(&msg,msg.idx.number)) { msg.hdr.attr^=MSG_DELETE; msg.idx.attr=msg.hdr.attr; // mail[smb.curmsg].attr=msg.hdr.attr; if((i=smb_putmsg(&smb,&msg))!=0) errormsg(WHERE,ERR_WRITE,smb.file,i); smb_unlockmsghdr(&smb,&msg); } smb_unlocksmbhdr(&smb); } if(smb.curmsg<smb.msgs-1) smb.curmsg++; else done=1; break; case 'F': /* Forward last piece */ domsg=0; bputs(text[ForwardMailTo]); if(!getstr(str,LEN_ALIAS,cfg.uq&UQ_NOUPRLWR ? K_NONE:K_UPRLWR)) break; i=finduser(str); if(!i) break; domsg=1; if(smb.curmsg<smb.msgs-1) smb.curmsg++; else done=1; smb_getmsgidx(&smb,&msg); forwardmail(&msg,i); if(msg.hdr.attr&MSG_PERMANENT) break; sprintf(str2,text[DeleteMailQ],msg.from); if(!yesno(str2)) break; if(msg.total_hfields) smb_freemsgmem(&msg); msg.total_hfields=0; msg.idx.offset=0; if(smb_locksmbhdr(&smb)==SMB_SUCCESS) { /* Lock the entire base */ if(loadmsg(&msg,msg.idx.number)) { msg.hdr.attr|=MSG_DELETE; msg.idx.attr=msg.hdr.attr; // mail[smb.curmsg].attr=msg.hdr.attr; if((i=smb_putmsg(&smb,&msg))!=0) errormsg(WHERE,ERR_WRITE,smb.file,i); smb_unlockmsghdr(&smb,&msg); } smb_unlocksmbhdr(&smb); } break; case 'H': domsg=0; msghdr(&msg); break; case 'L': /* List mail */ domsg=0; bprintf(text[StartWithN],(long)smb.curmsg+1); if((i=getnum(smb.msgs))>0) i--; else if(i==-1) break; else i=smb.curmsg; if(which==MAIL_SENT) bputs(text[MailSentLstHdr]); else if(which==MAIL_ALL) bputs(text[MailOnSystemLstHdr]); else bputs(text[MailWaitingLstHdr]); for(;i<smb.msgs && !msgabort();i++) { if(msg.total_hfields) smb_freemsgmem(&msg); msg.total_hfields=0; msg.idx.offset=mail[i].offset; if(!loadmsg(&msg,mail[i].number)) continue; smb_unlockmsghdr(&smb,&msg); if(which==MAIL_ALL) bprintf(text[MailOnSystemLstFmt] ,i+1,msg.from,msg.to ,msg.hdr.attr&MSG_DELETE ? '-' : msg.hdr.attr&MSG_REPLIED ? 'R' : msg.hdr.attr&MSG_READ ? ' ' : msg.from_net.type || msg.to_net.type ? 'N':'*' ,msg.subj); else bprintf(text[MailWaitingLstFmt],i+1 ,which==MAIL_SENT ? msg.to : (msg.hdr.attr&MSG_ANONYMOUS) && !SYSOP ? text[Anonymous] : msg.from ,msg.hdr.attr&MSG_DELETE ? '-' : msg.hdr.attr&MSG_REPLIED ? 'R' : msg.hdr.attr&MSG_READ ? ' ' : msg.from_net.type || msg.to_net.type ? 'N':'*' ,msg.subj); smb_freemsgmem(&msg); msg.total_hfields=0; } break; case 'Q': done=1; break; case 'C': /* Change attributes of last piece */ i=chmsgattr(msg.hdr.attr); if(msg.hdr.attr==i) break; if(msg.total_hfields) smb_freemsgmem(&msg); msg.total_hfields=0; msg.idx.offset=0; if(smb_locksmbhdr(&smb)==SMB_SUCCESS) { /* Lock the entire base */ if(loadmsg(&msg,msg.idx.number)) { msg.hdr.attr=msg.idx.attr=(ushort)i; if((i=smb_putmsg(&smb,&msg))!=0) errormsg(WHERE,ERR_WRITE,smb.file,i); smb_unlockmsghdr(&smb,&msg); } smb_unlocksmbhdr(&smb); } break; case '>': for(i=smb.curmsg+1;i<smb.msgs;i++) if(mail[i].subj==msg.idx.subj) break; if(i<smb.msgs) smb.curmsg=i; else domsg=0; break; case '<': /* Search Title backward */ for(i=smb.curmsg-1;i>-1;i--) if(mail[i].subj==msg.idx.subj) break; if(i>-1) smb.curmsg=i; else domsg=0; break; case '}': /* Search Author forward */ strcpy(str,msg.from); for(i=smb.curmsg+1;i<smb.msgs;i++) if(mail[i].from==msg.idx.from) break; if(i<smb.msgs) smb.curmsg=i; else domsg=0; break; case 'N': /* Got to next un-read message */ for(i=smb.curmsg+1;i<smb.msgs;i++) if(!(mail[i].attr&MSG_READ)) break; if(i<smb.msgs) smb.curmsg=i; else domsg=0; break; case '{': /* Search Author backward */ strcpy(str,msg.from); for(i=smb.curmsg-1;i>-1;i--) if(mail[i].from==msg.idx.from) break; if(i>-1) smb.curmsg=i; else domsg=0; break; case ']': /* Search To User forward */ strcpy(str,msg.to); for(i=smb.curmsg+1;i<smb.msgs;i++) if(mail[i].to==msg.idx.to) break; if(i<smb.msgs) smb.curmsg=i; else domsg=0; break; case '[': /* Search To User backward */ strcpy(str,msg.to); for(i=smb.curmsg-1;i>-1;i--) if(mail[i].to==msg.idx.to) break; if(i>-1) smb.curmsg=i; else domsg=0; break; case 0: case '+': if(smb.curmsg<smb.msgs-1) smb.curmsg++; else done=1; break; case '-': if(smb.curmsg>0) smb.curmsg--; break; case 'S': domsg=0; /* if(!yesno(text[SaveMsgToFile])) break; */ bputs(text[FileToWriteTo]); if(getstr(str,40,K_LINE)) msgtotxt(&msg,str,1,1); break; case 'E': editmsg(&msg,INVALID_SUB); break; case 'T': domsg=0; i=smb.curmsg; if(i) i++; j=i+10; if(j>smb.msgs) j=smb.msgs; if(which==MAIL_SENT) bputs(text[MailSentLstHdr]); else if(which==MAIL_ALL) bputs(text[MailOnSystemLstHdr]); else bputs(text[MailWaitingLstHdr]); for(;i<j;i++) { if(msg.total_hfields) smb_freemsgmem(&msg); msg.total_hfields=0; msg.idx.offset=mail[i].offset; if(!loadmsg(&msg,mail[i].number)) continue; smb_unlockmsghdr(&smb,&msg); if(which==MAIL_ALL) bprintf(text[MailOnSystemLstFmt] ,i+1,msg.from,msg.to ,msg.hdr.attr&MSG_DELETE ? '-' : msg.hdr.attr&MSG_REPLIED ? 'R' : msg.hdr.attr&MSG_READ ? ' ' : msg.from_net.type || msg.to_net.type ? 'N':'*' ,msg.subj); else bprintf(text[MailWaitingLstFmt],i+1 ,which==MAIL_SENT ? msg.to : (msg.hdr.attr&MSG_ANONYMOUS) && !SYSOP ? text[Anonymous] : msg.from ,msg.hdr.attr&MSG_DELETE ? '-' : msg.hdr.attr&MSG_REPLIED ? 'R' : msg.hdr.attr&MSG_READ ? ' ' : msg.from_net.type || msg.to_net.type ? 'N':'*' ,msg.subj); smb_freemsgmem(&msg); msg.total_hfields=0; } smb.curmsg=(i-1); break; case 'U': /* user edit */ msg.hdr.number=msg.idx.number; smb_getmsgidx(&smb,&msg); useredit(which==MAIL_SENT ? msg.idx.to : msg.idx.from); break; case 'P': /* Purge author and all mail to/from */ if(noyes(text[AreYouSureQ])) break; msg.hdr.number=msg.idx.number; smb_getmsgidx(&smb,&msg); purgeuser(msg.idx.from); if(smb.curmsg<smb.msgs-1) smb.curmsg++; break; case '?': strcpy(str,which==MAIL_YOUR ? "mailread" : which==MAIL_ALL ? "allmail" : "sentmail"); menu(str); if(SYSOP && which==MAIL_SENT) menu("syssmail"); else if(SYSOP && which==MAIL_YOUR) menu("sysmailr"); /* Sysop Mail Read */ domsg=0; break; } } if(msg.total_hfields) smb_freemsgmem(&msg); if(smb.msgs) free(mail); /***************************************/ /* Delete messages marked for deletion */ /***************************************/ if(cfg.sys_misc&SM_DELEMAIL) { if((i=smb_locksmbhdr(&smb))!=0) /* Lock the base, so nobody */ errormsg(WHERE,ERR_LOCK,smb.file,i); /* messes with the index */ else delmail(usernumber,which); } smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); }
bool sbbs_t::inetmail(char *into, char *subj, long mode) { char str[256],str2[256],msgpath[256],title[256],name[256],ch ,buf[SDT_BLOCK_LEN],*p,addr[256]; char tmp[512]; char your_addr[128]; ushort xlat=XLAT_NONE,net=NET_INTERNET; int i,j,x,file; long l; ulong length,offset; FILE *instream; smbmsg_t msg; if(useron.etoday>=cfg.level_emailperday[useron.level] && !SYSOP) { bputs(text[TooManyEmailsToday]); return(false); } strcpy(name,into); strcpy(addr,into); strcpy(title,subj); if((!SYSOP && !(cfg.inetmail_misc&NMAIL_ALLOW)) || useron.rest&FLAG('M')) { bputs(text[NoNetMailAllowed]); return(false); } if(cfg.inetmail_cost && !(useron.exempt&FLAG('S'))) { if(useron.cdt+useron.freecdt<cfg.inetmail_cost) { bputs(text[NotEnoughCredits]); return(false); } sprintf(str,text[NetMailCostContinueQ],cfg.inetmail_cost); if(noyes(str)) return(false); } /* Get destination user name */ p=strrchr(name,'@'); if(!p) p=strrchr(name,'!'); if(p) { *p=0; truncsp(name); } /* Get this user's internet mailing address */ usermailaddr(&cfg,your_addr ,cfg.inetmail_misc&NMAIL_ALIAS ? useron.alias : useron.name); bprintf(text[InternetMailing],addr,your_addr); action=NODE_SMAL; nodesync(); sprintf(msgpath,"%snetmail.msg",cfg.node_dir); if(!writemsg(msgpath,nulstr,title,mode,INVALID_SUB,into)) { bputs(text[Aborted]); return(false); } if(mode&WM_FILE) { sprintf(str2,"%sfile/%04u.out",cfg.data_dir,useron.number); MKDIR(str2); sprintf(str2,"%sfile/%04u.out/%s",cfg.data_dir,useron.number,title); if(fexistcase(str2)) { bputs(text[FileAlreadyThere]); remove(msgpath); return(false); } #if 0 /* no such thing as local logon */ if(online==ON_LOCAL) { /* Local upload */ bputs(text[EnterPath]); if(!getstr(str,60,K_LINE|K_UPPER)) { bputs(text[Aborted]); remove(msgpath); return(false); } backslash(str); strcat(str,title); mv(str,str2,1); } else #endif { /* Remote */ xfer_prot_menu(XFER_UPLOAD); mnemonics(text[ProtocolOrQuit]); strcpy(str,"Q"); for(x=0;x<cfg.total_prots;x++) if(cfg.prot[x]->ulcmd[0] && chk_ar(cfg.prot[x]->ar,&useron)) { sprintf(tmp,"%c",cfg.prot[x]->mnemonic); strcat(str,tmp); } ch=(char)getkeys(str,0); if(ch=='Q' || sys_status&SS_ABORT) { bputs(text[Aborted]); remove(msgpath); return(false); } for(x=0;x<cfg.total_prots;x++) if(cfg.prot[x]->ulcmd[0] && cfg.prot[x]->mnemonic==ch && chk_ar(cfg.prot[x]->ar,&useron)) break; if(x<cfg.total_prots) /* This should be always */ protocol(cfg.prot[x],XFER_UPLOAD,str2,nulstr,true); } sprintf(tmp,"%s%s",cfg.temp_dir,title); if(!fexistcase(str2) && fexistcase(tmp)) mv(tmp,str2,0); l=flength(str2); if(l>0) bprintf(text[FileNBytesReceived],title,ultoac(l,tmp)); else { bprintf(text[FileNotReceived],title); remove(msgpath); return(false); } } if((i=smb_stack(&smb,SMB_STACK_PUSH))!=SMB_SUCCESS) { errormsg(WHERE,ERR_OPEN,"MAIL",i); return(false); } sprintf(smb.file,"%smail",cfg.data_dir); smb.retry_time=cfg.smb_retry_time; smb.subnum=INVALID_SUB; if((i=smb_open(&smb))!=SMB_SUCCESS) { smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); return(false); } if(filelength(fileno(smb.shd_fp))<1) { /* Create it if it doesn't exist */ smb.status.max_crcs=cfg.mail_maxcrcs; smb.status.max_age=cfg.mail_maxage; smb.status.max_msgs=0; smb.status.attr=SMB_EMAIL; if((i=smb_create(&smb))!=SMB_SUCCESS) { smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_CREATE,smb.file,i); return(false); } } if((i=smb_locksmbhdr(&smb))!=SMB_SUCCESS) { smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_LOCK,smb.file,i); return(false); } length=flength(msgpath)+2; /* +2 for translation string */ if(length&0xfff00000UL) { smb_unlocksmbhdr(&smb); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_LEN,msgpath,length); return(false); } if((i=smb_open_da(&smb))!=SMB_SUCCESS) { smb_unlocksmbhdr(&smb); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); return(false); } if(cfg.sys_misc&SM_FASTMAIL) offset=smb_fallocdat(&smb,length,1); else offset=smb_allocdat(&smb,length,1); smb_close_da(&smb); if((file=open(msgpath,O_RDONLY|O_BINARY))==-1 || (instream=fdopen(file,"rb"))==NULL) { smb_freemsgdat(&smb,offset,length,1); smb_unlocksmbhdr(&smb); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_OPEN,msgpath,O_RDONLY|O_BINARY); return(false); } setvbuf(instream,NULL,_IOFBF,2*1024); fseek(smb.sdt_fp,offset,SEEK_SET); xlat=XLAT_NONE; fwrite(&xlat,2,1,smb.sdt_fp); x=SDT_BLOCK_LEN-2; /* Don't read/write more than 255 */ while(!feof(instream)) { memset(buf,0,x); j=fread(buf,1,x,instream); if(j<1) break; if(j>1 && (j!=x || feof(instream)) && buf[j-1]==LF && buf[j-2]==CR) buf[j-1]=buf[j-2]=0; fwrite(buf,j,1,smb.sdt_fp); x=SDT_BLOCK_LEN; } fflush(smb.sdt_fp); fclose(instream); memset(&msg,0,sizeof(smbmsg_t)); msg.hdr.version=smb_ver(); if(mode&WM_FILE) msg.hdr.auxattr|=MSG_FILEATTACH; msg.hdr.when_written.time=msg.hdr.when_imported.time=time(NULL); msg.hdr.when_written.zone=msg.hdr.when_imported.zone=sys_timezone(&cfg); msg.hdr.offset=offset; net=NET_INTERNET; smb_hfield_str(&msg,RECIPIENT,name); smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(net),&net); smb_hfield_str(&msg,RECIPIENTNETADDR,addr); strcpy(str,cfg.inetmail_misc&NMAIL_ALIAS ? useron.alias : useron.name); smb_hfield_str(&msg,SENDER,str); sprintf(str,"%u",useron.number); smb_hfield_str(&msg,SENDEREXT,str); /* smb_hfield(&msg,SENDERNETTYPE,sizeof(net),&net); smb_hfield(&msg,SENDERNETADDR,strlen(sys_inetaddr),sys_inetaddr); */ /* Security logging */ msg_client_hfields(&msg,&client); smb_hfield_str(&msg,SUBJECT,title); strcpy(str,title); smb_dfield(&msg,TEXT_BODY,length); i=smb_addmsghdr(&smb,&msg,SMB_SELFPACK); // calls smb_unlocksmbhdr() smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); smb_freemsgmem(&msg); if(i!=SMB_SUCCESS) { errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); smb_freemsgdat(&smb,offset,length,1); return(false); } if(mode&WM_FILE && online==ON_REMOTE) autohangup(); if(cfg.inetmail_sem[0]) /* update semaphore file */ ftouch(cmdstr(cfg.inetmail_sem,nulstr,nulstr,NULL)); if(!(useron.exempt&FLAG('S'))) subtract_cdt(&cfg,&useron,cfg.inetmail_cost); useron.emails++; logon_emails++; putuserrec(&cfg,useron.number,U_EMAILS,5,ultoa(useron.emails,tmp,10)); useron.etoday++; putuserrec(&cfg,useron.number,U_ETODAY,5,ultoa(useron.etoday,tmp,10)); sprintf(str,"%s sent Internet Mail to %s (%s)" ,useron.alias ,name,addr); logline("EN",str); return(true); }
bool sbbs_t::qnetmail(char *into, char *subj, long mode) { char str[256],msgpath[128],title[128],to[128],fulladdr[128] ,buf[SDT_BLOCK_LEN],*addr; char tmp[512]; ushort xlat=XLAT_NONE,net=NET_QWK,touser; int i,j,x,file; ulong length,offset; FILE *instream; smbmsg_t msg; if(useron.etoday>=cfg.level_emailperday[useron.level] && !SYSOP) { bputs(text[TooManyEmailsToday]); return(false); } strcpy(to,into); strcpy(title,subj); if(useron.rest&FLAG('M')) { bputs(text[NoNetMailAllowed]); return(false); } addr=strrchr(to,'@'); if(!addr) { bputs(text[InvalidNetMailAddr]); return(false); } *addr=0; addr++; strupr(addr); truncsp(addr); touser=qwk_route(addr,fulladdr); if(!fulladdr[0]) { bputs(text[InvalidNetMailAddr]); return(false); } truncsp(to); if(!stricmp(to,"SBBS") && !SYSOP) { bputs(text[InvalidNetMailAddr]); return(false); } bprintf(text[NetMailing],to,fulladdr ,useron.alias,cfg.sys_id); action=NODE_SMAL; nodesync(); sprintf(msgpath,"%snetmail.msg",cfg.node_dir); if(!writemsg(msgpath,nulstr,title,mode|WM_QWKNET,INVALID_SUB,to)) { bputs(text[Aborted]); return(false); } if((i=smb_stack(&smb,SMB_STACK_PUSH))!=SMB_SUCCESS) { errormsg(WHERE,ERR_OPEN,"MAIL",i); return(false); } sprintf(smb.file,"%smail",cfg.data_dir); smb.retry_time=cfg.smb_retry_time; smb.subnum=INVALID_SUB; if((i=smb_open(&smb))!=SMB_SUCCESS) { smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); return(false); } if(filelength(fileno(smb.shd_fp))<1) { /* Create it if it doesn't exist */ smb.status.max_crcs=cfg.mail_maxcrcs; smb.status.max_msgs=0; smb.status.max_age=cfg.mail_maxage; smb.status.attr=SMB_EMAIL; if((i=smb_create(&smb))!=SMB_SUCCESS) { smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_CREATE,smb.file,i,smb.last_error); return(false); } } if((i=smb_locksmbhdr(&smb))!=SMB_SUCCESS) { smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error); return(false); } length=flength(msgpath)+2; /* +2 for translation string */ if(length&0xfff00000UL) { smb_unlocksmbhdr(&smb); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_LEN,msgpath,length); return(false); } if((i=smb_open_da(&smb))!=SMB_SUCCESS) { smb_unlocksmbhdr(&smb); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); return(false); } if(cfg.sys_misc&SM_FASTMAIL) offset=smb_fallocdat(&smb,length,1); else offset=smb_allocdat(&smb,length,1); smb_close_da(&smb); if((file=open(msgpath,O_RDONLY|O_BINARY))==-1 || (instream=fdopen(file,"rb"))==NULL) { smb_freemsgdat(&smb,offset,length,1); smb_unlocksmbhdr(&smb); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_OPEN,msgpath,O_RDONLY|O_BINARY); return(false); } setvbuf(instream,NULL,_IOFBF,2*1024); fseek(smb.sdt_fp,offset,SEEK_SET); xlat=XLAT_NONE; fwrite(&xlat,2,1,smb.sdt_fp); x=SDT_BLOCK_LEN-2; /* Don't read/write more than 255 */ while(!feof(instream)) { memset(buf,0,x); j=fread(buf,1,x,instream); if(j<1) break; if(j>1 && (j!=x || feof(instream)) && buf[j-1]==LF && buf[j-2]==CR) buf[j-1]=buf[j-2]=0; fwrite(buf,j,1,smb.sdt_fp); x=SDT_BLOCK_LEN; } fflush(smb.sdt_fp); fclose(instream); memset(&msg,0,sizeof(smbmsg_t)); msg.hdr.version=smb_ver(); if(mode&WM_FILE) msg.hdr.auxattr|=MSG_FILEATTACH; msg.hdr.when_written.time=msg.hdr.when_imported.time=time(NULL); msg.hdr.when_written.zone=msg.hdr.when_imported.zone=sys_timezone(&cfg); msg.hdr.offset=offset; net=NET_QWK; smb_hfield_str(&msg,RECIPIENT,to); sprintf(str,"%u",touser); smb_hfield_str(&msg,RECIPIENTEXT,str); smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(net),&net); smb_hfield_str(&msg,RECIPIENTNETADDR,fulladdr); smb_hfield_str(&msg,SENDER,useron.alias); sprintf(str,"%u",useron.number); smb_hfield_str(&msg,SENDEREXT,str); /* Security logging */ msg_client_hfields(&msg,&client); smb_hfield_str(&msg,SUBJECT,title); smb_dfield(&msg,TEXT_BODY,length); i=smb_addmsghdr(&smb,&msg,SMB_SELFPACK); // calls smb_unlocksmbhdr() smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); smb_freemsgmem(&msg); if(i!=SMB_SUCCESS) { errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); smb_freemsgdat(&smb,offset,length,1); return(false); } useron.emails++; logon_emails++; putuserrec(&cfg,useron.number,U_EMAILS,5,ultoa(useron.emails,tmp,10)); useron.etoday++; putuserrec(&cfg,useron.number,U_ETODAY,5,ultoa(useron.etoday,tmp,10)); sprintf(str,"%s sent QWK NetMail to %s (%s)" ,useron.alias ,to,fulladdr); logline("EN",str); return(true); }
void sbbs_t::qwktonetmail(FILE *rep, char *block, char *into, uchar fromhub) { char *qwkbuf,to[129],name[129],sender[129],senderaddr[129] ,str[256],*p,*cp,*addr,fulladdr[129],ch; char tmp[512]; int i,fido,inet=0,qnet=0; ushort net; uint16_t xlat; long l,offset,length,m,n; faddr_t fidoaddr; fmsghdr_t hdr; smbmsg_t msg; struct tm tm; if(useron.rest&FLAG('M')) { bputs(text[NoNetMailAllowed]); return; } to[0]=0; name[0]=0; sender[0]=0; senderaddr[0]=0; fulladdr[0]=0; sprintf(str,"%.6s",block+116); n=atol(str); /* i = number of 128 byte records */ if(n<2L || n>999999L) { errormsg(WHERE,ERR_CHK,"QWK blocks",n); return; } if((qwkbuf=(char *)malloc(n*QWK_BLOCK_LEN))==NULL) { errormsg(WHERE,ERR_ALLOC,nulstr,n*QWK_BLOCK_LEN); return; } memcpy((char *)qwkbuf,block,QWK_BLOCK_LEN); fread(qwkbuf+QWK_BLOCK_LEN,n-1,QWK_BLOCK_LEN,rep); if(into==NULL) sprintf(to,"%-128.128s",(char *)qwkbuf+QWK_BLOCK_LEN); /* To user on first line */ else SAFECOPY(to,into); p=strchr(to,QWK_NEWLINE); /* chop off at first CR */ if(p) *p=0; SAFECOPY(name,to); p=strchr(name,'@'); if(p) *p=0; truncsp(name); p=strrchr(to,'@'); /* Find '@' in name@addr */ if(p && !isdigit(*(p+1)) && !strchr(p,'.') && !strchr(p,':')) { /* QWKnet */ qnet=1; *p=0; } else if(p==NULL || !isdigit(*(p+1)) || !cfg.total_faddrs) { if(p==NULL && cfg.dflt_faddr.zone) fidoaddr=cfg.dflt_faddr; else if(cfg.inetmail_misc&NMAIL_ALLOW) { /* Internet */ inet=1; } else if(cfg.dflt_faddr.zone) fidoaddr=cfg.dflt_faddr; else { bputs(text[InvalidNetMailAddr]); free(qwkbuf); return; } } else { fidoaddr=atofaddr(&cfg,p+1); /* Get fido address */ *p=0; /* Chop off address */ } if(!inet && !qnet && /* FidoNet */ ((!SYSOP && !(cfg.netmail_misc&NMAIL_ALLOW)) || !cfg.total_faddrs)) { bputs(text[NoNetMailAllowed]); free(qwkbuf); return; } truncsp(to); /* Truncate off space */ if(!stricmp(to,"SBBS") && !SYSOP && qnet) { free(qwkbuf); return; } l=QWK_BLOCK_LEN; /* Start of message text */ if(qnet || inet) { if(into==NULL) { /* If name@addr on first line, skip first line */ while(l<(n*QWK_BLOCK_LEN) && qwkbuf[l]!=QWK_NEWLINE) l++; l++; } memset(&msg,0,sizeof(smbmsg_t)); msg.hdr.version=smb_ver(); msg.hdr.when_imported.time=time32(NULL); msg.hdr.when_imported.zone=sys_timezone(&cfg); if(fromhub || useron.rest&FLAG('Q')) { net=NET_QWK; smb_hfield(&msg,SENDERNETTYPE,sizeof(net),&net); if(!strncmp(qwkbuf+l,"@VIA:",5)) { sprintf(str,"%.128s",qwkbuf+l+5); cp=strchr(str,QWK_NEWLINE); if(cp) *cp=0; l+=strlen(str)+1; cp=str; while(*cp && *cp<=' ') cp++; sprintf(senderaddr,"%s/%s" ,fromhub ? cfg.qhub[fromhub-1]->id : useron.alias,cp); strupr(senderaddr); smb_hfield(&msg,SENDERNETADDR,strlen(senderaddr),senderaddr); } else { if(fromhub) SAFECOPY(senderaddr, cfg.qhub[fromhub-1]->id); else SAFECOPY(senderaddr, useron.alias); strupr(senderaddr); smb_hfield(&msg,SENDERNETADDR,strlen(senderaddr),senderaddr); } sprintf(sender,"%.25s",block+46); /* From name */ } else { /* Not Networked */ msg.hdr.when_written.zone=sys_timezone(&cfg); sprintf(str,"%u",useron.number); smb_hfield(&msg,SENDEREXT,strlen(str),str); SAFECOPY(sender,(qnet || cfg.inetmail_misc&NMAIL_ALIAS) ? useron.alias : useron.name); } truncsp(sender); smb_hfield(&msg,SENDER,strlen(sender),sender); if(fromhub) msg.idx.from=0; else msg.idx.from=useron.number; if(!strncmp(qwkbuf+l,"@TZ:",4)) { sprintf(str,"%.128s",qwkbuf+l); cp=strchr(str,QWK_NEWLINE); if(cp) *cp=0; l+=strlen(str)+1; cp=str+4; while(*cp && *cp<=' ') cp++; msg.hdr.when_written.zone=(short)ahtoul(cp); } else msg.hdr.when_written.zone=sys_timezone(&cfg); memset(&tm,0,sizeof(tm)); tm.tm_mon=((qwkbuf[8]&0xf)*10)+(qwkbuf[9]&0xf); if(tm.tm_mon) tm.tm_mon--; /* 0 based */ tm.tm_mday=((qwkbuf[11]&0xf)*10)+(qwkbuf[12]&0xf); tm.tm_year=((qwkbuf[14]&0xf)*10)+(qwkbuf[15]&0xf); if(tm.tm_year<Y2K_2DIGIT_WINDOW) tm.tm_year+=100; tm.tm_hour=((qwkbuf[16]&0xf)*10)+(qwkbuf[17]&0xf); tm.tm_min=((qwkbuf[19]&0xf)*10)+(qwkbuf[20]&0xf); /* From QWK time */ tm.tm_sec=0; tm.tm_isdst=-1; /* Do not adjust for DST */ msg.hdr.when_written.time=mktime32(&tm); sprintf(str,"%.25s",block+71); /* Title */ smb_hfield(&msg,SUBJECT,strlen(str),str); } if(qnet) { p++; addr=p; msg.idx.to=qwk_route(addr,fulladdr); if(!fulladdr[0]) { /* Invalid address, so BOUNCE it */ /** errormsg(WHERE,ERR_CHK,addr,0); free(qwkbuf); smb_freemsgmem(msg); return; **/ smb_hfield(&msg,SENDER,strlen(cfg.sys_id),cfg.sys_id); msg.idx.from=0; msg.idx.to=useron.number; SAFECOPY(to,sender); SAFECOPY(fulladdr,senderaddr); SAFEPRINTF(str,"BADADDR: %s",addr); smb_hfield(&msg,SUBJECT,strlen(str),str); net=NET_NONE; smb_hfield(&msg,SENDERNETTYPE,sizeof(net),&net); } /* This is required for fixsmb to be able to rebuild the index */ SAFEPRINTF(str,"%u",msg.idx.to); smb_hfield_str(&msg,RECIPIENTEXT,str); smb_hfield(&msg,RECIPIENT,strlen(name),name); net=NET_QWK; smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(net),&net); truncsp(fulladdr); if(fulladdr[0]) smb_hfield(&msg,RECIPIENTNETADDR,strlen(fulladdr),fulladdr); bprintf(text[NetMailing],to,fulladdr,sender,cfg.sys_id); } if(inet) { /* Internet E-mail */ if(cfg.inetmail_cost && !(useron.exempt&FLAG('S'))) { if(useron.cdt+useron.freecdt<cfg.inetmail_cost) { bputs(text[NotEnoughCredits]); free(qwkbuf); smb_freemsgmem(&msg); return; } sprintf(str,text[NetMailCostContinueQ],cfg.inetmail_cost); if(noyes(str)) { free(qwkbuf); smb_freemsgmem(&msg); return; } } net=NET_INTERNET; smb_hfield(&msg,RECIPIENT,strlen(name),name); msg.idx.to=0; /* Out-bound NetMail set to 0 */ smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(net),&net); smb_hfield(&msg,RECIPIENTNETADDR,strlen(to),to); bprintf(text[NetMailing],name,to ,cfg.inetmail_misc&NMAIL_ALIAS ? useron.alias : useron.name ,cfg.sys_inetaddr); } if(qnet || inet) { bputs(text[WritingIndx]); if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) { errormsg(WHERE,ERR_OPEN,"MAIL",i); free(qwkbuf); smb_freemsgmem(&msg); return; } sprintf(smb.file,"%smail", cfg.data_dir); smb.retry_time=cfg.smb_retry_time; smb.subnum=INVALID_SUB; if((i=smb_open(&smb))!=0) { smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); free(qwkbuf); smb_freemsgmem(&msg); return; } if(smb_fgetlength(smb.shd_fp)<1L) { /* Create it if it doesn't exist */ smb.status.max_crcs=cfg.mail_maxcrcs; smb.status.max_msgs=0; smb.status.max_age=cfg.mail_maxage; smb.status.attr=SMB_EMAIL; if((i=smb_create(&smb))!=0) { smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_CREATE,smb.file,i,smb.last_error); free(qwkbuf); smb_freemsgmem(&msg); return; } } length=n*256L; // Extra big for CRLF xlat, was (n-1L)*256L (03/16/96) if(length&0xfff00000UL || !length) { smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); sprintf(str,"REP msg (%ld)",n); errormsg(WHERE,ERR_LEN,str,length); free(qwkbuf); smb_freemsgmem(&msg); return; } if((i=smb_open_da(&smb))!=0) { smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); free(qwkbuf); smb_freemsgmem(&msg); return; } if(cfg.sys_misc&SM_FASTMAIL) offset=smb_fallocdat(&smb,length,1); else offset=smb_allocdat(&smb,length,1); smb_close_da(&smb); smb_fseek(smb.sdt_fp,offset,SEEK_SET); xlat=XLAT_NONE; smb_fwrite(&smb,&xlat,2,smb.sdt_fp); m=2; for(;l<n*QWK_BLOCK_LEN && m<length;l++) { if(qwkbuf[l]==0 || qwkbuf[l]==LF) continue; if(qwkbuf[l]==QWK_NEWLINE) { smb_fwrite(&smb,crlf,2,smb.sdt_fp); m+=2; continue; } smb_fputc(qwkbuf[l],smb.sdt_fp); m++; } for(ch=0;m<length;m++) /* Pad out with NULLs */ smb_fputc(ch,smb.sdt_fp); smb_fflush(smb.sdt_fp); msg.hdr.offset=offset; smb_dfield(&msg,TEXT_BODY,length); i=smb_addmsghdr(&smb,&msg,SMB_SELFPACK); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); smb_freemsgmem(&msg); if(i!=SMB_SUCCESS) { errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); smb_freemsgdat(&smb,offset,length,1); } else { /* Successful */ if(inet) { if(cfg.inetmail_sem[0]) /* update semaphore file */ ftouch(cmdstr(cfg.inetmail_sem,nulstr,nulstr,NULL)); if(!(useron.exempt&FLAG('S'))) subtract_cdt(&cfg,&useron,cfg.inetmail_cost); } useron.emails++; logon_emails++; putuserrec(&cfg,useron.number,U_EMAILS,5,ultoa(useron.emails,tmp,10)); useron.etoday++; putuserrec(&cfg,useron.number,U_ETODAY,5,ultoa(useron.etoday,tmp,10)); sprintf(str,"%s sent %s NetMail to %s (%s) via QWK" ,useron.alias ,qnet ? "QWK":"Internet",name,qnet ? fulladdr : to); logline("EN",str); } free((char *)qwkbuf); return; } /****************************** FidoNet **********************************/ if(!fidoaddr.zone || !cfg.netmail_dir[0]) { // No fido netmail allowed bputs(text[InvalidNetMailAddr]); free(qwkbuf); return; } memset(&hdr,0,sizeof(hdr)); /* Initialize header to null */ if(fromhub || useron.rest&FLAG('Q')) { sprintf(str,"%.25s",block+46); /* From */ truncsp(str); sprintf(tmp,"@%s",fromhub ? cfg.qhub[fromhub-1]->id : useron.alias); strupr(tmp); strcat(str,tmp); } else SAFECOPY(str,cfg.netmail_misc&NMAIL_ALIAS ? useron.alias : useron.name); SAFECOPY(hdr.from,str); SAFECOPY(hdr.to,to); /* Look-up in nodelist? */ if(cfg.netmail_cost && !(useron.exempt&FLAG('S'))) { if(useron.cdt+useron.freecdt<cfg.netmail_cost) { bputs(text[NotEnoughCredits]); free(qwkbuf); return; } sprintf(str,text[NetMailCostContinueQ],cfg.netmail_cost); if(noyes(str)) { free(qwkbuf); return; } } hdr.destzone =fidoaddr.zone; hdr.destnet =fidoaddr.net; hdr.destnode =fidoaddr.node; hdr.destpoint =fidoaddr.point; for(i=0;i<cfg.total_faddrs;i++) if(fidoaddr.zone==cfg.faddr[i].zone && fidoaddr.net==cfg.faddr[i].net) break; if(i==cfg.total_faddrs) { for(i=0;i<cfg.total_faddrs;i++) if(fidoaddr.zone==cfg.faddr[i].zone) break; } if(i==cfg.total_faddrs) i=0; hdr.origzone =cfg.faddr[i].zone; hdr.orignet =cfg.faddr[i].net; hdr.orignode =cfg.faddr[i].node; hdr.origpoint =cfg.faddr[i].point; smb_faddrtoa(&cfg.faddr[i],str); bprintf(text[NetMailing],hdr.to,smb_faddrtoa(&fidoaddr,tmp),hdr.from,str); tm.tm_mon=((qwkbuf[8]&0xf)*10)+(qwkbuf[9]&0xf); if (tm.tm_mon) tm.tm_mon--; tm.tm_mday=((qwkbuf[11]&0xf)*10)+(qwkbuf[12]&0xf); tm.tm_year=((qwkbuf[14]&0xf)*10)+(qwkbuf[15]&0xf)+1900; tm.tm_hour=((qwkbuf[16]&0xf)*10)+(qwkbuf[17]&0xf); tm.tm_min=((qwkbuf[19]&0xf)*10)+(qwkbuf[20]&0xf); /* From QWK time */ tm.tm_sec=0; sprintf(hdr.time,"%02u %3.3s %02u %02u:%02u:%02u" /* To FidoNet */ ,tm.tm_mday,mon[tm.tm_mon],TM_YEAR(tm.tm_year) ,tm.tm_hour,tm.tm_min,tm.tm_sec); hdr.attr=(FIDO_LOCAL|FIDO_PRIVATE); if(cfg.netmail_misc&NMAIL_CRASH) hdr.attr|=FIDO_CRASH; if(cfg.netmail_misc&NMAIL_HOLD) hdr.attr|=FIDO_HOLD; if(cfg.netmail_misc&NMAIL_KILL) hdr.attr|=FIDO_KILLSENT; sprintf(str,"%.25s",block+71); /* Title */ truncsp(str); p=str; if((SYSOP || useron.exempt&FLAG('F')) && !strnicmp(p,"CR:",3)) { /* Crash over-ride by sysop */ p+=3; /* skip CR: */ if(*p==' ') p++; /* skip extra space if it exists */ hdr.attr|=FIDO_CRASH; } if((SYSOP || useron.exempt&FLAG('F')) && !strnicmp(p,"FR:",3)) { /* File request */ p+=3; /* skip FR: */ if(*p==' ') p++; hdr.attr|=FIDO_FREQ; } if((SYSOP || useron.exempt&FLAG('F')) && !strnicmp(p,"RR:",3)) { /* Return receipt request */ p+=3; /* skip RR: */ if(*p==' ') p++; hdr.attr|=FIDO_RRREQ; } if((SYSOP || useron.exempt&FLAG('F')) && !strnicmp(p,"FA:",3)) { /* File attachment */ p+=3; /* skip FA: */ if(*p==' ') p++; hdr.attr|=FIDO_FILE; } SAFECOPY(hdr.subj,p); md(cfg.netmail_dir); for(i=1;i;i++) { sprintf(str,"%s%u.msg", cfg.netmail_dir,i); if(!fexistcase(str)) break; } if(!i) { bputs(text[TooManyEmailsToday]); return; } if((fido=nopen(str,O_WRONLY|O_CREAT|O_EXCL))==-1) { free(qwkbuf); errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_EXCL); return; } write(fido,&hdr,sizeof(hdr)); pt_zone_kludge(hdr,fido); if(cfg.netmail_misc&NMAIL_DIRECT) { sprintf(str,"\1FLAGS DIR\r\n"); write(fido,str,strlen(str)); } l=QWK_BLOCK_LEN; if(into==NULL) { /* If name@addr on first line, skip first line */ while(l<n*QWK_BLOCK_LEN && qwkbuf[l]!=QWK_NEWLINE) l++; l++; } length=n*QWK_BLOCK_LEN; while(l<length) { if(qwkbuf[l]==CTRL_A) { /* Ctrl-A, so skip it and the next char */ l++; if(l>=length || toupper(qwkbuf[l])=='Z') /* EOF */ break; if((ch=ctrl_a_to_ascii_char(qwkbuf[l])) != 0) write(fido,&ch,1); } else if(qwkbuf[l]!=LF) { if(qwkbuf[l]==QWK_NEWLINE) /* QWK cr/lf char converted to hard CR */ qwkbuf[l]=CR; write(fido,(char *)qwkbuf+l,1); } l++; } l=0; write(fido,&l,1); /* Null terminator */ close(fido); free((char *)qwkbuf); if(cfg.netmail_sem[0]) /* update semaphore file */ ftouch(cmdstr(cfg.netmail_sem,nulstr,nulstr,NULL)); if(!(useron.exempt&FLAG('S'))) subtract_cdt(&cfg,&useron,cfg.netmail_cost); useron.emails++; logon_emails++; putuserrec(&cfg,useron.number,U_EMAILS,5,ultoa(useron.emails,tmp,10)); useron.etoday++; putuserrec(&cfg,useron.number,U_ETODAY,5,ultoa(useron.etoday,tmp,10)); sprintf(str,"%s sent NetMail to %s @%s via QWK" ,useron.alias ,hdr.to,smb_faddrtoa(&fidoaddr,tmp)); logline("EN",str); }