예제 #1
0
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);
}
예제 #2
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); 
	}
}
예제 #3
0
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);
}
예제 #4
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);
}
예제 #5
0
파일: un_rep.cpp 프로젝트: ftnapps/pkg-sbbs
bool sbbs_t::unpack_rep(char* repfile)
{
	char	str[MAX_PATH+1],fname[MAX_PATH+1]
			,*AttemptedToUploadREPpacket="Attempted to upload REP packet";
	char 	tmp[512];
	char	from[26];
	char	to[26];
	char	inbox[MAX_PATH+1];
	char	block[QWK_BLOCK_LEN];
	int 	file;
	uint	i,j,k,lastsub=INVALID_SUB;
	long	l,size,misc;
	ulong	n;
	ulong	ex;
	node_t	node;
	FILE*	rep;
	DIR*	dir;
	DIRENT*	dirent;
	BOOL	twit_list;

	sprintf(fname,"%stwitlist.cfg",cfg.ctrl_dir);
	twit_list=fexist(fname);

	if(repfile!=NULL)
		strcpy(str,repfile);
	else
		sprintf(str,"%s%s.rep",cfg.temp_dir,cfg.sys_id);
	if(!fexistcase(str)) {
		bputs(text[QWKReplyNotReceived]);
		logline("U!",AttemptedToUploadREPpacket);
		logline(nulstr,"REP file not received");
		return(false); 
	}
	for(k=0;k<cfg.total_fextrs;k++)
		if(!stricmp(cfg.fextr[k]->ext,useron.tmpext) && chk_ar(cfg.fextr[k]->ar,&useron))
			break;
	if(k>=cfg.total_fextrs)
		k=0;
	ex=EX_OUTL|EX_OUTR;
	if(online!=ON_REMOTE)
		ex|=EX_OFFLINE;
	i=external(cmdstr(cfg.fextr[k]->cmd,str,ALLFILES,NULL),ex);
	if(i) {
		bputs(text[QWKExtractionFailed]);
		logline("U!",AttemptedToUploadREPpacket);
		logline(nulstr,"Extraction failed");
		return(false); 
	}
	sprintf(str,"%s%s.msg",cfg.temp_dir,cfg.sys_id);
	if(!fexistcase(str)) {
		bputs(text[QWKReplyNotReceived]);
		logline("U!",AttemptedToUploadREPpacket);
		logline(nulstr,"MSG file not received");
		return(false); 
	}
	if((rep=fnopen(&file,str,O_RDONLY))==NULL) {
		errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
		return(false); 
	}
	size=filelength(file);
	fread(block,QWK_BLOCK_LEN,1,rep);
	if(strnicmp((char *)block,cfg.sys_id,strlen(cfg.sys_id))) {
		fclose(rep);
		bputs(text[QWKReplyNotReceived]);
		logline("U!",AttemptedToUploadREPpacket);
		logline(nulstr,"Incorrect BBSID");
		return(false); 
	}
	logline("U+","Uploaded REP packet");
	/********************/
	/* Process messages */
	/********************/
	bputs(text[QWKUnpacking]);

	for(l=QWK_BLOCK_LEN;l<size;l+=i*QWK_BLOCK_LEN) {
		if(terminated) {
			bprintf("!Terminated");
			break;
		}

		lncntr=0;					/* defeat pause */
		if(fseek(rep,l,SEEK_SET)!=0) {
			sprintf(str,"%s.msg", cfg.sys_id);
			errormsg(WHERE,ERR_SEEK,str,l);
			break;
		}
		if(fread(block,1,QWK_BLOCK_LEN,rep)!=QWK_BLOCK_LEN) {
			sprintf(str,"%s.msg", cfg.sys_id);
			errormsg(WHERE,ERR_READ,str,ftell(rep));
			break;
		}
		sprintf(tmp,"%.6s",block+116);
		i=atoi(tmp);  /* i = number of blocks */
		if(i<2) {
			sprintf(str,"%s.msg blocks (read '%s' at offset %ld)", cfg.sys_id, tmp, l);
			errormsg(WHERE,ERR_CHK,str,i);
			i=1;
			continue; 
		}
		if(atoi(block+1)==0) {					/**********/
			if(useron.rest&FLAG('E')) {         /* E-mail */
				bputs(text[R_Email]);			/**********/
				continue; 
			}

			sprintf(str,"%25.25s",block+21);
			truncsp(str);
			if(!stricmp(str,"NETMAIL")) {  /* QWK to FidoNet NetMail */
				qwktonetmail(rep,block,NULL,0);
				continue; 
			}
			if(strchr(str,'@')) {
				qwktonetmail(rep,block,str,0);
				continue; 
			}
			if(!stricmp(str,"SBBS")) {    /* to SBBS, config stuff */
				qwkcfgline(block+71,INVALID_SUB);
				continue; 
			}

			if(useron.etoday>=cfg.level_emailperday[useron.level]
				&& !(useron.rest&FLAG('Q'))) {
				bputs(text[TooManyEmailsToday]);
				continue; 
			}
			j=atoi(str);
			if(j && j>lastuser(&cfg))
				j=0;
			if(!j)
				j=matchuser(&cfg,str,TRUE /* sysop_alias */);
			if(!j) {
				bputs(text[UnknownUser]);
				continue; 
			}
			if(j==1 && useron.rest&FLAG('S')) {
				bprintf(text[R_Feedback],cfg.sys_op);
				continue; 
			}

			getuserrec(&cfg,j,U_MISC,8,str);
			misc=ahtoul(str);
			if(misc&NETMAIL && cfg.sys_misc&SM_FWDTONET) {
				getuserrec(&cfg,j,U_NETMAIL,LEN_NETMAIL,str);
				qwktonetmail(rep,block,str,0);
				continue; 
			}

			sprintf(smb.file,"%smail",cfg.data_dir);
			smb.retry_time=cfg.smb_retry_time;

			if(lastsub!=INVALID_SUB) {
				smb_close(&smb);
				lastsub=INVALID_SUB; 
			}

			smb.subnum=INVALID_SUB;
			if((k=smb_open(&smb))!=0) {
				errormsg(WHERE,ERR_OPEN,smb.file,k,smb.last_error);
				continue; 
			}

			if(!filelength(fileno(smb.shd_fp))) {
				smb.status.max_crcs=cfg.mail_maxcrcs;
				smb.status.max_msgs=0;
				smb.status.max_age=cfg.mail_maxage;
				smb.status.attr=SMB_EMAIL;
				if((k=smb_create(&smb))!=0) {
					smb_close(&smb);
					errormsg(WHERE,ERR_CREATE,smb.file,k);
					continue; 
				} 
			}

			if((k=smb_locksmbhdr(&smb))!=0) {
				smb_close(&smb);
				errormsg(WHERE,ERR_LOCK,smb.file,k);
				continue; 
			}

			if((k=smb_getstatus(&smb))!=0) {
				smb_close(&smb);
				errormsg(WHERE,ERR_READ,smb.file,k);
				continue; 
			}

			smb_unlocksmbhdr(&smb);

			if(!qwktomsg(rep,block,0,INVALID_SUB,j)) {
				smb_close(&smb);
				continue; 
			}
			smb_close(&smb);

			if(j==1) {
				useron.fbacks++;
				logon_fbacks++;
				putuserrec(&cfg,useron.number,U_FBACKS,5
					,ultoa(useron.fbacks,tmp,10)); 
			}
			else {
				useron.emails++;
				logon_emails++;
				putuserrec(&cfg,useron.number,U_EMAILS,5
					,ultoa(useron.emails,tmp,10)); 
			}
			useron.etoday++;
			putuserrec(&cfg,useron.number,U_ETODAY,5
				,ultoa(useron.etoday,tmp,10));
			bprintf(text[Emailed],username(&cfg,j,tmp),j);
			sprintf(str,"%s sent e-mail to %s #%d"
				,useron.alias,username(&cfg,j,tmp),j);
			logline("E+",str);
			if(useron.rest&FLAG('Q')) {
				sprintf(tmp,"%-25.25s",block+46);
				truncsp(tmp); 
			}
			else
				strcpy(tmp,useron.alias);
			for(k=1;k<=cfg.sys_nodes;k++) { /* Tell user, if online */
				getnodedat(k,&node,0);
				if(node.useron==j && !(node.misc&NODE_POFF)
					&& (node.status==NODE_INUSE
					|| node.status==NODE_QUIET)) {
					sprintf(str,text[EmailNodeMsg]
						,cfg.node_num,tmp);
					putnmsg(&cfg,k,str);
					break; 
				} 
			}
			if(k>cfg.sys_nodes) {
				sprintf(str,text[UserSentYouMail],tmp);
				putsmsg(&cfg,j,str); 
			} 
		}    /* end of email */

				/**************************/
		else {	/* message on a sub-board */
				/**************************/
			n=atol((char *)block+1); /* conference number */
			for(j=0;j<usrgrps;j++) {
				for(k=0;k<usrsubs[j];k++)
					if(cfg.sub[usrsub[j][k]]->qwkconf==n)
						break;
				if(k<usrsubs[j])
					break; 
			}

			if(j>=usrgrps) {
				if(n<1000) {			 /* version 1 method, start at 101 */
					j=n/100;
					k=n-(j*100); 
				}
				else {					 /* version 2 method, start at 1001 */
					j=n/1000;
					k=n-(j*1000); 
				}
				j--;	/* j is group */
				k--;	/* k is sub */
				if(j>=usrgrps || k>=usrsubs[j] || cfg.sub[usrsub[j][k]]->qwkconf) {
					bprintf(text[QWKInvalidConferenceN],n);
					sprintf(str,"%s: Invalid conference number %lu",useron.alias,n);
					logline("P!",str);
					continue; 
				} 
			}

			n=usrsub[j][k];

			/* if posting, add to new-scan config for QWKnet nodes automatically */
			if(useron.rest&FLAG('Q'))
				subscan[n].cfg|=SUB_CFG_NSCAN;

			sprintf(str,"%-25.25s","SBBS");
			if(!strnicmp((char *)block+21,str,25)) {	/* to SBBS, config stuff */
				qwkcfgline((char *)block+71,n);
				continue; 
			}

			if(!SYSOP && cfg.sub[n]->misc&SUB_QNET) {	/* QWK Netted */
				sprintf(str,"%-25.25s","DROP");         /* Drop from new-scan? */
				if(!strnicmp((char *)block+71,str,25))	/* don't allow post */
					continue;
				sprintf(str,"%-25.25s","ADD");          /* Add to new-scan? */
				if(!strnicmp((char *)block+71,str,25))	/* don't allow post */
					continue; 
			}

			if(useron.rest&FLAG('Q') && !(cfg.sub[n]->misc&SUB_QNET)) {
				bputs(text[CantPostOnSub]);
				logline("P!","Attempted to post on non-QWKnet sub");
				continue; 
			}

			if(useron.rest&FLAG('P')) {
				bputs(text[R_Post]);
				logline("P!","Post attempted");
				continue; 
			}

			if(useron.ptoday>=cfg.level_postsperday[useron.level]
				&& !(useron.rest&FLAG('Q'))) {
				bputs(text[TooManyPostsToday]);
				continue; 
			}

			if(useron.rest&FLAG('N')
				&& cfg.sub[n]->misc&(SUB_FIDO|SUB_PNET|SUB_QNET|SUB_INET)) {
				bputs(text[CantPostOnSub]);
				logline("P!","Networked post attempted");
				continue; 
			}

			if(!chk_ar(cfg.sub[n]->post_ar,&useron)) {
				bputs(text[CantPostOnSub]);
				logline("P!","Post attempted");
				continue; 
			}

			if((block[0]=='*' || block[0]=='+')
				&& !(cfg.sub[n]->misc&SUB_PRIV)) {
				bputs(text[PrivatePostsNotAllowed]);
				logline("P!","Private post attempt");
				continue; 
			}

			if(block[0]=='*' || block[0]=='+'           /* Private post */
				|| cfg.sub[n]->misc&SUB_PONLY) {
				sprintf(str,"%-25.25s",nulstr);
				sprintf(tmp,"%-25.25s","ALL");
				if(!strnicmp((char *)block+21,str,25)
					|| !strnicmp((char *)block+21,tmp,25)) {	/* to blank */
					bputs(text[NoToUser]);						/* or all */
					continue; 
				} 
			}

			if(!SYSOP && !(useron.rest&FLAG('Q'))) {
				sprintf(str,"%-25.25s","SYSOP");
				if(!strnicmp((char *)block+21,str,25)) {
					sprintf(str,"%-25.25s",username(&cfg,1,tmp));
					memcpy((char *)block+21,str,25);		/* change from sysop */
				}											/* to user name */
			}

			/* TWIT FILTER */
			if(twit_list) {
				sprintf(fname,"%stwitlist.cfg",cfg.ctrl_dir);
				sprintf(from,"%25.25s",block+46);	/* From user */
				truncsp(from);
				sprintf(to,"%25.25s",block+21);		/* To user */
				truncsp(to);

				if(findstr(from,fname) || findstr(to,fname)) {
					sprintf(str,"Filtering post from %s to %s on %s %s"
						,from
						,to
						,cfg.grp[cfg.sub[n]->grp]->sname,cfg.sub[n]->lname);
					logline("P!",str);
					continue; 
				}
			}

			if(n!=lastsub) {
				if(lastsub!=INVALID_SUB)
					smb_close(&smb);
				lastsub=INVALID_SUB;
				sprintf(smb.file,"%s%s",cfg.sub[n]->data_dir,cfg.sub[n]->code);
				smb.retry_time=cfg.smb_retry_time;
				smb.subnum=n;
				if((j=smb_open(&smb))!=0) {
					errormsg(WHERE,ERR_OPEN,smb.file,j,smb.last_error);
					continue; 
				}

				if(!filelength(fileno(smb.shd_fp))) {
					smb.status.max_crcs=cfg.sub[n]->maxcrcs;
					smb.status.max_msgs=cfg.sub[n]->maxmsgs;
					smb.status.max_age=cfg.sub[n]->maxage;
					smb.status.attr=cfg.sub[n]->misc&SUB_HYPER ? SMB_HYPERALLOC:0;
					if((j=smb_create(&smb))!=0) {
						smb_close(&smb);
						lastsub=INVALID_SUB;
						errormsg(WHERE,ERR_CREATE,smb.file,j);
						continue; 
					} 
				}

				if((j=smb_locksmbhdr(&smb))!=0) {
					smb_close(&smb);
					lastsub=INVALID_SUB;
					errormsg(WHERE,ERR_LOCK,smb.file,j);
					continue; 
				}
				if((j=smb_getstatus(&smb))!=0) {
					smb_close(&smb);
					lastsub=INVALID_SUB;
					errormsg(WHERE,ERR_READ,smb.file,j);
					continue; 
				}
				smb_unlocksmbhdr(&smb);
				lastsub=n; 
			}

			if(!qwktomsg(rep,block,0,n,0))
				continue;

			logon_posts++;
			user_posted_msg(&cfg, &useron, 1);
			bprintf(text[Posted],cfg.grp[cfg.sub[n]->grp]->sname
				,cfg.sub[n]->lname);
			sprintf(str,"%s posted on %s %s"
				,useron.alias,cfg.grp[cfg.sub[n]->grp]->sname,cfg.sub[n]->lname);
			signal_sub_sem(&cfg,n);
			logline("P+",str); 
			if(!(useron.rest&FLAG('Q')))
				user_event(EVENT_POST);
		}   /* end of public message */
	}

	update_qwkroute(NULL);			/* Write ROUTE.DAT */

	if(lastsub!=INVALID_SUB)
		smb_close(&smb);
	fclose(rep);

	if(useron.rest&FLAG('Q')) {             /* QWK Net Node */
		sprintf(str,"%s%s.msg",cfg.temp_dir,cfg.sys_id);
		if(fexistcase(str))
			remove(str);
		sprintf(str,"%s%s.rep",cfg.temp_dir,cfg.sys_id);
		if(fexistcase(str))
			remove(str);
		sprintf(str,"%sATTXREF.DAT",cfg.temp_dir);
		if(fexistcase(str))
			remove(str);

		dir=opendir(cfg.temp_dir);
		while(dir!=NULL && (dirent=readdir(dir))!=NULL) {				/* Extra files */
			// Move files
			sprintf(str,"%s%s",cfg.temp_dir,dirent->d_name);
			if(isdir(str))
				continue;

			// Create directory if necessary
			sprintf(inbox,"%sqnet/%s.in",cfg.data_dir,useron.alias);
			MKDIR(inbox); 

			sprintf(fname,"%s/%s",inbox,dirent->d_name);
			mv(str,fname,1);
			sprintf(str,text[ReceivedFileViaQWK],dirent->d_name,useron.alias);
			putsmsg(&cfg,1,str);
		} 
		if(dir!=NULL)
			closedir(dir);
		sprintf(str,"%sqnet-rep.now",cfg.data_dir);
		ftouch(str);
	}

	bputs(text[QWKUnpacked]);
	CRLF;
	/**********************************************/
	/* Hang-up now if that's what the user wanted */
	/**********************************************/
	autohangup();

	return(true);
}