static JSBool js_get_time_left(JSContext *cx, uintN argc, jsval *arglist) { JSObject *obj=JS_THIS_OBJECT(cx, arglist); jsval *argv=JS_ARGV(cx, arglist); private_t* p; int32 start_time=0; jsrefcount rc; scfg_t* scfg; scfg=JS_GetRuntimePrivate(JS_GetRuntime(cx)); JS_SET_RVAL(cx, arglist, JSVAL_VOID); if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) return JS_FALSE; if(argc) { if(!JS_ValueToInt32(cx, argv[0], &start_time)) return JS_FALSE; } rc=JS_SUSPENDREQUEST(cx); js_getuserdat(scfg,p); JS_SET_RVAL(cx, arglist, INT_TO_JSVAL((int32_t)gettimeleft(scfg, p->user, start_time))); JS_RESUMEREQUEST(cx, rc); return JS_TRUE; }
char sbbs_t::getkey(long mode) { char ch,coldkey,c=0,spin=sbbs_random(5); time_t last_telnet_cmd=0; if(!online || !input_thread_running) { YIELD(); // just in case someone is looping on getkey() when they shouldn't return(0); } sys_status&=~SS_ABORT; if((sys_status&SS_USERON || action==NODE_DFLT) && !(mode&(K_GETSTR|K_NOSPIN))) mode|=(useron.misc&SPIN); lncntr=0; timeout=time(NULL); if(mode&K_SPIN) outchar(' '); do { if(sys_status&SS_ABORT) { if(mode&K_SPIN) /* back space once if on spinning cursor */ backspace(); return(0); } if(mode&K_SPIN) { if(useron.misc&NO_EXASCII) { switch(c++) { case 0: outchar(BS); outchar('|'); break; case 1: outchar(BS); outchar('/'); break; case 2: outchar(BS); outchar('-'); break; case 3: outchar(BS); outchar('\\'); c=0; break; } } else { switch(spin) { case 0: switch(c++) { case 0: outchar(BS); outchar('³'); break; case 1: outchar(BS); outchar('/'); break; case 2: outchar(BS); outchar('Ä'); break; case 3: outchar(BS); outchar('\\'); c=0; break; } break; case 1: switch(c++) { case 0: outchar(BS); outchar('°'); break; case 1: outchar(BS); outchar('±'); break; case 2: outchar(BS); outchar('²'); break; case 3: outchar(BS); outchar('Û'); break; case 4: outchar(BS); outchar('²'); break; case 5: outchar(BS); outchar('±'); c=0; break; } break; case 2: switch(c++) { case 0: outchar(BS); outchar('-'); break; case 1: outchar(BS); outchar('='); break; case 2: outchar(BS); outchar('ð'); break; case 3: outchar(BS); outchar('='); c=0; break; } break; case 3: switch(c++) { case 0: outchar(BS); outchar('Ú'); break; case 1: outchar(BS); outchar('À'); break; case 2: outchar(BS); outchar('Ù'); break; case 3: outchar(BS); outchar('¿'); c=0; break; } break; case 4: switch(c++) { case 0: outchar(BS); outchar('Ü'); break; case 1: outchar(BS); outchar('Þ'); break; case 2: outchar(BS); outchar('ß'); break; case 3: outchar(BS); outchar('Ý'); c=0; break; } break; } } } ch=inkey(mode,mode&K_SPIN ? 250:1000); if(sys_status&SS_ABORT) return(0); now=time(NULL); if(ch) { if(mode&K_NUMBER && isprint(ch) && !isdigit(ch)) continue; if(mode&K_ALPHA && isprint(ch) && !isalpha(ch)) continue; if(mode&K_NOEXASC && ch&0x80) continue; if(mode&K_SPIN) backspace(); if(mode&K_COLD && ch>' ' && useron.misc&COLDKEYS) { if(mode&K_UPPER) outchar(toupper(ch)); else outchar(ch); while((coldkey=inkey(mode,1000))==0 && online && !(sys_status&SS_ABORT)) ; backspace(); if(coldkey==BS || coldkey==DEL) continue; if(coldkey>' ') ungetkey(coldkey); } if(mode&K_UPPER) return(toupper(ch)); return(ch); } if(sys_status&SS_USERON && !(sys_status&SS_LCHAT)) gettimeleft(); else if(online && now-answertime>SEC_LOGON && !(sys_status&SS_LCHAT)) { console&=~(CON_R_ECHOX|CON_L_ECHOX); console|=(CON_R_ECHO|CON_L_ECHO); bputs(text[TakenTooLongToLogon]); hangup(); } if(sys_status&SS_USERON && online && (timeleft/60)<(5-timeleft_warn) && !SYSOP && !(sys_status&SS_LCHAT)) { timeleft_warn=5-(timeleft/60); SAVELINE; attr(LIGHTGRAY); bprintf(text[OnlyXminutesLeft] ,((ushort)timeleft/60)+1,(timeleft/60) ? "s" : nulstr); RESTORELINE; } if(!(startup->options&BBS_OPT_NO_TELNET_GA) && now!=last_telnet_cmd && now-timeout>=60 && !((now-timeout)%60)) { // Let's make sure the socket is up // Sending will trigger a socket d/c detection send_telnet_cmd(TELNET_GA,0); last_telnet_cmd=now; } if(online==ON_REMOTE && !(console&CON_NO_INACT) && now-timeout>=cfg.sec_warn) { /* warning */ if(sys_status&SS_USERON && cfg.sec_warn!=cfg.sec_hangup) { SAVELINE; bputs(text[AreYouThere]); } else bputs("\7\7"); while(!inkey(K_NONE,100) && online && now-timeout>=cfg.sec_warn) { now=time(NULL); if(now-timeout>=cfg.sec_hangup) { if(online==ON_REMOTE) { console|=CON_R_ECHO; console&=~CON_R_ECHOX; } bputs(text[CallBackWhenYoureThere]); logline(nulstr,"Inactive"); hangup(); return(0); } } if(sys_status&SS_USERON && cfg.sec_warn!=cfg.sec_hangup) { bputs("\r\1n\1>"); RESTORELINE; } timeout=now; } } while(online); return(0); }
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::spy(uint i /* node_num */) { char ch; char ansi_seq[32]; int ansi_len; int in; if(!i || i>MAX_NODES) { bprintf("Invalid node number: %d\r\n",i); return(false); } if(i==cfg.node_num) { bprintf("Can't spy on yourself.\r\n"); return(false); } if(spy_socket[i-1]!=INVALID_SOCKET) { bprintf("Node %d already being spied (%lx)\r\n",i,spy_socket[i-1]); return(false); } bprintf("*** Synchronet Remote Spy on Node %d: Ctrl-C to Abort ***" "\r\n\r\n",i); spy_socket[i-1]=client_socket; ansi_len=0; while(online && client_socket!=INVALID_SOCKET && spy_socket[i-1]!=INVALID_SOCKET && !msgabort()) { in=incom(1000); if(in==NOINP) { gettimeleft(); continue; } ch=in; if(ch==ESC) { if(!ansi_len) { ansi_seq[ansi_len++]=ch; continue; } ansi_len=0; } if(ansi_len && ansi_len<(int)sizeof(ansi_seq)-2) { if(ansi_len==1) { if(ch=='[') { ansi_seq[ansi_len++]=ch; continue; } ansi_len=0; } if(ch=='R') { /* throw-away cursor position report */ ansi_len=0; continue; } ansi_seq[ansi_len++]=ch; if(isalpha(ch)) { RingBufWrite(node_inbuf[i-1],(uchar*)ansi_seq,ansi_len); ansi_len=0; } continue; } if(ch<' ') { lncntr=0; /* defeat pause */ spy_socket[i-1]=INVALID_SOCKET; /* disable spy output */ ch=handle_ctrlkey(ch,K_NONE); spy_socket[i-1]=client_socket; /* enable spy output */ if(ch==0) continue; } if(node_inbuf[i-1]!=NULL) RingBufWrite(node_inbuf[i-1],(uchar*)&ch,1); } spy_socket[i-1]=INVALID_SOCKET; 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); }
ulong sbbs_t::gettimeleft(bool handle_out_of_time) { char str[128]; char tmp[512]; event_t nextevent; now=time(NULL); timeleft = (ulong)::gettimeleft(&cfg, &useron, starttime); /* Timed event time reduction handler */ event_time=getnextevent(&cfg, &nextevent); if(event_time) event_code=nextevent.code; if(event_time && now+(time_t)timeleft>event_time) { /* less time, set flag */ if(event_time<now) timeleft=0; else timeleft=(ulong)(event_time-now); if(!(sys_status&SS_EVENT)) { lprintf(LOG_NOTICE,"Node %d Time reduced (to %s) due to upcoming event (%s) on %s" ,cfg.node_num,sectostr(timeleft,tmp),event_code,timestr(event_time)); sys_status|=SS_EVENT; } } if((long)timeleft<0) /* timeleft can't go negative */ timeleft=0; if(thisnode.status==NODE_NEWUSER) { timeleft=cfg.level_timepercall[cfg.new_level]; if(timeleft<10*60L) timeleft=10*60L; } if(handle_out_of_time && !gettimeleft_inside) /* The following code is not recursive */ { gettimeleft_inside=1; if(!timeleft && !SYSOP && !(sys_status&SS_LCHAT)) { logline(LOG_NOTICE,nulstr,"Ran out of time"); SAVELINE; if(sys_status&SS_EVENT) bprintf(text[ReducedTime],timestr(event_time)); bputs(text[TimesUp]); if(!(sys_status&(SS_EVENT|SS_USERON)) && useron.cdt>=100L*1024L && !(cfg.sys_misc&SM_NOCDTCVT)) { SAFEPRINTF(tmp,text[Convert100ktoNminQ],cfg.cdt_min_value); if(yesno(tmp)) { logline(" ","Credit to Minute Conversion"); useron.min=adjustuserrec(&cfg,useron.number,U_MIN,10,cfg.cdt_min_value); useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,10,-(102400L)); SAFEPRINTF(str,"Credit Adjustment: %ld",-(102400L)); logline("$-",str); SAFEPRINTF(str,"Minute Adjustment: %u",cfg.cdt_min_value); logline("*+",str); RESTORELINE; gettimeleft(); gettimeleft_inside=0; return timeleft; } } if(cfg.sys_misc&SM_TIME_EXP && !(sys_status&SS_EVENT) && !(useron.exempt&FLAG('E'))) { /* set to expired values */ bputs(text[AccountHasExpired]); SAFEPRINTF(str,"%s Expired",useron.alias); logentry("!%",str); if(cfg.level_misc[useron.level]&LEVEL_EXPTOVAL && cfg.level_expireto[useron.level]<10) { useron.flags1=cfg.val_flags1[cfg.level_expireto[useron.level]]; useron.flags2=cfg.val_flags2[cfg.level_expireto[useron.level]]; useron.flags3=cfg.val_flags3[cfg.level_expireto[useron.level]]; useron.flags4=cfg.val_flags4[cfg.level_expireto[useron.level]]; useron.exempt=cfg.val_exempt[cfg.level_expireto[useron.level]]; useron.rest=cfg.val_rest[cfg.level_expireto[useron.level]]; if(cfg.val_expire[cfg.level_expireto[useron.level]]) useron.expire=(time32_t)now +(cfg.val_expire[cfg.level_expireto[useron.level]]*24*60*60); else useron.expire=0; useron.level=cfg.val_level[cfg.level_expireto[useron.level]]; } else { if(cfg.level_misc[useron.level]&LEVEL_EXPTOLVL) useron.level=cfg.level_expireto[useron.level]; else useron.level=cfg.expired_level; useron.flags1&=~cfg.expired_flags1; /* expired status */ useron.flags2&=~cfg.expired_flags2; /* expired status */ useron.flags3&=~cfg.expired_flags3; /* expired status */ useron.flags4&=~cfg.expired_flags4; /* expired status */ useron.exempt&=~cfg.expired_exempt; useron.rest|=cfg.expired_rest; useron.expire=0; } putuserrec(&cfg,useron.number,U_LEVEL,2,ultoa(useron.level,str,10)); putuserrec(&cfg,useron.number,U_FLAGS1,8,ultoa(useron.flags1,str,16)); putuserrec(&cfg,useron.number,U_FLAGS2,8,ultoa(useron.flags2,str,16)); putuserrec(&cfg,useron.number,U_FLAGS3,8,ultoa(useron.flags3,str,16)); putuserrec(&cfg,useron.number,U_FLAGS4,8,ultoa(useron.flags4,str,16)); putuserrec(&cfg,useron.number,U_EXPIRE,8,ultoa((ulong)useron.expire,str,16)); putuserrec(&cfg,useron.number,U_EXEMPT,8,ultoa(useron.exempt,str,16)); putuserrec(&cfg,useron.number,U_REST,8,ultoa(useron.rest,str,16)); if(cfg.expire_mod[0]) exec_bin(cfg.expire_mod,&main_csi); RESTORELINE; gettimeleft(); gettimeleft_inside=0; return timeleft; } SYNC; hangup(); } gettimeleft_inside=0; } return timeleft; }
void sbbs_t::telnet_gate(char* destaddr, ulong mode, char* client_user_name, char* server_user_name, char* term_type) { char* p; uchar buf[512]; int i; int rd; uint attempts; ulong l; bool gotline; ushort port; ulong ip_addr; ulong save_console; SOCKET remote_socket; SOCKADDR_IN addr; if(mode&TG_RLOGIN) port=513; else port=IPPORT_TELNET; p=strchr(destaddr,':'); if(p!=NULL) { *p=0; port=atoi(p+1); } ip_addr=resolve_ip(destaddr); if(ip_addr==INADDR_NONE) { lprintf(LOG_NOTICE,"!TELGATE Failed to resolve address: %s",destaddr); bprintf("!Failed to resolve address: %s\r\n",destaddr); return; } if((remote_socket = open_socket(SOCK_STREAM, client.protocol)) == INVALID_SOCKET) { errormsg(WHERE,ERR_OPEN,"socket",0); return; } memset(&addr,0,sizeof(addr)); addr.sin_addr.s_addr = htonl(startup->telnet_interface); addr.sin_family = AF_INET; if((i=bind(remote_socket, (struct sockaddr *) &addr, sizeof (addr)))!=0) { lprintf(LOG_NOTICE,"!TELGATE ERROR %d (%d) binding to socket %d",i, ERROR_VALUE, remote_socket); bprintf("!ERROR %d (%d) binding to socket\r\n",i, ERROR_VALUE); close_socket(remote_socket); return; } memset(&addr,0,sizeof(addr)); addr.sin_addr.s_addr = ip_addr; addr.sin_family = AF_INET; addr.sin_port = htons(port); if((i=connect(remote_socket, (struct sockaddr *)&addr, sizeof(addr)))!=0) { lprintf(LOG_NOTICE,"!TELGATE ERROR %d (%d) connecting to server: %s" ,i,ERROR_VALUE, destaddr); bprintf("!ERROR %d (%d) connecting to server: %s\r\n" ,i,ERROR_VALUE, destaddr); close_socket(remote_socket); return; } l=1; if((i = ioctlsocket(remote_socket, FIONBIO, &l))!=0) { lprintf(LOG_NOTICE,"!TELGATE ERROR %d (%d) disabling socket blocking" ,i, ERROR_VALUE); close_socket(remote_socket); return; } lprintf(LOG_INFO,"Node %d %s gate to %s port %u on socket %d" ,cfg.node_num ,mode&TG_RLOGIN ? "RLogin" : "Telnet" ,destaddr,port,remote_socket); if(!(mode&TG_CTRLKEYS)) console|=CON_RAW_IN; if(mode&TG_RLOGIN) { p=(char*)buf; *(p++)=0; p+=sprintf(p,"%s",client_user_name==NULL ? useron.alias : client_user_name); p++; // Add NULL p+=sprintf(p,"%s",server_user_name==NULL ? useron.name : server_user_name); p++; // Add NULL if(term_type!=NULL) p+=sprintf(p,"%s",term_type); else p+=sprintf(p,"%s/%u",terminal, cur_rate); p++; // Add NULL l=p-(char*)buf; sendsocket(remote_socket,(char*)buf,l); mode|=TG_NOLF; /* Send LF (to remote host) when Telnet client sends CRLF (when not in binary mode) */ } /* This is required for gating to Unix telnetd */ if(mode&TG_NOTERMTYPE) request_telnet_opt(TELNET_DONT,TELNET_TERM_TYPE, 3000); // Re-negotiation of terminal type /* Text/NVT mode by default */ request_telnet_opt(TELNET_DONT,TELNET_BINARY_TX, 3000); if(!(telnet_mode&TELNET_MODE_OFF) && (mode&TG_PASSTHRU)) telnet_mode|=TELNET_MODE_GATE; // Pass-through telnet commands while(online) { if(!(mode&TG_NOCHKTIME)) gettimeleft(); rd=RingBufRead(&inbuf,buf,sizeof(buf)); if(rd) { #if 0 if(memchr(buf,TELNET_IAC,rd)) { char dump[2048]; dump[0]; p=dump; for(int i=0;i<rd;i++) p+=sprintf(p,"%u ",buf[i]); lprintf(LOG_DEBUG,"Node %d Telnet cmd from client: %s", cfg.node_num, dump); } #endif if(telnet_remote_option[TELNET_BINARY_TX]!=TELNET_WILL) { if(*buf==0x1d) { // ^] save_console=console; console&=~CON_RAW_IN; // Allow Ctrl-U/Ctrl-P CRLF; while(online) { SYNC; mnemonics("\1n\r\n\1h\1bTelnet Gate: \1y~D\1wisconnect, " "\1y~E\1wcho toggle, \1y~L\1wist Users, \1y~P\1wrivate message, " "\1y~Q\1wuit: "); switch(getkeys("DELPQ",0)) { case 'D': closesocket(remote_socket); break; case 'E': mode^=TG_ECHO; bprintf(text[EchoIsNow] ,mode&TG_ECHO ? text[ON]:text[OFF]); continue; case 'L': whos_online(true); continue; case 'P': nodemsg(); continue; } break; } attr(LIGHTGRAY); console=save_console; } else if(*buf<' ' && (mode&TG_CTRLKEYS)) handle_ctrlkey(*buf, K_NONE); gotline=false; if((mode&TG_LINEMODE) && buf[0]!='\r') { ungetkey(buf[0]); l=K_CHAT; if(!(mode&TG_ECHO)) l|=K_NOECHO; rd=getstr((char*)buf,sizeof(buf)-1,l); if(!rd) continue; strcat((char*)buf,crlf); rd+=2; gotline=true; } if((mode&TG_CRLF) && buf[rd-1]=='\r') buf[rd++]='\n'; else if((mode&TG_NOLF) && buf[rd-1]=='\n') rd--; if(!gotline && (mode&TG_ECHO) && rd) { RingBufWrite(&outbuf,buf,rd); } } /* Not Telnet Binary mode */ if(rd > 0) { for(attempts=0;attempts<60 && online; attempts++) /* added retry loop here, Jan-20-2003 */ { if((i=sendsocket(remote_socket,(char*)buf,rd))>=0) break; if(ERROR_VALUE!=EWOULDBLOCK) break; mswait(500); } if(i<0) { lprintf(LOG_NOTICE,"!TELGATE ERROR %d sending on socket %d",ERROR_VALUE,remote_socket); break; } } } rd=recv(remote_socket,(char*)buf,sizeof(buf),0); if(rd<0) { if(ERROR_VALUE==EWOULDBLOCK) { if(mode&TG_NODESYNC) { SYNC; } else { // Check if the node has been interrupted getnodedat(cfg.node_num,&thisnode,0); if(thisnode.misc&NODE_INTR) break; } YIELD(); continue; } lprintf(LOG_NOTICE,"!TELGATE ERROR %d receiving on socket %d",ERROR_VALUE,remote_socket); break; } if(!rd) { lprintf(LOG_INFO,"Node %d Telnet gate disconnected",cfg.node_num); break; } #if 0 if(memchr(buf,TELNET_IAC,rd)) { char dump[2048]; dump[0]; p=dump; for(int i=0;i<rd;i++) p+=sprintf(p,"%u ",buf[i]); lprintf(LOG_DEBUG,"Node %d Telnet cmd from server: %s", cfg.node_num, dump); } #endif RingBufWrite(&outbuf,buf,rd); } console&=~CON_RAW_IN; telnet_mode&=~TELNET_MODE_GATE; /* Disable Telnet Terminal Echo */ request_telnet_opt(TELNET_WILL,TELNET_ECHO); close_socket(remote_socket); lprintf(LOG_INFO,"Node %d Telnet gate to %s finished",cfg.node_num,destaddr); }
const char* sbbs_t::atcode(char* sp, char* str, size_t maxlen) { char* tp; uint i; uint ugrp; uint usub; long l; stats_t stats; node_t node; struct tm tm; str[0]=0; if(!strcmp(sp,"VER")) return(VERSION); if(!strcmp(sp,"REV")) { safe_snprintf(str,maxlen,"%c",REVISION); return(str); } if(!strcmp(sp,"FULL_VER")) { safe_snprintf(str,maxlen,"%s%c%s",VERSION,REVISION,beta_version); truncsp(str); #if defined(_DEBUG) strcat(str," Debug"); #endif return(str); } if(!strcmp(sp,"VER_NOTICE")) return(VERSION_NOTICE); if(!strcmp(sp,"OS_VER")) return(os_version(str)); #ifdef JAVASCRIPT if(!strcmp(sp,"JS_VER")) return((char *)JS_GetImplementationVersion()); #endif if(!strcmp(sp,"PLATFORM")) return(PLATFORM_DESC); if(!strcmp(sp,"COPYRIGHT")) return(COPYRIGHT_NOTICE); if(!strcmp(sp,"COMPILER")) { DESCRIBE_COMPILER(str); return(str); } if(!strcmp(sp,"UPTIME")) { extern volatile time_t uptime; time_t up=time(NULL)-uptime; if(up<0) up=0; char days[64]=""; if((up/(24*60*60))>=2) { sprintf(days,"%lu days ",(ulong)(up/(24L*60L*60L))); up%=(24*60*60); } safe_snprintf(str,maxlen,"%s%lu:%02lu" ,days ,(ulong)(up/(60L*60L)) ,(ulong)((up/60L)%60L) ); return(str); } if(!strcmp(sp,"SERVED")) { extern volatile ulong served; safe_snprintf(str,maxlen,"%lu",served); return(str); } if(!strcmp(sp,"SOCKET_LIB")) return(socklib_version(str,SOCKLIB_DESC)); if(!strcmp(sp,"MSG_LIB")) { safe_snprintf(str,maxlen,"SMBLIB %s",smb_lib_ver()); return(str); } if(!strcmp(sp,"BBS") || !strcmp(sp,"BOARDNAME")) return(cfg.sys_name); if(!strcmp(sp,"BAUD") || !strcmp(sp,"BPS")) { safe_snprintf(str,maxlen,"%lu",cur_rate); return(str); } if(!strcmp(sp,"CONN")) return(connection); if(!strcmp(sp,"SYSOP")) return(cfg.sys_op); if(!strcmp(sp,"LOCATION")) return(cfg.sys_location); if(!strcmp(sp,"NODE")) { safe_snprintf(str,maxlen,"%u",cfg.node_num); return(str); } if(!strcmp(sp,"TNODE")) { safe_snprintf(str,maxlen,"%u",cfg.sys_nodes); return(str); } if(!strcmp(sp,"INETADDR")) return(cfg.sys_inetaddr); if(!strcmp(sp,"HOSTNAME")) return(startup->host_name); if(!strcmp(sp,"FIDOADDR")) { if(cfg.total_faddrs) return(smb_faddrtoa(&cfg.faddr[0],str)); return(nulstr); } if(!strcmp(sp,"EMAILADDR")) return(usermailaddr(&cfg, str ,cfg.inetmail_misc&NMAIL_ALIAS ? useron.alias : useron.name)); if(!strcmp(sp,"QWKID")) return(cfg.sys_id); if(!strcmp(sp,"TIME") || !strcmp(sp,"SYSTIME")) { now=time(NULL); memset(&tm,0,sizeof(tm)); localtime_r(&now,&tm); if(cfg.sys_misc&SM_MILITARY) safe_snprintf(str,maxlen,"%02d:%02d:%02d" ,tm.tm_hour,tm.tm_min,tm.tm_sec); else safe_snprintf(str,maxlen,"%02d:%02d %s" ,tm.tm_hour==0 ? 12 : tm.tm_hour>12 ? tm.tm_hour-12 : tm.tm_hour, tm.tm_min, tm.tm_hour>11 ? "pm":"am"); return(str); } if(!strcmp(sp,"TIMEZONE")) return(smb_zonestr(sys_timezone(&cfg),str)); if(!strcmp(sp,"DATE") || !strcmp(sp,"SYSDATE")) { return(unixtodstr(&cfg,time32(NULL),str)); } if(!strcmp(sp,"DATETIME")) return(timestr(time(NULL))); if(!strcmp(sp,"TMSG")) { l=0; for(i=0;i<cfg.total_subs;i++) l+=getposts(&cfg,i); /* l=total posts */ safe_snprintf(str,maxlen,"%lu",l); return(str); } if(!strcmp(sp,"TUSER")) { safe_snprintf(str,maxlen,"%u",total_users(&cfg)); return(str); } if(!strcmp(sp,"TFILE")) { l=0; for(i=0;i<cfg.total_dirs;i++) l+=getfiles(&cfg,i); safe_snprintf(str,maxlen,"%lu",l); return(str); } if(!strcmp(sp,"TCALLS") || !strcmp(sp,"NUMCALLS")) { getstats(&cfg,0,&stats); safe_snprintf(str,maxlen,"%lu",stats.logons); return(str); } if(!strcmp(sp,"PREVON") || !strcmp(sp,"LASTCALLERNODE") || !strcmp(sp,"LASTCALLERSYSTEM")) return(lastuseron); if(!strcmp(sp,"CLS")) { CLS; return(nulstr); } if(!strcmp(sp,"PAUSE") || !strcmp(sp,"MORE")) { pause(); return(nulstr); } if(!strcmp(sp,"RESETPAUSE")) { lncntr=0; return(nulstr); } if(!strcmp(sp,"NOPAUSE") || !strcmp(sp,"POFF")) { sys_status^=SS_PAUSEOFF; return(nulstr); } if(!strcmp(sp,"PON") || !strcmp(sp,"AUTOMORE")) { sys_status^=SS_PAUSEON; return(nulstr); } /* NOSTOP */ /* STOP */ if(!strcmp(sp,"BELL") || !strcmp(sp,"BEEP")) return("\a"); if(!strcmp(sp,"EVENT")) { if(event_time==0) return("<none>"); return(timestr(event_time)); } /* LASTCALL */ if(!strncmp(sp,"NODE",4)) { i=atoi(sp+4); if(i && i<=cfg.sys_nodes) { getnodedat(i,&node,0); printnodedat(i,&node); } return(nulstr); } if(!strcmp(sp,"WHO")) { whos_online(true); return(nulstr); } /* User Codes */ if(!strcmp(sp,"USER") || !strcmp(sp,"ALIAS") || !strcmp(sp,"NAME")) return(useron.alias); if(!strcmp(sp,"FIRST")) { safe_snprintf(str,maxlen,"%s",useron.alias); tp=strchr(str,' '); if(tp) *tp=0; return(str); } if(!strcmp(sp,"USERNUM")) { safe_snprintf(str,maxlen,"%u",useron.number); return(str); } if(!strcmp(sp,"PHONE") || !strcmp(sp,"HOMEPHONE") || !strcmp(sp,"DATAPHONE") || !strcmp(sp,"DATA")) return(useron.phone); if(!strcmp(sp,"ADDR1")) return(useron.address); if(!strcmp(sp,"FROM")) return(useron.location); if(!strcmp(sp,"CITY")) { safe_snprintf(str,maxlen,"%s",useron.location); char* p=strchr(str,','); if(p) { *p=0; return(str); } return(nulstr); } if(!strcmp(sp,"STATE")) { char* p=strchr(useron.location,','); if(p) { p++; if(*p==' ') p++; return(p); } return(nulstr); } if(!strcmp(sp,"CPU")) return(useron.comp); if(!strcmp(sp,"HOST")) return(client_name); if(!strcmp(sp,"BDATE")) return(useron.birth); if(!strcmp(sp,"AGE")) { safe_snprintf(str,maxlen,"%u",getage(&cfg,useron.birth)); return(str); } if(!strcmp(sp,"CALLS") || !strcmp(sp,"NUMTIMESON")) { safe_snprintf(str,maxlen,"%u",useron.logons); return(str); } if(!strcmp(sp,"MEMO")) return(unixtodstr(&cfg,useron.pwmod,str)); if(!strcmp(sp,"SEC") || !strcmp(sp,"SECURITY")) { safe_snprintf(str,maxlen,"%u",useron.level); return(str); } if(!strcmp(sp,"SINCE")) return(unixtodstr(&cfg,useron.firston,str)); if(!strcmp(sp,"TIMEON") || !strcmp(sp,"TIMEUSED")) { now=time(NULL); safe_snprintf(str,maxlen,"%lu",(ulong)(now-logontime)/60L); return(str); } if(!strcmp(sp,"TUSED")) { /* Synchronet only */ now=time(NULL); return(sectostr((uint)(now-logontime),str)+1); } if(!strcmp(sp,"TLEFT")) { /* Synchronet only */ gettimeleft(); return(sectostr(timeleft,str)+1); } if(!strcmp(sp,"TPERD")) /* Synchronet only */ return(sectostr(cfg.level_timeperday[useron.level],str)+1); if(!strcmp(sp,"TPERC")) /* Synchronet only */ return(sectostr(cfg.level_timepercall[useron.level],str)+1); if(!strcmp(sp,"TIMELIMIT")) { safe_snprintf(str,maxlen,"%u",cfg.level_timepercall[useron.level]); return(str); } if(!strcmp(sp,"MINLEFT") || !strcmp(sp,"LEFT") || !strcmp(sp,"TIMELEFT")) { gettimeleft(); safe_snprintf(str,maxlen,"%lu",timeleft/60); return(str); } if(!strcmp(sp,"LASTON")) return(timestr(useron.laston)); if(!strcmp(sp,"LASTDATEON")) return(unixtodstr(&cfg,useron.laston,str)); if(!strcmp(sp,"LASTTIMEON")) { memset(&tm,0,sizeof(tm)); localtime32(&useron.laston,&tm); if(cfg.sys_misc&SM_MILITARY) safe_snprintf(str,maxlen,"%02d:%02d:%02d" ,tm.tm_hour, tm.tm_min, tm.tm_sec); else safe_snprintf(str,maxlen,"%02d:%02d %s" ,tm.tm_hour==0 ? 12 : tm.tm_hour>12 ? tm.tm_hour-12 : tm.tm_hour, tm.tm_min, tm.tm_hour>11 ? "pm":"am"); return(str); } if(!strcmp(sp,"MSGLEFT") || !strcmp(sp,"MSGSLEFT")) { safe_snprintf(str,maxlen,"%u",useron.posts); return(str); } if(!strcmp(sp,"MSGREAD")) { safe_snprintf(str,maxlen,"%lu",posts_read); return(str); } if(!strcmp(sp,"FREESPACE")) { safe_snprintf(str,maxlen,"%lu",getfreediskspace(cfg.temp_dir,0)); return(str); } if(!strcmp(sp,"FREESPACEK")) { safe_snprintf(str,maxlen,"%lu",getfreediskspace(cfg.temp_dir,1024)); return(str); } if(!strcmp(sp,"UPBYTES")) { safe_snprintf(str,maxlen,"%lu",useron.ulb); return(str); } if(!strcmp(sp,"UPK")) { safe_snprintf(str,maxlen,"%lu",useron.ulb/1024L); return(str); } if(!strcmp(sp,"UPS") || !strcmp(sp,"UPFILES")) { safe_snprintf(str,maxlen,"%u",useron.uls); return(str); } if(!strcmp(sp,"DLBYTES")) { safe_snprintf(str,maxlen,"%lu",useron.dlb); return(str); } if(!strcmp(sp,"DOWNK")) { safe_snprintf(str,maxlen,"%lu",useron.dlb/1024L); return(str); } if(!strcmp(sp,"DOWNS") || !strcmp(sp,"DLFILES")) { safe_snprintf(str,maxlen,"%u",useron.dls); return(str); } if(!strcmp(sp,"LASTNEW")) return(unixtodstr(&cfg,(time32_t)ns_time,str)); if(!strcmp(sp,"NEWFILETIME")) return(timestr(ns_time)); /* MAXDL */ if(!strcmp(sp,"MAXDK") || !strcmp(sp,"DLKLIMIT") || !strcmp(sp,"KBLIMIT")) { safe_snprintf(str,maxlen,"%lu",cfg.level_freecdtperday[useron.level]/1024L); return(str); } if(!strcmp(sp,"DAYBYTES")) { /* amt of free cdts used today */ safe_snprintf(str,maxlen,"%lu",cfg.level_freecdtperday[useron.level]-useron.freecdt); return(str); } if(!strcmp(sp,"BYTELIMIT")) { safe_snprintf(str,maxlen,"%lu",cfg.level_freecdtperday[useron.level]); return(str); } if(!strcmp(sp,"KBLEFT")) { safe_snprintf(str,maxlen,"%lu",(useron.cdt+useron.freecdt)/1024L); return(str); } if(!strcmp(sp,"BYTESLEFT")) { safe_snprintf(str,maxlen,"%lu",useron.cdt+useron.freecdt); return(str); } if(!strcmp(sp,"CONF")) { safe_snprintf(str,maxlen,"%s %s" ,usrgrps ? cfg.grp[usrgrp[curgrp]]->sname :nulstr ,usrgrps ? cfg.sub[usrsub[curgrp][cursub[curgrp]]]->sname : nulstr); return(str); } if(!strcmp(sp,"CONFNUM")) { safe_snprintf(str,maxlen,"%u %u",curgrp+1,cursub[curgrp]+1); return(str); } if(!strcmp(sp,"NUMDIR")) { safe_snprintf(str,maxlen,"%u %u",usrlibs ? curlib+1 : 0,usrlibs ? curdir[curlib]+1 : 0); return(str); } if(!strcmp(sp,"EXDATE") || !strcmp(sp,"EXPDATE")) return(unixtodstr(&cfg,useron.expire,str)); if(!strcmp(sp,"EXPDAYS")) { now=time(NULL); l=(long)(useron.expire-now); if(l<0) l=0; safe_snprintf(str,maxlen,"%lu",l/(1440L*60L)); return(str); } if(!strcmp(sp,"MEMO1")) return(useron.note); if(!strcmp(sp,"MEMO2") || !strcmp(sp,"COMPANY")) return(useron.name); if(!strcmp(sp,"ZIP")) return(useron.zipcode); if(!strcmp(sp,"HANGUP")) { hangup(); return(nulstr); } /* Synchronet Specific */ if(!strncmp(sp,"SETSTR:",7)) { strcpy(main_csi.str,sp+7); return(nulstr); } if(!strncmp(sp,"EXEC:",5)) { exec_bin(sp+5,&main_csi); return(nulstr); } if(!strncmp(sp,"EXEC_XTRN:",10)) { for(i=0;i<cfg.total_xtrns;i++) if(!stricmp(cfg.xtrn[i]->code,sp+10)) break; if(i<cfg.total_xtrns) exec_xtrn(i); return(nulstr); } if(!strncmp(sp,"MENU:",5)) { menu(sp+5); return(nulstr); } if(!strncmp(sp,"TYPE:",5)) { printfile(cmdstr(sp+5,nulstr,nulstr,str),0); return(nulstr); } if(!strncmp(sp,"INCLUDE:",8)) { printfile(cmdstr(sp+8,nulstr,nulstr,str),P_NOCRLF|P_SAVEATR); return(nulstr); } if(!strcmp(sp,"QUESTION")) return(question); if(!strcmp(sp,"HANDLE")) return(useron.handle); if(!strcmp(sp,"CID") || !strcmp(sp,"IP")) return(cid); if(!strcmp(sp,"LOCAL-IP")) return(local_addr); if(!strcmp(sp,"CRLF")) return("\r\n"); if(!strcmp(sp,"PUSHXY")) { ansi_save(); return(nulstr); } if(!strcmp(sp,"POPXY")) { ansi_restore(); return(nulstr); } if(!strncmp(sp,"UP:",3)) { cursor_up(atoi(sp+3)); return(str); } if(!strncmp(sp,"DOWN:",5)) { cursor_down(atoi(sp+5)); return(str); } if(!strncmp(sp,"LEFT:",5)) { cursor_left(atoi(sp+5)); return(str); } if(!strncmp(sp,"RIGHT:",6)) { cursor_right(atoi(sp+6)); return(str); } if(!strncmp(sp,"GOTOXY:",7)) { tp=strchr(sp,','); if(tp!=NULL) { tp++; ansi_gotoxy(atoi(sp+7),atoi(tp)); } return(nulstr); } if(!strcmp(sp,"GRP")) { if(SMB_IS_OPEN(&smb)) { if(smb.subnum==INVALID_SUB) return("Local"); if(smb.subnum<cfg.total_subs) return(cfg.grp[cfg.sub[smb.subnum]->grp]->sname); } return(usrgrps ? cfg.grp[usrgrp[curgrp]]->sname : nulstr); } if(!strcmp(sp,"GRPL")) { if(SMB_IS_OPEN(&smb)) { if(smb.subnum==INVALID_SUB) return("Local"); if(smb.subnum<cfg.total_subs) return(cfg.grp[cfg.sub[smb.subnum]->grp]->lname); } return(usrgrps ? cfg.grp[usrgrp[curgrp]]->lname : nulstr); } if(!strcmp(sp,"GN")) { if(SMB_IS_OPEN(&smb)) ugrp=getusrgrp(smb.subnum); else ugrp=usrgrps ? curgrp+1 : 0; safe_snprintf(str,maxlen,"%u",ugrp); return(str); } if(!strcmp(sp,"GL")) { if(SMB_IS_OPEN(&smb)) ugrp=getusrgrp(smb.subnum); else ugrp=usrgrps ? curgrp+1 : 0; safe_snprintf(str,maxlen,"%-4u",ugrp); return(str); } if(!strcmp(sp,"GR")) { if(SMB_IS_OPEN(&smb)) ugrp=getusrgrp(smb.subnum); else ugrp=usrgrps ? curgrp+1 : 0; safe_snprintf(str,maxlen,"%4u",ugrp); return(str); } if(!strcmp(sp,"SUB")) { if(SMB_IS_OPEN(&smb)) { if(smb.subnum==INVALID_SUB) return("Mail"); else if(smb.subnum<cfg.total_subs) return(cfg.sub[smb.subnum]->sname); } return(usrgrps ? cfg.sub[usrsub[curgrp][cursub[curgrp]]]->sname : nulstr); } if(!strcmp(sp,"SUBL")) { if(SMB_IS_OPEN(&smb)) { if(smb.subnum==INVALID_SUB) return("Mail"); else if(smb.subnum<cfg.total_subs) return(cfg.sub[smb.subnum]->lname); } return(usrgrps ? cfg.sub[usrsub[curgrp][cursub[curgrp]]]->lname : nulstr); } if(!strcmp(sp,"SN")) { if(SMB_IS_OPEN(&smb)) usub=getusrsub(smb.subnum); else usub=usrgrps ? cursub[curgrp]+1 : 0; safe_snprintf(str,maxlen,"%u",usub); return(str); } if(!strcmp(sp,"SL")) { if(SMB_IS_OPEN(&smb)) usub=getusrsub(smb.subnum); else usub=usrgrps ? cursub[curgrp]+1 : 0; safe_snprintf(str,maxlen,"%-4u",usub); return(str); } if(!strcmp(sp,"SR")) { if(SMB_IS_OPEN(&smb)) usub=getusrsub(smb.subnum); else usub=usrgrps ? cursub[curgrp]+1 : 0; safe_snprintf(str,maxlen,"%4u",usub); return(str); } if(!strcmp(sp,"LIB")) return(usrlibs ? cfg.lib[usrlib[curlib]]->sname : nulstr); if(!strcmp(sp,"LIBL")) return(usrlibs ? cfg.lib[usrlib[curlib]]->lname : nulstr); if(!strcmp(sp,"LN")) { safe_snprintf(str,maxlen,"%u",usrlibs ? curlib+1 : 0); return(str); } if(!strcmp(sp,"LL")) { safe_snprintf(str,maxlen,"%-4u",usrlibs ? curlib+1 : 0); return(str); } if(!strcmp(sp,"LR")) { safe_snprintf(str,maxlen,"%4u",usrlibs ? curlib+1 : 0); return(str); } if(!strcmp(sp,"DIR")) return(usrlibs ? cfg.dir[usrdir[curlib][curdir[curlib]]]->sname :nulstr); if(!strcmp(sp,"DIRL")) return(usrlibs ? cfg.dir[usrdir[curlib][curdir[curlib]]]->lname : nulstr); if(!strcmp(sp,"DN")) { safe_snprintf(str,maxlen,"%u",usrlibs ? curdir[curlib]+1 : 0); return(str); } if(!strcmp(sp,"DL")) { safe_snprintf(str,maxlen,"%-4u",usrlibs ? curdir[curlib]+1 : 0); return(str); } if(!strcmp(sp,"DR")) { safe_snprintf(str,maxlen,"%4u",usrlibs ? curdir[curlib]+1 : 0); return(str); } if(!strcmp(sp,"NOACCESS")) { if(noaccess_str==text[NoAccessTime]) safe_snprintf(str,maxlen,noaccess_str,noaccess_val/60,noaccess_val%60); else if(noaccess_str==text[NoAccessDay]) safe_snprintf(str,maxlen,noaccess_str,wday[noaccess_val]); else safe_snprintf(str,maxlen,noaccess_str,noaccess_val); return(str); } if(!strcmp(sp,"LAST")) { tp=strrchr(useron.alias,' '); if(tp) tp++; else tp=useron.alias; return(tp); } if(!strcmp(sp,"REAL") || !strcmp(sp,"FIRSTREAL")) { safe_snprintf(str,maxlen,"%s",useron.name); tp=strchr(str,' '); if(tp) *tp=0; return(str); } if(!strcmp(sp,"LASTREAL")) { tp=strrchr(useron.name,' '); if(tp) tp++; else tp=useron.name; return(tp); } if(!strcmp(sp,"MAILW")) { safe_snprintf(str,maxlen,"%u",getmail(&cfg,useron.number,0)); return(str); } if(!strcmp(sp,"MAILP")) { safe_snprintf(str,maxlen,"%u",getmail(&cfg,useron.number,1)); return(str); } if(!strncmp(sp,"MAILW:",6)) { safe_snprintf(str,maxlen,"%u",getmail(&cfg,atoi(sp+6),0)); return(str); } if(!strncmp(sp,"MAILP:",6)) { safe_snprintf(str,maxlen,"%u",getmail(&cfg,atoi(sp+6),1)); return(str); } if(!strcmp(sp,"MSGREPLY")) { safe_snprintf(str,maxlen,"%c",cfg.sys_misc&SM_RA_EMU ? 'R' : 'A'); return(str); } if(!strcmp(sp,"MSGREREAD")) { safe_snprintf(str,maxlen,"%c",cfg.sys_misc&SM_RA_EMU ? 'A' : 'R'); return(str); } if(!strncmp(sp,"STATS.",6)) { getstats(&cfg,0,&stats); sp+=6; if(!strcmp(sp,"LOGONS")) safe_snprintf(str,maxlen,"%lu",stats.logons); else if(!strcmp(sp,"LTODAY")) safe_snprintf(str,maxlen,"%lu",stats.ltoday); else if(!strcmp(sp,"TIMEON")) safe_snprintf(str,maxlen,"%lu",stats.timeon); else if(!strcmp(sp,"TTODAY")) safe_snprintf(str,maxlen,"%lu",stats.ttoday); else if(!strcmp(sp,"ULS")) safe_snprintf(str,maxlen,"%lu",stats.uls); else if(!strcmp(sp,"ULB")) safe_snprintf(str,maxlen,"%lu",stats.ulb); else if(!strcmp(sp,"DLS")) safe_snprintf(str,maxlen,"%lu",stats.dls); else if(!strcmp(sp,"DLB")) safe_snprintf(str,maxlen,"%lu",stats.dlb); else if(!strcmp(sp,"PTODAY")) safe_snprintf(str,maxlen,"%lu",stats.ptoday); else if(!strcmp(sp,"ETODAY")) safe_snprintf(str,maxlen,"%lu",stats.etoday); else if(!strcmp(sp,"FTODAY")) safe_snprintf(str,maxlen,"%lu",stats.ftoday); else if(!strcmp(sp,"NUSERS")) safe_snprintf(str,maxlen,"%u",stats.nusers); return(str); } /* Message header codes */ if(!strcmp(sp,"MSG_TO") && current_msg!=NULL) { if(current_msg->to==NULL) return(nulstr); if(current_msg->to_ext!=NULL) safe_snprintf(str,maxlen,"%s #%s",current_msg->to,current_msg->to_ext); else if(current_msg->to_net.type!=NET_NONE) { char tmp[128]; safe_snprintf(str,maxlen,"%s (%s)",current_msg->to ,smb_netaddrstr(¤t_msg->to_net,tmp)); } else return(current_msg->to); return(str); } if(!strcmp(sp,"MSG_TO_NAME") && current_msg!=NULL) return(current_msg->to==NULL ? nulstr : current_msg->to); if(!strcmp(sp,"MSG_TO_EXT") && current_msg!=NULL) { if(current_msg->to_ext==NULL) return(nulstr); return(current_msg->to_ext); } if(!strcmp(sp,"MSG_TO_NET") && current_msg!=NULL) return(smb_netaddrstr(¤t_msg->to_net,str)); if(!strcmp(sp,"MSG_FROM") && current_msg!=NULL) { if(current_msg->from==NULL) return(nulstr); if(current_msg->hdr.attr&MSG_ANONYMOUS && !SYSOP) return(text[Anonymous]); if(current_msg->from_ext!=NULL) safe_snprintf(str,maxlen,"%s #%s",current_msg->from,current_msg->from_ext); else if(current_msg->from_net.type!=NET_NONE) { char tmp[128]; safe_snprintf(str,maxlen,"%s (%s)",current_msg->from ,smb_netaddrstr(¤t_msg->from_net,tmp)); } else return(current_msg->from); return(str); } if(!strcmp(sp,"MSG_FROM_NAME") && current_msg!=NULL) { if(current_msg->from==NULL) return(nulstr); if(current_msg->hdr.attr&MSG_ANONYMOUS && !SYSOP) return(text[Anonymous]); return(current_msg->from); } if(!strcmp(sp,"MSG_FROM_EXT") && current_msg!=NULL) { if(!(current_msg->hdr.attr&MSG_ANONYMOUS) || SYSOP) if(current_msg->from_ext!=NULL) return(current_msg->from_ext); return(nulstr); } if(!strcmp(sp,"MSG_FROM_NET") && current_msg!=NULL) { if(current_msg->from_net.type!=NET_NONE && (!(current_msg->hdr.attr&MSG_ANONYMOUS) || SYSOP)) return(smb_netaddrstr(¤t_msg->from_net,str)); return(nulstr); } if(!strcmp(sp,"MSG_SUBJECT") && current_msg!=NULL) return(current_msg->subj==NULL ? nulstr : current_msg->subj); if(!strcmp(sp,"MSG_DATE") && current_msg!=NULL) return(timestr(current_msg->hdr.when_written.time)); if(!strcmp(sp,"MSG_TIMEZONE") && current_msg!=NULL) return(smb_zonestr(current_msg->hdr.when_written.zone,NULL)); if(!strcmp(sp,"MSG_ATTR") && current_msg!=NULL) { safe_snprintf(str,maxlen,"%s%s%s%s%s%s%s%s%s%s%s" ,current_msg->hdr.attr&MSG_PRIVATE ? "Private " :nulstr ,current_msg->hdr.attr&MSG_READ ? "Read " :nulstr ,current_msg->hdr.attr&MSG_DELETE ? "Deleted " :nulstr ,current_msg->hdr.attr&MSG_KILLREAD ? "Kill " :nulstr ,current_msg->hdr.attr&MSG_ANONYMOUS ? "Anonymous " :nulstr ,current_msg->hdr.attr&MSG_LOCKED ? "Locked " :nulstr ,current_msg->hdr.attr&MSG_PERMANENT ? "Permanent " :nulstr ,current_msg->hdr.attr&MSG_MODERATED ? "Moderated " :nulstr ,current_msg->hdr.attr&MSG_VALIDATED ? "Validated " :nulstr ,current_msg->hdr.attr&MSG_REPLIED ? "Replied " :nulstr ,current_msg->hdr.attr&MSG_NOREPLY ? "NoReply " :nulstr ); return(str); } if(!strcmp(sp,"MSG_ID") && current_msg!=NULL) return(current_msg->id==NULL ? nulstr : current_msg->id); if(!strcmp(sp,"MSG_REPLY_ID") && current_msg!=NULL) return(current_msg->reply_id==NULL ? nulstr : current_msg->reply_id); if(!strcmp(sp,"MSG_NUM") && current_msg!=NULL) { safe_snprintf(str,maxlen,"%lu",current_msg->hdr.number); return(str); } if(!strcmp(sp,"SMB_AREA")) { if(smb.subnum!=INVALID_SUB && smb.subnum<cfg.total_subs) safe_snprintf(str,maxlen,"%s %s" ,cfg.grp[cfg.sub[smb.subnum]->grp]->sname ,cfg.sub[smb.subnum]->sname); return(str); } if(!strcmp(sp,"SMB_AREA_DESC")) { if(smb.subnum!=INVALID_SUB && smb.subnum<cfg.total_subs) safe_snprintf(str,maxlen,"%s %s" ,cfg.grp[cfg.sub[smb.subnum]->grp]->lname ,cfg.sub[smb.subnum]->lname); return(str); } if(!strcmp(sp,"SMB_GROUP")) { if(smb.subnum!=INVALID_SUB && smb.subnum<cfg.total_subs) return(cfg.grp[cfg.sub[smb.subnum]->grp]->sname); return(nulstr); } if(!strcmp(sp,"SMB_GROUP_DESC")) { if(smb.subnum!=INVALID_SUB && smb.subnum<cfg.total_subs) return(cfg.grp[cfg.sub[smb.subnum]->grp]->lname); return(nulstr); } if(!strcmp(sp,"SMB_GROUP_NUM")) { if(smb.subnum!=INVALID_SUB && smb.subnum<cfg.total_subs) safe_snprintf(str,maxlen,"%u",getusrgrp(smb.subnum)); return(str); } if(!strcmp(sp,"SMB_SUB")) { if(smb.subnum==INVALID_SUB) return("Mail"); else if(smb.subnum<cfg.total_subs) return(cfg.sub[smb.subnum]->sname); return(nulstr); } if(!strcmp(sp,"SMB_SUB_DESC")) { if(smb.subnum==INVALID_SUB) return("Mail"); else if(smb.subnum<cfg.total_subs) return(cfg.sub[smb.subnum]->lname); return(nulstr); } if(!strcmp(sp,"SMB_SUB_CODE")) { if(smb.subnum==INVALID_SUB) return("MAIL"); else if(smb.subnum<cfg.total_subs) return(cfg.sub[smb.subnum]->code); return(nulstr); } if(!strcmp(sp,"SMB_SUB_NUM")) { if(smb.subnum!=INVALID_SUB && smb.subnum<cfg.total_subs) safe_snprintf(str,maxlen,"%u",getusrsub(smb.subnum)); return(str); } if(!strcmp(sp,"SMB_MSGS")) { safe_snprintf(str,maxlen,"%ld",smb.msgs); return(str); } if(!strcmp(sp,"SMB_CURMSG")) { safe_snprintf(str,maxlen,"%ld",smb.curmsg+1); return(str); } if(!strcmp(sp,"SMB_LAST_MSG")) { safe_snprintf(str,maxlen,"%lu",smb.status.last_msg); return(str); } if(!strcmp(sp,"SMB_MAX_MSGS")) { safe_snprintf(str,maxlen,"%lu",smb.status.max_msgs); return(str); } if(!strcmp(sp,"SMB_MAX_CRCS")) { safe_snprintf(str,maxlen,"%lu",smb.status.max_crcs); return(str); } if(!strcmp(sp,"SMB_MAX_AGE")) { safe_snprintf(str,maxlen,"%hu",smb.status.max_age); return(str); } if(!strcmp(sp,"SMB_TOTAL_MSGS")) { safe_snprintf(str,maxlen,"%lu",smb.status.total_msgs); return(str); } return(NULL); }