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::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 postmsg(char type, char* to, char* to_number, char* to_address, char* from, char* from_number, char* subject, FILE* fp) { char str[128]; char buf[1024]; uchar* msgtxt=NULL; uchar* newtxt; long msgtxtlen; ushort net; int i; ushort agent=AGENT_SMBUTIL; smbmsg_t msg; long dupechk_hashes=SMB_HASH_SOURCE_DUPE; /* Read message text from stream (file or stdin) */ msgtxtlen=0; while(!feof(fp)) { i=fread(buf,1,sizeof(buf),fp); if(i<1) break; if((msgtxt=(uchar*)realloc(msgtxt,msgtxtlen+i+1))==NULL) { fprintf(errfp,"\n%s!realloc(%ld) failure\n",beep,msgtxtlen+i+1); bail(1); } memcpy(msgtxt+msgtxtlen,buf,i); msgtxtlen+=i; } if(msgtxt!=NULL) { msgtxt[msgtxtlen]=0; /* Must be NULL-terminated */ if((newtxt=(uchar*)malloc((msgtxtlen*2)+1))==NULL) { fprintf(errfp,"\n%s!malloc(%ld) failure\n",beep,(msgtxtlen*2)+1); bail(1); } /* Expand LFs to CRLFs */ msgtxtlen=lf_expand(msgtxt, newtxt); free(msgtxt); msgtxt=newtxt; } memset(&msg,0,sizeof(smbmsg_t)); msg.hdr.when_written.time=(uint32_t)time(NULL); msg.hdr.when_written.zone=tzone; msg.hdr.when_imported=msg.hdr.when_written; if((to==NULL || stricmp(to,"All")==0) && to_address!=NULL) to=to_address; if(to==NULL) { printf("To User Name: "); fgets(str,sizeof(str),stdin); } else SAFECOPY(str,to); truncsp(str); if((i=smb_hfield_str(&msg,RECIPIENT,str))!=SMB_SUCCESS) { fprintf(errfp,"\n%s!smb_hfield_str(0x%02X) returned %d: %s\n" ,beep,RECIPIENT,i,smb.last_error); bail(1); } if(type=='E' || type=='N') smb.status.attr|=SMB_EMAIL; if(smb.status.attr&SMB_EMAIL) { if(to_address==NULL) { if(to_number==NULL) { printf("To User Number: "); gets(str); } else SAFECOPY(str,to_number); truncsp(str); if((i=smb_hfield_str(&msg,RECIPIENTEXT,str))!=SMB_SUCCESS) { fprintf(errfp,"\n%s!smb_hfield_str(0x%02X) returned %d: %s\n" ,beep,RECIPIENTEXT,i,smb.last_error); bail(1); } } } if(smb.status.attr&SMB_EMAIL && (type=='N' || to_address!=NULL)) { if(to_address==NULL) { printf("To Address (e.g. user@host): "); gets(str); } else SAFECOPY(str,to_address); truncsp(str); if(*str) { net=smb_netaddr_type(str); if((i=smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(net),&net))!=SMB_SUCCESS) { fprintf(errfp,"\n%s!smb_hfield(0x%02X) returned %d: %s\n" ,beep,RECIPIENTNETTYPE,i,smb.last_error); bail(1); } if((i=smb_hfield_str(&msg,RECIPIENTNETADDR,str))!=SMB_SUCCESS) { fprintf(errfp,"\n%s!smb_hfield_str(0x%02X) returned %d: %s\n" ,beep,RECIPIENTNETADDR,i,smb.last_error); bail(1); } } } if(from==NULL) { printf("From User Name: "); gets(str); } else SAFECOPY(str,from); truncsp(str); if((i=smb_hfield_str(&msg,SENDER,str))!=SMB_SUCCESS) { fprintf(errfp,"\n%s!smb_hfield_str(0x%02X) returned %d: %s\n" ,beep,SENDER,i,smb.last_error); bail(1); } if(smb.status.attr&SMB_EMAIL) { if(from_number==NULL) { printf("From User Number: "); gets(str); } else SAFECOPY(str,from_number); truncsp(str); if((i=smb_hfield_str(&msg,SENDEREXT,str))!=SMB_SUCCESS) { fprintf(errfp,"\n%s!smb_hfield_str(0x%02X) returned %d: %s\n" ,beep,SENDEREXT,i,smb.last_error); bail(1); } } if((i=smb_hfield(&msg, SENDERAGENT, sizeof(agent), &agent))!=SMB_SUCCESS) { fprintf(errfp,"\n%s!smb_hfield(0x%02X) returned %d: %s\n" ,beep,SENDERAGENT,i,smb.last_error); bail(1); } if(subject==NULL) { printf("Subject: "); gets(str); } else SAFECOPY(str,subject); truncsp(str); if((i=smb_hfield_str(&msg,SUBJECT,str))!=SMB_SUCCESS) { fprintf(errfp,"\n%s!smb_hfield_str(0x%02X) returned %d: %s\n" ,beep,SUBJECT,i,smb.last_error); bail(1); } safe_snprintf(str,sizeof(str),"SMBUTIL %s-%s r%s %s %s" ,SMBUTIL_VER ,PLATFORM_DESC ,revision ,__DATE__ ,compiler ); if((i=smb_hfield_str(&msg,FIDOPID,str))!=SMB_SUCCESS) { fprintf(errfp,"\n%s!smb_hfield_str(0x%02X) returned %d: %s\n" ,beep,FIDOPID,i,smb.last_error); bail(1); } if(mode&NOCRC || smb.status.max_crcs==0) /* no CRC checking means no body text dupe checking */ dupechk_hashes&=~(1<<SMB_HASH_SOURCE_BODY); if((i=smb_addmsg(&smb,&msg,smb.status.attr&SMB_HYPERALLOC ,dupechk_hashes,xlat,msgtxt,NULL))!=SMB_SUCCESS) { fprintf(errfp,"\n%s!smb_addmsg returned %d: %s\n" ,beep,i,smb.last_error); bail(1); } smb_freemsgmem(&msg); FREE_AND_NULL(msgtxt); }
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); }
bool sbbs_t::qwktomsg(FILE *qwk_fp, char *hdrblk, char fromhub, uint subnum , uint touser) { char* body; char* tail; char* header; char str[256],col=0,lastch=0,*p,qwkbuf[QWK_BLOCK_LEN+1]; uint i,j,k,lzh=0,skip=0; long bodylen,taillen; bool header_cont=false; bool success=false; ulong block,blocks; smbmsg_t msg; struct tm tm; ushort xlat=XLAT_NONE; int storage=SMB_SELFPACK; long dupechk_hashes=SMB_HASH_SOURCE_ALL; memset(&msg,0,sizeof(smbmsg_t)); /* Initialize message header */ msg.hdr.version=smb_ver(); blocks=atol(hdrblk+116); if(blocks<2) { errormsg(WHERE,ERR_CHK,"QWK packet header blocks",blocks); return(false); } if(subnum!=INVALID_SUB && (hdrblk[0]=='*' || hdrblk[0]=='+' || cfg.sub[subnum]->misc&SUB_PONLY)) msg.hdr.attr|=MSG_PRIVATE; if(subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_AONLY) msg.hdr.attr|=MSG_ANONYMOUS; if(subnum==INVALID_SUB && cfg.sys_misc&SM_DELREADM) msg.hdr.attr|=MSG_KILLREAD; if((fromhub || useron.rest&FLAG('Q')) && (hdrblk[0]=='*' || hdrblk[0]=='-' || hdrblk[0]=='`')) msg.hdr.attr|=MSG_READ; if(subnum!=INVALID_SUB && !fromhub && cfg.sub[subnum]->mod_ar[0] && chk_ar(cfg.sub[subnum]->mod_ar,&useron)) msg.hdr.attr|=MSG_MODERATED; if(subnum!=INVALID_SUB && !fromhub && cfg.sub[subnum]->misc&SUB_SYSPERM && sub_op(subnum)) msg.hdr.attr|=MSG_PERMANENT; memset(&tm,0,sizeof(tm)); tm.tm_mon = ((hdrblk[8]&0xf)*10)+(hdrblk[9]&0xf); if(tm.tm_mon>0) tm.tm_mon--; /* zero based */ tm.tm_mday=((hdrblk[11]&0xf)*10)+(hdrblk[12]&0xf); tm.tm_year=((hdrblk[14]&0xf)*10)+(hdrblk[15]&0xf); if(tm.tm_year<Y2K_2DIGIT_WINDOW) tm.tm_year+=100; tm.tm_hour=((hdrblk[16]&0xf)*10)+(hdrblk[17]&0xf); tm.tm_min=((hdrblk[19]&0xf)*10)+(hdrblk[20]&0xf); tm.tm_sec=0; tm.tm_isdst=-1; /* Do not adjust for DST */ msg.hdr.when_written.time=mktime(&tm); if(!(useron.rest&FLAG('Q')) && !fromhub) msg.hdr.when_written.zone=sys_timezone(&cfg); msg.hdr.when_imported.time=time(NULL); msg.hdr.when_imported.zone=sys_timezone(&cfg); hdrblk[116]=0; // don't include number of blocks in "re: msg number" if(!(useron.rest&FLAG('Q')) && !fromhub) msg.hdr.thread_back=atol((char *)hdrblk+108); if(subnum==INVALID_SUB) { /* E-mail */ if(cfg.sys_misc&SM_FASTMAIL) storage=SMB_FASTALLOC; /* duplicate message-IDs must be allowed in mail database */ dupechk_hashes&=~(1<<SMB_HASH_SOURCE_MSG_ID); username(&cfg,touser,str); smb_hfield_str(&msg,RECIPIENT,str); sprintf(str,"%u",touser); smb_hfield_str(&msg,RECIPIENTEXT,str); } else { if(cfg.sub[subnum]->misc&SUB_HYPER) storage = SMB_HYPERALLOC; else if(cfg.sub[subnum]->misc&SUB_FAST) storage = SMB_FASTALLOC; if(cfg.sub[subnum]->misc&SUB_LZH) xlat=XLAT_LZH; sprintf(str,"%25.25s",(char *)hdrblk+21); /* To user */ truncsp(str); smb_hfield_str(&msg,RECIPIENT,str); if(cfg.sub[subnum]->misc&SUB_LZH) xlat=XLAT_LZH; } sprintf(str,"%25.25s",hdrblk+71); /* Subject */ truncsp(str); smb_hfield_str(&msg,SUBJECT,str); /********************************/ /* Convert the QWK message text */ /********************************/ if((header=(char *)calloc((blocks-1L)*QWK_BLOCK_LEN*2L,sizeof(char)))==NULL) { smb_freemsgmem(&msg); errormsg(WHERE,ERR_ALLOC,"QWK msg header",(blocks-1L)*QWK_BLOCK_LEN*2L); return(false); } bodylen=0; if((body=(char *)malloc((blocks-1L)*QWK_BLOCK_LEN*2L))==NULL) { free(header); smb_freemsgmem(&msg); errormsg(WHERE,ERR_ALLOC,"QWK msg body",(blocks-1L)*QWK_BLOCK_LEN*2L); return(false); } taillen=0; if((tail=(char *)malloc((blocks-1L)*QWK_BLOCK_LEN*2L))==NULL) { free(header); free(body); smb_freemsgmem(&msg); errormsg(WHERE,ERR_ALLOC,"QWK msg tail",(blocks-1L)*QWK_BLOCK_LEN*2L); return(false); } memset(qwkbuf,0,sizeof(qwkbuf)); for(block=1;block<blocks;block++) { if(!fread(qwkbuf,1,QWK_BLOCK_LEN,qwk_fp)) break; for(k=0;k<QWK_BLOCK_LEN;k++) { if(qwkbuf[k]==0) continue; if(bodylen==0 && (qwkbuf[k]=='@' || header_cont)) { if((p=strchr(qwkbuf+k, QWK_NEWLINE))!=NULL) *p=0; strcat(header, qwkbuf+k); strcat(header, "\n"); if(p==NULL) { header_cont=true; break; } k+=strlen(qwkbuf+k); header_cont=false; continue; } if(!taillen && qwkbuf[k]==' ' && col==3 && bodylen>=3 && body[bodylen-3]=='-' && body[bodylen-2]=='-' && body[bodylen-1]=='-') { bodylen-=3; strcpy(tail,"--- "); taillen=4; col++; continue; } if(qwkbuf[k]==QWK_NEWLINE) { /* expand QWK_NEWLINE to crlf */ if(!taillen && col==3 && bodylen>=3 && body[bodylen-3]=='-' && body[bodylen-2]=='-' && body[bodylen-1]=='-') { bodylen-=3; strcpy(tail,"---"); taillen=3; } col=0; if(taillen) { tail[taillen++]=CR; tail[taillen++]=LF; } else { body[bodylen++]=CR; body[bodylen++]=LF; } continue; } /* beep restrict */ if(!fromhub && qwkbuf[k]==BEL && useron.rest&FLAG('B')) continue; /* ANSI restriction */ if(!fromhub && (qwkbuf[k]==1 || qwkbuf[k]==ESC) && useron.rest&FLAG('A')) continue; if(qwkbuf[k]!=1 && lastch!=1) col++; if(lastch==CTRL_A && !validattr(qwkbuf[k])) { if(taillen) taillen--; else bodylen--; lastch=0; continue; } lastch=qwkbuf[k]; if(taillen) tail[taillen++]=qwkbuf[k]; else body[bodylen++]=qwkbuf[k]; } } while(bodylen && body[bodylen-1]==' ') bodylen--; /* remove trailing spaces */ if(bodylen>=2 && body[bodylen-2]==CR && body[bodylen-1]==LF) bodylen-=2; while(taillen && tail[taillen-1]<=' ') taillen--; /* remove trailing garbage */ skip=0; if(useron.rest&FLAG('Q') || fromhub) { /* QWK Net */ if(!strnicmp(header,"@VIA:",5)) { if(!fromhub) set_qwk_flag(QWK_VIA); p=strchr(header, '\n'); if(p) { *p=0; skip=strlen(header)+1; } truncsp(header); p=header+5; /* Skip "@VIA:" */ while(*p && *p<=' ') p++; /* Skip any spaces */ if(route_circ(p,cfg.sys_id)) { free(header); free(body); free(tail); smb_freemsgmem(&msg); bprintf("\r\nCircular message path: %s\r\n",p); sprintf(str,"Circular message path: %s from %s" ,p,fromhub ? cfg.qhub[fromhub-1]->id:useron.alias); errorlog(str); return(false); } sprintf(str,"%s/%s" ,fromhub ? cfg.qhub[fromhub-1]->id : useron.alias,p); strupr(str); update_qwkroute(str); } else { if(fromhub) strcpy(str,cfg.qhub[fromhub-1]->id); else strcpy(str,useron.alias); } strupr(str); j=NET_QWK; smb_hfield(&msg,SENDERNETTYPE,2,&j); smb_hfield_str(&msg,SENDERNETADDR,str); sprintf(str,"%25.25s",hdrblk+46); /* From user */ truncsp(str); } else { sprintf(str,"%u",useron.number); smb_hfield_str(&msg,SENDEREXT,str); if((uint)subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_NAME) strcpy(str,useron.name); else strcpy(str,useron.alias); } smb_hfield_str(&msg,SENDER,str); if(!strnicmp(header+skip,"@MSGID:",7)) { if(!fromhub) set_qwk_flag(QWK_MSGID); p=strchr(header+skip, '\n'); i=skip; if(p) { *p=0; skip+=strlen(header+i)+1; } p=header+i+7; /* Skip "@MSGID:" */ while(*p && *p<=' ') p++; /* Skip any spaces */ truncstr(p," "); /* Truncate at first space char */ smb_hfield_str(&msg,RFC822MSGID,p); } if(!strnicmp(header+skip,"@REPLY:",7)) { if(!fromhub) set_qwk_flag(QWK_MSGID); p=strchr(header+skip, '\n'); i=skip; if(p) { *p=0; skip+=strlen(header+i)+1; } p=header+i+7; /* Skip "@REPLY:" */ while(*p && *p<=' ') p++; /* Skip any spaces */ truncstr(p," "); /* Truncate at first space char */ smb_hfield_str(&msg,RFC822REPLYID,p); } if(!strnicmp(header+skip,"@TZ:",4)) { if(!fromhub) set_qwk_flag(QWK_TZ); p=strchr(header+skip, '\n'); i=skip; if(p) { *p=0; skip+=strlen(header+i)+1; } p=header+i+4; /* Skip "@TZ:" */ while(*p && *p<=' ') p++; /* Skip any spaces */ msg.hdr.when_written.zone=(short)ahtoul(p); } if(!strnicmp(header+skip,"@REPLYTO:",9)) { p=strchr(header+skip, '\n'); i=skip; if(p) { *p=0; skip+=strlen(header+i)+1; } p=header+i+9; /* Skip "@REPLYTO:" */ while(*p && *p<=' ') p++; /* Skip any spaces */ smb_hfield_str(&msg,REPLYTO,p); } free(header); /* smb_addmsg required ASCIIZ strings */ body[bodylen]=0; tail[taillen]=0; if(online==ON_REMOTE) bputs(text[WritingIndx]); if(smb.status.max_crcs==0) /* no CRC checking means no body text dupe checking */ dupechk_hashes&=~(1<<SMB_HASH_SOURCE_BODY); if((i=smb_addmsg(&smb,&msg,storage,dupechk_hashes,xlat,(uchar*)body,(uchar*)tail))==SMB_SUCCESS) success=true; else if(i==SMB_DUPE_MSG) { bprintf("\r\n!%s\r\n",smb.last_error); if(!fromhub) { if(subnum==INVALID_SUB) { sprintf(str,"%s duplicate e-mail attempt (%s)",useron.alias,smb.last_error); logline("E!",str); } else { sprintf(str,"%s duplicate message attempt in %s %s (%s)" ,useron.alias ,cfg.grp[cfg.sub[subnum]->grp]->sname ,cfg.sub[subnum]->lname ,smb.last_error); logline("P!",str); } } } else errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); smb_freemsgmem(&msg); free(body); free(tail); return(success); }