Пример #1
0
int sbbs_t::exec_file(csi_t *csi)
{
	char	str[256],ch;
	int		s;
	uint 	i,j,x,y;
	file_t	f;

	switch(*(csi->ip++)) {

		case CS_FILE_SELECT_AREA:
			csi->logic=LOGIC_FALSE;
			if(!usrlibs) return(0);
			while(online) {
				j=0;
				if(usrlibs>1) {
					sprintf(str,"%smenu/libs.*", cfg.text_dir);
					if(fexist(str))
						menu("libs");
					else {
						bputs(text[CfgLibLstHdr]);
						for(i=0;i<usrlibs && !msgabort();i++) {
							if(i==curlib)
								outchar('*');
							else outchar(' ');
							if(i<9) outchar(' ');
							if(i<99) outchar(' ');
							bprintf(text[CfgLibLstFmt]
								,i+1,cfg.lib[usrlib[i]]->lname); 
						} 
					}
					sprintf(str,text[JoinWhichLib],curlib+1);
					mnemonics(str);
					j=getnum(usrlibs);
					if((int)j==-1)
						return(0);
					if(!j)
						j=curlib;
					else
						j--; 
				}
				sprintf(str,"%smenu/dirs%u.*", cfg.text_dir, usrlib[j]+1);
				if(fexist(str)) {
					sprintf(str,"dirs%u",usrlib[j]+1);
					menu(str); 
				}
				else {
					CLS;
					bprintf(text[DirLstHdr], cfg.lib[usrlib[j]]->lname);
					for(i=0;i<usrdirs[j] && !msgabort();i++) {
						if(i==curdir[j]) outchar('*');
						else outchar(' ');
						sprintf(str,text[DirLstFmt],i+1
							,cfg.dir[usrdir[j][i]]->lname,nulstr
							,getfiles(&cfg,usrdir[j][i]));
						if(i<9) outchar(' ');
						if(i<99) outchar(' ');
						bputs(str); 
					} 
				}
				sprintf(str,text[JoinWhichDir],curdir[j]+1);
				mnemonics(str);
				i=getnum(usrdirs[j]);
				if((int)i==-1) {
					if(usrlibs==1)
						return(0);
					continue; 
				}
				if(!i)
					i=curdir[j];
				else
					i--;
				curlib=j;
				curdir[curlib]=i;
				csi->logic=LOGIC_TRUE;
				return(0); 
			}
			return(0);

		case CS_FILE_GET_DIR_NUM:

			if(useron.misc&COLDKEYS) {
				i=atoi(csi->str);
				if(i && i<=usrdirs[curlib] && usrlibs)
					curdir[curlib]=i-1;
				return(0); 
			}

			ch=getkey(K_UPPER);
			outchar(ch);
			if((ch&0xf)*10U<=usrdirs[curlib] && (ch&0xf) && usrlibs) {
				i=(ch&0xf)*10;
				ch=getkey(K_UPPER);
				if(!isdigit(ch) && ch!=CR) {
					ungetkey(ch);
					curdir[curlib]=(i/10)-1;
					return(0); 
				}
				outchar(ch);
				if(ch==CR) {
					curdir[curlib]=(i/10)-1;
					return(0); 
				}
				logch(ch,0);
				i+=ch&0xf;
				if(i*10<=usrdirs[curlib]) { 	/* 100+ dirs */
					i*=10;
					ch=getkey(K_UPPER);
					if(!isdigit(ch) && ch!=CR) {
						ungetkey(ch);
						curdir[curlib]=(i/10)-1;
						return(0); 
					}
					outchar(ch);
					if(ch==CR) {
						curdir[curlib]=(i/10)-1;
						return(0); 
					}
					logch(ch,0);
					i+=ch&0xf; 
				}
				if(i<=usrdirs[curlib])
					curdir[curlib]=i-1;
				return(0); 
			}
			if((ch&0xf)<=(int)usrdirs[curlib] && (ch&0xf) && usrlibs)
				curdir[curlib]=(ch&0xf)-1;
			return(0);

		case CS_FILE_GET_LIB_NUM:

			if(useron.misc&COLDKEYS) {
				i=atoi(csi->str);
				if(i && i<=usrlibs)
					curlib=i-1;
				return(0); 
			}

			ch=getkey(K_UPPER);
			outchar(ch);
			if((ch&0xf)*10U<=usrlibs && (ch&0xf)) {
				i=(ch&0xf)*10;
				ch=getkey(K_UPPER);
				if(!isdigit(ch) && ch!=CR) {
					ungetkey(ch);
					curlib=(i/10)-1;
					return(0); 
				}
				outchar(ch);
				if(ch==CR) {
					curlib=(i/10)-1;
					return(0); 
				}
				logch(ch,0);
				i+=ch&0xf;
				if(i<=usrlibs)
					curlib=i-1;
				return(0); 
			}
			if((ch&0xf)<=(int)usrlibs && (ch&0xf))
				curlib=(ch&0xf)-1;
			return(0);

		case CS_FILE_SHOW_LIBRARIES:
			if(!usrlibs) return(0);
			sprintf(str,"%smenu/libs.*", cfg.text_dir);
			if(fexist(str)) {
				menu("libs");
				return(0); 
			}
			bputs(text[LibLstHdr]);
			for(i=0;i<usrlibs && !msgabort();i++) {
				if(i==curlib)
					outchar('*');
				else outchar(' ');
				if(i<9) outchar(' ');
				bprintf(text[LibLstFmt],i+1
					,cfg.lib[usrlib[i]]->lname,nulstr,usrdirs[i]); 
			}
			return(0);

		case CS_FILE_SHOW_DIRECTORIES:
			if(!usrlibs) return(0);
			sprintf(str,"%smenu/dirs%u.*", cfg.text_dir, usrlib[curlib]+1);
			if(fexist(str)) {
				sprintf(str,"dirs%u",usrlib[curlib]+1);
				menu(str);
				return(0); 
			}
			CRLF;
			bprintf(text[DirLstHdr],cfg.lib[usrlib[curlib]]->lname);
			for(i=0;i<usrdirs[curlib] && !msgabort();i++) {
				if(i==curdir[curlib]) outchar('*');
				else outchar(' ');
				sprintf(str,text[DirLstFmt],i+1
					,cfg.dir[usrdir[curlib][i]]->lname,nulstr
					,getfiles(&cfg,usrdir[curlib][i]));
				if(i<9) outchar(' ');
				if(i<99) outchar(' ');
				bputs(str); 
			}
			return(0);

		case CS_FILE_LIBRARY_UP:
			curlib++;
			if(curlib>=usrlibs)
				curlib=0;
			return(0);
		case CS_FILE_LIBRARY_DOWN:
			if(!curlib)
				curlib=usrlibs-1;
			else curlib--;
			return(0);
		case CS_FILE_DIRECTORY_UP:
			if(!usrlibs) return(0);
			curdir[curlib]++;
			if(curdir[curlib]>=usrdirs[curlib])
				curdir[curlib]=0;
			return(0);
		case CS_FILE_DIRECTORY_DOWN:
			if(!usrlibs) return(0);
			if(!curdir[curlib])
				curdir[curlib]=usrdirs[curlib]-1;
			else curdir[curlib]--;
			return(0);
		case CS_FILE_SET_AREA:
			csi->logic=LOGIC_TRUE;
			for(i=0;i<usrlibs;i++)
				for(j=0;j<usrdirs[i];j++)
					if(!stricmp(csi->str,cfg.dir[usrdir[i][j]]->code)) {
						curlib=i;
						curdir[i]=j;
						return(0); 
					}
			csi->logic=LOGIC_FALSE;
			return(0);
		case CS_FILE_SET_LIBRARY:
			csi->logic=LOGIC_TRUE;
			for(i=0;i<usrlibs;i++)
				if(!stricmp(cfg.lib[usrlib[i]]->sname,csi->str))
					break;
			if(i<usrlibs)
				curlib=i;
			else
				csi->logic=LOGIC_FALSE;
			return(0);

		case CS_FILE_UPLOAD:
			csi->logic=LOGIC_FALSE;
			if(usrlibs) {
				i=usrdir[curlib][curdir[curlib]];
				if(cfg.upload_dir!=INVALID_DIR
					&& !dir_op(i) && !(useron.exempt&FLAG('U'))
					&& !chk_ar(cfg.dir[i]->ul_ar,&useron,&client))
					i=cfg.upload_dir; 
			} else
				i=cfg.upload_dir;
			csi->logic=upload(i) ? LOGIC_TRUE:LOGIC_FALSE;
			return(0);
		case CS_FILE_UPLOAD_USER:
			csi->logic=LOGIC_FALSE;
			if(cfg.user_dir==INVALID_DIR) {
				bputs(text[NoUserDir]);
				return(0); 
			}
			csi->logic=upload(cfg.user_dir) ? LOGIC_TRUE:LOGIC_FALSE;
			return(0);
		case CS_FILE_UPLOAD_SYSOP:
			csi->logic=LOGIC_FALSE;
			if(cfg.sysop_dir==INVALID_DIR) {
				bputs(text[NoSysopDir]);
				return(0); 
			}
			csi->logic=upload(cfg.sysop_dir) ? LOGIC_TRUE:LOGIC_FALSE;
			return(0);
		case CS_FILE_DOWNLOAD:
			if(!usrlibs) return(0);
			if(useron.rest&FLAG('D')) {
				bputs(text[R_Download]);
				return(0); 
			}
			padfname(csi->str,str);
			strupr(str);
			if(!listfileinfo(usrdir[curlib][curdir[curlib]],str,FI_DOWNLOAD)) {
				bputs(text[SearchingAllDirs]);
				for(i=0;i<usrdirs[curlib];i++)
					if(i!=curdir[curlib] &&
						(s=listfileinfo(usrdir[curlib][i],str,FI_DOWNLOAD))!=0)
						if(s==-1 || (!strchr(str,'?') && !strchr(str,'*')))
							return(0);
				bputs(text[SearchingAllLibs]);
				for(i=0;i<usrlibs;i++) {
					if(i==curlib) continue;
					for(j=0;j<usrdirs[i];j++)
						if((s=listfileinfo(usrdir[i][j],str,FI_DOWNLOAD))!=0)
							if(s==-1 || (!strchr(str,'?') && !strchr(str,'*')))
								return(0); 
				} 
			}
			return(0);
		case CS_FILE_DOWNLOAD_USER: /* Download from user dir */
			csi->logic=LOGIC_FALSE;
			if(cfg.user_dir==INVALID_DIR) {
				bputs(text[NoUserDir]);
				return(0); 
			}
			if(useron.rest&FLAG('D')) {
				bputs(text[R_Download]);
				return(0); 
			}
			CRLF;
			if(!listfileinfo(cfg.user_dir,nulstr,FI_USERXFER))
				bputs(text[NoFilesForYou]);
			else
				csi->logic=LOGIC_TRUE;
			return(0);
		case CS_FILE_DOWNLOAD_BATCH:
			if(batdn_total && (text[DownloadBatchQ][0]==0 || yesno(text[DownloadBatchQ]))) {
				start_batch_download();
				csi->logic=LOGIC_TRUE; 
			}
			else
				csi->logic=LOGIC_FALSE;
			return(0);
		case CS_FILE_BATCH_ADD_LIST:
			batch_add_list(csi->str);
			return(0);
		case CS_FILE_BATCH_ADD:
			csi->logic=LOGIC_FALSE;
			if(!csi->str[0])
				return(0);
			padfname(csi->str,f.name);
			for(x=y=0;x<usrlibs;x++) {
				for(y=0;y<usrdirs[x];y++)
					if(findfile(&cfg,usrdir[x][y],f.name))
						break;
				if(y<usrdirs[x])
					break; 
			}
			if(x>=usrlibs)
				return(0);
			f.dir=usrdir[x][y];
			getfileixb(&cfg,&f);
			f.size=0;
			getfiledat(&cfg,&f);
			addtobatdl(&f);
			csi->logic=LOGIC_TRUE;
			return(0);
		case CS_FILE_BATCH_CLEAR:
			if(!batdn_total) {
				csi->logic=LOGIC_FALSE;
				return(0); 
			}
			csi->logic=LOGIC_TRUE;
			for(i=0;i<batdn_total;i++) {
				f.dir=batdn_dir[i];
				f.datoffset=batdn_offset[i];
				f.size=batdn_size[i];
				strcpy(f.name,batdn_name[i]);
				closefile(&f); 
			}
			batdn_total=0;
			return(0);

		case CS_FILE_VIEW:
			if(!usrlibs) return(0);
			padfname(csi->str,str);
			strupr(str);
			csi->logic=LOGIC_TRUE;
			if(listfiles(usrdir[curlib][curdir[curlib]],str,0,FL_VIEW))
				return(0);
			bputs(text[SearchingAllDirs]);
			for(i=0;i<usrdirs[curlib];i++) {
				if(i==curdir[curlib]) continue;
				if(listfiles(usrdir[curlib][i],str,0,FL_VIEW))
					break; 
			}
			if(i<usrdirs[curlib])
				return(0);
			bputs(text[SearchingAllLibs]);
			for(i=0;i<usrlibs;i++) {
				if(i==curlib) continue;
				for(j=0;j<usrdirs[i];j++)
					if(listfiles(usrdir[i][j],str,0,FL_VIEW))
						return(0); 
			}
			csi->logic=LOGIC_FALSE;
			bputs(text[FileNotFound]);
			return(0);
		case CS_FILE_LIST:	  /* List files in current dir */
			if(!usrlibs) return(0);
			csi->logic=LOGIC_FALSE;
			if(!getfiles(&cfg,usrdir[curlib][curdir[curlib]])) {
				bputs(text[EmptyDir]);
				return(0); 
			}
			padfname(csi->str,str);
			strupr(str);
			s=listfiles(usrdir[curlib][curdir[curlib]],str,0,0);
			if(s>1) {
				bprintf(text[NFilesListed],s); 
			}
			csi->logic=!s;
			return(0);
		case CS_FILE_LIST_EXTENDED: /* Extended Information on files */
			if(!usrlibs) return(0);
			padfname(csi->str,str);
			strupr(str);
			if(!listfileinfo(usrdir[curlib][curdir[curlib]],str,FI_INFO)) {
				bputs(text[SearchingAllDirs]);
				for(i=0;i<usrdirs[curlib];i++)
					if(i!=curdir[curlib] && (s=listfileinfo(usrdir[curlib][i]
						,str,FI_INFO))!=0)
						if(s==-1 || (!strchr(str,'?') && !strchr(str,'*')))
							return(0);
				bputs(text[SearchingAllLibs]);
				for(i=0;i<usrlibs;i++) {
					if(i==curlib) continue;
					for(j=0;j<usrdirs[i];j++)
						if((s=listfileinfo(usrdir[i][j],str,FI_INFO))!=0)
							if(s==-1 || (!strchr(str,'?') && !strchr(str,'*')))
								return(0); 
				} 
			}
			return(0);
		case CS_FILE_FIND_TEXT: 	/* Find text in descriptions */
			scandirs(FL_FINDDESC);
			return(0);
		case CS_FILE_FIND_TEXT_ALL: 	/* Find text in descriptions */
			scanalldirs(FL_FINDDESC);
			return(0);
		case CS_FILE_FIND_NAME: 	/* Find text in descriptions */
			scandirs(FL_NO_HDR);
			return(0);
		case CS_FILE_FIND_NAME_ALL: 	/* Find text in descriptions */
			scanalldirs(FL_NO_HDR);
			return(0);
		case CS_FILE_BATCH_SECTION:
			batchmenu();
			return(0);
		case CS_FILE_TEMP_SECTION:
			temp_xfer();
			return(0);
		case CS_FILE_PTRS_CFG:
			csi->logic=!inputnstime(&ns_time);
			return(0);
		case CS_FILE_NEW_SCAN:
			scandirs(FL_ULTIME);
			return(0);
		case CS_FILE_NEW_SCAN_ALL:
			scanalldirs(FL_ULTIME);
			return(0);
		case CS_FILE_REMOVE:
			if(!usrlibs) return(0);
			if(useron.rest&FLAG('R')) {
				bputs(text[R_RemoveFiles]);
				return(0); 
			}
			padfname(csi->str,str);
			strupr(str);
			if(!listfileinfo(usrdir[curlib][curdir[curlib]],str,FI_REMOVE)) {
				if(cfg.user_dir!=INVALID_DIR
					&& cfg.user_dir!=usrdir[curlib][curdir[curlib]])
					if((s=listfileinfo(cfg.user_dir,str,FI_REMOVE))!=0)
						if(s==-1 || (!strchr(str,'?') && !strchr(str,'*')))
							return(0);
				bputs(text[SearchingAllDirs]);
				for(i=0;i<usrdirs[curlib];i++)
					if(i!=curdir[curlib] && i!=cfg.user_dir
						&& (s=listfileinfo(usrdir[curlib][i],str,FI_REMOVE))!=0)
						if(s==-1 || (!strchr(str,'?') && !strchr(str,'*')))
							return(0);
				bputs(text[SearchingAllLibs]);
				for(i=0;i<usrlibs;i++) {
					if(i==curlib || i==cfg.user_dir) continue;
					for(j=0;j<usrdirs[i]; j++)
						if((s=listfileinfo(usrdir[i][j],str,FI_REMOVE))!=0)
							if(s==-1 || (!strchr(str,'?') && !strchr(str,'*')))
								return(0); 
				} 
			}
			return(0);
	 }

	errormsg(WHERE,ERR_CHK,"shell function",*(csi->ip-1));
	return(0);
}
Пример #2
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);
}