bool sbbs_t::syslog(const char* code, const char *entry) { char fname[MAX_PATH+1]; char str[128]; char tmp[64]; int file; struct tm tm; now=time(NULL); if(localtime_r(&now,&tm)==NULL) return(false); sprintf(fname,"%slogs/%2.2d%2.2d%2.2d.log",cfg.logs_dir,tm.tm_mon+1,tm.tm_mday ,TM_YEAR(tm.tm_year)); if((file=nopen(fname,O_WRONLY|O_APPEND|O_CREAT))==-1) { lprintf(LOG_ERR,"!ERRROR %d opening/creating %s",errno,fname); return(false); } sprintf(str,"%-2.2s %s %s\r\n\r\n",code, hhmmtostr(&cfg,&tm,tmp), entry); write(file,str,strlen(str)); close(file); return(true); }
void sbbs_t::logofflist() { char str[256]; int file; struct tm tm, tm_now; if(localtime_r(&now,&tm_now)==NULL) return; if(localtime_r(&logontime,&tm)==NULL) return; sprintf(str,"%slogs/%2.2d%2.2d%2.2d.lol",cfg.logs_dir,tm.tm_mon+1,tm.tm_mday ,TM_YEAR(tm.tm_year)); if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) { errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_APPEND); return; } sprintf(str,"%-*.*s %-2d %-8.8s %2.2d:%2.2d %2.2d:%2.2d %3d%3ld%3ld%3ld%3ld" "%3ld%3ld\r\n",LEN_ALIAS,LEN_ALIAS,useron.alias,cfg.node_num,connection ,tm.tm_hour,tm.tm_min,tm_now.tm_hour,tm_now.tm_min ,(int)(now-logontime)/60,posts_read,logon_posts,logon_emails ,logon_fbacks,logon_uls,logon_dls); write(file,str,strlen(str)); close(file); }
bool sbbs_t::netmail(const char *into, const char *title, long mode) { char str[256],subj[128],to[256],fname[128],*buf,*p,ch; char tmp[512]; int file,fido,x,cc_found,cc_sent; uint i; long length,l; faddr_t addr; fmsghdr_t hdr; struct tm tm; if(useron.etoday>=cfg.level_emailperday[useron.level] && !SYSOP && !(useron.exempt&FLAG('M'))) { bputs(text[TooManyEmailsToday]); return(false); } SAFECOPY(subj,title); strcpy(to,into); lookup_netuser(to); p=strrchr(to,'@'); /* Find '@' in name@addr */ if(p && !isdigit(*(p+1)) && !strchr(p,'.') && !strchr(p,':')) { mode&=~WM_FILE; qnetmail(to,title,mode|WM_NETMAIL); return(false); } if(!cfg.total_faddrs || p==NULL || !strchr(p+1,'/')) { if(!p && cfg.dflt_faddr.zone) addr=cfg.dflt_faddr; else if(cfg.inetmail_misc&NMAIL_ALLOW) { if(mode&WM_FILE && !SYSOP && !(cfg.inetmail_misc&NMAIL_FILE)) mode&=~WM_FILE; return(inetmail(into,title,mode|WM_NETMAIL)); } else if(cfg.dflt_faddr.zone) addr=cfg.dflt_faddr; else { bputs(text[InvalidNetMailAddr]); return(false); } } else { addr=atofaddr(&cfg,p+1); /* Get fido address */ *p=0; /* Chop off address */ } if(mode&WM_FILE && !SYSOP && !(cfg.netmail_misc&NMAIL_FILE)) mode&=~WM_FILE; if((!SYSOP && !(cfg.netmail_misc&NMAIL_ALLOW)) || useron.rest&FLAG('M') || !cfg.total_faddrs) { bputs(text[NoNetMailAllowed]); return(false); } truncsp(to); /* Truncate off space */ memset(&hdr,0,sizeof(hdr)); /* Initialize header to null */ strcpy(hdr.from,cfg.netmail_misc&NMAIL_ALIAS ? useron.alias : useron.name); 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]); return(false); } sprintf(str,text[NetMailCostContinueQ],cfg.netmail_cost); if(noyes(str)) return(false); } now=time(NULL); if(localtime_r(&now,&tm)!=NULL) sprintf(hdr.time,"%02u %3.3s %02u %02u:%02u:%02u" ,tm.tm_mday,mon[tm.tm_mon],TM_YEAR(tm.tm_year) ,tm.tm_hour,tm.tm_min,tm.tm_sec); hdr.destzone =addr.zone; hdr.destnet =addr.net; hdr.destnode =addr.node; hdr.destpoint =addr.point; for(i=0;i<cfg.total_faddrs;i++) if(addr.zone==cfg.faddr[i].zone && addr.net==cfg.faddr[i].net) break; if(i==cfg.total_faddrs) { for(i=0;i<cfg.total_faddrs;i++) if(addr.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(&addr,tmp),hdr.from,str); 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; if(mode&WM_FILE) hdr.attr|=FIDO_FILE; sprintf(str,"%sNETMAIL.MSG", cfg.node_dir); remove(str); /* Just incase it's already there */ // mode&=~WM_FILE; if(!writemsg(str,nulstr,subj,WM_NETMAIL|mode,INVALID_SUB,into)) { bputs(text[Aborted]); return(false); } if(mode&WM_FILE) { strcpy(fname,subj); sprintf(str,"%sfile/%04u.out", cfg.data_dir, useron.number); MKDIR(str); strcpy(tmp, cfg.data_dir); if(tmp[0]=='.') /* Relative path */ sprintf(tmp,"%s%s", cfg.node_dir, cfg.data_dir); sprintf(str,"%sfile/%04u.out/%s",tmp,useron.number,fname); strcpy(subj,str); if(fexistcase(str)) { bputs(text[FileAlreadyThere]); 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]); 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,subj,nulstr,true); } sprintf(tmp,"%s%s",cfg.temp_dir,title); if(!fexistcase(subj) && fexistcase(tmp)) mv(tmp,subj,0); l=(long)flength(subj); if(l>0) bprintf(text[FileNBytesReceived],fname,ultoac(l,tmp)); else { bprintf(text[FileNotReceived],fname); return(false); } } p=subj; 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); sprintf(str,"%sNETMAIL.MSG", cfg.node_dir); if((file=nopen(str,O_RDONLY))==-1) { errormsg(WHERE,ERR_OPEN,str,O_RDONLY); return(false); } length=(long)filelength(file); if((buf=(char *)malloc(length))==NULL) { close(file); errormsg(WHERE,ERR_ALLOC,str,length); return(false); } read(file,buf,length); close(file); md(cfg.netmail_dir); cc_sent=0; while(1) { for(i=1;i;i++) { sprintf(str,"%s%u.msg", cfg.netmail_dir,i); if(!fexistcase(str)) break; } if(!i) { bputs(text[TooManyEmailsToday]); return(false); } if((fido=nopen(str,O_WRONLY|O_CREAT|O_EXCL))==-1) { errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_EXCL); return(false); } write(fido,&hdr,sizeof(hdr)); pt_zone_kludge(hdr,fido); if(cfg.netmail_misc&NMAIL_DIRECT) { SAFECOPY(str,"\1FLAGS DIR\r\n"); write(fido,str,strlen(str)); } if(mode&WM_FILE) { SAFECOPY(str,"\1FLAGS KFS\r\n"); write(fido,str,strlen(str)); } if(cc_sent) { SAFEPRINTF(str,"* Originally to: %s\r\n\r\n",into); write(fido,str,strlen(str)); } l=0L; while(l<length) { if(buf[l]==CTRL_A) { /* Ctrl-A, so skip it and the next char */ l++; if(l>=length || toupper(buf[l])=='Z') /* EOF */ break; if((ch=ctrl_a_to_ascii_char(buf[l])) != 0) write(fido,&ch,1); } else if(buf[l]!=LF) { if((uchar)buf[l]==0x8d) /* r0dent i converted to normal i */ buf[l]='i'; write(fido,buf+l,1); } l++; } l=0; write(fido,&l,1); /* Null terminator */ close(fido); 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)); if(!(useron.exempt&FLAG('S'))) subtract_cdt(&cfg,&useron,cfg.netmail_cost); if(mode&WM_FILE) sprintf(str,"%s sent NetMail file attachment to %s (%s)" ,useron.alias ,hdr.to,smb_faddrtoa(&addr,tmp)); else sprintf(str,"%s sent NetMail to %s (%s)" ,useron.alias ,hdr.to,smb_faddrtoa(&addr,tmp)); logline("EN",str); cc_found=0; for(l=0;l<length && cc_found<=cc_sent;l++) if(l+3<length && !strnicmp(buf+l,"CC:",3)) { cc_found++; l+=2; } else { while(l<length && *(buf+l)!=LF) l++; } if(!cc_found) break; while(l<length && *(buf+l)==' ') l++; for(i=0;l<length && *(buf+l)!=LF && i<128;i++,l++) str[i]=buf[l]; if(!i) break; str[i]=0; p=strrchr(str,'@'); if(p) { addr=atofaddr(&cfg,p+1); *p=0; SAFECOPY(hdr.to,str); } else { atofaddr(&cfg,str); strcpy(hdr.to,"Sysop"); } hdr.destzone =addr.zone; hdr.destnet =addr.net; hdr.destnode =addr.node; hdr.destpoint =addr.point; cc_sent++; } if(cfg.netmail_sem[0]) /* update semaphore file */ ftouch(cmdstr(cfg.netmail_sem,nulstr,nulstr,NULL)); free(buf); 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); }
ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, uint subnum , int conf, FILE* hdrs) { char str[512],from[512],to[512],ch=0,tear=0,tearwatch=0,*buf,*p; char asc; char msgid[256]; char tmp[512]; long l,size=0,offset; int i; ushort hfield_type; struct tm tm; smbmsg_t remsg; time_t tt; offset=(long)ftell(qwk_fp); if(hdrs!=NULL) { fprintf(hdrs,"[%lx]\n",offset); /* Message-IDs */ fprintf(hdrs,"Message-ID: %s\n",get_msgid(&cfg,subnum,msg,msgid,sizeof(msgid))); if(msg->reply_id!=NULL) fprintf(hdrs,"In-Reply-To: %s\n",msg->reply_id); /* Time/Date/Zone info */ fprintf(hdrs,"WhenWritten: %-20s %04hx\n" ,xpDateTime_to_isoDateTimeStr( time_to_xpDateTime(msg->hdr.when_written.time,smb_tzutc(msg->hdr.when_written.zone)) ,/* separators: */"","","", /* precision: */0 ,str,sizeof(str)) ,msg->hdr.when_written.zone ); fprintf(hdrs,"WhenImported: %-20s %04hx\n" ,xpDateTime_to_isoDateTimeStr( time_to_xpDateTime(msg->hdr.when_imported.time,smb_tzutc(msg->hdr.when_imported.zone)) ,/* separators: */"","","", /* precision: */0 ,str,sizeof(str)) ,msg->hdr.when_imported.zone ); fprintf(hdrs,"WhenExported: %-20s %04hx\n" ,xpDateTime_to_isoDateTimeStr( xpDateTime_now() ,/* separators: */"","","", /* precision: */0 ,str,sizeof(str)) ,sys_timezone(&cfg) ); fprintf(hdrs,"ExportedFrom: %s %s %"PRIu32"\n" ,cfg.sys_id ,subnum==INVALID_SUB ? "mail":cfg.sub[subnum]->code ,msg->hdr.number ); /* SENDER */ fprintf(hdrs,"%s: %s\n",smb_hfieldtype(SENDER),msg->from); if(msg->from_net.type) fprintf(hdrs,"%s: %s\n",smb_hfieldtype(SENDERNETADDR),smb_netaddrstr(&msg->from_net,tmp)); if((p=(char*)smb_get_hfield(msg,hfield_type=SENDERIPADDR,NULL))!=NULL) fprintf(hdrs,"%s: %s\n",smb_hfieldtype(hfield_type),p); if((p=(char*)smb_get_hfield(msg,hfield_type=SENDERHOSTNAME,NULL))!=NULL) fprintf(hdrs,"%s: %s\n",smb_hfieldtype(hfield_type),p); if((p=(char*)smb_get_hfield(msg,hfield_type=SENDERPROTOCOL,NULL))!=NULL) fprintf(hdrs,"%s: %s\n",smb_hfieldtype(hfield_type),p); if(msg->from_org!=NULL) fprintf(hdrs,"Organization: %s\n",msg->from_org); else if(msg->from_net.type==NET_NONE) fprintf(hdrs,"Organization: %s\n",cfg.sys_name); /* Reply-To */ if((p=(char*)smb_get_hfield(msg,RFC822REPLYTO,NULL))==NULL) { if(msg->replyto_net.type==NET_INTERNET) p=(char*)msg->replyto_net.addr; else if(msg->replyto!=NULL) p=msg->replyto; } if(p!=NULL) fprintf(hdrs,"Reply-To: %s\n",p); /* use original RFC822 header field */ /* SUBJECT */ fprintf(hdrs,"%s: %s\n",smb_hfieldtype(SUBJECT),msg->subj); /* RECIPIENT */ fprintf(hdrs,"%s: %s\n",smb_hfieldtype(RECIPIENT),msg->to); if(msg->to_net.type) fprintf(hdrs,"%s: %s\n",smb_hfieldtype(RECIPIENTNETADDR),smb_netaddrstr(&msg->to_net,tmp)); /* FidoNet */ if((p=(char*)smb_get_hfield(msg,hfield_type=FIDOAREA,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); if((p=(char*)smb_get_hfield(msg,hfield_type=FIDOSEENBY,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); if((p=(char*)smb_get_hfield(msg,hfield_type=FIDOPATH,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); if((p=(char*)smb_get_hfield(msg,hfield_type=FIDOMSGID,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); if((p=(char*)smb_get_hfield(msg,hfield_type=FIDOREPLYID,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); if((p=(char*)smb_get_hfield(msg,hfield_type=FIDOPID,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); if((p=(char*)smb_get_hfield(msg,hfield_type=FIDOFLAGS,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); if((p=(char*)smb_get_hfield(msg,hfield_type=FIDOTID,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); /* Synchronet */ if((p=(char*)smb_get_hfield(msg,hfield_type=SMB_EDITOR,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); /* USENET */ if((p=(char*)smb_get_hfield(msg,hfield_type=USENETPATH,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); if((p=(char*)smb_get_hfield(msg,hfield_type=USENETNEWSGROUPS,NULL))!=NULL) fprintf(hdrs,"%s: %s\n", smb_hfieldtype(hfield_type), p); /* RFC822 header fields: */ for(i=0;i<msg->total_hfields;i++) if(msg->hfield[i].type==RFC822HEADER) fprintf(hdrs,"%s\n",truncsp_lines((char*)msg->hfield_dat[i])); /* Blank line: */ fprintf(hdrs,"\n"); } fprintf(qwk_fp,"%*s",QWK_BLOCK_LEN,""); /* Init header to space */ /* QWKE compatible kludges */ SAFECOPY(from,msg->from); if(msg->from_net.addr && (uint)subnum==INVALID_SUB && !(mode&QM_TO_QNET)) { if(msg->from_net.type==NET_FIDO) sprintf(from,"%.128s@%.128s" ,msg->from,smb_faddrtoa((faddr_t *)msg->from_net.addr,tmp)); else if(msg->from_net.type==NET_INTERNET || strchr((char*)msg->from_net.addr,'@')!=NULL) sprintf(from,"%.128s",(char*)msg->from_net.addr); else sprintf(from,"%.128s@%.128s",msg->from,(char*)msg->from_net.addr); } if(msg->hdr.attr&MSG_ANONYMOUS && !SYSOP) SAFECOPY(from,text[Anonymous]); else if((subnum==INVALID_SUB || (useron.qwk&QWK_EXT)) && strlen(from) > QWK_HFIELD_LEN) { size+=fprintf(qwk_fp,"From: %.128s%c", from, QWK_NEWLINE); SAFECOPY(from,msg->from); } SAFECOPY(to,msg->to); if(msg->to_net.addr && (uint)subnum==INVALID_SUB) { if(msg->to_net.type==NET_FIDO) sprintf(to,"%.128s@%s",msg->to,smb_faddrtoa((faddr_t *)msg->to_net.addr,tmp)); else if(msg->to_net.type==NET_INTERNET) sprintf(to,"%.128s",(char*)msg->to_net.addr); else if(msg->to_net.type==NET_QWK) { if(mode&QM_TO_QNET) { p=strchr((char *)msg->to_net.addr,'/'); if(p) { /* Another hop */ p++; SAFECOPY(to,"NETMAIL"); size+=fprintf(qwk_fp,"%.128s@%.128s%c",msg->to,p,QWK_NEWLINE); } else sprintf(to,"%.128s",msg->to); } else sprintf(to,"%.128s@%.128s",msg->to,(char*)msg->to_net.addr); } else sprintf(to,"%.128s@%.128s",msg->to,(char*)msg->to_net.addr); } if((subnum==INVALID_SUB || (useron.qwk&QWK_EXT)) && strlen(to) > QWK_HFIELD_LEN) { size+=fprintf(qwk_fp,"To: %.128s%c", to, QWK_NEWLINE); if(msg->to_net.type==NET_QWK) SAFECOPY(to,"NETMAIL"); else SAFECOPY(to,msg->to); } if((useron.qwk&QWK_EXT) && strlen(msg->subj) > QWK_HFIELD_LEN) size+=fprintf(qwk_fp,"Subject: %.128s%c", msg->subj, QWK_NEWLINE); if(msg->from_net.type==NET_QWK && mode&QM_VIA && !msg->forwarded) size+=fprintf(qwk_fp,"@VIA: %s%c" ,(char*)msg->from_net.addr,QWK_NEWLINE); if(mode&QM_MSGID && (uint)subnum!=INVALID_SUB) { size+=fprintf(qwk_fp,"@MSGID: %s%c" ,get_msgid(&cfg,subnum,msg,msgid,sizeof(msgid)),QWK_NEWLINE); if(msg->reply_id) { SAFECOPY(tmp,msg->reply_id); truncstr(tmp," "); size+=fprintf(qwk_fp,"@REPLY: %s%c" ,tmp,QWK_NEWLINE); } else if(msg->hdr.thread_back) { memset(&remsg,0,sizeof(remsg)); remsg.hdr.number=msg->hdr.thread_back; if(smb_getmsgidx(&smb, &remsg)) size+=fprintf(qwk_fp,"@REPLY: <%s>%c",smb.last_error,QWK_NEWLINE); else size+=fprintf(qwk_fp,"@REPLY: %s%c" ,get_msgid(&cfg,subnum,&remsg,msgid,sizeof(msgid)) ,QWK_NEWLINE); } } if(msg->hdr.when_written.zone && mode&QM_TZ) size+=fprintf(qwk_fp,"@TZ: %04hx%c",msg->hdr.when_written.zone,QWK_NEWLINE); if(msg->replyto!=NULL && mode&QM_REPLYTO) size+=fprintf(qwk_fp,"@REPLYTO: %s%c" ,msg->replyto,QWK_NEWLINE); p=0; for(i=0;i<msg->total_hfields;i++) { if(msg->hfield[i].type==SENDER) p=(char *)msg->hfield_dat[i]; if(msg->hfield[i].type==FORWARDED && p) { size+=fprintf(qwk_fp,"Forwarded from %s on %s%c",p ,timestr(*(time32_t *)msg->hfield_dat[i]) ,QWK_NEWLINE); } } buf=smb_getmsgtxt(&smb,msg,GETMSGTXT_ALL); if(!buf) return(0); for(l=0;buf[l];l++) { ch=buf[l]; if(ch=='\n') { if(tear) tear++; /* Count LFs after tearline */ if(tear>3) /* more than two LFs after the tear */ tear=0; if(tearwatch==4) { /* watch for LF---LF */ tear=1; tearwatch=0; } else if(!tearwatch) tearwatch=1; else tearwatch=0; if(l && buf[l-1]=='\r') /* Replace CRLF with funky char */ ch=QWK_NEWLINE; /* but leave sole LF (soft-NL) alone */ fputc(ch,qwk_fp); size++; continue; } if(ch=='\r') { /* Ignore CRs */ if(tearwatch<4) /* LF---CRLF is okay */ tearwatch=0; /* LF-CR- is not okay */ continue; } if(ch==' ' && tearwatch==4) { /* watch for "LF--- " */ tear=1; tearwatch=0; } if(ch=='-') { /* watch for "LF---" */ if(l==0 || (tearwatch && tearwatch<4)) tearwatch++; else tearwatch=0; } else tearwatch=0; if((uint)subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_ASCII) { if(ch<' ' && ch!=1) ch='.'; else if((uchar)ch>0x7f) ch=exascii_to_ascii_char(ch); } if(ch==QWK_NEWLINE) /* funky char */ ch='*'; if(ch==CTRL_A) { ch=buf[++l]; if(ch==0 || toupper(ch)=='Z') /* EOF */ break; if((asc=ctrl_a_to_ascii_char(ch)) != 0) { fputc(asc,qwk_fp); size++; continue; } if(mode&A_EXPAND) { str[0]=0; switch(toupper(ch)) { case 'W': SAFECOPY(str,ansi(LIGHTGRAY)); break; case 'K': SAFECOPY(str,ansi(BLACK)); break; case 'H': SAFECOPY(str,ansi(HIGH)); break; case 'I': SAFECOPY(str,ansi(BLINK)); break; case '-': case '_': case 'N': /* Normal */ SAFECOPY(str,ansi(ANSI_NORMAL)); break; case 'R': SAFECOPY(str,ansi(RED)); break; case 'G': SAFECOPY(str,ansi(GREEN)); break; case 'B': SAFECOPY(str,ansi(BLUE)); break; case 'C': SAFECOPY(str,ansi(CYAN)); break; case 'M': SAFECOPY(str,ansi(MAGENTA)); break; case 'Y': /* Yellow */ SAFECOPY(str,ansi(BROWN)); break; case '0': SAFECOPY(str,ansi(BG_BLACK)); break; case '1': SAFECOPY(str,ansi(BG_RED)); break; case '2': SAFECOPY(str,ansi(BG_GREEN)); break; case '3': SAFECOPY(str,ansi(BG_BROWN)); break; case '4': SAFECOPY(str,ansi(BG_BLUE)); break; case '5': SAFECOPY(str,ansi(BG_MAGENTA)); break; case '6': SAFECOPY(str,ansi(BG_CYAN)); break; case '7': SAFECOPY(str,ansi(BG_LIGHTGRAY)); break; } if(str[0]) size+=fwrite(str,sizeof(char),strlen(str),qwk_fp); continue; } /* End Expand */ if(mode&A_LEAVE && valid_ctrl_a_code(ch)) { fputc(CTRL_A,qwk_fp); fputc(ch,qwk_fp); size+=2L; } continue; } /* End of Ctrl-A shit */ fputc(ch,qwk_fp); size++; } free(buf); if(ch!=QWK_NEWLINE) { fputc(QWK_NEWLINE,qwk_fp); /* make sure it ends in CRLF */ size++; } if(mode&QM_TAGLINE && !(cfg.sub[subnum]->misc&SUB_NOTAG)) { if(!tear) /* no tear line */ SAFEPRINTF(str,"\1n---%c",QWK_NEWLINE); /* so add one */ else SAFECOPY(str,"\1n"); if(cfg.sub[subnum]->misc&SUB_ASCII) ch='*'; else ch='þ'; safe_snprintf(tmp,sizeof(tmp)," %c \1g%.10s\1n %c %.127s%c" ,ch,VERSION_NOTICE,ch,cfg.sub[subnum]->tagline,QWK_NEWLINE); strcat(str,tmp); if(!(mode&A_LEAVE)) remove_ctrl_a(str,str); size+=fwrite(str,sizeof(char),strlen(str),qwk_fp); } while(size%QWK_BLOCK_LEN) { /* Pad with spaces */ size++; fputc(' ',qwk_fp); } tt=msg->hdr.when_written.time; if(localtime_r(&tt,&tm)==NULL) memset(&tm,0,sizeof(tm)); safe_snprintf(tmp,sizeof(tmp),"%02u-%02u-%02u%02u:%02u" ,tm.tm_mon+1,tm.tm_mday,TM_YEAR(tm.tm_year) ,tm.tm_hour,tm.tm_min); if(msg->hdr.attr&MSG_PRIVATE) { if(msg->hdr.attr&MSG_READ) ch='*'; /* private, read */ else ch='+'; /* private, unread */ } else { if(msg->hdr.attr&MSG_READ) ch='-'; /* public, read */ else ch=' '; /* public, unread */ } safe_snprintf(str,sizeof(str),"%c%-7lu%-13.13s%-25.25s" "%-25.25s%-25.25s%12s%-8lu%-6lu\xe1%c%c%c%c%c" ,ch /* message status flag */ ,mode&QM_REP ? (ulong)conf /* conference or */ : msg->hdr.number&MAX_MSGNUM /* message number */ ,tmp /* date and time */ ,to /* To: */ ,from /* From: */ ,msg->subj /* Subject */ ,nulstr /* Password */ ,msg->hdr.thread_back&MAX_MSGNUM /* Message Re: Number */ ,(size/QWK_BLOCK_LEN)+1 /* Number of blocks */ ,(char)conf&0xff /* Conference number lo byte */ ,(ushort)conf>>8 /* hi byte */ ,' ' /* not used */ ,' ' /* not used */ ,useron.rest&FLAG('Q') ? '*' : ' ' /* Net tag line */ ); fseek(qwk_fp,offset,SEEK_SET); fwrite(str,QWK_BLOCK_LEN,1,qwk_fp); fseek(qwk_fp,size,SEEK_CUR); return(size); }