BOOL DLLCALL removefiledat(scfg_t* cfg, file_t* f) { char c,str[MAX_PATH+1],ixbname[12],*ixbbuf,fname[13]; int i,file; long l,length; SAFECOPY(fname,f->name); for(i=8;i<12;i++) /* Turn FILENAME.EXT into FILENAMEEXT */ fname[i]=fname[i+1]; SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code); if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) { return(FALSE); } length=(long)filelength(file); if(!length) { close(file); return(FALSE); } if((ixbbuf=(char *)malloc(length))==0) { close(file); return(FALSE); } if(lread(file,ixbbuf,length)!=length) { close(file); free((char *)ixbbuf); return(FALSE); } close(file); if((file=sopen(str,O_WRONLY|O_TRUNC|O_BINARY,SH_DENYRW))==-1) { return(FALSE); } for(l=0;l<length;l+=F_IXBSIZE) { for(i=0;i<11;i++) ixbname[i]=ixbbuf[l+i]; ixbname[i]=0; if(stricmp(ixbname,fname)) if(lwrite(file,&ixbbuf[l],F_IXBSIZE)!=F_IXBSIZE) { close(file); free((char *)ixbbuf); return(FALSE); } } free((char *)ixbbuf); close(file); SAFEPRINTF2(str,"%s%s.dat",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code); if((file=sopen(str,O_WRONLY|O_BINARY,SH_DENYRW))==-1) { return(FALSE); } lseek(file,f->datoffset,SEEK_SET); c=ETX; /* If first char of record is ETX, record is unused */ if(write(file,&c,1)!=1) { /* So write a D_T on the first byte of the record */ close(file); return(FALSE); } close(file); if(f->dir==cfg->user_dir) /* remove file from index */ rmuserxfers(cfg,0,0,f->name); return(TRUE); }
str_list_t DLLCALL semfile_list_init(const char* parent, const char* action, const char* service) { char path[MAX_PATH+1]; char hostname[128]; char* p; str_list_t list; if((list=strListInit())==NULL) return(NULL); SAFEPRINTF2(path,"%s%s",parent,action); strListPush(&list,path); SAFEPRINTF3(path,"%s%s.%s",parent,action,service); strListPush(&list,path); if(gethostname(hostname,sizeof(hostname))==0) { SAFEPRINTF3(path,"%s%s.%s",parent,action,hostname); strListPush(&list,path); SAFEPRINTF4(path,"%s%s.%s.%s",parent,action,hostname,service); strListPush(&list,path); if((p=strchr(hostname,'.'))!=NULL) { *p=0; SAFEPRINTF3(path,"%s%s.%s",parent,action,hostname); strListPush(&list,path); SAFEPRINTF4(path,"%s%s.%s.%s",parent,action,hostname,service); strListPush(&list,path); } } return(list); }
int DLLCALL update_uldate(scfg_t* cfg, file_t* f) { char str[MAX_PATH+1],fname[13]; int i,file; long l,length; /*******************/ /* Update IXB File */ /*******************/ SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code); if((file=nopen(str,O_RDWR))==-1) return(errno); length=(long)filelength(file); if(length%F_IXBSIZE) { close(file); return(-1); } SAFECOPY(fname,f->name); for(i=8;i<12;i++) /* Turn FILENAME.EXT into FILENAMEEXT */ fname[i]=fname[i+1]; for(l=0;l<length;l+=F_IXBSIZE) { read(file,str,F_IXBSIZE); /* Look for the filename in the IXB file */ str[11]=0; if(!stricmp(fname,str)) break; } if(l>=length) { close(file); return(-2); } lseek(file,l+14,SEEK_SET); write(file,&f->dateuled,4); close(file); /*******************************************/ /* Update last upload date/time stamp file */ /*******************************************/ SAFEPRINTF2(str,"%s%s.dab",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code); if((file=nopen(str,O_WRONLY|O_CREAT))==-1) return(errno); write(file,&f->dateuled,4); close(file); return(0); }
void DLLCALL getextdesc(scfg_t* cfg, uint dirnum, ulong datoffset, char *ext) { char str[MAX_PATH+1]; int file; memset(ext,0,F_EXBSIZE+1); SAFEPRINTF2(str,"%s%s.exb",cfg->dir[dirnum]->data_dir,cfg->dir[dirnum]->code); if((file=nopen(str,O_RDONLY))==-1) return; lseek(file,(datoffset/F_LEN)*F_EXBSIZE,SEEK_SET); read(file,ext,F_EXBSIZE); close(file); }
BOOL DLLCALL putfileixb(scfg_t* cfg, file_t* f) { char str[MAX_PATH+1],fname[13]; uchar* ixbbuf; int file; long l,length; SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code); if((file=sopen(str,O_RDWR|O_BINARY,SH_DENYRW))==-1) { return(FALSE); } length=(long)filelength(file); if(length%F_IXBSIZE) { close(file); return(FALSE); } if((ixbbuf=(uchar *)malloc(length))==NULL) { close(file); return(FALSE); } if(lread(file,ixbbuf,length)!=length) { close(file); free(ixbbuf); return(FALSE); } SAFECOPY(fname,f->name); for(l=8;l<12;l++) /* Turn FILENAME.EXT into FILENAMEEXT */ fname[l]=fname[l+1]; for(l=0;l<length;l+=F_IXBSIZE) { SAFEPRINTF(str,"%11.11s",ixbbuf+l); if(!stricmp(str,fname)) break; } free(ixbbuf); if(l>=length) { close(file); return(FALSE); } lseek(file,l+11+3,SEEK_SET); write(file,&f->dateuled,4); write(file,&f->datedled,4); close(file); return(TRUE); }
BOOL DLLCALL getfileixb(scfg_t* cfg, file_t* f) { char str[MAX_PATH+1],fname[13]; uchar * ixbbuf; int file; long l,length; SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code); if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) { return(FALSE); } length=(long)filelength(file); if(length%F_IXBSIZE) { close(file); return(FALSE); } if((ixbbuf=(uchar *)malloc(length))==NULL) { close(file); return(FALSE); } if(lread(file,ixbbuf,length)!=length) { close(file); free((char *)ixbbuf); return(FALSE); } close(file); SAFECOPY(fname,f->name); for(l=8;l<12;l++) /* Turn FILENAME.EXT into FILENAMEEXT */ fname[l]=fname[l+1]; for(l=0;l<length;l+=F_IXBSIZE) { SAFEPRINTF(str,"%11.11s",ixbbuf+l); if(!stricmp(str,fname)) break; } if(l>=length) { free((char *)ixbbuf); return(FALSE); } l+=11; f->datoffset=ixbbuf[l]|((long)ixbbuf[l+1]<<8)|((long)ixbbuf[l+2]<<16); f->dateuled=ixbbuf[l+3]|((long)ixbbuf[l+4]<<8) |((long)ixbbuf[l+5]<<16)|((long)ixbbuf[l+6]<<24); f->datedled=ixbbuf[l+7]|((long)ixbbuf[l+8]<<8) |((long)ixbbuf[l+9]<<16)|((long)ixbbuf[l+10]<<24); free((char *)ixbbuf); return(TRUE); }
void DLLCALL putextdesc(scfg_t* cfg, uint dirnum, ulong datoffset, char *ext) { char str[MAX_PATH+1],nulbuf[F_EXBSIZE]; int file; strip_invalid_attr(ext); /* eliminate bogus ctrl-a codes */ memset(nulbuf,0,sizeof(nulbuf)); SAFEPRINTF2(str,"%s%s.exb",cfg->dir[dirnum]->data_dir,cfg->dir[dirnum]->code); if((file=nopen(str,O_WRONLY|O_CREAT))==-1) return; lseek(file,0L,SEEK_END); while(filelength(file)<(long)(datoffset/F_LEN)*F_EXBSIZE) write(file,nulbuf,sizeof(nulbuf)); lseek(file,(datoffset/F_LEN)*F_EXBSIZE,SEEK_SET); write(file,ext,F_EXBSIZE); close(file); }
BOOL DLLCALL putfiledat(scfg_t* cfg, file_t* f) { char buf[F_LEN+1],str[MAX_PATH+1],tmp[128]; int file; long length; putrec(buf,F_CDT,LEN_FCDT,ultoa(f->cdt,tmp,10)); putrec(buf,F_DESC,LEN_FDESC,f->desc); putrec(buf,F_DESC+LEN_FDESC,2,crlf); putrec(buf,F_ULER,LEN_ALIAS+5,f->uler); putrec(buf,F_ULER+LEN_ALIAS+5,2,crlf); putrec(buf,F_TIMESDLED,5,ultoa(f->timesdled,tmp,10)); putrec(buf,F_TIMESDLED+5,2,crlf); putrec(buf,F_OPENCOUNT,3,ultoa(f->opencount,tmp,10)); putrec(buf,F_OPENCOUNT+3,2,crlf); buf[F_MISC]=(char)f->misc+' '; putrec(buf,F_ALTPATH,2,hexplus(f->altpath,tmp)); putrec(buf,F_ALTPATH+2,2,crlf); SAFEPRINTF2(str,"%s%s.dat",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code); if((file=sopen(str,O_WRONLY|O_BINARY,SH_DENYRW))==-1) { return(FALSE); } length=(long)filelength(file); if(length%F_LEN) { close(file); return(FALSE); } if(f->datoffset>length) { close(file); return(FALSE); } lseek(file,f->datoffset,SEEK_SET); if(write(file,buf,F_LEN)!=F_LEN) { close(file); return(FALSE); } length=(long)filelength(file); close(file); if(length%F_LEN) { return(FALSE); } return(TRUE); }
bool sbbs_t::chksyspass() { char str[256],str2[256]; if(online==ON_REMOTE && !(cfg.sys_misc&SM_R_SYSOP)) { logline(LOG_NOTICE,"S!","Remote sysop access disabled"); return(false); } bputs(text[SystemPassword]); getstr(str,40,K_UPPER|K_NOECHO); CRLF; if(strcmp(cfg.sys_pass,str)) { if(cfg.sys_misc&SM_ECHO_PW) SAFEPRINTF3(str2,"%s #%u System password attempt: '%s'" ,useron.alias,useron.number,str); else SAFEPRINTF2(str2,"%s #%u System password verification failure" ,useron.alias,useron.number); logline(LOG_NOTICE,"S!",str2); return(false); } return(true); }
BOOL DLLCALL findfile(scfg_t* cfg, uint dirnum, char *filename) { char str[MAX_PATH+1],fname[13],*ixbbuf; int i,file; long length,l; SAFECOPY(fname,filename); strupr(fname); for(i=8;i<12;i++) /* Turn FILENAME.EXT into FILENAMEEXT */ fname[i]=fname[i+1]; SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[dirnum]->data_dir,cfg->dir[dirnum]->code); if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) return(FALSE); length=(long)filelength(file); if(!length) { close(file); return(FALSE); } if((ixbbuf=(char *)malloc(length))==NULL) { close(file); return(FALSE); } if(lread(file,ixbbuf,length)!=length) { close(file); free((char *)ixbbuf); return(FALSE); } close(file); for(l=0;l<length;l+=F_IXBSIZE) { for(i=0;i<11;i++) if(toupper(fname[i])!=toupper(ixbbuf[l+i])) break; if(i==11) break; } free((char *)ixbbuf); if(l!=length) return(TRUE); return(FALSE); }
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::answer() { char str[MAX_PATH+1],str2[MAX_PATH+1],c; char tmp[(MAX_PATH > CRYPT_MAX_TEXTSIZE ? MAX_PATH:CRYPT_MAX_TEXTSIZE)+1]; char tmpname[CRYPT_MAX_TEXTSIZE+1]; char path[MAX_PATH+1]; int i,l,in; struct tm tm; useron.number=0; answertime=logontime=starttime=now=time(NULL); /* Caller ID is IP address */ SAFECOPY(cid,client_ipaddr); memset(&tm,0,sizeof(tm)); localtime_r(&now,&tm); safe_snprintf(str,sizeof(str),"%s %s %s %02d %u Node %3u" ,hhmmtostr(&cfg,&tm,str2) ,wday[tm.tm_wday] ,mon[tm.tm_mon],tm.tm_mday,tm.tm_year+1900,cfg.node_num); logline("@ ",str); safe_snprintf(str,sizeof(str),"%s %s [%s]", connection, client_name, cid); logline("@+:",str); if(client_ident[0]) { safe_snprintf(str,sizeof(str),"Identity: %s",client_ident); logline("@*",str); } online=ON_REMOTE; if(sys_status&SS_RLOGIN) { if(incom(1000)==0) { for(i=0;i<(int)sizeof(str)-1;i++) { in=incom(1000); if(in==0 || in==NOINP) break; str[i]=in; } str[i]=0; for(i=0;i<(int)sizeof(str2)-1;i++) { in=incom(1000); if(in==0 || in==NOINP) break; str2[i]=in; } str2[i]=0; for(i=0;i<(int)sizeof(terminal)-1;i++) { in=incom(1000); if(in==0 || in==NOINP) break; terminal[i]=in; } terminal[i]=0; lprintf(LOG_DEBUG,"Node %d RLogin: '******' / '%.*s' / '%s'" ,cfg.node_num ,LEN_ALIAS*2,str ,LEN_ALIAS*2,str2 ,terminal); SAFECOPY(rlogin_term, terminal); SAFECOPY(rlogin_name, str2); SAFECOPY(rlogin_pass, str); /* Truncate terminal speed (e.g. "/57600") from terminal-type string (but keep full terminal type/speed string in rlogin_term): */ truncstr(terminal,"/"); useron.number=userdatdupe(0, U_ALIAS, LEN_ALIAS, rlogin_name); if(useron.number) { getuserdat(&cfg,&useron); useron.misc&=~TERM_FLAGS; SAFEPRINTF(path,"%srlogin.cfg",cfg.ctrl_dir); if(!findstr(client.addr,path)) { SAFECOPY(tmp, rlogin_pass); for(i=0;i<3;i++) { if(stricmp(tmp,useron.pass)) { badlogin(useron.alias, tmp); rioctl(IOFI); /* flush input buffer */ bputs(text[InvalidLogon]); if(cfg.sys_misc&SM_ECHO_PW) safe_snprintf(str,sizeof(str),"(%04u) %-25s FAILED Password attempt: '%s'" ,0,useron.alias,tmp); else safe_snprintf(str,sizeof(str),"(%04u) %-25s FAILED Password attempt" ,0,useron.alias); logline(LOG_NOTICE,"+!",str); bputs(text[PasswordPrompt]); console|=CON_R_ECHOX; getstr(tmp,LEN_PASS*2,K_UPPER|K_LOWPRIO|K_TAB); console&=~(CON_R_ECHOX|CON_L_ECHOX); } else { if(REALSYSOP) { rioctl(IOFI); /* flush input buffer */ if(!chksyspass()) bputs(text[InvalidLogon]); else { i=0; break; } } else break; } } if(i) { if(stricmp(tmp,useron.pass)) { badlogin(useron.alias, tmp); bputs(text[InvalidLogon]); if(cfg.sys_misc&SM_ECHO_PW) safe_snprintf(str,sizeof(str),"(%04u) %-25s FAILED Password attempt: '%s'" ,0,useron.alias,tmp); else safe_snprintf(str,sizeof(str),"(%04u) %-25s FAILED Password attempt" ,0,useron.alias); logline(LOG_NOTICE,"+!",str); } lprintf(LOG_WARNING,"Node %d !CLIENT IP NOT LISTED in %s" ,cfg.node_num,path); useron.number=0; hangup(); } } } else lprintf(LOG_INFO,"Node %d RLogin: Unknown user: %s",cfg.node_num,rlogin_name); } if(rlogin_name[0]==0) { lprintf(LOG_NOTICE,"Node %d !RLogin: No user name received",cfg.node_num); sys_status&=~SS_RLOGIN; } } if(!(telnet_mode&TELNET_MODE_OFF)) { /* Disable Telnet Terminal Echo */ request_telnet_opt(TELNET_WILL,TELNET_ECHO); /* Will suppress Go Ahead */ request_telnet_opt(TELNET_WILL,TELNET_SUP_GA); /* Retrieve terminal type and speed from telnet client --RS */ request_telnet_opt(TELNET_DO,TELNET_TERM_TYPE); request_telnet_opt(TELNET_DO,TELNET_TERM_SPEED); request_telnet_opt(TELNET_DO,TELNET_SEND_LOCATION); request_telnet_opt(TELNET_DO,TELNET_NEGOTIATE_WINDOW_SIZE); request_telnet_opt(TELNET_DO,TELNET_NEW_ENVIRON); } #ifdef USE_CRYPTLIB if(sys_status&SS_SSH) { pthread_mutex_lock(&ssh_mutex); cryptGetAttributeString(ssh_session, CRYPT_SESSINFO_USERNAME, tmpname, &i); tmpname[i]=0; SAFECOPY(rlogin_name, tmpname); cryptGetAttributeString(ssh_session, CRYPT_SESSINFO_PASSWORD, tmp, &i); tmp[i]=0; SAFECOPY(rlogin_pass, tmp); pthread_mutex_unlock(&ssh_mutex); lprintf(LOG_DEBUG,"Node %d SSH login: '******'" ,cfg.node_num, tmpname); useron.number=userdatdupe(0, U_ALIAS, LEN_ALIAS, tmpname); if(useron.number) { getuserdat(&cfg,&useron); useron.misc&=~TERM_FLAGS; for(i=0;i<3;i++) { if(stricmp(tmp,useron.pass)) { badlogin(useron.alias, tmp); rioctl(IOFI); /* flush input buffer */ bputs(text[InvalidLogon]); if(cfg.sys_misc&SM_ECHO_PW) safe_snprintf(str,sizeof(str),"(%04u) %-25s FAILED Password attempt: '%s'" ,0,useron.alias,tmp); else safe_snprintf(str,sizeof(str),"(%04u) %-25s FAILED Password attempt" ,0,useron.alias); /* crash here Sept-12-2010 str 0x06b3fc4c "(0000) Guest FAILED Password attempt: '*****@*****.**'" and Oct-6-2010 str 0x070ffc4c "(0000) Woot903 FAILED Password attempt: 'p67890pppsdsjhsdfhhfhnhnfhfhfdhjksdjkfdskw3902391=`'" char [261] */ logline(LOG_NOTICE,"+!",str); bputs(text[PasswordPrompt]); console|=CON_R_ECHOX; getstr(tmp,LEN_PASS*2,K_UPPER|K_LOWPRIO|K_TAB); console&=~(CON_R_ECHOX|CON_L_ECHOX); } else { if(REALSYSOP) { rioctl(IOFI); /* flush input buffer */ if(!chksyspass()) bputs(text[InvalidLogon]); else { i=0; break; } } else break; } } if(i) { if(stricmp(tmp,useron.pass)) { badlogin(useron.alias, tmp); bputs(text[InvalidLogon]); if(cfg.sys_misc&SM_ECHO_PW) safe_snprintf(str,sizeof(str),"(%04u) %-25s FAILED Password attempt: '%s'" ,0,useron.alias,tmp); else safe_snprintf(str,sizeof(str),"(%04u) %-25s FAILED Password attempt" ,0,useron.alias); logline(LOG_NOTICE,"+!",str); } useron.number=0; hangup(); } } else lprintf(LOG_INFO,"Node %d SSH: Unknown user: %s",cfg.node_num,rlogin_name); } #endif /* Detect terminal type */ mswait(200); rioctl(IOFI); /* flush input buffer */ putcom( "\r\n" /* locate cursor at column 1 */ "\x1b[s" /* save cursor position (necessary for HyperTerm auto-ANSI) */ "\x1b[255B" /* locate cursor as far down as possible */ "\x1b[255C" /* locate cursor as far right as possible */ "\b_" /* need a printable at this location to actually move cursor */ "\x1b[6n" /* Get cursor position */ "\x1b[u" /* restore cursor position */ "\x1b[!_" /* RIP? */ "\x1b[30;40m\xc2\x9f""Zuul.connection.write('\\x1b""Are you the gatekeeper?')\xc2\x9c" /* ZuulTerm? */ "\x1b[0m_" /* "Normal" colors */ "\x1b[2J" /* clear screen */ "\x1b[H" /* home cursor */ "\xC" /* clear screen (in case not ANSI) */ "\r" /* Move cursor left (in case previous char printed) */ ); i=l=0; tos=1; lncntr=0; safe_snprintf(str, sizeof(str), "%s %s", VERSION_NOTICE, COPYRIGHT_NOTICE); strip_ctrl(str, str); center(str); while(i++<50 && l<(int)sizeof(str)-1) { /* wait up to 5 seconds for response */ c=incom(100)&0x7f; if(c==0) continue; i=0; if(l==0 && c!=ESC) // response must begin with escape char continue; str[l++]=c; if(c=='R') { /* break immediately if ANSI response */ mswait(500); break; } } while((c=(incom(100)&0x7f))!=0 && l<(int)sizeof(str)-1) str[l++]=c; str[l]=0; if(l) { c_escape_str(str,tmp,sizeof(tmp),TRUE); lprintf(LOG_DEBUG,"Node %d received terminal auto-detection response: '%s'" ,cfg.node_num,tmp); if(str[0]==ESC && str[1]=='[' && str[l-1]=='R') { int x,y; if(terminal[0]==0) SAFECOPY(terminal,"ANSI"); autoterm|=(ANSI|COLOR); if(sscanf(str+2,"%u;%u",&y,&x)==2) { lprintf(LOG_DEBUG,"Node %d received ANSI cursor position report: %ux%u" ,cfg.node_num, x, y); /* Sanity check the coordinates in the response: */ if(x>=40 && x<=255) cols=x; if(y>=10 && y<=255) rows=y; } } truncsp(str); if(strstr(str,"RIPSCRIP")) { if(terminal[0]==0) SAFECOPY(terminal,"RIP"); logline("@R",strstr(str,"RIPSCRIP")); autoterm|=(RIP|COLOR|ANSI); } else if(strstr(str,"Are you the gatekeeper?")) { if(terminal[0]==0) SAFECOPY(terminal,"HTML"); logline("@H",strstr(str,"Are you the gatekeeper?")); autoterm|=HTML; } } else if(terminal[0]==0) SAFECOPY(terminal,"DUMB"); rioctl(IOFI); /* flush left-over or late response chars */ if(!autoterm && str[0]) { c_escape_str(str,tmp,sizeof(tmp),TRUE); lprintf(LOG_NOTICE,"Node %d terminal auto-detection failed, response: '%s'" ,cfg.node_num, tmp); } /* AutoLogon via IP or Caller ID here */ if(!useron.number && !(sys_status&SS_RLOGIN) && (startup->options&BBS_OPT_AUTO_LOGON) && cid[0]) { useron.number=userdatdupe(0, U_NOTE, LEN_NOTE, cid); if(useron.number) { getuserdat(&cfg, &useron); if(!(useron.misc&AUTOLOGON) || !(useron.exempt&FLAG('V'))) useron.number=0; } } if(!online) return(false); if(stricmp(terminal,"sexpots")==0) { /* dial-up connection (via SexPOTS) */ SAFEPRINTF2(str,"%s connection detected at %lu bps", terminal, cur_rate); logline("@S",str); node_connection = (ushort)cur_rate; SAFEPRINTF(connection,"%lu",cur_rate); SAFECOPY(cid,"Unknown"); SAFECOPY(client_name,"Unknown"); if(telnet_location[0]) { /* Caller-ID info provided */ SAFEPRINTF(str, "CID: %s", telnet_location); logline("@*",str); SAFECOPY(cid,telnet_location); truncstr(cid," "); /* Only include phone number in CID */ char* p=telnet_location; FIND_WHITESPACE(p); SKIP_WHITESPACE(p); if(*p) { SAFECOPY(client_name,p); /* CID name, if provided (maybe 'P' or 'O' if private or out-of-area) */ } } SAFECOPY(client.addr,cid); SAFECOPY(client.host,client_name); client_on(client_socket,&client,TRUE /* update */); } else { if(telnet_location[0]) { /* Telnet Location info provided */ SAFEPRINTF(str, "Telnet Location: %s", telnet_location); logline("@*",str); } } useron.misc&=~TERM_FLAGS; useron.misc|=autoterm; SAFECOPY(useron.comp,client_name); if(!useron.number && rlogin_name[0]!=0 && !(cfg.sys_misc&SM_CLOSED) && !matchuser(&cfg, rlogin_name, /* Sysop alias: */FALSE)) { lprintf(LOG_INFO,"Node %d UNKNOWN %s-specified USERNAME: %s, starting new user signup",cfg.node_num,client.protocol,rlogin_name); bprintf("%s: %s\r\n", text[UNKNOWN_USER], rlogin_name); newuser(); } if(!useron.number) { /* manual/regular logon */ /* Display ANSWER screen */ rioctl(IOSM|PAUSE); sys_status|=SS_PAUSEON; SAFEPRINTF(str,"%sanswer",cfg.text_dir); SAFEPRINTF(path,"%s.rip",str); if((autoterm&RIP) && fexistcase(path)) printfile(path,P_NOABORT); else { SAFEPRINTF(path,"%s.html",str); if((autoterm&HTML) && fexistcase(path)) printfile(path,P_NOABORT); else { SAFEPRINTF(path,"%s.ans",str); if((autoterm&ANSI) && fexistcase(path)) printfile(path,P_NOABORT); else { SAFEPRINTF(path,"%s.asc",str); if(fexistcase(path)) printfile(path, P_NOABORT); } } } sys_status&=~SS_PAUSEON; exec_bin(cfg.login_mod,&main_csi); } else /* auto logon here */ if(logon()==false) return(false); if(!useron.number) hangup(); /* Save the IP to the user's note */ if(cid[0]) { SAFECOPY(useron.note,cid); putuserrec(&cfg,useron.number,U_NOTE,LEN_NOTE,useron.note); } /* Save host name to the user's computer description */ if(client_name[0]) { SAFECOPY(useron.comp,client_name); putuserrec(&cfg,useron.number,U_COMP,LEN_COMP,useron.comp); } if(!online) return(false); if(!(sys_status&SS_USERON)) { errormsg(WHERE,ERR_CHK,"User not logged on",0); hangup(); return(false); } if(useron.pass[0]) loginSuccess(startup->login_attempt_list, &client_addr); return(true); }
/* Important change as of Nov-16-2006, 'cmdline' may contain args */ long sbbs_t::exec_bin(const char *cmdline, csi_t *csi, const char* startup_dir) { char str[MAX_PATH+1]; char mod[MAX_PATH+1]; char modname[MAX_PATH+1]; char* p; int file; csi_t bin; SAFECOPY(mod,cmdline); p=mod; FIND_CHAR(p,' '); if(*p) { *p=0; /* terminate 'mod' */ p++; /* skip space */ SKIP_CHAR(p,' '); /* skip more spaces */ } if(*p) strcpy(main_csi.str, p); #ifdef JAVASCRIPT if((p=getfext(mod))!=NULL && stricmp(p,".js")==0) return(js_execfile(cmdline, startup_dir)); if(p==NULL && startup_dir!=NULL && *startup_dir) { SAFEPRINTF2(str,"%s%s.js", startup_dir, mod); if(fexistcase(str)) return(js_execfile(cmdline, startup_dir)); } if(cfg.mods_dir[0]) { SAFEPRINTF2(str,"%s%s.js",cfg.mods_dir,mod); if(fexistcase(str)) return(js_execfile(cmdline, startup_dir)); } #endif SAFECOPY(modname,mod); if(!strchr(modname,'.')) strcat(modname,".bin"); SAFEPRINTF2(str,"%s%s",cfg.mods_dir,modname); if(cfg.mods_dir[0]==0 || !fexistcase(str)) { #ifdef JAVASCRIPT SAFEPRINTF2(str,"%s%s.js",cfg.exec_dir,mod); if(fexistcase(str)) return(js_execfile(cmdline, startup_dir)); #endif SAFEPRINTF2(str,"%s%s",cfg.exec_dir,modname); fexistcase(str); } if((file=nopen(str,O_RDONLY))==-1) { errormsg(WHERE,ERR_OPEN,str,O_RDONLY); return(-1); } memcpy(&bin,csi,sizeof(csi_t)); clearvars(&bin); bin.length=(uint32_t)filelength(file); if((bin.cs=(uchar *)malloc(bin.length))==NULL) { close(file); errormsg(WHERE,ERR_ALLOC,str,bin.length); return(-1); } if(lread(file,bin.cs,bin.length)!=bin.length) { close(file); errormsg(WHERE,ERR_READ,str,bin.length); free(bin.cs); return(-1); } close(file); bin.ip=bin.cs; bin.rets=0; bin.cmdrets=0; bin.misc=0; while(exec(&bin)==0) if(!(bin.misc&CS_OFFLINE_EXEC)) { checkline(); if(!online) break; } freevars(&bin); free(bin.cs); csi->logic=bin.logic; return(bin.retval); }
int sbbs_t::exec(csi_t *csi) { char str[256],*path; char tmp[512]; uchar buf[1025],ch; int i,j,file; long l; FILE *stream; if(usrgrps) cursubnum=usrsub[curgrp][cursub[curgrp]]; /* Used for ARS */ else cursubnum=INVALID_SUB; if(usrlibs) { curdirnum=usrdir[curlib][curdir[curlib]]; /* Used for ARS */ path=cfg.dir[usrdir[curlib][curdir[curlib]]]->path; } else { curdirnum=INVALID_DIR; path=nulstr; } now=time(NULL); if(csi->ip>=csi->cs+csi->length) return(1); if(*csi->ip>=CS_FUNCTIONS) return(exec_function(csi)); /**********************************************/ /* Miscellaneous variable length instructions */ /**********************************************/ if(*csi->ip>=CS_MISC) return(exec_misc(csi,path)); /********************************/ /* ASCIIZ argument instructions */ /********************************/ if(*csi->ip>=CS_ASCIIZ) { switch(*(csi->ip++)) { case CS_STR_FUNCTION: switch(*(csi->ip++)) { case CS_LOGIN: csi->logic=login(csi->str,(char*)csi->ip); break; case CS_LOAD_TEXT: csi->logic=LOGIC_FALSE; for(i=0;i<TOTAL_TEXT;i++) if(text[i]!=text_sav[i]) { if(text[i]!=nulstr) free(text[i]); text[i]=text_sav[i]; } SAFEPRINTF2(str,"%s%s.dat" ,cfg.ctrl_dir,cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); if((stream=fnopen(&file,str,O_RDONLY))==NULL) { errormsg(WHERE,ERR_OPEN,str,O_RDONLY); break; } for(i=0;i<TOTAL_TEXT && !feof(stream);i++) { if((text[i]=readtext((long *)NULL,stream,i))==NULL) { i--; continue; } if(!strcmp(text[i],text_sav[i])) { /* If identical */ free(text[i]); /* Don't alloc */ text[i]=text_sav[i]; } else if(text[i][0]==0) { free(text[i]); text[i]=nulstr; } } if(i<TOTAL_TEXT) { fclose(stream); errormsg(WHERE,ERR_READ,str,TOTAL_TEXT); break; } fclose(stream); csi->logic=LOGIC_TRUE; break; default: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1)); break; } while(*(csi->ip++)); /* Find NULL */ return(0); case CS_LOG: log(cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); break; case CS_GETCMD: csi->cmd=(uchar)getkeys((char*)csi->ip,0); if((char)csi->cmd==-1) csi->cmd=3; break; case CS_CMDSTR: if(stricmp(csi->str,(char*)csi->ip)) { while(*(csi->ip++)); /* Find NULL */ skipto(csi,CS_END_CMD); csi->ip++; return(0); } break; case CS_CMDKEYS: for(i=0;csi->ip[i];i++) if(csi->cmd==csi->ip[i]) break; if(!csi->ip[i]) { while(*(csi->ip++)); /* Find NULL */ skipto(csi,CS_END_CMD); csi->ip++; return(0); } break; case CS_GET_TEMPLATE: gettmplt(csi->str,(char*)csi->ip,K_LINE); if(sys_status&SS_ABORT) csi->str[0]=0; csi->cmd=csi->str[0]; break; case CS_TRASHCAN: csi->logic=!trashcan(csi->str,(char*)csi->ip); break; case CS_CREATE_SIF: create_sif_dat((char*)csi->ip,csi->str); break; case CS_READ_SIF: read_sif_dat((char*)csi->ip,csi->str); break; case CS_MNEMONICS: mnemonics((char*)csi->ip); break; case CS_PRINT: putmsg(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),P_SAVEATR|P_NOABORT); break; case CS_PRINT_LOCAL: if(online==ON_LOCAL) eprintf(LOG_INFO,"%s",cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); else lputs(LOG_INFO,cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); break; case CS_PRINT_REMOTE: putcom(cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); break; case CS_PRINTFILE: printfile(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),P_SAVEATR); break; case CS_PRINTFILE_REMOTE: if(online!=ON_REMOTE || !(console&CON_R_ECHO)) break; console&=~CON_L_ECHO; printfile(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),P_SAVEATR); console|=CON_L_ECHO; break; case CS_PRINTFILE_LOCAL: if(!(console&CON_L_ECHO)) break; console&=~CON_R_ECHO; printfile(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),P_SAVEATR); console|=CON_R_ECHO; break; case CS_CHKFILE: csi->logic=!fexistcase(cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); break; case CS_EXEC: external(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),0); break; case CS_EXEC_INT: external(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),EX_STDIO); break; case CS_EXEC_XTRN: for(i=0;i<cfg.total_xtrns;i++) if(!stricmp(cfg.xtrn[i]->code,(char*)csi->ip)) break; if(i<cfg.total_xtrns) exec_xtrn(i); break; case CS_EXEC_BIN: exec_bin(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),csi,/* startup_dir: */NULL); break; case CS_YES_NO: csi->logic=!yesno(cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); break; case CS_NO_YES: csi->logic=!noyes(cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); break; case CS_MENU: menu(cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); break; case CS_SETSTR: strcpy(csi->str,cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); break; case CS_SET_MENU_DIR: cmdstr((char*)csi->ip,path,csi->str,menu_dir); break; case CS_SET_MENU_FILE: cmdstr((char*)csi->ip,path,csi->str,menu_file); break; case CS_COMPARE_STR: csi->logic=stricmp(csi->str,cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); break; case CS_COMPARE_KEYS: for(i=0;csi->ip[i];i++) if(csi->cmd==csi->ip[i]) break; if(csi->ip[i]) csi->logic=LOGIC_TRUE; else csi->logic=LOGIC_FALSE; break; case CS_COMPARE_WORD: csi->logic=strnicmp(csi->str,(char*)csi->ip,strlen((char*)csi->ip)); break; default: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1)); break; } while(*(csi->ip++)); /* Find NULL */ return(0); } if(*csi->ip>=CS_THREE_BYTE) { switch(*(csi->ip++)) { case CS_THREE_MORE_BYTES: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1)); return(0); case CS_GOTO: csi->ip=csi->cs+*((ushort *)(csi->ip)); return(0); case CS_CALL: if(csi->rets<MAX_RETS) { csi->ret[csi->rets++]=csi->ip+2; csi->ip=csi->cs+*((ushort *)(csi->ip)); } return(0); case CS_MSWAIT: mswait(*(ushort *)csi->ip); csi->ip+=2; return(0); case CS_TOGGLE_NODE_MISC: if(getnodedat(cfg.node_num,&thisnode,true)==0) { thisnode.misc^=*(ushort *)csi->ip; putnodedat(cfg.node_num,&thisnode); } csi->ip+=2; return(0); case CS_COMPARE_NODE_MISC: getnodedat(cfg.node_num,&thisnode,0); if((thisnode.misc&*(ushort *)csi->ip)==*(ushort *)csi->ip) csi->logic=LOGIC_TRUE; else csi->logic=LOGIC_FALSE; csi->ip+=2; return(0); case CS_ADJUST_USER_CREDITS: i=*(short *)csi->ip; l=i*1024L; if(l<0) subtract_cdt(&cfg,&useron,-l); else useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,10,l); csi->ip+=2; return(0); case CS_ADJUST_USER_MINUTES: i=*(short *)csi->ip; useron.min=adjustuserrec(&cfg,useron.number,U_MIN,10,i); csi->ip+=2; return(0); case CS_GETNUM: i=*(short *)csi->ip; csi->ip+=2; l=getnum(i); if(l<=0) { csi->str[0]=0; csi->logic=LOGIC_FALSE; } else { sprintf(csi->str,"%lu",l); csi->logic=LOGIC_TRUE; } return(0); case CS_TOGGLE_USER_FLAG: i=*(csi->ip++); ch=*(csi->ip++); switch(i) { case '1': useron.flags1^=FLAG(ch); putuserrec(&cfg,useron.number,U_FLAGS1,8 ,ultoa(useron.flags1,tmp,16)); break; case '2': useron.flags2^=FLAG(ch); putuserrec(&cfg,useron.number,U_FLAGS2,8 ,ultoa(useron.flags2,tmp,16)); break; case '3': useron.flags3^=FLAG(ch); putuserrec(&cfg,useron.number,U_FLAGS3,8 ,ultoa(useron.flags3,tmp,16)); break; case '4': useron.flags4^=FLAG(ch); putuserrec(&cfg,useron.number,U_FLAGS4,8 ,ultoa(useron.flags4,tmp,16)); break; case 'R': useron.rest^=FLAG(ch); putuserrec(&cfg,useron.number,U_REST,8 ,ultoa(useron.rest,tmp,16)); break; case 'E': useron.exempt^=FLAG(ch); putuserrec(&cfg,useron.number,U_EXEMPT,8 ,ultoa(useron.exempt,tmp,16)); break; default: errormsg(WHERE,ERR_CHK,"user flag type",*(csi->ip-2)); return(0); } return(0); case CS_REVERT_TEXT: i=*(ushort *)csi->ip; csi->ip+=2; if((ushort)i==0xffff) { for(i=0;i<TOTAL_TEXT;i++) { if(text[i]!=text_sav[i] && text[i]!=nulstr) free(text[i]); text[i]=text_sav[i]; } return(0); } i--; if(i>=TOTAL_TEXT) { errormsg(WHERE,ERR_CHK,"revert text #",i); return(0); } if(text[i]!=text_sav[i] && text[i]!=nulstr) free(text[i]); text[i]=text_sav[i]; return(0); default: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1)); return(0); } } if(*csi->ip>=CS_TWO_BYTE) { switch(*(csi->ip++)) { case CS_TWO_MORE_BYTES: switch(*(csi->ip++)) { case CS_USER_EVENT: user_event((user_event_t)*(csi->ip++)); return(0); } errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1)); return(0); case CS_SETLOGIC: csi->logic=*csi->ip++; return(0); case CS_CMDKEY: if( ((*csi->ip)==CS_DIGIT && isdigit(csi->cmd)) || ((*csi->ip)==CS_EDIGIT && csi->cmd&0x80 && isdigit(csi->cmd&0x7f))) { csi->ip++; return(0); } if(csi->cmd!=*csi->ip) { csi->ip++; skipto(csi,CS_END_CMD); /* skip code */ } csi->ip++; /* skip key */ return(0); case CS_CMDCHAR: if(csi->cmd!=*csi->ip) { csi->ip++; skipto(csi,CS_END_CMD); /* skip code */ } csi->ip++; /* skip key */ return(0); case CS_NODE_ACTION: action=*csi->ip++; return(0); case CS_NODE_STATUS: if(getnodedat(cfg.node_num,&thisnode,true)==0) { thisnode.status=*csi->ip++; putnodedat(cfg.node_num,&thisnode); } else csi->ip++; return(0); case CS_MULTINODE_CHAT: multinodechat(*csi->ip++); return(0); case CS_GETSTR: csi->logic=LOGIC_TRUE; getstr(csi->str,*csi->ip++,0); if(sys_status&SS_ABORT) { csi->str[0]=0; csi->logic=LOGIC_FALSE; } if(csi->str[0]=='/' && csi->str[1]) csi->cmd=csi->str[1]|0x80; else csi->cmd=csi->str[0]; return(0); case CS_GETLINE: getstr(csi->str,*csi->ip++,K_LINE); if(sys_status&SS_ABORT) csi->str[0]=0; if(csi->str[0]=='/' && csi->str[1]) csi->cmd=csi->str[1]|0x80; else csi->cmd=csi->str[0]; return(0); case CS_GETSTRUPR: getstr(csi->str,*csi->ip++,K_UPPER); if(sys_status&SS_ABORT) csi->str[0]=0; if(csi->str[0]=='/' && csi->str[1]) csi->cmd=csi->str[1]|0x80; else csi->cmd=csi->str[0]; return(0); case CS_GETNAME: getstr(csi->str,*csi->ip++,K_UPRLWR); if(sys_status&SS_ABORT) csi->str[0]=0; return(0); case CS_SHIFT_STR: i=*(csi->ip++); j=strlen(csi->str); if(i>j) i=j; if(i) memmove(csi->str,csi->str+i,j+1); return(0); case CS_COMPARE_KEY: if( ((*csi->ip)==CS_DIGIT && isdigit(csi->cmd)) || ((*csi->ip)==CS_EDIGIT && csi->cmd&0x80 && isdigit(csi->cmd&0x7f))) { csi->ip++; csi->logic=LOGIC_TRUE; } else { if(csi->cmd==*(csi->ip++)) csi->logic=LOGIC_TRUE; else csi->logic=LOGIC_FALSE; } return(0); case CS_COMPARE_CHAR: if(csi->cmd==*(csi->ip++)) csi->logic=LOGIC_TRUE; else csi->logic=LOGIC_FALSE; return(0); case CS_SET_USER_LEVEL: useron.level=*(csi->ip++); putuserrec(&cfg,useron.number,U_LEVEL,2,ultoa(useron.level,tmp,10)); return(0); case CS_SET_USER_STRING: csi->logic=LOGIC_FALSE; if(!csi->str[0]) { csi->ip++; return(0); } switch(*(csi->ip++)) { case USER_STRING_ALIAS: if(!isalpha(csi->str[0]) || trashcan(csi->str,"name")) break; i=matchuser(&cfg,csi->str,TRUE /*sysop_alias*/); if(i && i!=useron.number) break; sprintf(useron.alias,"%.*s",LEN_ALIAS,csi->str); putuserrec(&cfg,useron.number,U_ALIAS,LEN_ALIAS,useron.alias); putusername(&cfg,useron.number,useron.alias); csi->logic=LOGIC_TRUE; break; case USER_STRING_REALNAME: if(trashcan(csi->str,"name")) break; if(cfg.uq&UQ_DUPREAL && userdatdupe(useron.number,U_NAME,LEN_NAME,csi->str)) break; sprintf(useron.name,"%.*s",LEN_NAME,csi->str); putuserrec(&cfg,useron.number,U_NAME,LEN_NAME ,useron.name); csi->logic=LOGIC_TRUE; break; case USER_STRING_HANDLE: if(trashcan(csi->str,"name")) break; if(cfg.uq&UQ_DUPHAND && userdatdupe(useron.number,U_HANDLE,LEN_HANDLE,csi->str)) break; sprintf(useron.handle,"%.*s",LEN_HANDLE,csi->str); putuserrec(&cfg,useron.number,U_HANDLE,LEN_HANDLE ,useron.handle); csi->logic=LOGIC_TRUE; break; case USER_STRING_COMPUTER: sprintf(useron.comp,"%.*s",LEN_COMP,csi->str); putuserrec(&cfg,useron.number,U_COMP,LEN_COMP ,useron.comp); csi->logic=LOGIC_TRUE; break; case USER_STRING_NOTE: sprintf(useron.note,"%.*s",LEN_NOTE,csi->str); putuserrec(&cfg,useron.number,U_NOTE,LEN_NOTE ,useron.note); csi->logic=LOGIC_TRUE; break; case USER_STRING_ADDRESS: sprintf(useron.address,"%.*s",LEN_ADDRESS,csi->str); putuserrec(&cfg,useron.number,U_ADDRESS,LEN_ADDRESS ,useron.address); csi->logic=LOGIC_TRUE; break; case USER_STRING_LOCATION: sprintf(useron.location,"%.*s",LEN_LOCATION,csi->str); putuserrec(&cfg,useron.number,U_LOCATION,LEN_LOCATION ,useron.location); csi->logic=LOGIC_TRUE; break; case USER_STRING_ZIPCODE: sprintf(useron.zipcode,"%.*s",LEN_ZIPCODE,csi->str); putuserrec(&cfg,useron.number,U_ZIPCODE,LEN_ZIPCODE ,useron.zipcode); csi->logic=LOGIC_TRUE; break; case USER_STRING_PASSWORD: sprintf(useron.pass,"%.*s",LEN_PASS,csi->str); putuserrec(&cfg,useron.number,U_PASS,LEN_PASS ,useron.pass); csi->logic=LOGIC_TRUE; break; case USER_STRING_BIRTHDAY: if(!getage(&cfg,csi->str)) break; sprintf(useron.birth,"%.*s",LEN_BIRTH,csi->str); putuserrec(&cfg,useron.number,U_BIRTH,LEN_BIRTH ,useron.birth); csi->logic=LOGIC_TRUE; break; case USER_STRING_PHONE: if(trashcan(csi->str,"phone")) break; sprintf(useron.phone,"%.*s",LEN_PHONE,csi->str); putuserrec(&cfg,useron.number,U_PHONE,LEN_PHONE ,useron.phone); csi->logic=LOGIC_TRUE; break; case USER_STRING_MODEM: sprintf(useron.modem,"%.*s",LEN_MODEM,csi->str); putuserrec(&cfg,useron.number,U_MODEM,LEN_MODEM ,useron.phone); csi->logic=LOGIC_TRUE; break; case USER_STRING_COMMENT: sprintf(useron.comment,"%.*s",LEN_COMMENT,csi->str); putuserrec(&cfg,useron.number,U_COMMENT,LEN_COMMENT ,useron.comment); csi->logic=LOGIC_TRUE; break; case USER_STRING_NETMAIL: sprintf(useron.netmail,"%.*s",LEN_NETMAIL,csi->str); putuserrec(&cfg,useron.number,U_NETMAIL,LEN_NETMAIL ,useron.netmail); csi->logic=LOGIC_TRUE; break; default: errormsg(WHERE,ERR_CHK,"user string type",*(csi->ip-1)); return(0); } return(0); default: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1)); return(0); } } /*********************************/ /* Single Byte Instrcutions ONLY */ /*********************************/ switch(*(csi->ip++)) { case CS_ONE_MORE_BYTE: /* Just one MORE byte */ switch(*(csi->ip++)) { case CS_OFFLINE: csi->misc|=CS_OFFLINE_EXEC; return(0); case CS_ONLINE: csi->misc&=~CS_OFFLINE_EXEC; return(0); case CS_NEWUSER: if(newuser()) csi->logic=LOGIC_TRUE; else csi->logic=LOGIC_FALSE; return(0); case CS_LOGON: if(logon()) csi->logic=LOGIC_TRUE; else csi->logic=LOGIC_FALSE; return(0); case CS_LOGOUT: logout(); return(0); case CS_EXIT: return(1); case CS_LOOP_BEGIN: if(csi->loops<MAX_LOOPDEPTH) csi->loop_home[csi->loops++]=(csi->ip-1); return(0); case CS_BREAK_LOOP: if(csi->loops) { skipto(csi,CS_END_LOOP); csi->ip+=2; csi->loops--; } return(0); case CS_END_LOOP: case CS_CONTINUE_LOOP: if(csi->loops) csi->ip=csi->loop_home[csi->loops-1]; return(0); default: errormsg(WHERE,ERR_CHK,"one byte extended function" ,*(csi->ip-1)); return(0); } case CS_CRLF: CRLF; return(0); case CS_CLS: CLS; return(0); case CS_PAUSE: pause(); return(0); case CS_PAUSE_RESET: lncntr=0; return(0); case CS_GETLINES: ansi_getlines(); return(0); case CS_HANGUP: hangup(); return(0); case CS_LOGKEY: logch(csi->cmd,0); return(0); case CS_LOGKEY_COMMA: logch(csi->cmd,1); return(0); case CS_LOGSTR: log(csi->str); return(0); case CS_CHKSYSPASS: csi->logic=!chksyspass(); return(0); case CS_PUT_NODE: if(getnodedat(cfg.node_num,&thisnode,true)==0) putnodedat(cfg.node_num,&thisnode); return(0); case CS_SYNC: SYNC; return(0); case CS_ASYNC: ASYNC; return(0); case CS_GETTIMELEFT: gettimeleft(); return(0); case CS_RETURN: if(!csi->rets) return(1); csi->ip=csi->ret[--csi->rets]; return(0); case CS_GETKEY: csi->cmd=getkey(K_UPPER); return(0); case CS_GETCHAR: csi->cmd=getkey(0); return(0); case CS_INKEY: csi->cmd=toupper(inkey(K_NONE,1)); if(csi->cmd) csi->logic=LOGIC_TRUE; else csi->logic=LOGIC_FALSE; return(0); case CS_INCHAR: csi->cmd=inkey(K_NONE,1); if(csi->cmd) csi->logic=LOGIC_TRUE; else csi->logic=LOGIC_FALSE; return(0); case CS_GETKEYE: csi->cmd=getkey(K_UPPER); if(csi->cmd=='/') { outchar('/'); csi->cmd=getkey(K_UPPER); csi->cmd|=0x80; } return(0); case CS_GETFILESPEC: if(getfilespec(csi->str)) csi->logic=LOGIC_TRUE; else csi->logic=LOGIC_FALSE; return(0); case CS_SAVELINE: SAVELINE; return(0); case CS_RESTORELINE: RESTORELINE; return(0); case CS_SELECT_SHELL: csi->logic=select_shell() ? LOGIC_TRUE:LOGIC_FALSE; return(0); case CS_SET_SHELL: csi->logic=LOGIC_TRUE; for(i=0;i<cfg.total_shells;i++) if(!stricmp(csi->str,cfg.shell[i]->code) && chk_ar(cfg.shell[i]->ar,&useron,&client)) break; if(i<cfg.total_shells) { useron.shell=i; putuserrec(&cfg,useron.number,U_SHELL,8,cfg.shell[i]->code); } else csi->logic=LOGIC_FALSE; return(0); case CS_SELECT_EDITOR: csi->logic=select_editor() ? LOGIC_TRUE:LOGIC_FALSE; return(0); case CS_SET_EDITOR: csi->logic=LOGIC_TRUE; for(i=0;i<cfg.total_xedits;i++) if(!stricmp(csi->str,cfg.xedit[i]->code) && chk_ar(cfg.xedit[i]->ar,&useron,&client)) break; if(i<cfg.total_xedits) { useron.xedit=i+1; putuserrec(&cfg,useron.number,U_XEDIT,8,cfg.xedit[i]->code); } else csi->logic=LOGIC_FALSE; return(0); case CS_CLEAR_ABORT: sys_status&=~SS_ABORT; return(0); case CS_FINDUSER: i=finduser(csi->str); if(i) { csi->logic=LOGIC_TRUE; username(&cfg,i,csi->str); } else csi->logic=LOGIC_FALSE; return(0); case CS_UNGETKEY: ungetkey(csi->cmd&0x7f); return(0); case CS_UNGETSTR: j=strlen(csi->str); for(i=0;i<j;i++) ungetkey(csi->str[i]); return(0); case CS_PRINTKEY: if((csi->cmd&0x7f)>=' ') outchar(csi->cmd&0x7f); return(0); case CS_PRINTSTR: putmsg(csi->str,P_SAVEATR|P_NOABORT|P_NOATCODES); return(0); case CS_CMD_HOME: if(csi->cmdrets<MAX_CMDRETS) csi->cmdret[csi->cmdrets++]=(csi->ip-1); return(0); case CS_END_CMD: if(csi->cmdrets) csi->ip=csi->cmdret[--csi->cmdrets]; return(0); case CS_CMD_POP: if(csi->cmdrets) csi->cmdrets--; return(0); case CS_IF_TRUE: if(csi->logic!=LOGIC_TRUE) { skipto(csi,CS_ELSEORENDIF); csi->ip++; } return(0); case CS_IF_GREATER: if(csi->logic!=LOGIC_GREATER) { skipto(csi,CS_ELSEORENDIF); csi->ip++; } return(0); case CS_IF_GREATER_OR_EQUAL: if(csi->logic!=LOGIC_GREATER && csi->logic!=LOGIC_EQUAL) { skipto(csi,CS_ELSEORENDIF); csi->ip++; } return(0); case CS_IF_LESS: if(csi->logic!=LOGIC_LESS) { skipto(csi,CS_ELSEORENDIF); csi->ip++; } return(0); case CS_IF_LESS_OR_EQUAL: if(csi->logic!=LOGIC_LESS && csi->logic!=LOGIC_EQUAL) { skipto(csi,CS_ELSEORENDIF); csi->ip++; } return(0); case CS_IF_FALSE: if(csi->logic==LOGIC_TRUE) { skipto(csi,CS_ELSEORENDIF); csi->ip++; } return(0); case CS_ELSE: skipto(csi,CS_ENDIF); csi->ip++; return(0); case CS_END_CASE: skipto(csi,CS_END_SWITCH); csi->misc&=~CS_IN_SWITCH; csi->ip++; return(0); case CS_DEFAULT: case CS_END_SWITCH: csi->misc&=~CS_IN_SWITCH; return(0); case CS_ENDIF: return(0); default: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1)); return(0); } }
BOOL DLLCALL addfiledat(scfg_t* cfg, file_t* f) { char str[MAX_PATH+1],fname[13],c,fdat[F_LEN+1]; char tmp[128]; uchar *ixbbuf,idx[3]; int i,file; long l,length; time_t now; time_t uldate; /************************/ /* Add data to DAT File */ /************************/ SAFEPRINTF2(str,"%s%s.dat",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code); if((file=sopen(str,O_RDWR|O_BINARY|O_CREAT,SH_DENYRW,DEFFILEMODE))==-1) { return(FALSE); } length=(long)filelength(file); if(length==0L) l=0L; else { if(length%F_LEN) { close(file); return(FALSE); } for(l=0;l<length;l+=F_LEN) { /* Find empty slot */ lseek(file,l,SEEK_SET); read(file,&c,1); if(c==ETX) break; } if(l/F_LEN>=MAX_FILES) { close(file); return(FALSE); } } putrec(fdat,F_CDT,LEN_FCDT,ultoa(f->cdt,tmp,10)); putrec(fdat,F_DESC,LEN_FDESC,f->desc); putrec(fdat,F_DESC+LEN_FDESC,2,crlf); putrec(fdat,F_ULER,LEN_ALIAS+5,f->uler); putrec(fdat,F_ULER+LEN_ALIAS+5,2,crlf); putrec(fdat,F_TIMESDLED,5,ultoa(f->timesdled,tmp,10)); putrec(fdat,F_TIMESDLED+5,2,crlf); putrec(fdat,F_OPENCOUNT,3,ultoa(f->opencount,tmp,10)); putrec(fdat,F_OPENCOUNT+3,2,crlf); fdat[F_MISC]=(char)f->misc+' '; putrec(fdat,F_ALTPATH,2,hexplus(f->altpath,tmp)); putrec(fdat,F_ALTPATH+2,2,crlf); f->datoffset=l; idx[0]=(uchar)(l&0xff); /* Get offset within DAT file for IXB file */ idx[1]=(uchar)((l>>8)&0xff); idx[2]=(uchar)((l>>16)&0xff); lseek(file,l,SEEK_SET); if(write(file,fdat,F_LEN)!=F_LEN) { close(file); return(FALSE); } length=(long)filelength(file); close(file); if(length%F_LEN) { return(FALSE); } /*******************************************/ /* Update last upload date/time stamp file */ /*******************************************/ SAFEPRINTF2(str,"%s%s.dab",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code); if((file=sopen(str,O_WRONLY|O_CREAT|O_BINARY,SH_DENYRW,DEFFILEMODE))!=-1) { now=time(NULL); /* TODO: 32-bit *or* LE required */ write(file,&now,4); close(file); } /************************/ /* Add data to IXB File */ /************************/ SAFECOPY(fname,f->name); for(i=8;i<12;i++) /* Turn FILENAME.EXT into FILENAMEEXT */ fname[i]=fname[i+1]; SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code); if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYRW,DEFFILEMODE))==-1) { return(FALSE); } length=(long)filelength(file); if(length) { /* IXB file isn't empty */ if(length%F_IXBSIZE) { close(file); return(FALSE); } if((ixbbuf=(uchar *)malloc(length))==NULL) { close(file); return(FALSE); } if(lread(file,ixbbuf,length)!=length) { close(file); free((char *)ixbbuf); return(FALSE); } /************************************************/ /* Sort by Name or Date, Assending or Decending */ /************************************************/ if(cfg->dir[f->dir]->sort==SORT_NAME_A || cfg->dir[f->dir]->sort==SORT_NAME_D) { for(l=0;l<length;l+=F_IXBSIZE) { for(i=0;i<12 && toupper(fname[i])==toupper(ixbbuf[l+i]);i++); if(i==12) { /* file already in directory index */ close(file); free((char *)ixbbuf); return(FALSE); } if(cfg->dir[f->dir]->sort==SORT_NAME_A && toupper(fname[i])<toupper(ixbbuf[l+i])) break; if(cfg->dir[f->dir]->sort==SORT_NAME_D && toupper(fname[i])>toupper(ixbbuf[l+i])) break; } } else { /* sort by date */ for(l=0;l<length;l+=F_IXBSIZE) { uldate=(ixbbuf[l+14]|((long)ixbbuf[l+15]<<8) |((long)ixbbuf[l+16]<<16)|((long)ixbbuf[l+17]<<24)); if(cfg->dir[f->dir]->sort==SORT_DATE_A && f->dateuled<uldate) break; if(cfg->dir[f->dir]->sort==SORT_DATE_D && f->dateuled>uldate) break; } } lseek(file,l,SEEK_SET); if(write(file,fname,11)!=11) { /* Write filename to IXB file */ close(file); free((char *)ixbbuf); return(FALSE); } if(write(file,idx,3)!=3) { /* Write DAT offset into IXB file */ close(file); free((char *)ixbbuf); return(FALSE); } write(file,&f->dateuled,4); write(file,&f->datedled,4); /* Write 0 for datedled */ if(lwrite(file,&ixbbuf[l],length-l)!=length-l) { /* Write rest of IXB */ close(file); free((char *)ixbbuf); return(FALSE); } free((char *)ixbbuf); } else { /* IXB file is empty... No files */ if(write(file,fname,11)!=11) { /* Write filename it IXB file */ close(file); return(FALSE); } if(write(file,idx,3)!=3) { /* Write DAT offset into IXB file */ close(file); return(FALSE); } write(file,&f->dateuled,4); write(file,&f->datedled,4); } length=(long)filelength(file); close(file); return(TRUE); }
void prep_cfg(scfg_t* cfg) { int i; #if 0 /* def __unix__ */ strlwr(cfg->text_dir); /* temporary Unix-compatibility hack */ strlwr(cfg->temp_dir); /* temporary Unix-compatibility hack */ strlwr(cfg->data_dir); /* temporary Unix-compatibility hack */ strlwr(cfg->exec_dir); /* temporary Unix-compatibility hack */ #endif /* Fix-up paths */ prep_dir(cfg->ctrl_dir, cfg->data_dir, sizeof(cfg->data_dir)); prep_dir(cfg->ctrl_dir, cfg->logs_dir, sizeof(cfg->logs_dir)); prep_dir(cfg->ctrl_dir, cfg->exec_dir, sizeof(cfg->exec_dir)); prep_dir(cfg->ctrl_dir, cfg->mods_dir, sizeof(cfg->mods_dir)); prep_dir(cfg->ctrl_dir, cfg->text_dir, sizeof(cfg->text_dir)); prep_dir(cfg->ctrl_dir, cfg->netmail_dir, sizeof(cfg->netmail_dir)); prep_dir(cfg->ctrl_dir, cfg->echomail_dir, sizeof(cfg->echomail_dir)); prep_dir(cfg->ctrl_dir, cfg->fidofile_dir, sizeof(cfg->fidofile_dir)); prep_path(cfg->netmail_sem); prep_path(cfg->echomail_sem); prep_path(cfg->inetmail_sem); #if 0 /* def __unix__ */ /* temporary hack for Unix compatibility */ strlwr(cfg->logon_mod); strlwr(cfg->logoff_mod); strlwr(cfg->newuser_mod); strlwr(cfg->login_mod); strlwr(cfg->logout_mod); strlwr(cfg->sync_mod); strlwr(cfg->expire_mod); #endif for(i=0;i<cfg->total_subs;i++) { if(!cfg->sub[i]->data_dir[0]) /* no data storage path specified */ sprintf(cfg->sub[i]->data_dir,"%ssubs",cfg->data_dir); prep_dir(cfg->ctrl_dir, cfg->sub[i]->data_dir, sizeof(cfg->sub[i]->data_dir)); /* default QWKnet tagline */ if(!cfg->sub[i]->tagline[0]) SAFECOPY(cfg->sub[i]->tagline,cfg->qnet_tagline); /* default origin line */ if(!cfg->sub[i]->origline[0]) SAFECOPY(cfg->sub[i]->origline,cfg->origline); /* A sub-board's internal code is the combination of the grp's code_prefix & the sub's code_suffix */ SAFEPRINTF2(cfg->sub[i]->code,"%s%s" ,cfg->grp[cfg->sub[i]->grp]->code_prefix ,cfg->sub[i]->code_suffix); strlwr(cfg->sub[i]->code); /* data filenames are all lowercase */ prep_path(cfg->sub[i]->post_sem); } for(i=0;i<cfg->total_libs;i++) { if(cfg->lib[i]->parent_path[0]) prep_dir(cfg->ctrl_dir, cfg->lib[i]->parent_path, sizeof(cfg->lib[i]->parent_path)); } for(i=0;i<cfg->total_dirs;i++) { if(!cfg->dir[i]->data_dir[0]) /* no data storage path specified */ sprintf(cfg->dir[i]->data_dir,"%sdirs",cfg->data_dir); prep_dir(cfg->ctrl_dir, cfg->dir[i]->data_dir, sizeof(cfg->dir[i]->data_dir)); /* A directory's internal code is the combination of the lib's code_prefix & the dir's code_suffix */ SAFEPRINTF2(cfg->dir[i]->code,"%s%s" ,cfg->lib[cfg->dir[i]->lib]->code_prefix ,cfg->dir[i]->code_suffix); strlwr(cfg->dir[i]->code); /* data filenames are all lowercase */ if(!cfg->dir[i]->path[0]) /* no file storage path specified */ sprintf(cfg->dir[i]->path,"%sdirs/%s/",cfg->data_dir,cfg->dir[i]->code); else if(cfg->lib[cfg->dir[i]->lib]->parent_path[0]) prep_dir(cfg->lib[cfg->dir[i]->lib]->parent_path, cfg->dir[i]->path, sizeof(cfg->dir[i]->path)); else prep_dir(cfg->ctrl_dir, cfg->dir[i]->path, sizeof(cfg->dir[i]->path)); prep_path(cfg->dir[i]->upload_sem); } /* make data filenames are all lowercase */ for(i=0;i<cfg->total_shells;i++) strlwr(cfg->shell[i]->code); for(i=0;i<cfg->total_gurus;i++) strlwr(cfg->guru[i]->code); for(i=0;i<cfg->total_txtsecs;i++) strlwr(cfg->txtsec[i]->code); for(i=0;i<cfg->total_xtrnsecs;i++) strlwr(cfg->xtrnsec[i]->code); for(i=0;i<cfg->total_xtrns;i++) { strlwr(cfg->xtrn[i]->code); prep_dir(cfg->ctrl_dir, cfg->xtrn[i]->path, sizeof(cfg->xtrn[i]->path)); } for(i=0;i<cfg->total_events;i++) { strlwr(cfg->event[i]->code); /* data filenames are all lowercase */ prep_dir(cfg->ctrl_dir, cfg->event[i]->dir, sizeof(cfg->event[i]->dir)); } for(i=0;i<cfg->total_xedits;i++) strlwr(cfg->xedit[i]->code); cfg->prepped=TRUE; /* data prepared for run-time, DO NOT SAVE TO DISK! */ }
BOOL sbbs_t::newuser() { char c,str[512]; char tmp[512]; uint i; long kmode; bool usa; bputs(text[StartingNewUserRegistration]); getnodedat(cfg.node_num,&thisnode,0); if(thisnode.misc&NODE_LOCK) { bputs(text[NodeLocked]); logline(LOG_WARNING,"N!","New user locked node logon attempt"); hangup(); return(FALSE); } if(cfg.sys_misc&SM_CLOSED) { bputs(text[NoNewUsers]); hangup(); return(FALSE); } getnodedat(cfg.node_num,&thisnode,1); thisnode.status=NODE_NEWUSER; thisnode.connection=node_connection; putnodedat(cfg.node_num,&thisnode); memset(&useron,0,sizeof(user_t)); /* Initialize user info to null */ if(cfg.new_pass[0] && online==ON_REMOTE) { c=0; while(++c<4) { bputs(text[NewUserPasswordPrompt]); getstr(str,40,K_UPPER); if(!strcmp(str,cfg.new_pass)) break; SAFEPRINTF(tmp,"NUP Attempted: '%s'",str); logline(LOG_NOTICE,"N!",tmp); } if(c==4) { SAFEPRINTF(str,"%snupguess.msg",cfg.text_dir); if(fexist(str)) printfile(str,P_NOABORT); hangup(); return(FALSE); } } /* Sets defaults per sysop config */ useron.misc|=(cfg.new_misc&~(DELETED|INACTIVE|QUIET|NETMAIL)); useron.qwk=QWK_DEFAULT; useron.firston=useron.laston=useron.pwmod=time32(NULL); if(cfg.new_expire) { now=time(NULL); useron.expire=(time32_t)(now+((long)cfg.new_expire*24L*60L*60L)); } else useron.expire=0; useron.sex=' '; useron.prot=cfg.new_prot; SAFECOPY(useron.comp,client_name); /* hostname or CID name */ SAFECOPY(useron.note,cid); /* IP address or CID number */ if((i=userdatdupe(0,U_NOTE,LEN_NOTE,cid, /* del */true))!=0) { /* Duplicate IP address */ SAFEPRINTF2(useron.comment,"Warning: same IP address as user #%d %s" ,i,username(&cfg,i,str)); logline(LOG_NOTICE,"N!",useron.comment); } SAFECOPY(useron.alias,"New"); /* just for status line */ SAFECOPY(useron.modem,connection); if(!lastuser(&cfg)) { /* Automatic sysop access for first user */ bprintf("Creating sysop account... System password required.\r\n"); if(!chksyspass()) return(FALSE); useron.level=99; useron.exempt=useron.flags1=useron.flags2=0xffffffffUL; useron.flags3=useron.flags4=0xffffffffUL; useron.rest=0L; } else { useron.level=cfg.new_level; useron.flags1=cfg.new_flags1; useron.flags2=cfg.new_flags2; useron.flags3=cfg.new_flags3; useron.flags4=cfg.new_flags4; useron.rest=cfg.new_rest; useron.exempt=cfg.new_exempt; } useron.cdt=cfg.new_cdt; useron.min=cfg.new_min; useron.freecdt=cfg.level_freecdtperday[useron.level]; if(cfg.total_fcomps) SAFECOPY(useron.tmpext,cfg.fcomp[0]->ext); else SAFECOPY(useron.tmpext,"ZIP"); useron.shell=cfg.new_shell; useron.alias[0]=0; kmode=(cfg.uq&UQ_NOEXASC)|K_EDIT|K_AUTODEL; if(!(cfg.uq&UQ_NOUPRLWR)) kmode|=K_UPRLWR; while(online) { if(autoterm || (text[AutoTerminalQ][0] && yesno(text[AutoTerminalQ]))) { useron.misc|=AUTOTERM; useron.misc|=autoterm; } else useron.misc&=~AUTOTERM; if(!(useron.misc&AUTOTERM)) { if(text[AnsiTerminalQ][0] && yesno(text[AnsiTerminalQ])) useron.misc|=ANSI; else useron.misc&=~ANSI; } if(useron.misc&ANSI) { useron.rows=0; /* Auto-rows */ if(!(cfg.uq&UQ_COLORTERM) || useron.misc&(RIP|WIP|HTML) || text[ColorTerminalQ][0]==0 || yesno(text[ColorTerminalQ])) useron.misc|=COLOR; else useron.misc&=~COLOR; } else useron.rows=24; if(text[ExAsciiTerminalQ][0] && !yesno(text[ExAsciiTerminalQ])) useron.misc|=NO_EXASCII; else useron.misc&=~NO_EXASCII; if(rlogin_name[0]) SAFECOPY(useron.alias,rlogin_name); while(online) { if(cfg.uq&UQ_ALIASES) bputs(text[EnterYourAlias]); else bputs(text[EnterYourRealName]); getstr(useron.alias,LEN_ALIAS,kmode); truncsp(useron.alias); if (!check_name(&cfg,useron.alias) || (!(cfg.uq&UQ_ALIASES) && !strchr(useron.alias,' '))) { bputs(text[YouCantUseThatName]); if(text[ContinueQ][0] && !yesno(text[ContinueQ])) return(FALSE); continue; } break; } if(!online) return(FALSE); if((cfg.uq&UQ_ALIASES) && (cfg.uq&UQ_REALNAME)) { while(online) { bputs(text[EnterYourRealName]); getstr(useron.name,LEN_NAME,kmode); if (!check_name(&cfg,useron.name) || !strchr(useron.name,' ') || ((cfg.uq&UQ_DUPREAL) && userdatdupe(useron.number,U_NAME,LEN_NAME,useron.name))) bputs(text[YouCantUseThatName]); else break; if(text[ContinueQ][0] && !yesno(text[ContinueQ])) return(FALSE); } } else if(cfg.uq&UQ_COMPANY) { bputs(text[EnterYourCompany]); getstr(useron.name,LEN_NAME,(cfg.uq&UQ_NOEXASC)|K_EDIT|K_AUTODEL); } if(!useron.name[0]) SAFECOPY(useron.name,useron.alias); if(!online) return(FALSE); if(!useron.handle[0]) SAFECOPY(useron.handle,useron.alias); while((cfg.uq&UQ_HANDLE) && online) { bputs(text[EnterYourHandle]); if(!getstr(useron.handle,LEN_HANDLE ,K_LINE|K_EDIT|K_AUTODEL|(cfg.uq&UQ_NOEXASC)) || strchr(useron.handle,0xff) || ((cfg.uq&UQ_DUPHAND) && userdatdupe(0,U_HANDLE,LEN_HANDLE,useron.handle)) || trashcan(useron.handle,"name")) bputs(text[YouCantUseThatName]); else break; if(text[ContinueQ][0] && !yesno(text[ContinueQ])) return(FALSE); } if(!online) return(FALSE); if(cfg.uq&UQ_ADDRESS) while(online) { /* Get address and zip code */ bputs(text[EnterYourAddress]); if(getstr(useron.address,LEN_ADDRESS,kmode)) break; } if(!online) return(FALSE); while((cfg.uq&UQ_LOCATION) && online) { bputs(text[EnterYourCityState]); if(getstr(useron.location,LEN_LOCATION,kmode) && ((cfg.uq&UQ_NOCOMMAS) || strchr(useron.location,','))) break; bputs(text[CommaInLocationRequired]); useron.location[0]=0; } if(cfg.uq&UQ_ADDRESS) while(online) { bputs(text[EnterYourZipCode]); if(getstr(useron.zipcode,LEN_ZIPCODE ,K_UPPER|(cfg.uq&UQ_NOEXASC)|K_EDIT|K_AUTODEL)) break; } if(!online) return(FALSE); if(cfg.uq&UQ_PHONE) { if(text[CallingFromNorthAmericaQ][0]) usa=yesno(text[CallingFromNorthAmericaQ]); else usa=false; while(online && text[EnterYourPhoneNumber][0]) { bputs(text[EnterYourPhoneNumber]); if(!usa) { if(getstr(useron.phone,LEN_PHONE ,K_UPPER|K_LINE|(cfg.uq&UQ_NOEXASC)|K_EDIT|K_AUTODEL)<5) continue; } else { if(gettmplt(useron.phone,cfg.sys_phonefmt ,K_LINE|(cfg.uq&UQ_NOEXASC)|K_EDIT)<strlen(cfg.sys_phonefmt)) continue; } if(!trashcan(useron.phone,"phone")) break; } } if(!online) return(FALSE); if(cfg.uq&UQ_SEX) { bputs(text[EnterYourSex]); useron.sex=(char)getkeys("MF",0); } while((cfg.uq&UQ_BIRTH) && online) { bprintf(text[EnterYourBirthday] ,cfg.sys_misc&SM_EURODATE ? "DD/MM/YY" : "MM/DD/YY"); if(gettmplt(useron.birth,"nn/nn/nn",K_EDIT)==8 && getage(&cfg,useron.birth)) break; } if(!online) return(FALSE); while(!(cfg.uq&UQ_NONETMAIL) && online) { bputs(text[EnterNetMailAddress]); if(getstr(useron.netmail,LEN_NETMAIL,K_EDIT|K_AUTODEL|K_LINE) && !trashcan(useron.netmail,"email")) break; } if(useron.netmail[0] && cfg.sys_misc&SM_FWDTONET && text[ForwardMailQ][0] && yesno(text[ForwardMailQ])) useron.misc|=NETMAIL; else useron.misc&=~NETMAIL; if(text[UserInfoCorrectQ][0]==0 || yesno(text[UserInfoCorrectQ])) break; } if(!online) return(FALSE); SAFEPRINTF(str,"New user: %s",useron.alias); logline("N",str); if(!online) return(FALSE); CLS; SAFEPRINTF(str,"%ssbbs.msg",cfg.text_dir); printfile(str,P_NOABORT); if(lncntr) pause(); CLS; SAFEPRINTF(str,"%ssystem.msg",cfg.text_dir); printfile(str,P_NOABORT); if(lncntr) pause(); CLS; SAFEPRINTF(str,"%snewuser.msg",cfg.text_dir); printfile(str,P_NOABORT); if(lncntr) pause(); CLS; answertime=time(NULL); /* could take 10 minutes to get this far */ /* Default editor (moved here, after terminal type setup Jan-2003) */ for(i=0;i<cfg.total_xedits;i++) if(!stricmp(cfg.xedit[i]->code,cfg.new_xedit) && chk_ar(cfg.xedit[i]->ar,&useron,&client)) break; if(i<cfg.total_xedits) useron.xedit=i+1; if(cfg.total_xedits && (cfg.uq&UQ_XEDIT) && text[UseExternalEditorQ][0]) { if(yesno(text[UseExternalEditorQ])) { for(i=0;i<cfg.total_xedits;i++) uselect(1,i,text[ExternalEditorHeading],cfg.xedit[i]->name,cfg.xedit[i]->ar); if((int)(i=uselect(0,useron.xedit ? useron.xedit-1 : 0,0,0,0))>=0) useron.xedit=i+1; } else useron.xedit=0; } if(cfg.total_shells>1 && (cfg.uq&UQ_CMDSHELL)) { for(i=0;i<cfg.total_shells;i++) uselect(1,i,text[CommandShellHeading],cfg.shell[i]->name,cfg.shell[i]->ar); if((int)(i=uselect(0,useron.shell,0,0,0))>=0) useron.shell=i; } if(rlogin_pass[0] && chkpass(rlogin_pass,&useron,true)) { CRLF; SAFECOPY(useron.pass, rlogin_pass); strupr(useron.pass); /* passwords are case insensitive, but assumed (in some places) to be uppercase in the user database */ } else { c=0; while(c<LEN_PASS) { /* Create random password */ useron.pass[c]=sbbs_random(43)+'0'; if(isalnum(useron.pass[c])) c++; } useron.pass[c]=0; bprintf(text[YourPasswordIs],useron.pass); if(cfg.sys_misc&SM_PWEDIT && text[NewPasswordQ][0] && yesno(text[NewPasswordQ])) while(online) { bputs(text[NewPassword]); getstr(str,LEN_PASS,K_UPPER|K_LINE); truncsp(str); if(chkpass(str,&useron,true)) { SAFECOPY(useron.pass,str); CRLF; bprintf(text[YourPasswordIs],useron.pass); break; } CRLF; } c=0; while(online) { bprintf(text[NewUserPasswordVerify]); console|=CON_R_ECHOX; str[0]=0; getstr(str,LEN_PASS*2,K_UPPER); console&=~(CON_R_ECHOX|CON_L_ECHOX); if(!strcmp(str,useron.pass)) break; if(cfg.sys_misc&SM_ECHO_PW) SAFEPRINTF3(tmp,"%s FAILED Password verification: '%s' instead of '%s'" ,useron.alias ,str ,useron.pass); else SAFEPRINTF(tmp,"%s FAILED Password verification" ,useron.alias); logline(LOG_NOTICE,nulstr,tmp); if(++c==4) { logline(LOG_NOTICE,"N!","Couldn't figure out password."); hangup(); } bputs(text[IncorrectPassword]); bprintf(text[YourPasswordIs],useron.pass); } } if(!online) return(FALSE); if(cfg.new_magic[0]) { bputs(text[MagicWordPrompt]); str[0]=0; getstr(str,50,K_UPPER); if(strcmp(str,cfg.new_magic)) { bputs(text[FailedMagicWord]); SAFEPRINTF2(tmp,"%s failed magic word: '%s'",useron.alias,str); logline("N!",tmp); hangup(); } if(!online) return(FALSE); } bputs(text[CheckingSlots]); if((i=newuserdat(&cfg,&useron))!=0) { SAFEPRINTF(str,"user record #%u",useron.number); errormsg(WHERE,ERR_CREATE,str,i); hangup(); return(FALSE); } SAFEPRINTF2(str,"Created user record #%u: %s",useron.number,useron.alias); logline(nulstr,str); if(cfg.new_sif[0]) { SAFEPRINTF2(str,"%suser/%4.4u.dat",cfg.data_dir,useron.number); create_sif_dat(cfg.new_sif,str); } if(!(cfg.uq&UQ_NODEF)) maindflts(&useron); delallmail(useron.number, MAIL_ANY); if(useron.number!=1 && cfg.node_valuser) { SAFEPRINTF(str,"%sfeedback.msg",cfg.text_dir); CLS; printfile(str,P_NOABORT); safe_snprintf(str,sizeof(str),text[NewUserFeedbackHdr] ,nulstr,getage(&cfg,useron.birth),useron.sex,useron.birth ,useron.name,useron.phone,useron.comp,useron.modem); email(cfg.node_valuser,str,"New User Validation",WM_EMAIL|WM_SUBJ_RO|WM_FORCEFWD); if(!useron.fbacks && !useron.emails) { if(online) { /* didn't hang up */ bprintf(text[NoFeedbackWarning],username(&cfg,cfg.node_valuser,tmp)); email(cfg.node_valuser,str,"New User Validation",WM_EMAIL|WM_SUBJ_RO|WM_FORCEFWD); } /* give 'em a 2nd try */ if(!useron.fbacks && !useron.emails) { bprintf(text[NoFeedbackWarning],username(&cfg,cfg.node_valuser,tmp)); logline(LOG_NOTICE,"N!","Aborted feedback"); hangup(); putuserrec(&cfg,useron.number,U_COMMENT,60,"Didn't leave feedback"); putuserrec(&cfg,useron.number,U_MISC,8 ,ultoa(useron.misc|DELETED,tmp,16)); putusername(&cfg,useron.number,nulstr); return(FALSE); } } } answertime=starttime=time(NULL); /* set answertime to now */ #ifdef JAVASCRIPT js_create_user_objects(); #endif if(cfg.newuser_mod[0]) exec_bin(cfg.newuser_mod,&main_csi); user_event(EVENT_NEWUSER); getuserdat(&cfg,&useron); // In case event(s) modified user data logline("N+","Successful new user logon"); sys_status|=SS_NEWUSER; return(TRUE); }
bool sbbs_t::logon() { char str[256],c; char tmp[512]; int file; uint i,j,mailw; long kmode; ulong totallogons; node_t node; struct tm tm; now=time(NULL); if(localtime_r(&now,&tm)==NULL) return(false); if(!useron.number) return(false); client.user=useron.alias; client_on(client_socket,&client,TRUE /* update */); #ifdef JAVASCRIPT js_create_user_objects(); #endif if(useron.rest&FLAG('Q')) qwklogon=1; if(SYSOP && !(cfg.sys_misc&SM_R_SYSOP)) return(false); if(useron.rest&FLAG('G')) { /* Guest account */ useron.misc=(cfg.new_misc&(~ASK_NSCAN)); useron.rows=0; useron.misc&=~(ANSI|RIP|WIP|NO_EXASCII|COLOR|HTML); useron.misc|=autoterm; if(!(useron.misc&ANSI) && text[AnsiTerminalQ][0] && yesno(text[AnsiTerminalQ])) useron.misc|=ANSI; if(useron.misc&(RIP|WIP|HTML) || (useron.misc&ANSI && text[ColorTerminalQ][0] && yesno(text[ColorTerminalQ]))) useron.misc|=COLOR; if(text[ExAsciiTerminalQ][0] && !yesno(text[ExAsciiTerminalQ])) useron.misc|=NO_EXASCII; for(i=0;i<cfg.total_xedits;i++) if(!stricmp(cfg.xedit[i]->code,cfg.new_xedit) && chk_ar(cfg.xedit[i]->ar,&useron,&client)) break; if(i<cfg.total_xedits) useron.xedit=i+1; else useron.xedit=0; useron.prot=cfg.new_prot; useron.shell=cfg.new_shell; } if(!chk_ar(cfg.node_ar,&useron,&client)) { bputs(text[NoNodeAccess]); sprintf(str,"(%04u) %-25s Insufficient node access" ,useron.number,useron.alias); logline(LOG_NOTICE,"+!",str); return(false); } getnodedat(cfg.node_num,&thisnode,1); if(thisnode.misc&NODE_LOCK) { putnodedat(cfg.node_num,&thisnode); /* must unlock! */ if(!SYSOP && !(useron.exempt&FLAG('N'))) { bputs(text[NodeLocked]); sprintf(str,"(%04u) %-25s Locked node logon attempt" ,useron.number,useron.alias); logline(LOG_NOTICE,"+!",str); return(false); } if(yesno(text[RemoveNodeLockQ])) { getnodedat(cfg.node_num,&thisnode,1); logline("S-","Removed Node Lock"); thisnode.misc&=~NODE_LOCK; } else getnodedat(cfg.node_num,&thisnode,1); } if(useron.exempt&FLAG('H')) console|=CON_NO_INACT; if((useron.exempt&FLAG('Q') && useron.misc&QUIET)) thisnode.status=NODE_QUIET; else thisnode.status=NODE_INUSE; action=thisnode.action=NODE_LOGN; thisnode.connection=node_connection; thisnode.misc&=~(NODE_ANON|NODE_INTR|NODE_MSGW|NODE_POFF|NODE_AOFF); if(useron.chat&CHAT_NOACT) thisnode.misc|=NODE_AOFF; if(useron.chat&CHAT_NOPAGE) thisnode.misc|=NODE_POFF; thisnode.useron=useron.number; putnodedat(cfg.node_num,&thisnode); getusrsubs(); getusrdirs(); if(useron.misc&CURSUB && !(useron.rest&FLAG('G'))) { for(i=0;i<usrgrps;i++) { for(j=0;j<usrsubs[i];j++) { if(!strcmp(cfg.sub[usrsub[i][j]]->code,useron.cursub)) break; } if(j<usrsubs[i]) { curgrp=i; cursub[i]=j; break; } } for(i=0;i<usrlibs;i++) { for(j=0;j<usrdirs[i];j++) if(!strcmp(cfg.dir[usrdir[i][j]]->code,useron.curdir)) break; if(j<usrdirs[i]) { curlib=i; curdir[i]=j; break; } } } if(useron.misc&AUTOTERM) { useron.misc&=~(ANSI|RIP|WIP|HTML); useron.misc|=autoterm; } if(!chk_ar(cfg.shell[useron.shell]->ar,&useron,&client)) { useron.shell=cfg.new_shell; if(!chk_ar(cfg.shell[useron.shell]->ar,&useron,&client)) { for(i=0;i<cfg.total_shells;i++) if(chk_ar(cfg.shell[i]->ar,&useron,&client)) break; if(i==cfg.total_shells) useron.shell=0; } } logon_ml=useron.level; logontime=time(NULL); starttime=logontime; useron.logontime=(time32_t)logontime; last_ns_time=ns_time=useron.ns_time; // ns_time-=(useron.tlast*60); /* file newscan time == last logon time */ delfiles(cfg.temp_dir,ALLFILES); sprintf(str,"%smsgs/n%3.3u.msg",cfg.data_dir,cfg.node_num); remove(str); /* remove any pending node messages */ sprintf(str,"%smsgs/n%3.3u.ixb",cfg.data_dir,cfg.node_num); remove(str); /* remove any pending node message indices */ if(!SYSOP && online==ON_REMOTE && !qwklogon) { rioctl(IOCM|ABORT); /* users can't abort anything */ rioctl(IOCS|ABORT); } CLS; if(useron.rows) rows=useron.rows; unixtodstr(&cfg,(time32_t)logontime,str); if(!strncmp(str,useron.birth,5) && !(useron.rest&FLAG('Q'))) { bputs(text[HappyBirthday]); pause(); CLS; user_event(EVENT_BIRTHDAY); } useron.ltoday++; gettimeleft(); sprintf(str,"%sfile/%04u.dwn",cfg.data_dir,useron.number); batch_add_list(str); if(!qwklogon) { /* QWK Nodes don't go through this */ if(cfg.sys_pwdays && (ulong)logontime>(useron.pwmod+((ulong)cfg.sys_pwdays*24UL*60UL*60UL))) { bprintf(text[TimeToChangePw],cfg.sys_pwdays); c=0; while(c<LEN_PASS) { /* Create random password */ str[c]=sbbs_random(43)+'0'; if(isalnum(str[c])) c++; } str[c]=0; bprintf(text[YourPasswordIs],str); if(cfg.sys_misc&SM_PWEDIT && yesno(text[NewPasswordQ])) while(online) { bputs(text[NewPassword]); getstr(str,LEN_PASS,K_UPPER|K_LINE); truncsp(str); if(chkpass(str,&useron,true)) break; CRLF; } while(online) { if(cfg.sys_misc&SM_PWEDIT) { CRLF; bputs(text[VerifyPassword]); } else bputs(text[NewUserPasswordVerify]); console|=CON_R_ECHOX; getstr(tmp,LEN_PASS*2,K_UPPER); console&=~(CON_R_ECHOX|CON_L_ECHOX); if(strcmp(str,tmp)) { bputs(text[Wrong]); continue; } break; } strcpy(useron.pass,str); useron.pwmod=time32(NULL); putuserrec(&cfg,useron.number,U_PWMOD,8,ultoa((ulong)useron.pwmod,str,16)); bputs(text[PasswordChanged]); pause(); } if(useron.ltoday>cfg.level_callsperday[useron.level] && !(useron.exempt&FLAG('L'))) { bputs(text[NoMoreLogons]); sprintf(str,"(%04u) %-25s Out of logons" ,useron.number,useron.alias); logline(LOG_NOTICE,"+!",str); hangup(); return(false); } if(useron.rest&FLAG('L') && useron.ltoday>1) { bputs(text[R_Logons]); sprintf(str,"(%04u) %-25s Out of logons" ,useron.number,useron.alias); logline(LOG_NOTICE,"+!",str); hangup(); return(false); } kmode=(cfg.uq&UQ_NOEXASC); if(!(cfg.uq&UQ_NOUPRLWR)) kmode|=K_UPRLWR; if(!(useron.rest&FLAG('G'))) { if(!useron.name[0] && ((cfg.uq&UQ_ALIASES && cfg.uq&UQ_REALNAME) || cfg.uq&UQ_COMPANY)) while(online) { if(cfg.uq&UQ_ALIASES && cfg.uq&UQ_REALNAME) bputs(text[EnterYourRealName]); else bputs(text[EnterYourCompany]); getstr(useron.name,LEN_NAME,kmode); if(cfg.uq&UQ_ALIASES && cfg.uq&UQ_REALNAME) { if(trashcan(useron.name,"name") || !useron.name[0] || !strchr(useron.name,' ') || strchr(useron.name,0xff) || (cfg.uq&UQ_DUPREAL && userdatdupe(useron.number,U_NAME,LEN_NAME ,useron.name,0,0))) bputs(text[YouCantUseThatName]); else break; } else break; } if(cfg.uq&UQ_HANDLE && !useron.handle[0]) { sprintf(useron.handle,"%.*s",LEN_HANDLE,useron.alias); while(online) { bputs(text[EnterYourHandle]); if(!getstr(useron.handle,LEN_HANDLE ,K_LINE|K_EDIT|K_AUTODEL|(cfg.uq&UQ_NOEXASC)) || strchr(useron.handle,0xff) || (cfg.uq&UQ_DUPHAND && userdatdupe(useron.number,U_HANDLE,LEN_HANDLE ,useron.handle,0,0)) || trashcan(useron.handle,"name")) bputs(text[YouCantUseThatName]); else break; } } if(cfg.uq&UQ_LOCATION && !useron.location[0]) while(online) { bputs(text[EnterYourCityState]); if(getstr(useron.location,LEN_LOCATION,kmode)) break; } if(cfg.uq&UQ_ADDRESS && !useron.address[0]) while(online) { bputs(text[EnterYourAddress]); if(getstr(useron.address,LEN_ADDRESS,kmode)) break; } if(cfg.uq&UQ_ADDRESS && !useron.zipcode[0]) while(online) { bputs(text[EnterYourZipCode]); if(getstr(useron.zipcode,LEN_ZIPCODE,K_UPPER|(cfg.uq&UQ_NOEXASC))) break; } if(cfg.uq&UQ_PHONE && !useron.phone[0]) { if(text[CallingFromNorthAmericaQ][0]) i=yesno(text[CallingFromNorthAmericaQ]); else i=0; while(online) { bputs(text[EnterYourPhoneNumber]); if(i) { if(gettmplt(useron.phone,cfg.sys_phonefmt ,K_LINE|(cfg.uq&UQ_NOEXASC))<strlen(cfg.sys_phonefmt)) continue; } else { if(getstr(useron.phone,LEN_PHONE ,K_UPPER|(cfg.uq&UQ_NOEXASC))<5) continue; } if(!trashcan(useron.phone,"phone")) break; } } if(!(cfg.uq&UQ_NONETMAIL) && !useron.netmail[0]) { while(online) { bputs(text[EnterNetMailAddress]); if(getstr(useron.netmail,LEN_NETMAIL,K_EDIT|K_AUTODEL|K_LINE) && !trashcan(useron.netmail,"email")) break; } if(useron.netmail[0] && cfg.sys_misc&SM_FWDTONET && !noyes(text[ForwardMailQ])) useron.misc|=NETMAIL; else useron.misc&=~NETMAIL; } if(cfg.new_sif[0]) { sprintf(str,"%suser/%4.4u.dat",cfg.data_dir,useron.number); if(flength(str)<1L) create_sif_dat(cfg.new_sif,str); } } } if(!online) { sprintf(str,"(%04u) %-25s Unsuccessful logon" ,useron.number,useron.alias); logline(LOG_NOTICE,"+!",str); return(false); } SAFECOPY(useron.modem,connection); useron.logons++; putuserdat(&cfg,&useron); getmsgptrs(); sys_status|=SS_USERON; /* moved from further down */ if(useron.rest&FLAG('Q')) { sprintf(str,"(%04u) %-25s QWK Network Connection" ,useron.number,useron.alias); logline("++",str); return(true); } /********************/ /* SUCCESSFUL LOGON */ /********************/ totallogons=logonstats(); sprintf(str,"(%04u) %-25s Logon %lu - %u" ,useron.number,useron.alias,totallogons,useron.ltoday); logline("++",str); if(!qwklogon && cfg.logon_mod[0]) exec_bin(cfg.logon_mod,&main_csi); if(thisnode.status!=NODE_QUIET && (!REALSYSOP || cfg.sys_misc&SM_SYSSTAT)) { sprintf(str,"%slogon.lst",cfg.data_dir); if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) { errormsg(WHERE,ERR_OPEN,str,O_RDWR|O_CREAT|O_APPEND); return(false); } getuserrec(&cfg,useron.number,U_NOTE,LEN_NOTE,useron.note); getuserrec(&cfg,useron.number,U_LOCATION,LEN_LOCATION,useron.location); sprintf(str,text[LastFewCallersFmt],cfg.node_num ,totallogons,useron.alias ,cfg.sys_misc&SM_LISTLOC ? useron.location : useron.note ,tm.tm_hour,tm.tm_min ,connection,useron.ltoday > 999 ? 999 : useron.ltoday); write(file,str,strlen(str)); close(file); } if(cfg.sys_logon[0]) /* execute system logon event */ external(cmdstr(cfg.sys_logon,nulstr,nulstr,NULL),EX_STDOUT); /* EX_SH */ if(qwklogon) return(true); sys_status|=SS_PAUSEON; /* always force pause on during this section */ mailw=getmail(&cfg,useron.number,0); if(!(cfg.sys_misc&SM_NOSYSINFO)) { bprintf(text[SiSysName],cfg.sys_name); //bprintf(text[SiNodeNumberName],cfg.node_num,cfg.node_name); bprintf(text[LiUserNumberName],useron.number,useron.alias); bprintf(text[LiLogonsToday],useron.ltoday ,cfg.level_callsperday[useron.level]); bprintf(text[LiTimeonToday],useron.ttoday ,cfg.level_timeperday[useron.level]+useron.min); bprintf(text[LiMailWaiting],mailw); strcpy(str,text[LiSysopIs]); if(startup->options&BBS_OPT_SYSOP_AVAILABLE || (cfg.sys_chat_ar[0] && chk_ar(cfg.sys_chat_ar,&useron,&client))) strcat(str,text[LiSysopAvailable]); else strcat(str,text[LiSysopNotAvailable]); bprintf("%s\r\n\r\n",str); } if(sys_status&SS_EVENT) bprintf(text[ReducedTime],timestr(event_time)); getnodedat(cfg.node_num,&thisnode,1); thisnode.misc&=~(NODE_AOFF|NODE_POFF); if(useron.chat&CHAT_NOACT) thisnode.misc|=NODE_AOFF; if(useron.chat&CHAT_NOPAGE) thisnode.misc|=NODE_POFF; putnodedat(cfg.node_num,&thisnode); getsmsg(useron.number); /* Moved from further down */ SYNC; c=0; for(i=1;i<=cfg.sys_nodes;i++) if(i!=cfg.node_num) { getnodedat(i,&node,0); if(!(cfg.sys_misc&SM_NONODELIST) && (node.status==NODE_INUSE || ((node.status==NODE_QUIET || node.errors) && SYSOP))) { if(!c) bputs(text[NodeLstHdr]); printnodedat(i,&node); c=1; } if(node.status==NODE_INUSE && i!=cfg.node_num && node.useron==useron.number && !SYSOP && !(useron.exempt&FLAG('G'))) { SAFEPRINTF2(str,"(%04u) %-25s On two nodes at the same time" ,useron.number,useron.alias); logline(LOG_NOTICE,"+!",str); bputs(text[UserOnTwoNodes]); hangup(); return(false); } if(thisnode.status!=NODE_QUIET && (node.status==NODE_INUSE || node.status==NODE_QUIET) && !(node.misc&NODE_AOFF) && node.useron!=useron.number) { sprintf(str,text[NodeLoggedOnAtNbps] ,cfg.node_num ,thisnode.misc&NODE_ANON ? text[UNKNOWN_USER] : useron.alias ,connection); putnmsg(&cfg,i,str); } } if(cfg.sys_exp_warn && useron.expire && useron.expire>now /* Warn user of coming */ && (useron.expire-now)/(1440L*60L)<=cfg.sys_exp_warn) /* expiration */ bprintf(text[AccountWillExpireInNDays],(useron.expire-now)/(1440L*60L)); if(criterrs && SYSOP) bprintf(text[CriticalErrors],criterrs); if((i=getuserxfers(0,useron.number,0))!=0) bprintf(text[UserXferForYou],i,i>1 ? "s" : nulstr); if((i=getuserxfers(useron.number,0,0))!=0) bprintf(text[UnreceivedUserXfer],i,i>1 ? "s" : nulstr); SYNC; sys_status&=~SS_PAUSEON; /* Turn off the pause override flag */ if(online==ON_REMOTE) rioctl(IOSM|ABORT); /* Turn abort ability on */ if(text[ReadYourMailNowQ][0] && mailw) { if(yesno(text[ReadYourMailNowQ])) readmail(useron.number,MAIL_YOUR); } if(usrgrps && useron.misc&ASK_NSCAN && text[NScanAllGrpsQ][0] && yesno(text[NScanAllGrpsQ])) scanallsubs(SCAN_NEW); if(usrgrps && useron.misc&ASK_SSCAN && text[SScanAllGrpsQ][0] && yesno(text[SScanAllGrpsQ])) scanallsubs(SCAN_TOYOU); return(true); }
bool sbbs_t::qwk_import_msg(FILE *qwk_fp, char *hdrblk, ulong blocks ,char fromhub, uint subnum ,uint touser, smbmsg_t* msg) { char* body; char* tail; char* qwkbuf; char str[256],col=0,lastch=0,*p; char from[128]; uint i,k; long bodylen,taillen; bool success=false; uint16_t net_type; ushort xlat=XLAT_NONE; int storage=SMB_SELFPACK; long dupechk_hashes=SMB_HASH_SOURCE_DUPE; str_list_t kludges; 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,&client)) msg->hdr.attr|=MSG_MODERATED; if(subnum!=INVALID_SUB && !fromhub && cfg.sub[subnum]->misc&SUB_SYSPERM && sub_op(subnum)) msg->hdr.attr|=MSG_PERMANENT; if(!(useron.rest&FLAG('Q')) && !fromhub && msg->hdr.when_written.zone==0) msg->hdr.when_written.zone=sys_timezone(&cfg); msg->hdr.when_imported.time=time32(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); 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; } /********************************/ /* Convert the QWK message text */ /********************************/ if((qwkbuf=(char *)malloc((blocks-1)*QWK_BLOCK_LEN))==NULL) { errormsg(WHERE,ERR_ALLOC,"QWK msg buf",(blocks-1)*QWK_BLOCK_LEN); return(false); } if(fread(qwkbuf,QWK_BLOCK_LEN,blocks-1,qwk_fp) != blocks-1) { free(qwkbuf); errormsg(WHERE,ERR_READ,"QWK msg blocks",(blocks-1)*QWK_BLOCK_LEN); } bodylen=0; if((body=(char *)malloc((blocks-1L)*QWK_BLOCK_LEN*2L))==NULL) { free(qwkbuf); 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(qwkbuf); free(body); errormsg(WHERE,ERR_ALLOC,"QWK msg tail",(blocks-1L)*QWK_BLOCK_LEN*2L); return(false); } kludges=strListInit(); for(k=0;k<(blocks-1)*QWK_BLOCK_LEN;k++) { if(qwkbuf[k]==0) continue; if(bodylen==0 && (qwkbuf[k]=='@' || (((useron.qwk&QWK_EXT) || subnum==INVALID_SUB) && (strnicmp(qwkbuf+k,"To:",3)==0 || strnicmp(qwkbuf+k,"From:",5)==0 || strnicmp(qwkbuf+k,"Subject:",8)==0)))) { if((p=strchr(qwkbuf+k, QWK_NEWLINE))==NULL) { body[bodylen++]=qwkbuf[k]; continue; } *p=0; /* Converts QWK_NEWLINE to NUL */ strListPush(&kludges, qwkbuf+k); k+=strlen(qwkbuf+k); continue; } if(!taillen && qwkbuf[k]==' ' && col==3 && bodylen>=3 && body[bodylen-3]=='-' && body[bodylen-2]=='-' && body[bodylen-1]=='-') { bodylen-=3; strcpy(tail,"--- "); /* DO NOT USE SAFECOPY */ taillen=4; col++; continue; } if(qwkbuf[k]==QWK_NEWLINE) { /* expand QWK_NEWLINE to crlf */ if(!bodylen && !taillen) /* Ignore blank lines at top of message */ continue; if(!taillen && col==3 && bodylen>=3 && body[bodylen-3]=='-' && body[bodylen-2]=='-' && body[bodylen-1]=='-') { bodylen-=3; strcpy(tail,"---"); /* DO NOT USE SAFECOPY */ 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]==CTRL_A || qwkbuf[k]==ESC) && useron.rest&FLAG('A')) continue; if(qwkbuf[k]!=CTRL_A && lastch!=CTRL_A) col++; if(lastch==CTRL_A && !valid_ctrl_a_code(qwkbuf[k])) { if(taillen) taillen--; else bodylen--; lastch=0; continue; } lastch=qwkbuf[k]; if(taillen) tail[taillen++]=qwkbuf[k]; else body[bodylen++]=qwkbuf[k]; } free(qwkbuf); 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 */ /* Parse QWK Kludges (QWKE standard and SyncQNET legacy) here: */ if(useron.rest&FLAG('Q') || fromhub) { /* QWK Net */ if((p=iniGetString(kludges,ROOT_SECTION,"@VIA",NULL,NULL)) != NULL) { if(!fromhub) set_qwk_flag(QWK_VIA); if(route_circ(p,cfg.sys_id)) { bprintf("\r\nCircular message path: %s\r\n",p); lprintf(LOG_ERR,"Circular message path: %s from %s" ,p,fromhub ? cfg.qhub[fromhub-1]->id:useron.alias); strListFree(&kludges); free(body); free(tail); return(false); } SAFEPRINTF2(str,"%s/%s" ,fromhub ? cfg.qhub[fromhub-1]->id : useron.alias,p); strupr(str); update_qwkroute(str); } else { if(fromhub) SAFECOPY(str,cfg.qhub[fromhub-1]->id); else SAFECOPY(str,useron.alias); } /* From network type & address: */ strupr(str); net_type=NET_QWK; smb_hfield_netaddr(msg, SENDERNETADDR, str, &net_type); smb_hfield_bin(msg,SENDERNETTYPE,net_type); } else { sprintf(str,"%u",useron.number); smb_hfield_str(msg,SENDEREXT,str); if((uint)subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_NAME) SAFECOPY(from,useron.name); else SAFECOPY(from,useron.alias); smb_hfield_str(msg,SENDER,from); } if((p=iniGetString(kludges,ROOT_SECTION,"@MSGID",NULL,NULL)) != NULL) { if(!fromhub) set_qwk_flag(QWK_MSGID); truncstr(p," "); /* Truncate at first space char */ if(msg->id==NULL) smb_hfield_str(msg,RFC822MSGID,p); } if((p=iniGetString(kludges,ROOT_SECTION,"@REPLY",NULL,NULL)) != NULL) { if(!fromhub) set_qwk_flag(QWK_MSGID); truncstr(p," "); /* Truncate at first space char */ if(msg->reply_id==NULL) smb_hfield_str(msg,RFC822REPLYID,p); } if((p=iniGetString(kludges,ROOT_SECTION,"@TZ",NULL,NULL)) != NULL) { if(!fromhub) set_qwk_flag(QWK_TZ); msg->hdr.when_written.zone=(short)ahtoul(p); } if((p=iniGetString(kludges,ROOT_SECTION,"@REPLYTO",NULL,NULL)) != NULL) { if(msg->replyto==NULL) smb_hfield_str(msg,REPLYTO,p); } /* QWKE standard: */ if((p=iniGetString(kludges,ROOT_SECTION,"Subject",NULL,NULL)) != NULL) smb_hfield_replace_str(msg,SUBJECT,p); if((p=iniGetString(kludges,ROOT_SECTION,"To",NULL,NULL)) != NULL) smb_hfield_replace_str(msg,RECIPIENT,p); if((useron.rest&FLAG('Q')) && (p=iniGetString(kludges,ROOT_SECTION,"From",NULL,NULL)) != NULL) smb_hfield_replace_str(msg,SENDER,p); strListFree(&kludges); /* smb_addmsg requires 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) { SAFEPRINTF2(str,"%s duplicate e-mail attempt (%s)",useron.alias,smb.last_error); logline(LOG_NOTICE,"E!",str); } else { SAFEPRINTF4(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(LOG_NOTICE,"P!",str); } } } else errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); free(body); free(tail); return(success); }
BOOL DLLCALL getfiledat(scfg_t* cfg, file_t* f) { char buf[F_LEN+1],str[MAX_PATH+1]; int file; long length; SAFEPRINTF2(str,"%s%s.dat",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code); if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) { return(FALSE); } length=(long)filelength(file); if(f->datoffset>length) { close(file); return(FALSE); } if(length%F_LEN) { close(file); return(FALSE); } lseek(file,f->datoffset,SEEK_SET); if(read(file,buf,F_LEN)!=F_LEN) { close(file); return(FALSE); } close(file); getrec(buf,F_ALTPATH,2,str); f->altpath=hptoi(str); getrec(buf,F_CDT,LEN_FCDT,str); f->cdt=atol(str); if(!f->size) { /* only read disk if this is null */ getfilepath(cfg,f,str); if((f->size=(long)flength(str))>=0) f->date=(time32_t)fdate(str); /* } else { f->size=f->cdt; f->date=0; } */ } #if 0 if((f->size>0L) && cur_cps) f->timetodl=(ushort)(f->size/(ulong)cur_cps); else #endif f->timetodl=0; getrec(buf,F_DESC,LEN_FDESC,f->desc); getrec(buf,F_ULER,LEN_ALIAS,f->uler); getrec(buf,F_TIMESDLED,5,str); f->timesdled=atoi(str); getrec(buf,F_OPENCOUNT,3,str); f->opencount=atoi(str); if(buf[F_MISC]!=ETX) f->misc=buf[F_MISC]-' '; else f->misc=0; return(TRUE); }
bool sbbs_t::pack_rep(uint hubnum) { char str[MAX_PATH+1]; char tmp[MAX_PATH+1],tmp2[MAX_PATH+1]; char hubid_upper[LEN_QWKID+1]; char hubid_lower[LEN_QWKID+1]; int file,mode; uint i,j,k; long msgcnt,submsgs,packedmail,netfiles=0,deleted; uint32_t u; uint32_t posts; uint32_t mailmsgs; ulong msgs; uint32_t last; post_t* post; mail_t* mail; FILE* rep; FILE* hdrs=NULL; DIR* dir; DIRENT* dirent; smbmsg_t msg; msgcnt=0L; delfiles(cfg.temp_dir,ALLFILES); SAFECOPY(hubid_upper,cfg.qhub[hubnum]->id); strupr(hubid_upper); SAFECOPY(hubid_lower,cfg.qhub[hubnum]->id); strlwr(hubid_lower); SAFEPRINTF2(str,"%s%s.REP",cfg.data_dir,hubid_upper); if(fexistcase(str)) { eprintf(LOG_INFO,"Updating %s", str); external(cmdstr(cfg.qhub[hubnum]->unpack,str,ALLFILES,NULL),EX_OFFLINE); } else eprintf(LOG_INFO,"Creating %s", str); /*************************************************/ /* Create SYSID.MSG, write header and leave open */ /*************************************************/ SAFEPRINTF2(str,"%s%s.MSG",cfg.temp_dir,hubid_upper); fexistcase(str); if((rep=fnopen(&file,str,O_CREAT|O_WRONLY|O_TRUNC))==NULL) { errormsg(WHERE,ERR_CREATE,str,O_CREAT|O_WRONLY|O_TRUNC); return(false); } if(filelength(file)<1) { /* New REP packet */ SAFEPRINTF2(str,"%-*s" ,QWK_BLOCK_LEN,hubid_upper); /* So write header */ fwrite(str,QWK_BLOCK_LEN,1,rep); } fseek(rep,0L,SEEK_END); /* Always includes HEADERS.DAT in .REP packets which are only for QWKnet hubs */ /* And *usually* a Synchronet system */ SAFEPRINTF(str,"%sHEADERS.DAT",cfg.temp_dir); fexistcase(str); if((hdrs=fopen(str,"a"))==NULL) errormsg(WHERE,ERR_CREATE,str,0); /*********************/ /* Pack new messages */ /*********************/ SAFEPRINTF(smb.file,"%smail",cfg.data_dir); smb.retry_time=cfg.smb_retry_time; smb.subnum=INVALID_SUB; if((i=smb_open(&smb))!=0) { fclose(rep); if(hdrs!=NULL) fclose(hdrs); errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); return(false); } /***********************/ /* Pack E-mail, if any */ /***********************/ qwkmail_last=0; mail=loadmail(&smb,&mailmsgs,0,MAIL_YOUR,0); packedmail=0; if(mailmsgs) { eprintf(LOG_INFO,"Packing NetMail for %s", cfg.qhub[hubnum]->id); for(u=0;u<mailmsgs;u++) { // bprintf("\b\b\b\b\b%-5lu",u+1); memset(&msg,0,sizeof(msg)); msg.idx=mail[u]; if(msg.idx.number>qwkmail_last) qwkmail_last=msg.idx.number; if(!loadmsg(&msg,mail[u].number)) continue; SAFEPRINTF(str,"%s/",cfg.qhub[hubnum]->id); if(msg.to_net.type!=NET_QWK || (strcmp((char *)msg.to_net.addr,cfg.qhub[hubnum]->id) && strncmp((char *)msg.to_net.addr,str,strlen(str)))) { smb_unlockmsghdr(&smb,&msg); smb_freemsgmem(&msg); continue; } msgtoqwk(&msg,rep,QM_TO_QNET|QM_REP|A_LEAVE,INVALID_SUB,0,hdrs); packedmail++; smb_unlockmsghdr(&smb,&msg); smb_freemsgmem(&msg); YIELD(); /* yield */ } eprintf(LOG_INFO,"Packed %d NetMail messages",packedmail); } smb_close(&smb); /* Close the e-mail */ if(mailmsgs) free(mail); for(i=0;i<cfg.qhub[hubnum]->subs;i++) { j=cfg.qhub[hubnum]->sub[i]; /* j now equals the real sub num */ msgs=getlastmsg(j,&last,0); lncntr=0; /* defeat pause */ if(!msgs || last<=subscan[j].ptr) { if(subscan[j].ptr>last) { subscan[j].ptr=last; subscan[j].last=last; } eprintf(LOG_INFO,remove_ctrl_a(text[NScanStatusFmt],tmp) ,cfg.grp[cfg.sub[j]->grp]->sname ,cfg.sub[j]->lname,0L,msgs); continue; } SAFEPRINTF2(smb.file,"%s%s" ,cfg.sub[j]->data_dir,cfg.sub[j]->code); smb.retry_time=cfg.smb_retry_time; smb.subnum=j; if((k=smb_open(&smb))!=0) { errormsg(WHERE,ERR_OPEN,smb.file,k,smb.last_error); continue; } post=loadposts(&posts,j,subscan[j].ptr,LP_BYSELF|LP_OTHERS|LP_PRIVATE|LP_REP,NULL); eprintf(LOG_INFO,remove_ctrl_a(text[NScanStatusFmt],tmp) ,cfg.grp[cfg.sub[j]->grp]->sname ,cfg.sub[j]->lname,posts,msgs); if(!posts) { /* no new messages */ smb_close(&smb); continue; } subscan[j].ptr=last; /* set pointer */ eprintf(LOG_INFO,"%s",remove_ctrl_a(text[QWKPackingSubboard],tmp)); /* ptr to last msg */ submsgs=0; for(u=0;u<posts;u++) { // bprintf("\b\b\b\b\b%-5lu",u+1); memset(&msg,0,sizeof(msg)); msg.idx=post[u]; if(!loadmsg(&msg,post[u].number)) continue; if(msg.from_net.type && msg.from_net.type!=NET_QWK && !(cfg.sub[j]->misc&SUB_GATE)) { smb_freemsgmem(&msg); smb_unlockmsghdr(&smb,&msg); continue; } if(!strnicmp(msg.subj,"NE:",3) || (msg.from_net.type==NET_QWK && route_circ((char *)msg.from_net.addr,cfg.qhub[hubnum]->id))) { smb_freemsgmem(&msg); smb_unlockmsghdr(&smb,&msg); continue; } mode=cfg.qhub[hubnum]->mode[i]|QM_TO_QNET|QM_REP; if(mode&A_LEAVE) mode|=(QM_VIA|QM_TZ|QM_MSGID); if(msg.from_net.type!=NET_QWK) mode|=QM_TAGLINE; msgtoqwk(&msg,rep,mode,j,cfg.qhub[hubnum]->conf[i],hdrs); smb_freemsgmem(&msg); smb_unlockmsghdr(&smb,&msg); msgcnt++; submsgs++; if(!(u%50)) YIELD(); /* yield */ } eprintf(LOG_INFO,remove_ctrl_a(text[QWKPackedSubboard],tmp),submsgs,msgcnt); free(post); smb_close(&smb); YIELD(); /* yield */ } if(hdrs!=NULL) fclose(hdrs); fclose(rep); /* close HUB_ID.MSG */ CRLF; /* Look for extra files to send out */ SAFEPRINTF2(str,"%sqnet/%s.out",cfg.data_dir,hubid_lower); dir=opendir(str); while(dir!=NULL && (dirent=readdir(dir))!=NULL) { SAFEPRINTF3(str,"%sqnet/%s.out/%s",cfg.data_dir,hubid_lower,dirent->d_name); if(isdir(str)) continue; SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,dirent->d_name); eprintf(LOG_INFO,remove_ctrl_a(text[RetrievingFile],tmp),str); if(!mv(str,tmp2,/* copy: */TRUE)) netfiles++; } if(dir!=NULL) closedir(dir); if(netfiles) CRLF; if(!msgcnt && !netfiles && !packedmail) { eprintf(LOG_INFO,remove_ctrl_a(text[QWKNoNewMessages],tmp)); return(true); // Changed from false Mar-11-2005 (needs to be true to save updated ptrs) } /*******************/ /* Compress Packet */ /*******************/ SAFEPRINTF2(str,"%s%s.REP",cfg.data_dir,hubid_upper); SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,ALLFILES); i=external(cmdstr(cfg.qhub[hubnum]->pack,str,tmp2,NULL) ,EX_OFFLINE|EX_WILDCARD); if(!fexistcase(str)) { eprintf(LOG_WARNING,"%s",remove_ctrl_a(text[QWKCompressionFailed],tmp)); if(i) errormsg(WHERE,ERR_EXEC,cmdstr(cfg.qhub[hubnum]->pack,str,tmp2,NULL),i); else lprintf(LOG_ERR, "Couldn't compress REP packet"); return(false); } SAFEPRINTF2(str,"%sqnet/%s.out/",cfg.data_dir,hubid_lower); delfiles(str,ALLFILES); if(packedmail) { /* Delete NetMail */ SAFEPRINTF(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); return(true); } mail=loadmail(&smb,&mailmsgs,0,MAIL_YOUR,0); if((i=smb_locksmbhdr(&smb))!=0) { /* Lock the base, so nobody */ if(mailmsgs) free(mail); smb_close(&smb); errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error); /* messes with the index */ return(true); } if((i=smb_getstatus(&smb))!=0) { if(mailmsgs) free(mail); smb_close(&smb); errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error); return(true); } deleted=0; /* Mark as READ and DELETE */ for(u=0;u<mailmsgs;u++) { if(mail[u].number>qwkmail_last) continue; memset(&msg,0,sizeof(msg)); /* !IMPORTANT: search by number (do not initialize msg.idx.offset) */ if(!loadmsg(&msg,mail[u].number)) continue; SAFEPRINTF(str,"%s/",cfg.qhub[hubnum]->id); if(msg.to_net.type!=NET_QWK || (strcmp((char *)msg.to_net.addr,cfg.qhub[hubnum]->id) && strncmp((char *)msg.to_net.addr,str,strlen(str)))) { smb_unlockmsghdr(&smb,&msg); smb_freemsgmem(&msg); continue; } msg.hdr.attr|=MSG_DELETE; 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_unlockmsghdr(&smb,&msg); smb_freemsgmem(&msg); } if(deleted && cfg.sys_misc&SM_DELEMAIL) delmail(0,MAIL_YOUR); smb_close(&smb); if(mailmsgs) free(mail); eprintf(LOG_INFO,"Deleted %d sent NetMail messages",deleted); } return(true); }
BOOL wait_for_call(COM_HANDLE com_handle) { char str[128]; char* p; BOOL result=TRUE; DWORD events=0; time_t start=time(NULL); ZERO_VAR(cid_name); ZERO_VAR(cid_number); if(!comRaiseDTR(com_handle)) lprintf(LOG_ERR,"ERROR %u raising DTR", COM_ERROR_VALUE); if(com_alreadyconnected) return TRUE; if(!mdm_null) { if(mdm_init[0]) { lprintf(LOG_INFO,"Initializing modem:"); if(!modem_command(com_handle, mdm_init)) return FALSE; } if(!mdm_manswer && mdm_autoans[0]) { lprintf(LOG_INFO,"Setting modem to auto-answer:"); if(!modem_command(com_handle, mdm_autoans)) return FALSE; } if(mdm_cid[0]) { lprintf(LOG_INFO,"Enabling modem Caller-ID:"); if(!modem_command(com_handle, mdm_cid)) return FALSE; } } lprintf(LOG_INFO,"Waiting for incoming call (%s) ...", mdm_manswer ? "Ring Indication" : "Carrier Detect"); while(1) { if(terminated) return FALSE; if(comReadLine(com_handle, str, sizeof(str), /* timeout (ms): */250) > 0) { truncsp(str); if(str[0]==0) continue; lprintf(LOG_DEBUG,"Received from modem: '%s'", str); p=str; SKIP_WHITESPACE(p); if(*p) { lprintf(LOG_INFO, "Modem Message: %s", p); if(strncmp(p,"CONNECT ",8)==0) { long rate=atoi(p+8); if(rate) SAFEPRINTF2(termspeed,"%u,%u", rate, rate); } else if(strncmp(p,"NMBR",4)==0 || strncmp(p,"MESG",4)==0) { p+=4; FIND_CHAR(p,'='); SKIP_CHAR(p,'='); SKIP_WHITESPACE(p); if(cid_number[0]==0) /* Don't overwrite, if multiple messages received */ SAFECOPY(cid_number, p); } else if(strncmp(p,"NAME",4)==0) { p+=4; FIND_CHAR(p,'='); SKIP_CHAR(p,'='); SKIP_WHITESPACE(p); SAFECOPY(cid_name, p); } else if(strcmp(p,"NO CARRIER")==0) { ZERO_VAR(cid_name); ZERO_VAR(cid_number); } else if(mdm_ring[0] && strcmp(p,mdm_ring)==0 && mdm_manswer && mdm_answer[0]) { if(!modem_send(com_handle, mdm_answer)) { lprintf(LOG_ERR,"ERROR %u sending modem command (%s) on %s" ,COM_ERROR_VALUE, mdm_answer, com_dev); } } } continue; /* don't check DCD until we've received all the modem msgs */ } if(carrier_detect(com_handle)) break; if(mdm_reinit && (time(NULL)-start)/60 >= mdm_reinit) { lprintf(LOG_INFO,"Re-initialization timer elapsed: %u minutes", mdm_reinit); return TRUE; } } if(strcmp(cid_name,"P")==0) SAFECOPY(cid_name,"Private"); else if(strcmp(cid_name,"O")==0) SAFECOPY(cid_name,"Out-of-area"); if(strcmp(cid_number,"P")==0) SAFECOPY(cid_number,"Private"); else if(strcmp(cid_number,"O")==0) SAFECOPY(cid_number,"Out-of-area"); lprintf(LOG_INFO,"Carrier detected"); return TRUE; }
void sub_cfg(uint grpnum) { static int dflt,tog_dflt,opt_dflt,net_dflt,adv_dflt,bar; char str[128],str2[128],done=0,code[128]; char path[MAX_PATH+1]; char data_dir[MAX_PATH+1]; int j,m,n,ptridx,q,s; uint i,subnum[MAX_OPTS+1]; static sub_t savsub; while(1) { for(i=0,j=0;i<cfg.total_subs && j<MAX_OPTS;i++) if(cfg.sub[i]->grp==grpnum) { subnum[j]=i; if(cfg.sub[subnum[0]]->qwkconf) sprintf(opt[j],"%-5u %s" ,cfg.sub[i]->qwkconf,cfg.sub[i]->lname); else sprintf(opt[j],"%s" ,cfg.sub[i]->lname); j++; } subnum[j]=cfg.total_subs; opt[j][0]=0; sprintf(str,"%s Sub-boards",cfg.grp[grpnum]->sname); i=WIN_SAV|WIN_ACT; if(j) i|=WIN_DEL|WIN_GET|WIN_DELACT; if(j<MAX_OPTS) i|=WIN_INS|WIN_XTR|WIN_INSACT; if(savsub.sname[0]) i|=WIN_PUT; uifc.helpbuf= "`Message Sub-boards:`\n" "\n" "This is a list of message sub-boards that have been configured for the\n" "selected message group.\n" "\n" "To add a sub-board, select the desired position with the arrow keys and\n" "hit ~ INS ~.\n" "\n" "To delete a sub-board, select it with the arrow keys and hit ~ DEL ~.\n" "\n" "To configure a sub-board, select it with the arrow keys and hit ~ ENTER ~.\n" ; i=uifc.list(i,24,1,LEN_SLNAME+5,&dflt,&bar,str,opt); if((signed)i==-1) return; if((i&MSK_ON)==MSK_INS) { i&=MSK_OFF; strcpy(str,"General"); uifc.helpbuf= "`Sub-board Long Name:`\n" "\n" "This is a description of the message sub-board which is displayed in all\n" "sub-board listings.\n" ; if(uifc.input(WIN_MID|WIN_SAV,0,0,"Sub-board Long Name",str,LEN_SLNAME ,K_EDIT)<1) continue; sprintf(str2,"%.*s",LEN_SSNAME,str); uifc.helpbuf= "`Sub-board Short Name:`\n" "\n" "This is a short description of the message sub-board which is displayed\n" "at the main and reading messages prompts.\n" ; if(uifc.input(WIN_MID|WIN_SAV,0,0,"Sub-board Short Name",str2,LEN_SSNAME ,K_EDIT)<1) continue; #if 0 sprintf(str3,"%.10s",str2); uifc.helpbuf= "`Sub-board QWK Name:`\n" "\n" "This is the name of the sub-board used for QWK off-line readers.\n" ; if(uifc.input(WIN_MID|WIN_SAV,0,0,"Sub-board QWK Name",str3,10 ,K_EDIT)<1) continue; #endif SAFECOPY(code,str2); prep_code(code,/* prefix: */NULL); uifc.helpbuf= "`Sub-board Internal Code Suffix:`\n" "\n" "Every sub-board must have its own unique code for Synchronet to refer to\n" "it internally. This code should be descriptive of the sub-board's topic,\n" "usually an abreviation of the sub-board's name.\n" "\n" "`Note:` The internal code is constructed from the message group's code\n" "prefix (if present) and the sub-board's code suffix.\n" ; if(uifc.input(WIN_MID|WIN_SAV,0,0,"Sub-board Internal Code Suffix",code,LEN_CODE ,K_EDIT|K_UPPER)<1) continue; if(!code_ok(code)) { uifc.helpbuf=invalid_code; uifc.msg("Invalid Code"); uifc.helpbuf=0; continue; } if((cfg.sub=(sub_t **)realloc(cfg.sub,sizeof(sub_t *)*(cfg.total_subs+1)))==NULL) { errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_subs+1); cfg.total_subs=0; bail(1); continue; } for(ptridx=0;ptridx<USHRT_MAX;ptridx++) { /* Search for unused pointer indx */ for(n=0;n<cfg.total_subs;n++) if(cfg.sub[n]->ptridx==ptridx) break; if(n==cfg.total_subs) break; } if(j) { for(n=cfg.total_subs;n>subnum[i];n--) cfg.sub[n]=cfg.sub[n-1]; for(q=0;q<cfg.total_qhubs;q++) for(s=0;s<cfg.qhub[q]->subs;s++) if(cfg.qhub[q]->sub[s]>=subnum[i]) cfg.qhub[q]->sub[s]++; } if((cfg.sub[subnum[i]]=(sub_t *)malloc(sizeof(sub_t)))==NULL) { errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(sub_t)); continue; } memset((sub_t *)cfg.sub[subnum[i]],0,sizeof(sub_t)); cfg.sub[subnum[i]]->grp=grpnum; if(cfg.total_faddrs) cfg.sub[subnum[i]]->faddr=cfg.faddr[0]; else memset(&cfg.sub[subnum[i]]->faddr,0,sizeof(faddr_t)); cfg.sub[subnum[i]]->maxmsgs=500; strcpy(cfg.sub[subnum[i]]->code_suffix,code); strcpy(cfg.sub[subnum[i]]->lname,str); strcpy(cfg.sub[subnum[i]]->sname,str2); strcpy(cfg.sub[subnum[i]]->qwkname,code); if(strchr(str,'.') && strchr(str,' ')==NULL) strcpy(cfg.sub[subnum[i]]->newsgroup,str); cfg.sub[subnum[i]]->misc=(SUB_NSDEF|SUB_SSDEF|SUB_QUOTE|SUB_TOUSER |SUB_HDRMOD|SUB_FAST); cfg.sub[subnum[i]]->ptridx=ptridx; cfg.total_subs++; uifc.changes=1; continue; } if((i&MSK_ON)==MSK_DEL) { i&=MSK_OFF; uifc.helpbuf= "`Delete Data in Sub-board:`\n" "\n" "If you want to delete all the messages for this sub-board, select `Yes`.\n" ; j=1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); opt[2][0]=0; SAFEPRINTF2(str,"%s%s.*" ,cfg.grp[cfg.sub[subnum[i]]->grp]->code_prefix ,cfg.sub[subnum[i]]->code_suffix); strlwr(str); if(!cfg.sub[subnum[i]]->data_dir[0]) SAFEPRINTF(data_dir,"%ssubs/",cfg.data_dir); else SAFECOPY(data_dir,cfg.sub[subnum[i]]->data_dir); SAFEPRINTF2(path,"%s%s",data_dir,str); if(fexist(path)) { SAFEPRINTF(str2,"Delete %s",path); j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0 ,str2,opt); if(j==-1) continue; if(j==0) { delfiles(data_dir,str); clearptrs(subnum[i]); } } free(cfg.sub[subnum[i]]); cfg.total_subs--; for(j=subnum[i];j<cfg.total_subs;j++) cfg.sub[j]=cfg.sub[j+1]; for(q=0;q<cfg.total_qhubs;q++) for(s=0;s<cfg.qhub[q]->subs;s++) { if(cfg.qhub[q]->sub[s]==subnum[i]) cfg.qhub[q]->sub[s]=INVALID_SUB; else if(cfg.qhub[q]->sub[s]>subnum[i]) cfg.qhub[q]->sub[s]--; } uifc.changes=1; continue; } if((i&MSK_ON)==MSK_GET) { i&=MSK_OFF; savsub=*cfg.sub[subnum[i]]; continue; } if((i&MSK_ON)==MSK_PUT) { i&=MSK_OFF; ptridx=cfg.sub[subnum[i]]->ptridx; *cfg.sub[subnum[i]]=savsub; cfg.sub[subnum[i]]->ptridx=ptridx; cfg.sub[subnum[i]]->grp=grpnum; uifc.changes=1; continue; } i=subnum[i]; j=0; done=0; while(!done) { n=0; sprintf(opt[n++],"%-27.27s%s","Long Name",cfg.sub[i]->lname); sprintf(opt[n++],"%-27.27s%s","Short Name",cfg.sub[i]->sname); sprintf(opt[n++],"%-27.27s%s","QWK Name",cfg.sub[i]->qwkname); sprintf(opt[n++],"%-27.27s%s%s","Internal Code" ,cfg.grp[cfg.sub[i]->grp]->code_prefix, cfg.sub[i]->code_suffix); sprintf(opt[n++],"%-27.27s%s","Newsgroup Name",cfg.sub[i]->newsgroup); sprintf(opt[n++],"%-27.27s%.40s","Access Requirements" ,cfg.sub[i]->arstr); sprintf(opt[n++],"%-27.27s%.40s","Reading Requirements" ,cfg.sub[i]->read_arstr); sprintf(opt[n++],"%-27.27s%.40s","Posting Requirements" ,cfg.sub[i]->post_arstr); sprintf(opt[n++],"%-27.27s%.40s","Operator Requirements" ,cfg.sub[i]->op_arstr); sprintf(opt[n++],"%-27.27s%.40s","Moderated Posting User" ,cfg.sub[i]->mod_arstr); sprintf(opt[n++],"%-27.27s%"PRIu32,"Maximum Messages" ,cfg.sub[i]->maxmsgs); if(cfg.sub[i]->maxage) sprintf(str,"Enabled (%u days old)",cfg.sub[i]->maxage); else strcpy(str,"Disabled"); sprintf(opt[n++],"%-27.27s%s","Purge by Age",str); if(cfg.sub[i]->maxcrcs) sprintf(str,"Enabled (%"PRIu32" message CRCs)",cfg.sub[i]->maxcrcs); else strcpy(str,"Disabled"); sprintf(opt[n++],"%-27.27s%s","Duplicate Checking",str); strcpy(opt[n++],"Toggle Options..."); strcpy(opt[n++],"Network Options..."); strcpy(opt[n++],"Advanced Options..."); opt[n][0]=0; sprintf(str,"%s Sub-board",cfg.sub[i]->sname); uifc.helpbuf= "`Sub-board Configuration:`\n" "\n" "This menu allows you to configure the individual selected sub-board.\n" "Options with a trailing `...` provide a sub-menu of more options.\n" ; switch(uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT ,0,0,60,&opt_dflt,0,str,opt)) { case -1: done=1; break; case 0: uifc.helpbuf= "`Sub-board Long Name:`\n" "\n" "This is a description of the message sub-board which is displayed in all\n" "sub-board listings.\n" ; strcpy(str,cfg.sub[i]->lname); /* save */ if(!uifc.input(WIN_MID|WIN_SAV,0,17,"Name to use for Listings" ,cfg.sub[i]->lname,LEN_SLNAME,K_EDIT)) strcpy(cfg.sub[i]->lname,str); /* restore */ break; case 1: uifc.helpbuf= "`Sub-board Short Name:`\n" "\n" "This is a short description of the message sub-board which is displayed\n" "at the main and reading messages prompts.\n" ; uifc.input(WIN_MID|WIN_SAV,0,17,"Name to use for Prompts" ,cfg.sub[i]->sname,LEN_SSNAME,K_EDIT); break; case 2: uifc.helpbuf= "`Sub-board QWK Name:`\n" "\n" "This is the name of the sub-board used for QWK off-line readers.\n" ; uifc.input(WIN_MID|WIN_SAV,0,17,"Name to use for QWK Packets" ,cfg.sub[i]->qwkname,10,K_EDIT); break; case 3: uifc.helpbuf= "`Sub-board Internal Code Suffix:`\n" "\n" "Every sub-board must have its own unique code for Synchronet to refer\n" "to it internally. This code should be descriptive of the sub-board's\n" "topic, usually an abreviation of the sub-board's name.\n" "\n" "`Note:` The internal code displayed is the complete internal code\n" "constructed from the message group's code prefix and the sub-board's\n" "code suffix.\n" ; strcpy(str,cfg.sub[i]->code_suffix); uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code Suffix (unique)" ,str,LEN_CODE,K_EDIT|K_UPPER); if(code_ok(str)) strcpy(cfg.sub[i]->code_suffix,str); else { uifc.helpbuf=invalid_code; uifc.msg("Invalid Code"); uifc.helpbuf=0; } break; case 4: uifc.helpbuf= "Newsgroup Name:\n" "\n" "This is the name of the sub-board used for newsgroup readers. If no name\n" "is configured here, a name will be automatically generated from the\n" "sub-board's name and group name.\n" ; uifc.input(WIN_MID|WIN_SAV,0,17,"" ,cfg.sub[i]->newsgroup,sizeof(cfg.sub[i]->newsgroup)-1,K_EDIT); break; case 5: sprintf(str,"%s Access",cfg.sub[i]->sname); getar(str,cfg.sub[i]->arstr); break; case 6: sprintf(str,"%s Reading",cfg.sub[i]->sname); getar(str,cfg.sub[i]->read_arstr); break; case 7: sprintf(str,"%s Posting",cfg.sub[i]->sname); getar(str,cfg.sub[i]->post_arstr); break; case 8: sprintf(str,"%s Operator",cfg.sub[i]->sname); getar(str,cfg.sub[i]->op_arstr); break; case 9: sprintf(str,"%s Moderated Posting User",cfg.sub[i]->sname); getar(str,cfg.sub[i]->mod_arstr); break; case 10: sprintf(str,"%"PRIu32,cfg.sub[i]->maxmsgs); uifc.helpbuf= "`Maximum Number of Messages:`\n" "\n" "This value is the maximum number of messages that will be kept in the\n" "sub-board. Once this maximum number of messages is reached, the oldest\n" "messages will be automatically purged. Usually, 100 messages is a\n" "sufficient maximum.\n" ; uifc.input(WIN_MID|WIN_SAV,0,17,"Maximum Number of Messages" ,str,9,K_EDIT|K_NUMBER); cfg.sub[i]->maxmsgs=atoi(str); cfg.sub[i]->misc|=SUB_HDRMOD; break; case 11: sprintf(str,"%u",cfg.sub[i]->maxage); uifc.helpbuf= "`Maximum Age of Messages:`\n" "\n" "This value is the maximum number of days that messages will be kept in\n" "the sub-board.\n" ; uifc.input(WIN_MID|WIN_SAV,0,17,"Maximum Age of Messages (in days)" ,str,5,K_EDIT|K_NUMBER); cfg.sub[i]->maxage=atoi(str); cfg.sub[i]->misc|=SUB_HDRMOD; break; case 12: sprintf(str,"%"PRIu32,cfg.sub[i]->maxcrcs); uifc.helpbuf= "`Maximum Number of CRCs:`\n" "\n" "This value is the maximum number of CRCs that will be kept in the\n" "sub-board for duplicate message checking. Once this maximum number of\n" "CRCs is reached, the oldest CRCs will be automatically purged.\n" ; uifc.input(WIN_MID|WIN_SAV,0,17,"Maximum Number of CRCs" ,str,9,K_EDIT|K_NUMBER); cfg.sub[i]->maxcrcs=atol(str); cfg.sub[i]->misc|=SUB_HDRMOD; break; case 13: while(1) { n=0; sprintf(opt[n++],"%-27.27s%s","Allow Private Posts" ,cfg.sub[i]->misc&SUB_PRIV ? cfg.sub[i]->misc&SUB_PONLY ? "Only":"Yes":"No"); sprintf(opt[n++],"%-27.27s%s","Allow Anonymous Posts" ,cfg.sub[i]->misc&SUB_ANON ? cfg.sub[i]->misc&SUB_AONLY ? "Only":"Yes":"No"); sprintf(opt[n++],"%-27.27s%s","Post Using Real Names" ,cfg.sub[i]->misc&SUB_NAME ? "Yes":"No"); sprintf(opt[n++],"%-27.27s%s","Users Can Edit Posts" ,cfg.sub[i]->misc&SUB_EDIT ? cfg.sub[i]->misc&SUB_EDITLAST ? "Last" : "Yes" : "No"); sprintf(opt[n++],"%-27.27s%s","Users Can Delete Posts" ,cfg.sub[i]->misc&SUB_DEL ? cfg.sub[i]->misc&SUB_DELLAST ? "Last" : "Yes" : "No"); sprintf(opt[n++],"%-27.27s%s","Default On for New Scan" ,cfg.sub[i]->misc&SUB_NSDEF ? "Yes":"No"); sprintf(opt[n++],"%-27.27s%s","Forced On for New Scan" ,cfg.sub[i]->misc&SUB_FORCED ? "Yes":"No"); sprintf(opt[n++],"%-27.27s%s","Default On for Your Scan" ,cfg.sub[i]->misc&SUB_SSDEF ? "Yes":"No"); sprintf(opt[n++],"%-27.27s%s","Public 'To' User" ,cfg.sub[i]->misc&SUB_TOUSER ? "Yes":"No"); sprintf(opt[n++],"%-27.27s%s","Allow Message Quoting" ,cfg.sub[i]->misc&SUB_QUOTE ? "Yes":"No"); sprintf(opt[n++],"%-27.27s%s","Suppress User Signatures" ,cfg.sub[i]->misc&SUB_NOUSERSIG ? "Yes":"No"); sprintf(opt[n++],"%-27.27s%s","Permanent Operator Msgs" ,cfg.sub[i]->misc&SUB_SYSPERM ? "Yes":"No"); sprintf(opt[n++],"%-27.27s%s","Kill Read Messages" ,cfg.sub[i]->misc&SUB_KILL ? "Yes" : (cfg.sub[i]->misc&SUB_KILLP ? "Pvt" : "No")); sprintf(opt[n++],"%-27.27s%s","Compress Messages (LZH)" ,cfg.sub[i]->misc&SUB_LZH ? "Yes" : "No"); opt[n][0]=0; uifc.helpbuf= "`Sub-board Toggle Options:`\n" "\n" "This menu allows you to toggle certain options for the selected\n" "sub-board between two or more settings, such as `Yes` and `No`.\n" ; n=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,3,2,36,&tog_dflt,0 ,"Toggle Options",opt); if(n==-1) break; switch(n) { case 0: if(cfg.sub[i]->misc&SUB_PONLY) n=2; else n=(cfg.sub[i]->misc&SUB_PRIV) ? 0:1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); strcpy(opt[2],"Only"); opt[3][0]=0; uifc.helpbuf= "`Allow Private Posts on Sub-board:`\n" "\n" "If you want users to be able to post private messages to other users\n" "on this sub-board, set this value to `Yes`. Usually, E-mail is the\n" "preferred method of private communication. If you want users to be able\n" "to post private messages only on this sub-board, select `Only`.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Allow Private Posts",opt); if(n==-1) break; if(!n && (cfg.sub[i]->misc&(SUB_PRIV|SUB_PONLY)) !=SUB_PRIV) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_PONLY; cfg.sub[i]->misc|=SUB_PRIV; break; } if(n==1 && cfg.sub[i]->misc&SUB_PRIV) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_PRIV; break; } if(n==2 && (cfg.sub[i]->misc&(SUB_PRIV|SUB_PONLY)) !=(SUB_PRIV|SUB_PONLY)) { uifc.changes=1; cfg.sub[i]->misc|=(SUB_PRIV|SUB_PONLY); } break; case 1: if(cfg.sub[i]->misc&SUB_AONLY) n=2; else n=(cfg.sub[i]->misc&SUB_ANON) ? 0:1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); strcpy(opt[2],"Only"); opt[3][0]=0; uifc.helpbuf= "`Allow Anonymous Posts on Sub-board:`\n" "\n" "If you want users with the `A` exemption to be able to post anonymously on\n" "this sub-board, select `Yes`. If you want all posts on this sub-board to be\n" "forced anonymous, select `Only`. If you do not want anonymous posts allowed\n" "on this sub-board at all, select `No`.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Allow Anonymous Posts",opt); if(n==-1) break; if(!n && (cfg.sub[i]->misc&(SUB_ANON|SUB_AONLY)) !=SUB_ANON) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_AONLY; cfg.sub[i]->misc|=SUB_ANON; break; } if(n==1 && cfg.sub[i]->misc&(SUB_ANON|SUB_AONLY)) { uifc.changes=1; cfg.sub[i]->misc&=~(SUB_ANON|SUB_AONLY); break; } if(n==2 && (cfg.sub[i]->misc&(SUB_ANON|SUB_AONLY)) !=(SUB_ANON|SUB_AONLY)) { uifc.changes=1; cfg.sub[i]->misc|=(SUB_ANON|SUB_AONLY); } break; case 2: n=(cfg.sub[i]->misc&SUB_NAME) ? 0:1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); opt[2][0]=0; uifc.helpbuf= "`User Real Names in Posts on Sub-board:`\n" "\n" "If you allow aliases on your system, you can have messages on this\n" "sub-board automatically use the real name of the posting user by setting\n" "this option to `Yes`.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Use Real Names in Posts",opt); if(n==-1) break; if(!n && !(cfg.sub[i]->misc&SUB_NAME)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_NAME; break; } if(n==1 && cfg.sub[i]->misc&SUB_NAME) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_NAME; } break; case 3: if(cfg.sub[i]->misc&SUB_EDITLAST) n=2; else n=(cfg.sub[i]->misc&SUB_EDIT) ? 0:1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); strcpy(opt[2],"Last Post Only"); opt[3][0]=0; uifc.helpbuf= "`Users Can Edit Posts on Sub-board:`\n" "\n" "If you wish to allow users to edit their messages after they have been\n" "posted, this option to `Yes`. If you wish to allow users to edit only the\n" "last message on a message base, set this option to `Last Post Only`.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Users Can Edit Messages",opt); if(n==-1) break; if(n==0 /* yes */ && (cfg.sub[i]->misc&(SUB_EDIT|SUB_EDITLAST)) !=SUB_EDIT ) { uifc.changes=1; cfg.sub[i]->misc|=SUB_EDIT; cfg.sub[i]->misc&=~SUB_EDITLAST; break; } if(n==1 /* no */ && cfg.sub[i]->misc&(SUB_EDIT|SUB_EDITLAST) ) { uifc.changes=1; cfg.sub[i]->misc&=~(SUB_EDIT|SUB_EDITLAST); break; } if(n==2 /* last only */ && (cfg.sub[i]->misc&(SUB_EDIT|SUB_EDITLAST)) !=(SUB_EDIT|SUB_EDITLAST) ) { uifc.changes=1; cfg.sub[i]->misc|=(SUB_EDIT|SUB_EDITLAST); break; } break; case 4: if(cfg.sub[i]->misc&SUB_DELLAST) n=2; else n=(cfg.sub[i]->misc&SUB_DEL) ? 0:1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); strcpy(opt[2],"Last Post Only"); opt[3][0]=0; uifc.helpbuf= "`Users Can Delete Posts on Sub-board:`\n" "\n" "If you want users to be able to delete any of their own posts on this\n" "sub-board, set this option to `Yes`. If you want to allow users the\n" "ability to delete their message only if it is the last message on the\n" "sub-board, select `Last Post Only`. If you want to disallow users from\n" "deleting any of their posts, set this option to `No`.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Users Can Delete Posts",opt); if(n==-1) break; if(!n && (cfg.sub[i]->misc&(SUB_DEL|SUB_DELLAST)) !=SUB_DEL) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_DELLAST; cfg.sub[i]->misc|=SUB_DEL; break; } if(n==1 && cfg.sub[i]->misc&SUB_DEL) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_DEL; break; } if(n==2 && (cfg.sub[i]->misc&(SUB_DEL|SUB_DELLAST)) !=(SUB_DEL|SUB_DELLAST)) { uifc.changes=1; cfg.sub[i]->misc|=(SUB_DEL|SUB_DELLAST); } break; case 5: n=(cfg.sub[i]->misc&SUB_NSDEF) ? 0:1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); opt[2][0]=0; uifc.helpbuf= "`Default On for New Scan:`\n" "\n" "If you want this sub-board to be included in all user new message scans\n" "by default, set this option to `Yes`.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Default On for New Scan",opt); if(n==-1) break; if(!n && !(cfg.sub[i]->misc&SUB_NSDEF)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_NSDEF; break; } if(n==1 && cfg.sub[i]->misc&SUB_NSDEF) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_NSDEF; } break; case 6: n=(cfg.sub[i]->misc&SUB_FORCED) ? 0:1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); opt[2][0]=0; uifc.helpbuf= "`Forced On for New Scan:`\n" "\n" "If you want this sub-board to be included in all user new message scans\n" "even if the user has removed it from their new scan configuration, set\n" "this option to `Yes`.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Forced New Scan",opt); if(n==-1) break; if(!n && !(cfg.sub[i]->misc&SUB_FORCED)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_FORCED; break; } if(n==1 && cfg.sub[i]->misc&SUB_FORCED) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_FORCED; } break; case 7: n=(cfg.sub[i]->misc&SUB_SSDEF) ? 0:1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); opt[2][0]=0; uifc.helpbuf= "`Default On for Your Scan:`\n" "\n" "If you want this sub-board to be included in all user personal message\n" "scans by default, set this option to `Yes`.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Default On for Your Scan",opt); if(n==-1) break; if(!n && !(cfg.sub[i]->misc&SUB_SSDEF)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_SSDEF; break; } if(n==1 && cfg.sub[i]->misc&SUB_SSDEF) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_SSDEF; } break; case 8: n=(cfg.sub[i]->misc&SUB_TOUSER) ? 0:1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); opt[2][0]=0; uifc.helpbuf= "`Prompt for 'To' User on Public Posts:`\n" "\n" "If you want all posts on this sub-board to be prompted for a 'To' user,\n" "set this option to `Yes`. This is a useful option for sub-boards that\n" "are on a network that does not allow private posts.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Prompt for 'To' User on Public Posts",opt); if(n==-1) break; if(!n && !(cfg.sub[i]->misc&SUB_TOUSER)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_TOUSER; break; } if(n==1 && cfg.sub[i]->misc&SUB_TOUSER) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_TOUSER; } break; case 9: n=(cfg.sub[i]->misc&SUB_QUOTE) ? 0:1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); opt[2][0]=0; uifc.helpbuf= "`Allow Message Quoting:`\n" "\n" "If you want users to be allowed to quote messages on this sub-board, set\n" "this option to `Yes`.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Allow Message Quoting",opt); if(n==-1) break; if(!n && !(cfg.sub[i]->misc&SUB_QUOTE)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_QUOTE; break; } if(n==1 && cfg.sub[i]->misc&SUB_QUOTE) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_QUOTE; } break; case 10: n=(cfg.sub[i]->misc&SUB_NOUSERSIG) ? 0:1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); opt[2][0]=0; uifc.helpbuf= "Suppress User Signatures:\n" "\n" "If you do not wish to have user signatures automatically appended to\n" "messages posted in this sub-board, set this option to Yes.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Suppress User Signatures",opt); if(n==-1) break; if(!n && !(cfg.sub[i]->misc&SUB_NOUSERSIG)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_NOUSERSIG; break; } if(n==1 && cfg.sub[i]->misc&SUB_NOUSERSIG) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_NOUSERSIG; } break; case 11: n=(cfg.sub[i]->misc&SUB_SYSPERM) ? 0:1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); opt[2][0]=0; uifc.helpbuf= "`Operator Messages Automatically Permanent:`\n" "\n" "If you want messages posted by `System` and `Sub-board Operators` to be\n" "automatically permanent (non-purgable) for this sub-board, set this\n" "option to `Yes`.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Permanent Operator Messages",opt); if(n==-1) break; if(!n && !(cfg.sub[i]->misc&SUB_SYSPERM)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_SYSPERM; break; } if(n==1 && cfg.sub[i]->misc&SUB_SYSPERM) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_SYSPERM; } break; case 12: if(cfg.sub[i]->misc&SUB_KILLP) n=2; else n=(cfg.sub[i]->misc&SUB_KILL) ? 0:1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); strcpy(opt[2],"Private"); opt[3][0]=0; uifc.helpbuf= "`Kill Read Messages Automatically:`\n" "\n" "If you want messages that have been read by the intended recipient to\n" "be automatically deleted by `SMBUTIL`, set this option to `Yes` or\n" "`Private` if you want only private messages to be automatically deleted.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Kill Read Messages",opt); if(n==-1) break; if(!n && !(cfg.sub[i]->misc&SUB_KILL)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_KILL; cfg.sub[i]->misc&=~SUB_KILLP; break; } if(n==1 && cfg.sub[i]->misc&(SUB_KILL|SUB_KILLP)) { uifc.changes=1; cfg.sub[i]->misc&=~(SUB_KILL|SUB_KILLP); } if(n==2 && !(cfg.sub[i]->misc&SUB_KILLP)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_KILLP; cfg.sub[i]->misc&=~SUB_KILL; break; } break; case 13: n=(cfg.sub[i]->misc&SUB_LZH) ? 0:1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); opt[2][0]=0; uifc.helpbuf= "`Compress Messages with LZH Encoding:`\n" "\n" "If you want all messages in this sub-board to be automatically\n" "compressed via `LZH` (Lempel/Ziv/Huffman algorithm used in LHarc, LHA,\n" "and other popular compression and archive programs), this option to `Yes`.\n" "\n" "Compression will slow down the reading and writing of messages slightly,\n" "but the storage space saved can be as much as `50 percent`.\n" "\n" "Before setting this option to `Yes`, make sure that all of the SMB\n" "compatible mail programs you use support the `LZH` translation.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Compress Messages (LZH)",opt); if(n==-1) break; if(!n && !(cfg.sub[i]->misc&SUB_LZH)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_LZH; break; } if(n==1 && cfg.sub[i]->misc&SUB_LZH) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_LZH; } break; } } break; case 14: while(1) { n=0; sprintf(opt[n++],"%-27.27s%s","Append Tag/Origin Line" ,cfg.sub[i]->misc&SUB_NOTAG ? "No":"Yes"); sprintf(opt[n++],"%-27.27s%s","Export ASCII Only" ,cfg.sub[i]->misc&SUB_ASCII ? "Yes":"No"); sprintf(opt[n++],"%-27.27s%s","Gate Between Net Types" ,cfg.sub[i]->misc&SUB_GATE ? "Yes":"No"); sprintf(opt[n++],"%-27.27s%s","QWK Networked" ,cfg.sub[i]->misc&SUB_QNET ? "Yes":"No"); sprintf(opt[n++],"QWK Tagline"); sprintf(opt[n++],"%-27.27s%s","Internet (UUCP/NNTP)" ,cfg.sub[i]->misc&SUB_INET ? "Yes":"No"); sprintf(opt[n++],"%-27.27s%s","PostLink or PCRelay" ,cfg.sub[i]->misc&SUB_PNET ? "Yes":"No"); sprintf(opt[n++],"%-27.27s%s","FidoNet EchoMail" ,cfg.sub[i]->misc&SUB_FIDO ? "Yes":"No"); sprintf(opt[n++],"%-27.27s%s","FidoNet Address" ,smb_faddrtoa(&cfg.sub[i]->faddr,tmp)); sprintf(opt[n++],"EchoMail Origin Line"); opt[n][0]=0; uifc.helpbuf= "`Sub-board Network Options:`\n" "\n" "This menu contains options for the selected sub-board that pertain\n" "specifically to message networking.\n" ; n=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,3,2,60,&net_dflt,0 ,"Network Options",opt); if(n==-1) break; switch(n) { case 0: n=0; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); opt[2][0]=0; uifc.helpbuf= "`Append Tag/Origin Line to Posts:`\n" "\n" "If you want to disable the automatic addition of a network tagline or\n" "origin line to the bottom of outgoing networked posts from this\n" "sub-board, set this option to `No`.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Append Tag/Origin Line to Posts",opt); if(n==-1) break; if(!n && cfg.sub[i]->misc&SUB_NOTAG) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_NOTAG; break; } if(n==1 && !(cfg.sub[i]->misc&SUB_NOTAG)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_NOTAG; } break; case 1: n=0; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); opt[2][0]=0; uifc.helpbuf= "`Export ASCII Characters Only:`\n" "\n" "If the network that this sub-board is echoed on does not allow extended\n" "ASCII (>127) or control codes (<20, not including CR), set this option\n" "to `Yes`.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Export ASCII Characters Only",opt); if(n==-1) break; if(n && cfg.sub[i]->misc&SUB_ASCII) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_ASCII; break; } if(!n && !(cfg.sub[i]->misc&SUB_ASCII)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_ASCII; } break; case 2: n=1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); opt[2][0]=0; uifc.helpbuf= "`Gate Between Net Types:`\n" "\n" "If this sub-board is networked using more than one network technology,\n" "and you want messages to be `gated` between the networks, set this\n" "option to `Yes`.\n" "\n" "If this option is set to `No`, messages imported from one network type\n" "will `not` be exported to another network type. This is the default and\n" "should be used unless you have `specific` permission from both networks\n" "to gate this sub-board. Incorrectly gated sub-boards can cause duplicate\n" "messages loops and cross-posted messages.\n" "\n" "This option does not affect the exporting of messages created on your\n" "BBS.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Gate Between Net Types",opt); if(n==-1) break; if(!n && !(cfg.sub[i]->misc&SUB_GATE)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_GATE; break; } if(n==1 && cfg.sub[i]->misc&SUB_GATE) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_GATE; } break; case 3: n=1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); opt[2][0]=0; uifc.helpbuf= "`Sub-board Networked via QWK Packets:`\n" "\n" "If this sub-board is networked with other BBSs via QWK packets, this\n" "option should be set to `Yes`. With this option set to `Yes`, titles of\n" "posts on this sub-board will be limited to the QWK packet limitation of\n" "25 characters. It also allows the `N`etwork restriction to function\n" "properly.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Networked via QWK Packets",opt); if(n==-1) break; if(!n && !(cfg.sub[i]->misc&SUB_QNET)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_QNET; break; } if(n==1 && cfg.sub[i]->misc&SUB_QNET) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_QNET; } break; case 4: uifc.helpbuf= "`Sub-board QWK Network Tagline:`\n" "\n" "If you want to use a different QWK tagline than the configured default\n" "tagline in the `Networks` configuration, you should enter that tagline\n" "here. If this option is left blank, the default tagline is used.\n" ; uifc.input(WIN_MID|WIN_SAV,0,0,nulstr,cfg.sub[i]->tagline ,sizeof(cfg.sub[i]->tagline)-1,K_MSG|K_EDIT); break; case 5: n=1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); opt[2][0]=0; uifc.helpbuf= "`Sub-board Networked via Internet:`\n" "\n" "If this sub-board is networked to the Internet via UUCP or NNTP, this\n" "option should be set to `Yes`.\n" "\n" "It will allow the `N`etwork user restriction to function properly.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Networked via Internet",opt); if(n==-1) break; if(!n && !(cfg.sub[i]->misc&SUB_INET)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_INET; break; } if(n==1 && cfg.sub[i]->misc&SUB_INET) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_INET; } break; case 6: n=1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); opt[2][0]=0; uifc.helpbuf= "`Sub-board Networked via PostLink or PCRelay:`\n" "\n" "If this sub-board is networked with other BBSs via PostLink or PCRelay,\n" "this option should be set to `Yes`. With this option set to `Yes`,\n" "titles of posts on this sub-board will be limited to the UTI\n" "specification limitation of 25 characters. It also allows the `N`etwork\n" "restriction to function properly.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Networked via PostLink or PCRelay",opt); if(n==-1) break; if(!n && !(cfg.sub[i]->misc&SUB_PNET)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_PNET; break; } if(n==1 && cfg.sub[i]->misc&SUB_PNET) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_PNET; } break; case 7: n=1; strcpy(opt[0],"Yes"); strcpy(opt[1],"No"); opt[2][0]=0; uifc.helpbuf= "`Sub-board Networked via FidoNet EchoMail:`\n" "\n" "If this sub-board is part of a FidoNet EchoMail conference, set this\n" "option to `Yes`.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Networked via FidoNet EchoMail",opt); if(n==-1) break; if(!n && !(cfg.sub[i]->misc&SUB_FIDO)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_FIDO; break; } if(n==1 && cfg.sub[i]->misc&SUB_FIDO) { uifc.changes=1; cfg.sub[i]->misc&=~SUB_FIDO; } break; case 8: smb_faddrtoa(&cfg.sub[i]->faddr,str); uifc.helpbuf= "`Sub-board FidoNet Address:`\n" "\n" "If this sub-board is part of a FidoNet EchoMail conference, this is\n" "the address used for this sub-board. Format: `Zone:Net/Node[.Point]`\n" ; uifc.input(WIN_MID|WIN_SAV,0,0,"FidoNet Address" ,str,25,K_EDIT); cfg.sub[i]->faddr=atofaddr(str); break; case 9: uifc.helpbuf= "`Sub-board FidoNet Origin Line:`\n" "\n" "If this sub-board is part of a FidoNet EchoMail conference and you\n" "want to use an origin line other than the default origin line in the\n" "`Networks` configuration, set this value to the desired origin line.\n" "\n" "If this option is blank, the default origin line is used.\n" ; uifc.input(WIN_MID|WIN_SAV,0,0,nulstr,cfg.sub[i]->origline ,sizeof(cfg.sub[i]->origline)-1,K_EDIT); break; } } break; case 15: while(1) { n=0; if(cfg.sub[i]->qwkconf) sprintf(str,"Static (%u)",cfg.sub[i]->qwkconf); else strcpy(str,"Dynamic"); sprintf(opt[n++],"%-27.27s%s","QWK Conference Number" ,str); sprintf(opt[n++],"%-27.27s%s","Storage Method" ,cfg.sub[i]->misc&SUB_HYPER ? "Hyper Allocation" : cfg.sub[i]->misc&SUB_FAST ? "Fast Allocation" : "Self-packing"); if(!cfg.sub[i]->data_dir[0]) sprintf(str,"%ssubs/",cfg.data_dir); else strcpy(str,cfg.sub[i]->data_dir); sprintf(opt[n++],"%-27.27s%.40s","Storage Directory",str); sprintf(opt[n++],"%-27.27s%.40s","Semaphore File",cfg.sub[i]->post_sem); sprintf(opt[n++],"%-27.27s%u","Pointer File Index",cfg.sub[i]->ptridx); opt[n][0]=0; uifc.helpbuf= "`Sub-board Advanced Options:`\n" "\n" "This menu contains options for the selected sub-board that are advanced\n" "in nature.\n" ; n=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,3,2,60,&adv_dflt,0 ,"Advanced Options",opt); if(n==-1) break; switch(n) { case 0: uifc.helpbuf= "`Sub-board QWK Conference Number:`\n" "\n" "If you wish to have the QWK conference number for this sub-board\n" "automatically generated by Synchronet (based on the group number\n" "and sub-board number for the user), set this option to `Dynamic`.\n" "\n" "If you wish to have the same QWK conference number for this sub-board\n" "regardless of which user access it, set this option to `Static`\n" "by entering the conference number you want to use.\n" ; if(cfg.sub[i]->qwkconf) sprintf(str,"%u",cfg.sub[i]->qwkconf); else str[0]=0; if(uifc.input(WIN_MID|WIN_SAV,0,17 ,"QWK Conference Number (0=Dynamic)" ,str,5,K_EDIT|K_NUMBER)>=0) cfg.sub[i]->qwkconf=atoi(str); break; case 1: n=0; strcpy(opt[0],"Hyper Allocation"); strcpy(opt[1],"Fast Allocation"); strcpy(opt[2],"Self-packing"); opt[3][0]=0; uifc.helpbuf= "`Self-Packing` is the slowest storage method because it conserves disk\n" " space as it imports messages by using deleted message header and data\n" " blocks for new messages automatically. If you use this storage method,\n" " you will not need to run `SMBUTIL P` on this message base unless you\n" " accumilate a large number of deleted message blocks and wish to free\n" " that disk space. You can switch from self-packing to fast allocation\n" " storage method and back again as you wish.\n" "`Fast Allocation` is faster than self-packing because it does not search\n" " for deleted message blocks for new messages. It automatically places\n" " all new message blocks at the end of the header and data files. If you\n" " use this storage method, you will need to run `SMBUTIL P` on this\n" " message base periodically or it will continually use up disk space.\n" "`Hyper Allocation` is the fastest storage method because it does not\n" " maintain allocation files at all. Once a message base is setup to use\n" " this storage method, it should not be changed without first deleting\n" " the message base data files in your `DATA\\DIRS\\SUBS` directory for this\n" " sub-board. You must use `SMBUTIL P` as with the fast allocation method.\n" ; n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0 ,"Storage Method",opt); if(n==-1) break; if(!n && !(cfg.sub[i]->misc&SUB_HYPER)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_HYPER; cfg.sub[i]->misc&=~SUB_FAST; cfg.sub[i]->misc|=SUB_HDRMOD; break; } if(!n) break; if(cfg.sub[i]->misc&SUB_HYPER) { /* Switching from hyper */ strcpy(opt[0],"Yes"); strcpy(opt[1],"No, I want to use Hyper Allocation"); opt[2][0]=0; m=0; if(uifc.list(WIN_SAV|WIN_MID,0,0,0,&m,0 ,"Delete all messages in this sub-board?",opt)!=0) break; if(cfg.sub[i]->data_dir[0]) sprintf(str,"%s",cfg.sub[i]->data_dir); else sprintf(str,"%ssubs/",cfg.data_dir); sprintf(str2,"%s%s.*" ,cfg.grp[cfg.sub[i]->grp]->code_prefix ,cfg.sub[i]->code_suffix); strlwr(str2); delfiles(str,str2); } if(cfg.sub[i]->misc&SUB_HYPER) cfg.sub[i]->misc|=SUB_HDRMOD; if(n==1 && !(cfg.sub[i]->misc&SUB_FAST)) { uifc.changes=1; cfg.sub[i]->misc|=SUB_FAST; cfg.sub[i]->misc&=~SUB_HYPER; break; } if(n==2 && cfg.sub[i]->misc&(SUB_FAST|SUB_HYPER)) { uifc.changes=1; cfg.sub[i]->misc&=~(SUB_FAST|SUB_HYPER); break; } break; case 2: uifc.helpbuf= "`Sub-board Storage Directory:`\n" "\n" "Use this if you wish to place the data directory for this sub-board on\n" "another drive or in another directory besides the default setting.\n" ; uifc.input(WIN_MID|WIN_SAV,0,17,"Directory" ,cfg.sub[i]->data_dir,sizeof(cfg.sub[i]->data_dir)-1,K_EDIT); break; case 3: uifc.helpbuf= "`Sub-board Semaphore File:`\n" "\n" "This is a filename that will be created as a semaphore (signal) to an\n" "external program or event whenever a message is posted in this sub-board.\n" ; uifc.input(WIN_MID|WIN_SAV,0,17,"Semaphore File" ,cfg.sub[i]->post_sem,sizeof(cfg.sub[i]->post_sem)-1,K_EDIT); break; case 4: uifc.helpbuf= "`Sub-board Pointer Index:`\n" "\n" "You should normally have no reason to modify this value. If you get\n" "crossed-up or duplicate ptridx values, then you may want to adjust\n" "this value, but do so with great care and trepidation.\n" ; sprintf(str,"%u",cfg.sub[i]->ptridx); if(uifc.input(WIN_MID|WIN_SAV,0,17 ,"Pointer File Index (Danger!)" ,str,5,K_EDIT|K_NUMBER)>=0) cfg.sub[i]->ptridx=atoi(str); break; } } break; } } } }