bool sbbs_t::postmsg(uint subnum, smbmsg_t *remsg, long wm_mode) { char str[256],title[LEN_TITLE+1],top[256]; char msg_id[256]; char touser[64]; char from[64]; char pid[128]; char* editor=NULL; char* msgbuf=NULL; uint16_t xlat; ushort msgattr; int i,storage; long dupechk_hashes; long length; FILE* fp; smbmsg_t msg; uint reason; if(remsg) { sprintf(title,"%.*s",LEN_TITLE,remsg->subj); if(remsg->hdr.attr&MSG_ANONYMOUS) SAFECOPY(from,text[Anonymous]); else SAFECOPY(from,remsg->from); // If user posted this message, reply to the original recipient again if((remsg->from_ext!=NULL && atoi(remsg->from_ext)==useron.number) || stricmp(useron.alias,remsg->from)==0 || stricmp(useron.name,remsg->from)==0) SAFECOPY(touser,remsg->to); else SAFECOPY(touser,from); msgattr=(ushort)(remsg->hdr.attr&MSG_PRIVATE); sprintf(top,text[RegardingByToOn],title,from,remsg->to ,timestr(remsg->hdr.when_written.time) ,smb_zonestr(remsg->hdr.when_written.zone,NULL)); } else { title[0]=0; touser[0]=0; top[0]=0; msgattr=0; } /* Security checks */ if(!can_user_post(&cfg,subnum,&useron,&client,&reason)) { bputs(text[reason]); return false; } bprintf(text[Posting],cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname); action=NODE_PMSG; nodesync(); if(!(msgattr&MSG_PRIVATE) && (cfg.sub[subnum]->misc&SUB_PONLY || (cfg.sub[subnum]->misc&SUB_PRIV && !noyes(text[PrivatePostQ])))) msgattr|=MSG_PRIVATE; if(sys_status&SS_ABORT) return(false); if( #if 0 /* we *do* support internet posts to specific people July-11-2002 */ !(cfg.sub[subnum]->misc&SUB_INET) && // Prompt for TO: user #endif (cfg.sub[subnum]->misc&SUB_TOUSER || msgattr&MSG_PRIVATE || touser[0])) { if(!touser[0] && !(msgattr&MSG_PRIVATE)) SAFECOPY(touser,"All"); bputs(text[PostTo]); i=LEN_ALIAS; if(cfg.sub[subnum]->misc&SUB_QNET) i=25; if(cfg.sub[subnum]->misc&SUB_FIDO) i=FIDO_NAME_LEN-1; if(cfg.sub[subnum]->misc&(SUB_PNET|SUB_INET)) i=60; getstr(touser,i,K_UPRLWR|K_LINE|K_EDIT|K_AUTODEL); if(stricmp(touser,"ALL") && !(cfg.sub[subnum]->misc&(SUB_PNET|SUB_FIDO|SUB_QNET|SUB_INET|SUB_ANON))) { if(cfg.sub[subnum]->misc&SUB_NAME) { if(!userdatdupe(useron.number,U_NAME,LEN_NAME,touser)) { bputs(text[UnknownUser]); return(false); } } else { if((i=finduser(touser))==0) return(false); username(&cfg,i,touser); } } if(sys_status&SS_ABORT) return(false); } if(!touser[0]) SAFECOPY(touser,"All"); // Default to ALL if(!stricmp(touser,"SYSOP") && !SYSOP) // Change SYSOP to user #1 username(&cfg,1,touser); if(msgattr&MSG_PRIVATE && !stricmp(touser,"ALL")) { bputs(text[NoToUser]); return(false); } if(msgattr&MSG_PRIVATE) wm_mode|=WM_PRIVATE; if(cfg.sub[subnum]->misc&SUB_AONLY || (cfg.sub[subnum]->misc&SUB_ANON && useron.exempt&FLAG('A') && !noyes(text[AnonymousQ]))) msgattr|=MSG_ANONYMOUS; if(cfg.sub[subnum]->mod_ar[0] && chk_ar(cfg.sub[subnum]->mod_ar,&useron,&client)) msgattr|=MSG_MODERATED; if(cfg.sub[subnum]->misc&SUB_SYSPERM && sub_op(subnum)) msgattr|=MSG_PERMANENT; if(msgattr&MSG_PRIVATE) bputs(text[PostingPrivately]); if(msgattr&MSG_ANONYMOUS) bputs(text[PostingAnonymously]); if(cfg.sub[subnum]->misc&SUB_NAME) bputs(text[UsingRealName]); msg_tmp_fname(useron.xedit, str, sizeof(str)); if(!writemsg(str,top,title,wm_mode,subnum,touser,&editor) || (length=(long)flength(str))<1) { /* Bugfix Aug-20-2003: Reject negative length */ bputs(text[Aborted]); return(false); } bputs(text[WritingIndx]); if((i=smb_stack(&smb,SMB_STACK_PUSH))!=SMB_SUCCESS) { errormsg(WHERE,ERR_OPEN,cfg.sub[subnum]->code,i,smb.last_error); return(false); } smb.subnum=subnum; if((i=msgbase_open(&cfg,&smb,&storage,&dupechk_hashes,&xlat))!=SMB_SUCCESS) { errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); smb_stack(&smb,SMB_STACK_POP); return(false); } if((i=smb_locksmbhdr(&smb))!=SMB_SUCCESS) { smb_close(&smb); errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error); smb_stack(&smb,SMB_STACK_POP); return(false); } if((i=smb_getstatus(&smb))!=SMB_SUCCESS) { smb_close(&smb); errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error); smb_stack(&smb,SMB_STACK_POP); return(false); } if((msgbuf=(char*)calloc(length+1,sizeof(char))) == NULL) { smb_close(&smb); errormsg(WHERE,ERR_ALLOC,"msgbuf",length+1); smb_stack(&smb,SMB_STACK_POP); return(false); } if((fp=fopen(str,"rb"))==NULL) { free(msgbuf); smb_close(&smb); errormsg(WHERE,ERR_OPEN,str,O_RDONLY|O_BINARY); smb_stack(&smb,SMB_STACK_POP); return(false); } i=fread(msgbuf,1,length,fp); fclose(fp); if(i != length) { free(msgbuf); smb_close(&smb); errormsg(WHERE,ERR_READ,str,length); smb_stack(&smb,SMB_STACK_POP); return(false); } truncsp(msgbuf); /* ToDo: split body/tail */ memset(&msg,0,sizeof(msg)); msg.hdr.attr=msgattr; msg.hdr.when_written.time=msg.hdr.when_imported.time=time32(NULL); msg.hdr.when_written.zone=msg.hdr.when_imported.zone=sys_timezone(&cfg); msg.hdr.number=smb.status.last_msg+1; /* this *should* be the new message number */ if(remsg) { msg.hdr.thread_back=remsg->hdr.number; /* needed for threading backward */ if((msg.hdr.thread_id=remsg->hdr.thread_id) == 0) msg.hdr.thread_id=remsg->hdr.number; /* Add RFC-822 Reply-ID (generate if necessary) */ if(remsg->id!=NULL) smb_hfield_str(&msg,RFC822REPLYID,remsg->id); /* Add FidoNet Reply if original message has FidoNet MSGID */ if(remsg->ftn_msgid!=NULL) smb_hfield_str(&msg,FIDOREPLYID,remsg->ftn_msgid); if((i=smb_updatethread(&smb, remsg, smb.status.last_msg+1))!=SMB_SUCCESS) errormsg(WHERE,"updating thread",smb.file,i,smb.last_error); } smb_hfield_str(&msg,RECIPIENT,touser); SAFECOPY(str,cfg.sub[subnum]->misc&SUB_NAME ? useron.name : useron.alias); smb_hfield_str(&msg,SENDER,str); sprintf(str,"%u",useron.number); smb_hfield_str(&msg,SENDEREXT,str); /* Security logging */ msg_client_hfields(&msg,&client); smb_hfield_str(&msg,SENDERSERVER,startup->host_name); smb_hfield_str(&msg,SUBJECT,title); /* Generate default (RFC822) message-id (always) */ get_msgid(&cfg,subnum,&msg,msg_id,sizeof(msg_id)); smb_hfield_str(&msg,RFC822MSGID,msg_id); /* Generate FTN (FTS-9) MSGID */ if(cfg.sub[subnum]->misc&SUB_FIDO) { ftn_msgid(cfg.sub[subnum],&msg,msg_id,sizeof(msg_id)); smb_hfield_str(&msg,FIDOMSGID,msg_id); } /* Generate FidoNet Program Identifier */ smb_hfield_str(&msg,FIDOPID,msg_program_id(pid)); if(editor!=NULL) smb_hfield_str(&msg,SMB_EDITOR,editor); i=smb_addmsg(&smb,&msg,storage,dupechk_hashes,xlat,(uchar*)msgbuf,NULL); free(msgbuf); if(i==SMB_DUPE_MSG) { attr(cfg.color[clr_err]); bprintf(text[CantPostMsg], smb.last_error); } else if(i!=SMB_SUCCESS) errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); smb_close(&smb); smb_stack(&smb,SMB_STACK_POP); smb_freemsgmem(&msg); if(i!=SMB_SUCCESS) return(false); logon_posts++; user_posted_msg(&cfg, &useron, 1); bprintf(text[Posted],cfg.grp[cfg.sub[subnum]->grp]->sname ,cfg.sub[subnum]->lname); sprintf(str,"%s posted on %s %s" ,useron.alias,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname); logline("P+",str); signal_sub_sem(&cfg,subnum); user_event(EVENT_POST); return(true); }
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); }
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 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); }
int sbbs_t::login(char *username, char *pw) { char str[128]; char tmp[512]; long useron_misc=useron.misc; useron.number=0; #if 0 if(cfg.node_dollars_per_call && noyes(text[AreYouSureQ])) return(LOGIC_FALSE); #endif SAFECOPY(str,username); if(str[0]=='*') { memmove(str,str+1,strlen(str)); qwklogon=1; } else qwklogon=0; if(!(cfg.node_misc&NM_NO_NUM) && isdigit((uchar)str[0])) { useron.number=atoi(str); getuserdat(&cfg,&useron); if(useron.number && useron.misc&(DELETED|INACTIVE)) useron.number=0; } if(!useron.number) { useron.number=matchuser(&cfg,str,FALSE); if(!useron.number && (uchar)str[0]<0x7f && str[1] && isalpha(str[0]) && strchr(str,' ') && cfg.node_misc&NM_LOGON_R) useron.number=userdatdupe(0,U_NAME,LEN_NAME,str); if(useron.number) { getuserdat(&cfg,&useron); if(useron.number && useron.misc&(DELETED|INACTIVE)) useron.number=0; } } if(!useron.number) { if(cfg.node_misc&NM_LOGON_P) { SAFECOPY(useron.alias,str); bputs(pw); console|=CON_R_ECHOX; getstr(str,LEN_PASS*2,K_UPPER|K_LOWPRIO|K_TAB); console&=~(CON_R_ECHOX|CON_L_ECHOX); badlogin(useron.alias, str); bputs(text[InvalidLogon]); /* why does this always fail? */ if(cfg.sys_misc&SM_ECHO_PW) sprintf(tmp,"(%04u) %-25s FAILED Password attempt: '%s'" ,0,useron.alias,str); else sprintf(tmp,"(%04u) %-25s FAILED Password attempt" ,0,useron.alias); logline(LOG_NOTICE,"+!",tmp); } else { bputs(text[UnknownUser]); sprintf(tmp,"Unknown User '%s'",str); logline(LOG_NOTICE,"+!",tmp); } useron.misc=useron_misc; return(LOGIC_FALSE); } if(!online) { useron.number=0; return(LOGIC_FALSE); } if(useron.pass[0] || REALSYSOP) { bputs(pw); console|=CON_R_ECHOX; getstr(str,LEN_PASS*2,K_UPPER|K_LOWPRIO|K_TAB); console&=~(CON_R_ECHOX|CON_L_ECHOX); if(!online) { useron.number=0; return(LOGIC_FALSE); } if(stricmp(useron.pass,str)) { badlogin(useron.alias, str); bputs(text[InvalidLogon]); if(cfg.sys_misc&SM_ECHO_PW) sprintf(tmp,"(%04u) %-25s FAILED Password: '******' Attempt: '%s'" ,useron.number,useron.alias,useron.pass,str); else sprintf(tmp,"(%04u) %-25s FAILED Password attempt" ,useron.number,useron.alias); logline(LOG_NOTICE,"+!",tmp); useron.number=0; useron.misc=useron_misc; return(LOGIC_FALSE); } if(REALSYSOP && !chksyspass()) { bputs(text[InvalidLogon]); useron.number=0; useron.misc=useron_misc; return(LOGIC_FALSE); } } return(LOGIC_TRUE); }