Esempio n. 1
0
void sbbs_t::xfer_prot_menu(enum XFER_TYPE type)
{
	char path[MAX_PATH+1];

	sprintf(path,"%smenu/%s.*",cfg.text_dir,prot_menu_file[type]);
	if(fexistcase(path)) {
		menu(prot_menu_file[type]);
		return;
	}

	CRLF;
	int printed=0;
	for(int i=0;i<cfg.total_prots;i++) {
		if(!chk_ar(cfg.prot[i]->ar,&useron))
			continue;
		if(type==XFER_UPLOAD && cfg.prot[i]->ulcmd[0]==0)
			continue;
		if(type==XFER_DOWNLOAD && cfg.prot[i]->dlcmd[0]==0)
			continue;
		if(type==XFER_BATCH_UPLOAD && cfg.prot[i]->batulcmd[0]==0)
			continue;
		if(type==XFER_BATCH_DOWNLOAD && cfg.prot[i]->batdlcmd[0]==0)
			continue;
		if(type==XFER_BIDIR && cfg.prot[i]->bicmd[0]==0)
			continue;
		if(printed && (printed%2)==0)
			CRLF;
		bprintf(text[TransferProtLstFmt],cfg.prot[i]->mnemonic,cfg.prot[i]->name);
		printed++;
	}
	CRLF;
}
Esempio n. 2
0
void sbbs_t::fileinfo(file_t* f)
{
	char	ext[513];
	char 	tmp[512];
	char	path[MAX_PATH+1];
	char	fpath[MAX_PATH+1];
	uint	i,j;

	for(i=0;i<usrlibs;i++)
		if(usrlib[i]==cfg.dir[f->dir]->lib)
			break;
	for(j=0;j<usrdirs[i];j++)
		if(usrdir[i][j]==f->dir)
			break;

	getfilepath(&cfg,f,path);
	bprintf(text[FiLib],i+1,cfg.lib[cfg.dir[f->dir]->lib]->lname);
	bprintf(text[FiDir],j+1,cfg.dir[f->dir]->lname);
	bprintf(text[FiFilename],getfname(path));
	SAFECOPY(fpath,path);
	fexistcase(fpath);
	if(strcmp(path,fpath) && strcmp(f->desc,getfname(fpath)))	/* Different "actual" filename */
		bprintf(text[FiFilename],getfname(fpath));

	if(f->size!=-1L)
		bprintf(text[FiFileSize],ultoac(f->size,tmp));
	bprintf(text[FiCredits]
		,(cfg.dir[f->dir]->misc&DIR_FREE || !f->cdt) ? "FREE" : ultoac(f->cdt,tmp));
	bprintf(text[FiDescription],f->desc);
	bprintf(text[FiUploadedBy],f->misc&FM_ANON ? text[UNKNOWN_USER] : f->uler);
	if(f->date)
		bprintf(text[FiFileDate],timestr(&f->date));
	bprintf(text[FiDateUled],timestr(&f->dateuled));
	bprintf(text[FiDateDled],f->datedled ? timestr(&f->datedled) : "Never");
	bprintf(text[FiTimesDled],f->timesdled);
	if(f->size!=-1L)
		bprintf(text[FiTransferTime],sectostr(f->timetodl,tmp));
	if(f->altpath) {
		if(f->altpath<=cfg.altpaths) {
			if(SYSOP)
				bprintf(text[FiAlternatePath],cfg.altpath[f->altpath-1]); 
		}
		else
			bprintf(text[InvalidAlternatePathN],f->altpath); 
	}
	CRLF;
	if(f->misc&FM_EXTDESC) {
		getextdesc(&cfg,f->dir,f->datoffset,ext);
		CRLF;
		putmsg(ext,P_NOATCODES);
		CRLF; }
	if(f->size==-1L)
		bprintf(text[FileIsNotOnline],f->name);
	if(f->opencount)
		bprintf(text[FileIsOpen],f->opencount,f->opencount>1 ? "s" : nulstr);

}
Esempio n. 3
0
char *complete_path(char *dest, char *path, char *filename)
{
	if(path != NULL) {
		strcpy(dest, path);
		backslash(dest);
	}
	else
		dest[0]=0;

	if(filename != NULL)
		strcat(dest, filename);
	fexistcase(dest);			/* TODO: Hack: Fixes upr/lwr case fname */
	return(dest);
}
Esempio n. 4
0
bool sbbs_t::trashcan(char *insearchof, char *name)
{
	char str[MAX_PATH+1];
	bool result;

	result=::trashcan(&cfg, insearchof, name)
		? true:false; // This is a dumb bool conversion to make BC++ happy
	if(result) {
		sprintf(str,"%sbad%s.msg",cfg.text_dir,name);
		if(fexistcase(str)) {
			printfile(str,0);
			mswait(500); // give time for tx buffer to clear before disconnect
		}
	}
	return(result);
}
Esempio n. 5
0
long sbbs_t::js_execfile(const char *cmd, const char* startup_dir, JSObject* scope)
{
	char*		p;
	char*		args=NULL;
	char*		fname;
	int			argc=0;
	char		cmdline[MAX_PATH+1];
	char		path[MAX_PATH+1];
	JSObject*	js_scope=scope;
	JSObject*	js_script=NULL;
	jsval		rval;
	int32		result=0;

	if(js_cx==NULL) {
		errormsg(WHERE,ERR_CHK,"JavaScript support",0);
		errormsg(WHERE,ERR_EXEC,cmd,0);
		return -1;
	}

	SAFECOPY(cmdline,cmd);
	p=strchr(cmdline,' ');
	if(p!=NULL) {
		*p=0;
		args=p+1;
	}
	fname=cmdline;

	path[0]=0;
	if(strcspn(fname,"/\\")==strlen(fname)) {
		if(startup_dir!=NULL && *startup_dir)
			SAFEPRINTF3(path,"%s%s%s",startup_dir,fname,js_ext(fname));
		if(path[0]==0 || !fexistcase(path)) {
			SAFEPRINTF3(path,"%s%s%s",cfg.mods_dir,fname,js_ext(fname));
			if(cfg.mods_dir[0]==0 || !fexistcase(path))
				SAFEPRINTF3(path,"%s%s%s",cfg.exec_dir,fname,js_ext(fname));
		}
	} else
		SAFECOPY(path,fname);

	if(!fexistcase(path)) {
		errormsg(WHERE,ERR_OPEN,path,O_RDONLY);
		return -1;
	}

	JS_BEGINREQUEST(js_cx);
	if(js_scope==NULL)
		js_scope=JS_NewObject(js_cx, NULL, NULL, js_glob);

	if(js_scope!=NULL) {

		JSObject* argv=JS_NewArrayObject(js_cx, 0, NULL);

		JS_DefineProperty(js_cx, js_scope, "argv", OBJECT_TO_JSVAL(argv)
			,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);

		/* TODO: Handle quoted "one arg" syntax here? */
		if(args!=NULL && argv!=NULL) {
			while(*args) {
				p=strchr(args,' ');
				if(p!=NULL)
					*p=0;
				while(*args && *args==' ') args++; /* Skip spaces */
				JSString* arg = JS_NewStringCopyZ(js_cx, args);
				if(arg==NULL)
					break;
				jsval val=STRING_TO_JSVAL(arg);
				if(!JS_SetElement(js_cx, argv, argc, &val))
					break;
				argc++;
				if(p==NULL)	/* last arg */
					break;
				args+=(strlen(args)+1);
			}
		}
		JS_DefineProperty(js_cx, js_scope, "argc", INT_TO_JSVAL(argc)
			,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);

		JS_ClearPendingException(js_cx);

		js_script=JS_CompileFile(js_cx, js_scope, path);
	}

	if(js_scope==NULL || js_script==NULL) {
		JS_ReportPendingException(js_cx);	/* Added Feb-2-2006, rswindell */
		JS_ENDREQUEST(js_cx);
		errormsg(WHERE,"compiling",path,0);
		return -1;
	}

	if(scope==NULL) {
		js_callback.counter=0;	// Reset loop counter

#if JS_VERSION>180
		JS_SetOperationCallback(js_cx, js_OperationCallback);
#else
		JS_SetBranchCallback(js_cx, js_BranchCallback);
#endif

		js_PrepareToExecute(js_cx, js_glob, path, startup_dir);
	}
	JS_ExecuteScript(js_cx, js_scope, js_script, &rval);

	if(scope==NULL) {
		JS_GetProperty(js_cx, js_scope, "exit_code", &rval);
		if(rval!=JSVAL_VOID)
			JS_ValueToInt32(js_cx,rval,&result);

		js_EvalOnExit(js_cx, js_scope, &js_callback);
	}

	JS_ReportPendingException(js_cx);	/* Added Dec-4-2005, rswindell */

	JS_DestroyScript(js_cx, js_script);

	if(scope==NULL)
		JS_ClearScope(js_cx, js_scope);

	JS_GC(js_cx);

	JS_ENDREQUEST(js_cx);

	return(result);
}
Esempio n. 6
0
/* Important change as of Nov-16-2006, 'cmdline' may contain args */
long sbbs_t::exec_bin(const char *cmdline, csi_t *csi, const char* startup_dir)
{
    char    str[MAX_PATH+1];
	char	mod[MAX_PATH+1];
	char	modname[MAX_PATH+1];
	char*	p;
	int 	file;
    csi_t   bin;

	SAFECOPY(mod,cmdline);
	p=mod;
	FIND_CHAR(p,' ');
	if(*p) {
		*p=0;				/* terminate 'mod' */
		p++;				/* skip space */
		SKIP_CHAR(p,' ');	/* skip more spaces */
	}
	if(*p)
		strcpy(main_csi.str, p);

#ifdef JAVASCRIPT
	if((p=getfext(mod))!=NULL && stricmp(p,".js")==0)
		return(js_execfile(cmdline, startup_dir));
	if(p==NULL && startup_dir!=NULL && *startup_dir) {
		SAFEPRINTF2(str,"%s%s.js", startup_dir, mod);
		if(fexistcase(str))
			return(js_execfile(cmdline, startup_dir));
	}
	if(cfg.mods_dir[0]) {
		SAFEPRINTF2(str,"%s%s.js",cfg.mods_dir,mod);
		if(fexistcase(str)) 
			return(js_execfile(cmdline, startup_dir));
	}
#endif

	SAFECOPY(modname,mod);
	if(!strchr(modname,'.'))
		strcat(modname,".bin");

	SAFEPRINTF2(str,"%s%s",cfg.mods_dir,modname);
	if(cfg.mods_dir[0]==0 || !fexistcase(str)) {

#ifdef JAVASCRIPT
		SAFEPRINTF2(str,"%s%s.js",cfg.exec_dir,mod);
		if(fexistcase(str)) 
			return(js_execfile(cmdline, startup_dir));
#endif

		SAFEPRINTF2(str,"%s%s",cfg.exec_dir,modname);
		fexistcase(str);
	}
	if((file=nopen(str,O_RDONLY))==-1) {
		errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
		return(-1); 
	}

	memcpy(&bin,csi,sizeof(csi_t));
	clearvars(&bin);
	bin.length=(uint32_t)filelength(file);
	if((bin.cs=(uchar *)malloc(bin.length))==NULL) {
		close(file);
		errormsg(WHERE,ERR_ALLOC,str,bin.length);
		return(-1); 
	}
	if(lread(file,bin.cs,bin.length)!=bin.length) {
		close(file);
		errormsg(WHERE,ERR_READ,str,bin.length);
		free(bin.cs);
		return(-1); 
	}
	close(file);

	bin.ip=bin.cs;
	bin.rets=0;
	bin.cmdrets=0;
	bin.misc=0;

	while(exec(&bin)==0)
		if(!(bin.misc&CS_OFFLINE_EXEC)) {
			checkline();
			if(!online)
				break; 
		}

	freevars(&bin);
	free(bin.cs);
	csi->logic=bin.logic;
	return(bin.retval);
}
Esempio n. 7
0
bool sbbs_t::ftp_put(csi_t* csi, SOCKET ctrl_sock, char* src, char* dest)
{
	char		cmd[512];
	char		rsp[512];
	char		path[MAX_PATH+1];
	char		buf[4097];
	int			rd;
	int			result;
	ulong		total=0;
	SOCKET		data_sock;
	union xp_sockaddr	addr;
	socklen_t	addr_len;
	FILE*		fp=NULL;
	bool		error=false;
	struct timeval	tv;
	fd_set			socket_set;

	SAFECOPY(path,src);

	if(!fexistcase(path))
		return(false);

	if((data_sock=ftp_data_sock(csi, ctrl_sock, &addr.in))==INVALID_SOCKET) {
		bprintf("ftp: failure, line %d",__LINE__);
		return(false);
	}

	if(csi->ftp_mode&CS_FTP_PASV) {

#if 0	// Debug
		bprintf("Connecting to %s:%hd\r\n"
			,inet_ntoa(addr.in.sin_addr)
			,ntohs(addr.in.sin_port));
#endif

		if(connect(data_sock,&addr.addr,sizeof(addr.in))!=0) {
			bprintf("ftp: failure, line %d",__LINE__);
			csi->socket_error=ERROR_VALUE;
			close_socket(data_sock);
			return(false);
		}
	}

	if((fp=fopen(path,"rb"))==NULL) {
		bprintf("ftp: failure, line %d",__LINE__);
		close_socket(data_sock);
		return(false);
	}

	sprintf(cmd,"STOR %s",dest);

	if(!ftp_cmd(csi,ctrl_sock,cmd,rsp) 
		|| atoi(rsp)!=150 /* Open data connection */) {
		bprintf("ftp: failure, line %d",__LINE__);
		close_socket(data_sock);
		return(false);
	}

	if(!(csi->ftp_mode&CS_FTP_PASV)) {	/* Normal (Active) FTP */

		/* Setup for select() */
		tv.tv_sec=TIMEOUT_SOCK_LISTEN;
		tv.tv_usec=0;

		FD_ZERO(&socket_set);
		FD_SET(data_sock,&socket_set);

		result=select(data_sock+1,&socket_set,NULL,NULL,&tv);
		if(result<1) {
			csi->socket_error=ERROR_VALUE;
			closesocket(data_sock);
			return(false);
		}

		SOCKET accept_sock;

		addr_len=sizeof(addr);
		if((accept_sock=accept_socket(data_sock,&addr,&addr_len))
			==INVALID_SOCKET) {
			csi->socket_error=ERROR_VALUE;
			closesocket(data_sock);
			return(false);
		}

		close_socket(data_sock);
		data_sock=accept_sock;
	}

	while(online && !feof(fp)) {

		rd=fread(buf,sizeof(char),sizeof(buf),fp);
		if(rd<1) /* EOF or READ error */
			break;

		if(!socket_check(ctrl_sock,NULL,NULL,0))
			break; /* Control connection lost */

		if(sendsocket(data_sock,buf,rd)<1) {
			error=true;
			break;
		}

		total+=rd;
		
		if(csi->ftp_mode&CS_FTP_HASH)
			outchar('#');
	}

	if(csi->ftp_mode&CS_FTP_HASH) {
		CRLF;
	}

	fclose(fp);

	close_socket(data_sock);

	if(!ftp_cmd(csi,ctrl_sock,NULL,rsp) 
		|| atoi(rsp)!=226 /* Upload complete */)
		return(false);

	if(!error)
		bprintf("ftp: %lu bytes sent.\r\n", total);

	return(!error);
}
Esempio n. 8
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); 
	}
}
Esempio n. 9
0
bool sbbs_t::netmail(const char *into, const char *title, long mode)
{
	char	str[256],subj[128],to[256],fname[128],*buf,*p,ch;
	char 	tmp[512];
	int		file,fido,x,cc_found,cc_sent;
	uint	i;
	long	length,l;
	faddr_t addr;
	fmsghdr_t hdr;
	struct tm tm;

	if(useron.etoday>=cfg.level_emailperday[useron.level] && !SYSOP && !(useron.exempt&FLAG('M'))) {
		bputs(text[TooManyEmailsToday]);
		return(false); 
	}

	SAFECOPY(subj,title);

	strcpy(to,into);

	lookup_netuser(to);

	p=strrchr(to,'@');      /* Find '@' in name@addr */
	if(p && !isdigit(*(p+1)) && !strchr(p,'.') && !strchr(p,':')) {
		mode&=~WM_FILE;
		qnetmail(to,title,mode|WM_NETMAIL);
		return(false); 
	}
	if(!cfg.total_faddrs || p==NULL || !strchr(p+1,'/')) {
		if(!p && cfg.dflt_faddr.zone)
			addr=cfg.dflt_faddr;
		else if(cfg.inetmail_misc&NMAIL_ALLOW) {
			if(mode&WM_FILE && !SYSOP && !(cfg.inetmail_misc&NMAIL_FILE))
				mode&=~WM_FILE;
			return(inetmail(into,title,mode|WM_NETMAIL));
		}
		else if(cfg.dflt_faddr.zone)
			addr=cfg.dflt_faddr;
		else {
			bputs(text[InvalidNetMailAddr]);
			return(false); 
		} 
	} else {
		addr=atofaddr(&cfg,p+1); 	/* Get fido address */
		*p=0;					/* Chop off address */
	}

	if(mode&WM_FILE && !SYSOP && !(cfg.netmail_misc&NMAIL_FILE))
		mode&=~WM_FILE;

	if((!SYSOP && !(cfg.netmail_misc&NMAIL_ALLOW)) || useron.rest&FLAG('M')
		|| !cfg.total_faddrs) {
		bputs(text[NoNetMailAllowed]);
		return(false); 
	}

	truncsp(to);				/* Truncate off space */

	memset(&hdr,0,sizeof(hdr));   /* Initialize header to null */
	strcpy(hdr.from,cfg.netmail_misc&NMAIL_ALIAS ? useron.alias : useron.name);
	SAFECOPY(hdr.to,to);

	/* Look-up in nodelist? */

	if(cfg.netmail_cost && !(useron.exempt&FLAG('S'))) {
		if(useron.cdt+useron.freecdt<cfg.netmail_cost) {
			bputs(text[NotEnoughCredits]);
			return(false); 
		}
		sprintf(str,text[NetMailCostContinueQ],cfg.netmail_cost);
		if(noyes(str))
			return(false); 
	}

	now=time(NULL);
	if(localtime_r(&now,&tm)!=NULL)
		sprintf(hdr.time,"%02u %3.3s %02u  %02u:%02u:%02u"
			,tm.tm_mday,mon[tm.tm_mon],TM_YEAR(tm.tm_year)
			,tm.tm_hour,tm.tm_min,tm.tm_sec);

	hdr.destzone	=addr.zone;
	hdr.destnet 	=addr.net;
	hdr.destnode	=addr.node;
	hdr.destpoint	=addr.point;

	for(i=0;i<cfg.total_faddrs;i++)
		if(addr.zone==cfg.faddr[i].zone && addr.net==cfg.faddr[i].net)
			break;
	if(i==cfg.total_faddrs) {
		for(i=0;i<cfg.total_faddrs;i++)
			if(addr.zone==cfg.faddr[i].zone)
				break; 
	}
	if(i==cfg.total_faddrs)
		i=0;
	hdr.origzone	=cfg.faddr[i].zone;
	hdr.orignet 	=cfg.faddr[i].net;
	hdr.orignode	=cfg.faddr[i].node;
	hdr.origpoint	=cfg.faddr[i].point;

	smb_faddrtoa(&cfg.faddr[i],str);
	bprintf(text[NetMailing],hdr.to,smb_faddrtoa(&addr,tmp),hdr.from,str);

	hdr.attr=(FIDO_LOCAL|FIDO_PRIVATE);

	if(cfg.netmail_misc&NMAIL_CRASH) hdr.attr|=FIDO_CRASH;
	if(cfg.netmail_misc&NMAIL_HOLD)  hdr.attr|=FIDO_HOLD;
	if(cfg.netmail_misc&NMAIL_KILL)  hdr.attr|=FIDO_KILLSENT;
	if(mode&WM_FILE) hdr.attr|=FIDO_FILE;

	sprintf(str,"%sNETMAIL.MSG", cfg.node_dir);
	remove(str);	/* Just incase it's already there */
	// mode&=~WM_FILE;
	if(!writemsg(str,nulstr,subj,WM_NETMAIL|mode,INVALID_SUB,into)) {
		bputs(text[Aborted]);
		return(false); 
	}

	if(mode&WM_FILE) {
		strcpy(fname,subj);
		sprintf(str,"%sfile/%04u.out", cfg.data_dir, useron.number);
		MKDIR(str);
		strcpy(tmp, cfg.data_dir);
		if(tmp[0]=='.')    /* Relative path */
			sprintf(tmp,"%s%s", cfg.node_dir, cfg.data_dir);
		sprintf(str,"%sfile/%04u.out/%s",tmp,useron.number,fname);
		strcpy(subj,str);
		if(fexistcase(str)) {
			bputs(text[FileAlreadyThere]);
			return(false); 
		}
		{ /* Remote */
			xfer_prot_menu(XFER_UPLOAD);
			mnemonics(text[ProtocolOrQuit]);
			strcpy(str,"Q");
			for(x=0;x<cfg.total_prots;x++)
				if(cfg.prot[x]->ulcmd[0] && chk_ar(cfg.prot[x]->ar,&useron,&client)) {
					sprintf(tmp,"%c",cfg.prot[x]->mnemonic);
					strcat(str,tmp); 
				}
			ch=(char)getkeys(str,0);
			if(ch=='Q' || sys_status&SS_ABORT) {
				bputs(text[Aborted]);
				return(false); 
			}
			for(x=0;x<cfg.total_prots;x++)
				if(cfg.prot[x]->ulcmd[0] && cfg.prot[x]->mnemonic==ch
					&& chk_ar(cfg.prot[x]->ar,&useron,&client))
					break;
			if(x<cfg.total_prots)	/* This should be always */
				protocol(cfg.prot[x],XFER_UPLOAD,subj,nulstr,true); 
		}
		sprintf(tmp,"%s%s",cfg.temp_dir,title);
		if(!fexistcase(subj) && fexistcase(tmp))
			mv(tmp,subj,0);
		l=(long)flength(subj);
		if(l>0)
			bprintf(text[FileNBytesReceived],fname,ultoac(l,tmp));
		else {
			bprintf(text[FileNotReceived],fname);
			return(false); 
		} 
	}

	p=subj;
	if((SYSOP || useron.exempt&FLAG('F'))
		&& !strnicmp(p,"CR:",3)) {     /* Crash over-ride by sysop */
		p+=3;				/* skip CR: */
		if(*p==' ') p++; 	/* skip extra space if it exists */
		hdr.attr|=FIDO_CRASH; 
	}

	if((SYSOP || useron.exempt&FLAG('F'))
		&& !strnicmp(p,"FR:",3)) {     /* File request */
		p+=3;				/* skip FR: */
		if(*p==' ') p++;
		hdr.attr|=FIDO_FREQ; 
	}

	if((SYSOP || useron.exempt&FLAG('F'))
		&& !strnicmp(p,"RR:",3)) {     /* Return receipt request */
		p+=3;				/* skip RR: */
		if(*p==' ') p++;
		hdr.attr|=FIDO_RRREQ; 
	}

	if((SYSOP || useron.exempt&FLAG('F'))
		&& !strnicmp(p,"FA:",3)) {     /* File Attachment */
		p+=3;				/* skip FA: */
		if(*p==' ') p++;
		hdr.attr|=FIDO_FILE; 
	}

	SAFECOPY(hdr.subj,p);

	sprintf(str,"%sNETMAIL.MSG", cfg.node_dir);
	if((file=nopen(str,O_RDONLY))==-1) {
		errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
		return(false); 
	}
	length=(long)filelength(file);
	if((buf=(char *)malloc(length))==NULL) {
		close(file);
		errormsg(WHERE,ERR_ALLOC,str,length);
		return(false); 
	}
	read(file,buf,length);
	close(file);

	md(cfg.netmail_dir);
	cc_sent=0;
	while(1) {
		for(i=1;i;i++) {
			sprintf(str,"%s%u.msg", cfg.netmail_dir,i);
			if(!fexistcase(str))
				break; 
		}
		if(!i) {
			bputs(text[TooManyEmailsToday]);
			return(false); 
		}
		if((fido=nopen(str,O_WRONLY|O_CREAT|O_EXCL))==-1) {
			errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_EXCL);
			return(false); 
		}
		write(fido,&hdr,sizeof(hdr));

		pt_zone_kludge(hdr,fido);

		if(cfg.netmail_misc&NMAIL_DIRECT) {
			SAFECOPY(str,"\1FLAGS DIR\r\n");
			write(fido,str,strlen(str)); 
		}
		if(mode&WM_FILE) {
			SAFECOPY(str,"\1FLAGS KFS\r\n");
			write(fido,str,strlen(str)); 
		}

		if(cc_sent) {
			SAFEPRINTF(str,"* Originally to: %s\r\n\r\n",into);
			write(fido,str,strlen(str)); 
		}

		l=0L;
		while(l<length) {
			if(buf[l]==CTRL_A) {		/* Ctrl-A, so skip it and the next char */
				l++;
				if(l>=length || toupper(buf[l])=='Z')	/* EOF */
					break;
				if((ch=ctrl_a_to_ascii_char(buf[l])) != 0)
					write(fido,&ch,1);
			}
			else if(buf[l]!=LF) {
				if((uchar)buf[l]==0x8d)   /* r0dent i converted to normal i */
					buf[l]='i';
				write(fido,buf+l,1); 
			}
			l++; 
		}
		l=0;
		write(fido,&l,1);	/* Null terminator */
		close(fido);

		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));

		if(!(useron.exempt&FLAG('S')))
			subtract_cdt(&cfg,&useron,cfg.netmail_cost);
		if(mode&WM_FILE)
			sprintf(str,"%s sent NetMail file attachment to %s (%s)"
				,useron.alias
				,hdr.to,smb_faddrtoa(&addr,tmp));
		else
			sprintf(str,"%s sent NetMail to %s (%s)"
				,useron.alias
				,hdr.to,smb_faddrtoa(&addr,tmp));
		logline("EN",str);

		cc_found=0;
		for(l=0;l<length && cc_found<=cc_sent;l++)
			if(l+3<length && !strnicmp(buf+l,"CC:",3)) {
				cc_found++;
				l+=2; 
			}
			else {
				while(l<length && *(buf+l)!=LF)
					l++; 
			}
		if(!cc_found)
			break;
		while(l<length && *(buf+l)==' ') l++;
		for(i=0;l<length && *(buf+l)!=LF && i<128;i++,l++)
			str[i]=buf[l];
		if(!i)
			break;
		str[i]=0;
		p=strrchr(str,'@');
		if(p) {
			addr=atofaddr(&cfg,p+1);
			*p=0;
			SAFECOPY(hdr.to,str); 
		}
		else {
			atofaddr(&cfg,str);
			strcpy(hdr.to,"Sysop"); 
		}
		hdr.destzone	=addr.zone;
		hdr.destnet 	=addr.net;
		hdr.destnode	=addr.node;
		hdr.destpoint	=addr.point;
		cc_sent++; 
	}

	if(cfg.netmail_sem[0])		/* update semaphore file */
		ftouch(cmdstr(cfg.netmail_sem,nulstr,nulstr,NULL));

	free(buf);
	return(true);
}
Esempio n. 10
0
static int receive_files(char** fname_list, int fnames)
{
	char	str[MAX_PATH+1];
	char	fname[MAX_PATH+1];
	int		i;
	int		fnum=0;
	uint	errors;
	uint	total_files=0;
	uint	cps;
	uint	wr;
	BOOL	success=FALSE;
	long	fmode;
	long	serial_num=-1;
	ulong	file_bytes=0,file_bytes_left=0;
	ulong	total_bytes=0;
	FILE*	fp;
	time_t	t,startfile,ftime;

	if(fnames>1)
		lprintf(LOG_INFO,"Receiving %u files",fnames);

	outbuf.highwater_mark=0;	/* don't delay ACK/NAK transmits */

	/* Purge input buffer */
	while(is_connected(NULL) && (i=recv_byte(NULL,0))!=NOINP)
		lprintf(LOG_WARNING,"Throwing out received: %s",chr((uchar)i));

	while(is_connected(NULL)) {
		if(mode&XMODEM) {
			SAFECOPY(str,fname_list[0]);	/* we'll have at least one fname */
			file_bytes=file_bytes_left=0x7fffffff;
		}

		else {
			if(mode&YMODEM) {
				lprintf(LOG_INFO,"Fetching Ymodem header block");
				for(errors=0;errors<=xm.max_errors && !xm.cancelled;errors++) {
					if(errors>(xm.max_errors/2) && mode&CRC && !(mode&GMODE))
						mode&=~CRC;
					xmodem_put_nak(&xm, /* expected_block: */ 0);
					if(xmodem_get_block(&xm, block, /* expected_block: */ 0) == 0) {
						send_byte(NULL,ACK,10);
						break; 
					} 
				}
				if(errors>=xm.max_errors || xm.cancelled) {
					lprintf(LOG_ERR,"Error fetching Ymodem header block");
					xmodem_cancel(&xm);
					return(1); 
				}
				if(!block[0]) {
					lprintf(LOG_INFO,"Received Ymodem termination block");
					return(0); 
				}
				file_bytes=ftime=total_files=total_bytes=0;
				i=sscanf(block+strlen(block)+1,"%ld %lo %lo %lo %d %ld"
					,&file_bytes			/* file size (decimal) */
					,&ftime 				/* file time (octal unix format) */
					,&fmode 				/* file mode (not used) */
					,&serial_num			/* program serial number */
					,&total_files			/* remaining files to be sent */
					,&total_bytes			/* remaining bytes to be sent */
					);
				lprintf(LOG_DEBUG,"Ymodem header (%u fields): %s", i, block+strlen(block)+1);
				SAFECOPY(fname,block);

			} else {	/* Zmodem */
				lprintf(LOG_INFO,"Waiting for Zmodem sender...");

				i=zmodem_recv_init(&zm);

				if(zm.cancelled)
					return(1);
				if(i<0)
					return(-1);
				switch(i) {
					case ZFILE:
						SAFECOPY(fname,zm.current_file_name);
						file_bytes = zm.current_file_size;
						ftime = zm.current_file_time;
						total_files = zm.files_remaining;
						total_bytes = zm.bytes_remaining;
						break;
					case ZFIN:
					case ZCOMPL:
						return(!success);
					default:
						return(-1);
				}
			}

			if(!file_bytes)
				file_bytes=0x7fffffff;
			file_bytes_left=file_bytes;
			if(!total_files)
				total_files=fnames-fnum;
			if(!total_files)
				total_files=1;
			if(total_bytes<file_bytes)
				total_bytes=file_bytes;

			lprintf(LOG_DEBUG,"Incoming filename: %.64s ",fname);

			if(mode&RECVDIR)
				sprintf(str,"%s%s",fname_list[0],getfname(fname));
			else {
				SAFECOPY(str,getfname(fname));
				for(i=0;i<fnames;i++) {
					if(!fname_list[i][0])	/* name blank or already used */
						continue;
					if(!stricmp(getfname(fname_list[i]),str)) {
						SAFECOPY(str,fname_list[i]);
						fname_list[i][0]=0;
						break; 
					} 
				}
				if(i==fnames) { 				/* Not found in list */
					if(fnames)
						fprintf(statfp," - Not in receive list!");
					if(!fnames || fnum>=fnames || !fname_list[fnum][0])
						SAFECOPY(str,getfname(fname));	/* worst case */
					else {
						SAFECOPY(str,fname_list[fnum]);
						fname_list[fnum][0]=0; 
					} 
				} 
			}
			fprintf(statfp,"File size: %lu bytes\n", file_bytes);
			if(total_files>1)
				fprintf(statfp,"Remaining: %lu bytes in %u files\n", total_bytes, total_files);
		}

		lprintf(LOG_DEBUG,"Receiving: %.64s ",str);

		fnum++;

		if(!(mode&RECVDIR) && fnames && fnum>fnames) {
			lprintf(LOG_WARNING,"Attempt to send more files than specified");
			xmodem_cancel(&xm);
			break; 
		}

		if(fexistcase(str) && !(mode&OVERWRITE)) {
			lprintf(LOG_WARNING,"%s already exists",str);
			if(mode&ZMODEM) {
				zmodem_send_zskip(&zm);
				continue;
			}
			xmodem_cancel(&xm);
			return(1); 
		}
		if((fp=fnopen(NULL,str,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY))==NULL
			&& (fp=fopen(str,"wb"))==NULL) {
			lprintf(LOG_ERR,"Error %d creating %s",errno,str);
			if(mode&ZMODEM) {
				zmodem_send_zskip(&zm);
				continue;
			}
			xmodem_cancel(&xm);
			return(1); 
		}

		if(mode&XMODEM)
			lprintf(LOG_INFO,"Receiving %s via Xmodem %s"
				,str
				,mode&CRC ? "CRC-16":"Checksum");
		else
			lprintf(LOG_INFO,"Receiving %s (%lu KB) via %s %s"
				,str
				,file_bytes/1024
				,mode&YMODEM ? mode&GMODE ? "Ymodem-G" : "Ymodem" :"Zmodem"
				,mode&ZMODEM ? "" : (mode&CRC ? "CRC-16" : "Checksum"));

		startfile=time(NULL);
		success=FALSE;
		if(mode&ZMODEM) {

			errors=zmodem_recv_file_data(&zm,fp,0);

			/*
 			 * wait for the eof header
			 */

			for(;errors<=zm.max_errors && !success && !zm.cancelled; errors++) {
				if(zmodem_recv_header_and_check(&zm))
					success=TRUE;
			} 

		} else {
			errors=0;
			block_num=1;
			xmodem_put_nak(&xm, block_num);
			while(is_connected(NULL)) {
				xmodem_progress(NULL,block_num,ftell(fp),file_bytes,startfile);
				i=xmodem_get_block(&xm, block, block_num); 	

				if(i!=0) {
					if(i==EOT)	{		/* end of transfer */
						success=TRUE;
						xmodem_put_ack(&xm);
						break;
					}
					if(i==CAN) {		/* Cancel */
						xm.cancelled=TRUE;
						break;
					}

					if(mode&GMODE)
						return(-1);

					if(++errors>=xm.max_errors) {
						lprintf(LOG_ERR,"Too many errors (%u)",errors);
						xmodem_cancel(&xm);
						break;
					}
					if(block_num==1 && errors>(xm.max_errors/2) && mode&CRC && !(mode&GMODE))
						mode&=~CRC;
					xmodem_put_nak(&xm, block_num);
					continue;
				}
				if(!(mode&GMODE))
					send_byte(NULL,ACK,10);
				if(file_bytes_left<=0L)  { /* No more bytes to send */
					lprintf(LOG_WARNING,"Attempt to send more byte specified in header");
					break; 
				}
				wr=xm.block_size;
				if(wr>file_bytes_left)
					wr=file_bytes_left;
				if(fwrite(block,1,wr,fp)!=wr) {
					lprintf(LOG_ERR,"Error writing %u bytes to file at offset %lu"
						,wr,ftell(fp));
					xmodem_cancel(&xm);
					return(1); 
				}
				file_bytes_left-=wr; 
				block_num++;
			}
		}

		/* Use correct file size */
		fflush(fp);
		if(file_bytes < (ulong)filelength(fileno(fp))) {
			lprintf(LOG_INFO,"Truncating file to %lu bytes", file_bytes);
			chsize(fileno(fp),file_bytes);
		} else
			file_bytes = filelength(fileno(fp));
		fclose(fp);
		
		t=time(NULL)-startfile;
		if(!t) t=1;
		if(success)
			lprintf(LOG_INFO,"Successful - Time: %lu:%02lu  CPS: %lu"
				,t/60,t%60,file_bytes/t);	
		else
			lprintf(LOG_ERR,"File Transfer %s", aborted ? "Aborted":"Failure");

		if(!(mode&XMODEM) && ftime)
			setfdate(str,ftime); 

		if(logfp) {
			lprintf(LOG_DEBUG,"Updating DSZLOG: %s", dszlog);
			fprintf(logfp,"%c %6lu %5u bps %4lu cps %3u errors %5u %4u "
				"%s %d\n"
				,success ? (mode&ZMODEM ? 'Z' : 'R') : 'E'
				,file_bytes
				,115200	/* baud */
				,file_bytes/t
				,errors
				,flows
				,mode&ZMODEM ? zm.block_size : xm.block_size
				,dszlog_filename(str)
				,serial_num); 
			fflush(logfp);
		}

		if(aborted) {
			lprintf(LOG_DEBUG,"Locally aborted, sending cancel to remote");
			if(mode&ZMODEM)
				zmodem_abort_receive(&zm);
			xm.cancelled=FALSE;
			xmodem_cancel(&xm);
			break;
		}

		if(mode&XMODEM)	/* maximum of one file */
			break;
		if((cps=file_bytes/t)==0)
			cps=1;
		total_files--;
		total_bytes-=file_bytes;
		if(total_files>1 && total_bytes)
			lprintf(LOG_INFO,"Remaining - Time: %lu:%02lu  Files: %u  KBytes: %lu"
				,(total_bytes/cps)/60
				,(total_bytes/cps)%60
				,total_files
				,total_bytes/1024
				);
	}
	return(!success);	/* 0=success */
}
Esempio n. 11
0
void sbbs_t::qwktonetmail(FILE *rep, char *block, char *into, uchar fromhub)
{
	char	*qwkbuf,to[129],name[129],sender[129],senderaddr[129]
			   ,str[256],*p,*cp,*addr,fulladdr[129],ch;
	char 	tmp[512];
	int 	i,fido,inet=0,qnet=0;
	ushort	net;
	uint16_t xlat;
	long	l,offset,length,m,n;
	faddr_t fidoaddr;
    fmsghdr_t hdr;
	smbmsg_t msg;
	struct	tm tm;

	if(useron.rest&FLAG('M')) { 
		bputs(text[NoNetMailAllowed]);
		return; 
	}

	to[0]=0;
	name[0]=0;
	sender[0]=0;
	senderaddr[0]=0;
	fulladdr[0]=0;

	sprintf(str,"%.6s",block+116);
	n=atol(str);	  /* i = number of 128 byte records */

	if(n<2L || n>999999L) {
		errormsg(WHERE,ERR_CHK,"QWK blocks",n);
		return; 
	}
	if((qwkbuf=(char *)malloc(n*QWK_BLOCK_LEN))==NULL) {
		errormsg(WHERE,ERR_ALLOC,nulstr,n*QWK_BLOCK_LEN);
		return; 
	}
	memcpy((char *)qwkbuf,block,QWK_BLOCK_LEN);
	fread(qwkbuf+QWK_BLOCK_LEN,n-1,QWK_BLOCK_LEN,rep);

	if(into==NULL)
		sprintf(to,"%-128.128s",(char *)qwkbuf+QWK_BLOCK_LEN);  /* To user on first line */
	else
		SAFECOPY(to,into);

	p=strchr(to,QWK_NEWLINE);		/* chop off at first CR */
	if(p) *p=0;

	SAFECOPY(name,to);
	p=strchr(name,'@');
	if(p) *p=0;
	truncsp(name);


	p=strrchr(to,'@');       /* Find '@' in name@addr */
	if(p && !isdigit(*(p+1)) && !strchr(p,'.') && !strchr(p,':')) { /* QWKnet */
		qnet=1;
		*p=0; 
	}
	else if(p==NULL || !isdigit(*(p+1)) || !cfg.total_faddrs) {
		if(p==NULL && cfg.dflt_faddr.zone)
			fidoaddr=cfg.dflt_faddr;
		else if(cfg.inetmail_misc&NMAIL_ALLOW) {	/* Internet */
			inet=1;
			}
		else if(cfg.dflt_faddr.zone)
			fidoaddr=cfg.dflt_faddr;
		else {
			bputs(text[InvalidNetMailAddr]);
			free(qwkbuf);
			return; 
		} 
	}
	else {
		fidoaddr=atofaddr(&cfg,p+1); 	/* Get fido address */
		*p=0;					/* Chop off address */
	}


	if(!inet && !qnet &&		/* FidoNet */
		((!SYSOP && !(cfg.netmail_misc&NMAIL_ALLOW)) || !cfg.total_faddrs)) {
		bputs(text[NoNetMailAllowed]);
		free(qwkbuf);
		return; 
	}

	truncsp(to);			/* Truncate off space */

	if(!stricmp(to,"SBBS") && !SYSOP && qnet) {
		free(qwkbuf);
		return; 
	}

	l=QWK_BLOCK_LEN;		/* Start of message text */

	if(qnet || inet) {

		if(into==NULL) {	  /* If name@addr on first line, skip first line */
			while(l<(n*QWK_BLOCK_LEN) && qwkbuf[l]!=QWK_NEWLINE) l++;
			l++; 
		}

		memset(&msg,0,sizeof(smbmsg_t));
		msg.hdr.version=smb_ver();
		msg.hdr.when_imported.time=time32(NULL);
		msg.hdr.when_imported.zone=sys_timezone(&cfg);

		if(fromhub || useron.rest&FLAG('Q')) {
			net=NET_QWK;
			smb_hfield(&msg,SENDERNETTYPE,sizeof(net),&net);
			if(!strncmp(qwkbuf+l,"@VIA:",5)) {
				sprintf(str,"%.128s",qwkbuf+l+5);
				cp=strchr(str,QWK_NEWLINE);
				if(cp) *cp=0;
				l+=strlen(str)+1;
				cp=str;
				while(*cp && *cp<=' ') cp++;
				sprintf(senderaddr,"%s/%s"
					,fromhub ? cfg.qhub[fromhub-1]->id : useron.alias,cp);
				strupr(senderaddr);
				smb_hfield(&msg,SENDERNETADDR,strlen(senderaddr),senderaddr); 
			}
			else {
				if(fromhub)
					SAFECOPY(senderaddr, cfg.qhub[fromhub-1]->id);
				else
					SAFECOPY(senderaddr, useron.alias);
				strupr(senderaddr);
				smb_hfield(&msg,SENDERNETADDR,strlen(senderaddr),senderaddr); 
			}
			sprintf(sender,"%.25s",block+46);     /* From name */
		}
		else {	/* Not Networked */
			msg.hdr.when_written.zone=sys_timezone(&cfg);
			sprintf(str,"%u",useron.number);
			smb_hfield(&msg,SENDEREXT,strlen(str),str);
			SAFECOPY(sender,(qnet || cfg.inetmail_misc&NMAIL_ALIAS)
				? useron.alias : useron.name);
			}
		truncsp(sender);
		smb_hfield(&msg,SENDER,strlen(sender),sender);
		if(fromhub)
			msg.idx.from=0;
		else
			msg.idx.from=useron.number;
		if(!strncmp(qwkbuf+l,"@TZ:",4)) {
			sprintf(str,"%.128s",qwkbuf+l);
			cp=strchr(str,QWK_NEWLINE);
			if(cp) *cp=0;
			l+=strlen(str)+1;
			cp=str+4;
			while(*cp && *cp<=' ') cp++;
			msg.hdr.when_written.zone=(short)ahtoul(cp); 
		}
		else
			msg.hdr.when_written.zone=sys_timezone(&cfg);
		memset(&tm,0,sizeof(tm));
		tm.tm_mon=((qwkbuf[8]&0xf)*10)+(qwkbuf[9]&0xf);
		if(tm.tm_mon) tm.tm_mon--;	/* 0 based */
		tm.tm_mday=((qwkbuf[11]&0xf)*10)+(qwkbuf[12]&0xf);
		tm.tm_year=((qwkbuf[14]&0xf)*10)+(qwkbuf[15]&0xf);
		if(tm.tm_year<Y2K_2DIGIT_WINDOW)
			tm.tm_year+=100;
		tm.tm_hour=((qwkbuf[16]&0xf)*10)+(qwkbuf[17]&0xf);
		tm.tm_min=((qwkbuf[19]&0xf)*10)+(qwkbuf[20]&0xf);  /* From QWK time */
		tm.tm_sec=0;

		tm.tm_isdst=-1;	/* Do not adjust for DST */
		msg.hdr.when_written.time=mktime32(&tm);

		sprintf(str,"%.25s",block+71);              /* Title */
		smb_hfield(&msg,SUBJECT,strlen(str),str);
	}

	if(qnet) {

		p++;
		addr=p;
		msg.idx.to=qwk_route(addr,fulladdr);
		if(!fulladdr[0]) {		/* Invalid address, so BOUNCE it */
		/**
			errormsg(WHERE,ERR_CHK,addr,0);
			free(qwkbuf);
			smb_freemsgmem(msg);
			return;
		**/
			smb_hfield(&msg,SENDER,strlen(cfg.sys_id),cfg.sys_id);
			msg.idx.from=0;
			msg.idx.to=useron.number;
			SAFECOPY(to,sender);
			SAFECOPY(fulladdr,senderaddr);
			SAFEPRINTF(str,"BADADDR: %s",addr);
			smb_hfield(&msg,SUBJECT,strlen(str),str);
			net=NET_NONE;
			smb_hfield(&msg,SENDERNETTYPE,sizeof(net),&net);
		}
		/* This is required for fixsmb to be able to rebuild the index */
		SAFEPRINTF(str,"%u",msg.idx.to);
		smb_hfield_str(&msg,RECIPIENTEXT,str);

		smb_hfield(&msg,RECIPIENT,strlen(name),name);
		net=NET_QWK;
		smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(net),&net);

		truncsp(fulladdr);
		if(fulladdr[0])
			smb_hfield(&msg,RECIPIENTNETADDR,strlen(fulladdr),fulladdr);

		bprintf(text[NetMailing],to,fulladdr,sender,cfg.sys_id); 
	}

	if(inet) {				/* Internet E-mail */

		if(cfg.inetmail_cost && !(useron.exempt&FLAG('S'))) {
			if(useron.cdt+useron.freecdt<cfg.inetmail_cost) {
				bputs(text[NotEnoughCredits]);
				free(qwkbuf);
				smb_freemsgmem(&msg);
				return; 
			}
			sprintf(str,text[NetMailCostContinueQ],cfg.inetmail_cost);
			if(noyes(str)) {
				free(qwkbuf);
				smb_freemsgmem(&msg);
				return; 
			} 
		}

		net=NET_INTERNET;
		smb_hfield(&msg,RECIPIENT,strlen(name),name);
		msg.idx.to=0;   /* Out-bound NetMail set to 0 */
		smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(net),&net);
		smb_hfield(&msg,RECIPIENTNETADDR,strlen(to),to);

		bprintf(text[NetMailing],name,to
			,cfg.inetmail_misc&NMAIL_ALIAS ? useron.alias : useron.name
			,cfg.sys_inetaddr); 
	}

	if(qnet || inet) {

		bputs(text[WritingIndx]);

		if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) {
			errormsg(WHERE,ERR_OPEN,"MAIL",i);
			free(qwkbuf);
			smb_freemsgmem(&msg);
			return; 
		}
		sprintf(smb.file,"%smail", cfg.data_dir);
		smb.retry_time=cfg.smb_retry_time;
		smb.subnum=INVALID_SUB;
		if((i=smb_open(&smb))!=0) {
			smb_stack(&smb,SMB_STACK_POP);
			errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
			free(qwkbuf);
			smb_freemsgmem(&msg);
			return; 
		}

		if(smb_fgetlength(smb.shd_fp)<1L) {   /* Create it if it doesn't exist */
			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((i=smb_create(&smb))!=0) {
				smb_close(&smb);
				smb_stack(&smb,SMB_STACK_POP);
				errormsg(WHERE,ERR_CREATE,smb.file,i,smb.last_error);
				free(qwkbuf);
				smb_freemsgmem(&msg);
				return; 
			} 
		}

		length=n*256L;	// Extra big for CRLF xlat, was (n-1L)*256L (03/16/96)


		if(length&0xfff00000UL || !length) {
			smb_close(&smb);
			smb_stack(&smb,SMB_STACK_POP);
			sprintf(str,"REP msg (%ld)",n);
			errormsg(WHERE,ERR_LEN,str,length);
			free(qwkbuf);
			smb_freemsgmem(&msg);
			return; 
		}

		if((i=smb_open_da(&smb))!=0) {
			smb_close(&smb);
			smb_stack(&smb,SMB_STACK_POP);
			errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
			free(qwkbuf);
			smb_freemsgmem(&msg);
			return; 
		}
		if(cfg.sys_misc&SM_FASTMAIL)
			offset=smb_fallocdat(&smb,length,1);
		else
			offset=smb_allocdat(&smb,length,1);
		smb_close_da(&smb);

		smb_fseek(smb.sdt_fp,offset,SEEK_SET);
		xlat=XLAT_NONE;
		smb_fwrite(&smb,&xlat,2,smb.sdt_fp);
		m=2;
		for(;l<n*QWK_BLOCK_LEN && m<length;l++) {
			if(qwkbuf[l]==0 || qwkbuf[l]==LF)
				continue;
			if(qwkbuf[l]==QWK_NEWLINE) {
				smb_fwrite(&smb,crlf,2,smb.sdt_fp);
				m+=2;
				continue; 
			}
			smb_fputc(qwkbuf[l],smb.sdt_fp);
			m++; 
		}

		for(ch=0;m<length;m++)			/* Pad out with NULLs */
			smb_fputc(ch,smb.sdt_fp);
		smb_fflush(smb.sdt_fp);

		msg.hdr.offset=offset;

		smb_dfield(&msg,TEXT_BODY,length);

		i=smb_addmsghdr(&smb,&msg,SMB_SELFPACK);
		smb_close(&smb);
		smb_stack(&smb,SMB_STACK_POP);

		smb_freemsgmem(&msg);
		if(i!=SMB_SUCCESS) {
			errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); 
			smb_freemsgdat(&smb,offset,length,1);
		}
		else {		/* Successful */
			if(inet) {
				if(cfg.inetmail_sem[0]) 	 /* update semaphore file */
					ftouch(cmdstr(cfg.inetmail_sem,nulstr,nulstr,NULL));
				if(!(useron.exempt&FLAG('S')))
					subtract_cdt(&cfg,&useron,cfg.inetmail_cost); 
			}

			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));

			sprintf(str,"%s sent %s NetMail to %s (%s) via QWK"
				,useron.alias
				,qnet ? "QWK":"Internet",name,qnet ? fulladdr : to);
			logline("EN",str); 
		}

		free((char *)qwkbuf);
		return; 
	}


	/****************************** FidoNet **********************************/

	if(!fidoaddr.zone || !cfg.netmail_dir[0]) {  // No fido netmail allowed
		bputs(text[InvalidNetMailAddr]);
		free(qwkbuf);
		return; 
	}

	memset(&hdr,0,sizeof(hdr));   /* Initialize header to null */

	if(fromhub || useron.rest&FLAG('Q')) {
		sprintf(str,"%.25s",block+46);              /* From */
		truncsp(str);
		sprintf(tmp,"@%s",fromhub ? cfg.qhub[fromhub-1]->id : useron.alias);
		strupr(tmp);
		strcat(str,tmp); 
	}
	else
		SAFECOPY(str,cfg.netmail_misc&NMAIL_ALIAS ? useron.alias : useron.name);
	SAFECOPY(hdr.from,str);

	SAFECOPY(hdr.to,to);

	/* Look-up in nodelist? */

	if(cfg.netmail_cost && !(useron.exempt&FLAG('S'))) {
		if(useron.cdt+useron.freecdt<cfg.netmail_cost) {
			bputs(text[NotEnoughCredits]);
			free(qwkbuf);
			return; 
		}
		sprintf(str,text[NetMailCostContinueQ],cfg.netmail_cost);
		if(noyes(str)) {
			free(qwkbuf);
			return; 
		} 
	}

	hdr.destzone	=fidoaddr.zone;
	hdr.destnet 	=fidoaddr.net;
	hdr.destnode	=fidoaddr.node;
	hdr.destpoint	=fidoaddr.point;

	for(i=0;i<cfg.total_faddrs;i++)
		if(fidoaddr.zone==cfg.faddr[i].zone && fidoaddr.net==cfg.faddr[i].net)
			break;
	if(i==cfg.total_faddrs) {
		for(i=0;i<cfg.total_faddrs;i++)
			if(fidoaddr.zone==cfg.faddr[i].zone)
				break; 
	}
	if(i==cfg.total_faddrs)
		i=0;
	hdr.origzone	=cfg.faddr[i].zone;
	hdr.orignet 	=cfg.faddr[i].net;
	hdr.orignode	=cfg.faddr[i].node;
	hdr.origpoint   =cfg.faddr[i].point;

	smb_faddrtoa(&cfg.faddr[i],str);
	bprintf(text[NetMailing],hdr.to,smb_faddrtoa(&fidoaddr,tmp),hdr.from,str);
	tm.tm_mon=((qwkbuf[8]&0xf)*10)+(qwkbuf[9]&0xf);
	if (tm.tm_mon) tm.tm_mon--;
	tm.tm_mday=((qwkbuf[11]&0xf)*10)+(qwkbuf[12]&0xf);
	tm.tm_year=((qwkbuf[14]&0xf)*10)+(qwkbuf[15]&0xf)+1900;
	tm.tm_hour=((qwkbuf[16]&0xf)*10)+(qwkbuf[17]&0xf);
	tm.tm_min=((qwkbuf[19]&0xf)*10)+(qwkbuf[20]&0xf);		/* From QWK time */
	tm.tm_sec=0;
	sprintf(hdr.time,"%02u %3.3s %02u  %02u:%02u:%02u"          /* To FidoNet */
		,tm.tm_mday,mon[tm.tm_mon],TM_YEAR(tm.tm_year)
		,tm.tm_hour,tm.tm_min,tm.tm_sec);
	hdr.attr=(FIDO_LOCAL|FIDO_PRIVATE);

	if(cfg.netmail_misc&NMAIL_CRASH) hdr.attr|=FIDO_CRASH;
	if(cfg.netmail_misc&NMAIL_HOLD)  hdr.attr|=FIDO_HOLD;
	if(cfg.netmail_misc&NMAIL_KILL)  hdr.attr|=FIDO_KILLSENT;

	sprintf(str,"%.25s",block+71);      /* Title */
	truncsp(str);
	p=str;
	if((SYSOP || useron.exempt&FLAG('F'))
		&& !strnicmp(p,"CR:",3)) {     /* Crash over-ride by sysop */
		p+=3;               /* skip CR: */
		if(*p==' ') p++;     /* skip extra space if it exists */
		hdr.attr|=FIDO_CRASH; 
	}

	if((SYSOP || useron.exempt&FLAG('F'))
		&& !strnicmp(p,"FR:",3)) {     /* File request */
		p+=3;               /* skip FR: */
		if(*p==' ') p++;
		hdr.attr|=FIDO_FREQ; 
	}

	if((SYSOP || useron.exempt&FLAG('F'))
		&& !strnicmp(p,"RR:",3)) {     /* Return receipt request */
		p+=3;               /* skip RR: */
		if(*p==' ') p++;
		hdr.attr|=FIDO_RRREQ; 
	}

	if((SYSOP || useron.exempt&FLAG('F'))
		&& !strnicmp(p,"FA:",3)) {     /* File attachment */
		p+=3;				/* skip FA: */
		if(*p==' ') p++;
		hdr.attr|=FIDO_FILE; 
	}

	SAFECOPY(hdr.subj,p);

	md(cfg.netmail_dir);
	for(i=1;i;i++) {
		sprintf(str,"%s%u.msg", cfg.netmail_dir,i);
		if(!fexistcase(str))
			break; 
	}
	if(!i) {
		bputs(text[TooManyEmailsToday]);
		return; 
	}
	if((fido=nopen(str,O_WRONLY|O_CREAT|O_EXCL))==-1) {
		free(qwkbuf);
		errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_EXCL);
		return; 
	}
	write(fido,&hdr,sizeof(hdr));

	pt_zone_kludge(hdr,fido);

	if(cfg.netmail_misc&NMAIL_DIRECT) {
		sprintf(str,"\1FLAGS DIR\r\n");
		write(fido,str,strlen(str)); 
	}

	l=QWK_BLOCK_LEN;

	if(into==NULL) {	  /* If name@addr on first line, skip first line */
		while(l<n*QWK_BLOCK_LEN && qwkbuf[l]!=QWK_NEWLINE) l++;
		l++; 
	}

	length=n*QWK_BLOCK_LEN;
	while(l<length) {
		if(qwkbuf[l]==CTRL_A) {   /* Ctrl-A, so skip it and the next char */
			l++;
			if(l>=length || toupper(qwkbuf[l])=='Z')	/* EOF */
				break;
			if((ch=ctrl_a_to_ascii_char(qwkbuf[l])) != 0)
				write(fido,&ch,1);
		}
		else if(qwkbuf[l]!=LF) {
			if(qwkbuf[l]==QWK_NEWLINE) /* QWK cr/lf char converted to hard CR */
				qwkbuf[l]=CR;
			write(fido,(char *)qwkbuf+l,1); 
		}
		l++;
	}
	l=0;
	write(fido,&l,1);	/* Null terminator */
	close(fido);
	free((char *)qwkbuf);
	if(cfg.netmail_sem[0])		/* update semaphore file */
		ftouch(cmdstr(cfg.netmail_sem,nulstr,nulstr,NULL));
	if(!(useron.exempt&FLAG('S')))
		subtract_cdt(&cfg,&useron,cfg.netmail_cost);

	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));

	sprintf(str,"%s sent NetMail to %s @%s via QWK"
		,useron.alias
		,hdr.to,smb_faddrtoa(&fidoaddr,tmp));
	logline("EN",str);
}
Esempio n. 12
0
bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack)
{
	char	str[MAX_PATH+1],ch,*p;
	char 	tmp[MAX_PATH+1],tmp2[MAX_PATH+1];
	char*	fname;
	char*	fmode;
	int 	mode;
	uint	i,j,k,conf;
	long	l,size,msgndx,posts,ex;
	long	mailmsgs=0;
	ulong	totalcdt,totaltime,lastmsg
			,files,submsgs,msgs,netfiles=0,preqwk=0;
	ulong	subs_scanned=0;
	float	f;	/* Sparky is responsible */
	time_t	start;
	node_t	node;
	mail_t	*mail;
	post_t	*post;
	glob_t	g;
	FILE	*stream,*qwk,*personal,*ndx;
	DIR*	dir;
	DIRENT*	dirent;
	struct	tm tm;
	smbmsg_t msg;

	ex=EX_OUTL|EX_OUTR;	/* Need sh for wildcard expansion */
	if(prepack)
		ex|=EX_OFFLINE;

	delfiles(cfg.temp_dir,ALLFILES);
	sprintf(str,"%sfile/%04u.qwk",cfg.data_dir,useron.number);
	if(fexistcase(str)) {
		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;
		p=cmdstr(cfg.fextr[k]->cmd,str,ALLFILES,NULL);
		if((i=external(p,ex))==0)
			preqwk=1; 
		else 
			errormsg(WHERE,ERR_EXEC,p,i);
	}

	if(useron.rest&FLAG('Q') && useron.qwk&QWK_RETCTLA)
		useron.qwk|=(QWK_NOINDEX|QWK_NOCTRL|QWK_VIA|QWK_TZ|QWK_MSGID);

	if(useron.qwk&QWK_EXPCTLA)
		mode=A_EXPAND;
	else if(useron.qwk&QWK_RETCTLA)
		mode=A_LEAVE;
	else mode=0;
	if(useron.qwk&QWK_TZ)
		mode|=QM_TZ;
	if(useron.qwk&QWK_VIA)
		mode|=QM_VIA;
	if(useron.qwk&QWK_MSGID)
		mode|=QM_MSGID;

	(*msgcnt)=0L;
	if(/* !prepack && */ !(useron.qwk&QWK_NOCTRL)) {
		/***************************/
		/* Create CONTROL.DAT file */
		/***************************/
		sprintf(str,"%sCONTROL.DAT",cfg.temp_dir);
		if((stream=fopen(str,"wb"))==NULL) {
			errormsg(WHERE,ERR_OPEN,str,0);
			return(false); 
		}

		now=time(NULL);
		if(localtime_r(&now,&tm)==NULL)
			return(false);

		fprintf(stream,"%s\r\n%s\r\n%s\r\n%s, Sysop\r\n0000,%s\r\n"
			"%02u-%02u-%u,%02u:%02u:%02u\r\n"
			,cfg.sys_name
			,cfg.sys_location
			,cfg.node_phone
			,cfg.sys_op
			,cfg.sys_id
			,tm.tm_mon+1,tm.tm_mday,tm.tm_year+1900
			,tm.tm_hour,tm.tm_min,tm.tm_sec);
		k=0;
		for(i=0;i<usrgrps;i++)
			for(j=0;j<usrsubs[i];j++)
				k++;	/* k is how many subs */
		fprintf(stream,"%s\r\n\r\n0\r\n0\r\n%u\r\n",useron.alias,k);
		fprintf(stream,"0\r\nE-mail\r\n");   /* first conference is e-mail */
		char confname[256];
		for(i=0;i<usrgrps;i++) 
			for(j=0;j<usrsubs[i];j++) {
				if(useron.qwk&QWK_EXT)	/* 255 char max */
					sprintf(confname,"%s %s"
						,cfg.grp[cfg.sub[usrsub[i][j]]->grp]->sname
						,cfg.sub[usrsub[i][j]]->lname);
				else					/* 10 char max */
					strcpy(confname,cfg.sub[usrsub[i][j]]->qwkname);
				fprintf(stream,"%u\r\n%s\r\n"
					,cfg.sub[usrsub[i][j]]->qwkconf ? cfg.sub[usrsub[i][j]]->qwkconf
					: ((i+1)*1000)+j+1,confname);
			}
		fprintf(stream,"HELLO\r\nBBSNEWS\r\nGOODBYE\r\n");
		fclose(stream);
		/***********************/
		/* Create DOOR.ID File */
		/***********************/
		sprintf(str,"%sDOOR.ID",cfg.temp_dir);
		if((stream=fopen(str,"wb"))==NULL) {
			errormsg(WHERE,ERR_OPEN,str,0);
			return(false); 
		}
		p="CONTROLTYPE = ";
		fprintf(stream,"DOOR = %.10s\r\nVERSION = %s%c\r\n"
			"SYSTEM = %s\r\n"
			"CONTROLNAME = SBBS\r\n"
			"%sADD\r\n"
			"%sDROP\r\n"
			"%sYOURS\r\n"
			"%sRESET\r\n"
			"%sRESETALL\r\n"
			"%sFILES\r\n"
			"%sATTACH\r\n"
			"%sOWN\r\n"
			"%smail\r\n"
			"%sDELMAIL\r\n"
			"%sCTRL-A\r\n"
			"%sFREQ\r\n"
			"%sNDX\r\n"
			"%sTZ\r\n"
			"%sVIA\r\n"
			"%sCONTROL\r\n"
			"MIXEDCASE = YES\r\n"
			,VERSION_NOTICE
			,VERSION,REVISION
			,VERSION_NOTICE
			,p,p,p,p
			,p,p,p,p
			,p,p,p,p
			,p,p,p,p
			);
		fclose(stream);
		if(useron.rest&FLAG('Q')) {
			/***********************/
			/* Create NETFLAGS.DAT */
			/***********************/
			sprintf(str,"%sNETFLAGS.DAT",cfg.temp_dir);
			if((stream=fopen(str,"wb"))==NULL) {
				errormsg(WHERE,ERR_CREATE,str,0);
				return(false); 
			}
			ch=1;						/* Net enabled */
			if(usrgrps)
				for(i=0;i<(usrgrps*1000)+usrsubs[usrgrps-1];i++)
					fputc(ch,stream);
			fclose(stream); 
		}
	}

	/****************************************************/
	/* Create MESSAGES.DAT, write header and leave open */
	/****************************************************/
	sprintf(str,"%sMESSAGES.DAT",cfg.temp_dir);
	if(fexistcase(str))
		fmode="r+b";
	else
		fmode="w+b";
	if((qwk=fopen(str,fmode))==NULL) {
		errormsg(WHERE,ERR_OPEN,str,0);
		return(false); 
	}
	l=filelength(fileno(qwk));
	if(l<1) {
		fprintf(qwk,"%-128.128s","Produced by " VERSION_NOTICE "  " COPYRIGHT_NOTICE);
		msgndx=1; 
	} else {
		msgndx=l/QWK_BLOCK_LEN;
		fseek(qwk,0,SEEK_END);
	}
	sprintf(str,"%sNEWFILES.DAT",cfg.temp_dir);
	remove(str);
	if(!(useron.rest&FLAG('T')) && useron.qwk&QWK_FILES)
		files=create_filelist("NEWFILES.DAT",FL_ULTIME);
	else
		files=0;

	start=time(NULL);

	if(useron.rest&FLAG('Q'))
		useron.qwk|=(QWK_EMAIL|QWK_ALLMAIL|QWK_DELMAIL);

	if(!(useron.qwk&QWK_NOINDEX)) {
		sprintf(str,"%sPERSONAL.NDX",cfg.temp_dir);
		if((personal=fopen(str,"ab"))==NULL) {
			fclose(qwk);
			errormsg(WHERE,ERR_OPEN,str,0);
			return(false); 
		}
	}
	else
		personal=NULL;

	if(useron.qwk&(QWK_EMAIL|QWK_ALLMAIL) /* && !prepack */) {
		sprintf(smb.file,"%smail",cfg.data_dir);
		smb.retry_time=cfg.smb_retry_time;
		smb.subnum=INVALID_SUB;
		if((i=smb_open(&smb))!=0) {
			fclose(qwk);
			if(personal)
				fclose(personal);
			errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
			return(false); 
		}

		/***********************/
		/* Pack E-mail, if any */
		/***********************/
		qwkmail_last=0;
		mail=loadmail(&smb,&mailmsgs,useron.number,0,useron.qwk&QWK_ALLMAIL ? 0
			: LM_UNREAD);
		if(mailmsgs && !(sys_status&SS_ABORT)) {
			bputs(text[QWKPackingEmail]);
			if(!(useron.qwk&QWK_NOINDEX)) {
				sprintf(str,"%s000.NDX",cfg.temp_dir);
				if((ndx=fopen(str,"ab"))==NULL) {
					fclose(qwk);
					if(personal)
						fclose(personal);
					smb_close(&smb);
					errormsg(WHERE,ERR_OPEN,str,0);
					free(mail);
					return(false); 
				}
			}
			else
				ndx=NULL;

			if(useron.rest&FLAG('Q'))
				mode|=QM_TO_QNET;
			else
				mode&=~QM_TO_QNET;

			for(l=0;l<mailmsgs;l++) {
				bprintf("\b\b\b\b\b\b\b\b\b\b\b\b%4lu of %-4lu"
					,l+1,mailmsgs);

				memset(&msg,0,sizeof(msg));
				msg.idx=mail[l];
				if(msg.idx.number>qwkmail_last)
					qwkmail_last=msg.idx.number;
				if(!loadmsg(&msg,mail[l].number))
					continue;

				if(msg.hdr.auxattr&MSG_FILEATTACH && useron.qwk&QWK_ATTACH) {
					sprintf(str,"%sfile/%04u.in/%s"
						,cfg.data_dir,useron.number,msg.subj);
					sprintf(tmp,"%s%s",cfg.temp_dir,msg.subj);
					if(fexistcase(str) && !fexistcase(tmp))
						mv(str,tmp,1); 
				}

				size=msgtoqwk(&msg,qwk,mode,INVALID_SUB,0);
				smb_unlockmsghdr(&smb,&msg);
				smb_freemsgmem(&msg);
				if(ndx) {
					msgndx++;
					f=ltomsbin(msgndx); 	/* Record number */
					ch=0;					/* Sub number, not used */
					if(personal) {
						fwrite(&f,4,1,personal);
						fwrite(&ch,1,1,personal); 
					}
					fwrite(&f,4,1,ndx);
					fwrite(&ch,1,1,ndx);
					msgndx+=size/QWK_BLOCK_LEN; 
				} 
				YIELD();	/* yield */
			}
			bprintf(text[QWKPackedEmail],mailmsgs);
			if(ndx)
				fclose(ndx); 
		}
		smb_close(&smb);					/* Close the e-mail */
		if(mailmsgs)
			free(mail);
		}

	/*********************/
	/* Pack new messages */
	/*********************/
	for(i=0;i<usrgrps;i++) {
		for(j=0;j<usrsubs[i] && !msgabort();j++) {
			if(subscan[usrsub[i][j]].cfg&SUB_CFG_NSCAN
				|| (!(useron.rest&FLAG('Q'))
				&& cfg.sub[usrsub[i][j]]->misc&SUB_FORCED)) {
				if(!chk_ar(cfg.sub[usrsub[i][j]]->read_ar,&useron))
					continue;
				lncntr=0;						/* defeat pause */
				if(useron.rest&FLAG('Q') && !(cfg.sub[usrsub[i][j]]->misc&SUB_QNET))
					continue;	/* QWK Net Node and not QWK networked, so skip */

				subs_scanned++;
				msgs=getlastmsg(usrsub[i][j],&lastmsg,0);
				if(!msgs || lastmsg<=subscan[usrsub[i][j]].ptr) { /* no msgs */
					if(subscan[usrsub[i][j]].ptr>lastmsg)	{ /* corrupted ptr */
						outchar('*');
						subscan[usrsub[i][j]].ptr=lastmsg; /* so fix automatically */
						subscan[usrsub[i][j]].last=lastmsg; 
					}
					bprintf(text[NScanStatusFmt]
						,cfg.grp[cfg.sub[usrsub[i][j]]->grp]->sname
						,cfg.sub[usrsub[i][j]]->lname,0L,msgs);
					continue; 
				}

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

				k=0;
				if(useron.qwk&QWK_BYSELF)
					k|=LP_BYSELF;
				if(useron.rest&FLAG('Q') || !(subscan[usrsub[i][j]].cfg&SUB_CFG_YSCAN))
					k|=LP_OTHERS;
				post=loadposts(&posts,usrsub[i][j],subscan[usrsub[i][j]].ptr,k);

				bprintf(text[NScanStatusFmt]
					,cfg.grp[cfg.sub[usrsub[i][j]]->grp]->sname
					,cfg.sub[usrsub[i][j]]->lname,posts,msgs);
				if(!posts)	{ /* no new messages */
					smb_close(&smb);
					continue; 
				}
				bputs(text[QWKPackingSubboard]);	
				submsgs=0;
				conf=cfg.sub[usrsub[i][j]]->qwkconf;
				if(!conf)
					conf=((i+1)*1000)+j+1;

				if(!(useron.qwk&QWK_NOINDEX)) {
					sprintf(str,"%s%u.NDX",cfg.temp_dir,conf);
					if((ndx=fopen(str,"ab"))==NULL) {
						fclose(qwk);
						if(personal)
							fclose(personal);
						smb_close(&smb);
						errormsg(WHERE,ERR_OPEN,str,0);
						free(post);
						return(false); 
					}
				}
				else
					ndx=NULL;

				for(l=0;l<posts && !msgabort();l++) {
					bprintf("\b\b\b\b\b%-5lu",l+1);

					subscan[usrsub[i][j]].ptr=post[l].number;	/* set ptr */
					subscan[usrsub[i][j]].last=post[l].number; /* set last read */

					memset(&msg,0,sizeof(msg));
					msg.idx=post[l];
					if(!loadmsg(&msg,post[l].number))
						continue;

					if(useron.rest&FLAG('Q')) {
						if(msg.from_net.type && msg.from_net.type!=NET_QWK &&
							!(cfg.sub[usrsub[i][j]]->misc&SUB_GATE)) { /* From other */
							smb_freemsgmem(&msg);			 /* net, don't gate */
							smb_unlockmsghdr(&smb,&msg);
							continue; 
						}
						mode|=(QM_TO_QNET|QM_TAGLINE);
						if(msg.from_net.type==NET_QWK) {
							mode&=~QM_TAGLINE;
							if(route_circ((char *)msg.from_net.addr,useron.alias)
								|| !strnicmp(msg.subj,"NE:",3)) {
								smb_freemsgmem(&msg);
								smb_unlockmsghdr(&smb,&msg);
								continue; 
							} 
						} 
					}
					else
						mode&=~(QM_TAGLINE|QM_TO_QNET);

					size=msgtoqwk(&msg,qwk,mode,usrsub[i][j],conf);
					smb_unlockmsghdr(&smb,&msg);

					if(ndx) {
						msgndx++;
						f=ltomsbin(msgndx); 	/* Record number */
						ch=0;					/* Sub number, not used */
						if(personal
							&& (!stricmp(msg.to,useron.alias)
								|| !stricmp(msg.to,useron.name))) {
							fwrite(&f,4,1,personal);
							fwrite(&ch,1,1,personal); 
						}
						fwrite(&f,4,1,ndx);
						fwrite(&ch,1,1,ndx);
						msgndx+=size/QWK_BLOCK_LEN; 
					}

					smb_freemsgmem(&msg);
					(*msgcnt)++;
					submsgs++;
					if(cfg.max_qwkmsgs
						&& !(useron.exempt&FLAG('O')) && (*msgcnt)>=cfg.max_qwkmsgs) {
						bputs(text[QWKmsgLimitReached]);
						break; 
					} 
					if(!(l%50))
						YIELD();	/* yield */
				}
				if(!(sys_status&SS_ABORT))
					bprintf(text[QWKPackedSubboard],submsgs,(*msgcnt));
				if(ndx) {
					fclose(ndx);
					sprintf(str,"%s%u.NDX",cfg.temp_dir,conf);
					if(!flength(str))
						remove(str); 
				}
				smb_close(&smb);
				free(post);
				if(l<posts)
					break; 
				YIELD();	/* yield */
			}
		}
		if(j<usrsubs[i]) /* if sub aborted, abort all */
			break; 
	}

	if(online==ON_LOCAL) /* event */
		eprintf(LOG_INFO,"%s scanned %lu sub-boards for new messages"
			,useron.alias,subs_scanned);
	else
		lprintf(LOG_INFO,"Node %d %s scanned %lu sub-boards for new messages"
			,cfg.node_num,useron.alias,subs_scanned);

	if((*msgcnt)+mailmsgs && time(NULL)-start) {
		bprintf("\r\n\r\n\1n\1hPacked %lu messages (%lu bytes) in %lu seconds "
			"(%lu messages/second)."
			,(*msgcnt)+mailmsgs
			,ftell(qwk)
			,time(NULL)-start
			,((*msgcnt)+mailmsgs)/(time(NULL)-start));
		sprintf(str,"Packed %lu messages (%lu bytes) in %lu seconds (%lu msgs/sec)"
			,(*msgcnt)+mailmsgs
			,ftell(qwk)
			,(ulong)(time(NULL)-start)
			,((*msgcnt)+mailmsgs)/(time(NULL)-start));
		if(online==ON_LOCAL) /* event */
			eprintf(LOG_INFO,"%s",str);
		else
			lprintf(LOG_INFO,"%s",str);
	}

	fclose(qwk);			/* close MESSAGE.DAT */
	if(personal) {
		fclose(personal);		 /* close PERSONAL.NDX */
		sprintf(str,"%sPERSONAL.NDX",cfg.temp_dir);
		if(!flength(str))
			remove(str); 
	}
	CRLF;

	if(!prepack && (sys_status&SS_ABORT || !online))
		return(false);

	if(/*!prepack && */ useron.rest&FLAG('Q')) { /* If QWK Net node, check for files */
		sprintf(str,"%sqnet/%s.out/",cfg.data_dir,useron.alias);
		dir=opendir(str);
		while(dir!=NULL && (dirent=readdir(dir))!=NULL) {    /* Move files into temp dir */
			sprintf(str,"%sqnet/%s.out/%s",cfg.data_dir,useron.alias,dirent->d_name);
			if(isdir(str))
				continue;
			sprintf(tmp2,"%s%s",cfg.temp_dir,dirent->d_name);
			lncntr=0;	/* Default pause */
			if(online==ON_LOCAL)
				eprintf(LOG_INFO,"Including %s in packet",str);
			else
				lprintf(LOG_INFO,"Including %s in packet",str);
			bprintf(text[RetrievingFile],str);
			if(!mv(str,tmp2,1))
				netfiles++;
		}
		if(dir!=NULL)
			closedir(dir);
		if(netfiles)
			CRLF; 
	}

	if(batdn_total) {
		for(i=0,totalcdt=0;i<batdn_total;i++)
			if(!is_download_free(&cfg,batdn_dir[i],&useron))
				totalcdt+=batdn_cdt[i];
		if(totalcdt>useron.cdt+useron.freecdt) {
			bprintf(text[YouOnlyHaveNCredits]
				,ultoac(useron.cdt+useron.freecdt,tmp)); 
		}
		else {
			for(i=0,totaltime=0;i<batdn_total;i++) {
				if(!(cfg.dir[batdn_dir[i]]->misc&DIR_TFREE) && cur_cps)
					totaltime+=batdn_size[i]/(ulong)cur_cps; 
			}
			if(!(useron.exempt&FLAG('T')) && !SYSOP && totaltime>timeleft)
				bputs(text[NotEnoughTimeToDl]);
			else {
				for(i=0;i<batdn_total;i++) {
					lncntr=0;
					unpadfname(batdn_name[i],tmp);
					sprintf(tmp2,"%s%s",cfg.temp_dir,tmp);
					if(!fexistcase(tmp2)) {
						seqwait(cfg.dir[batdn_dir[i]]->seqdev);
						bprintf(text[RetrievingFile],tmp);
						sprintf(str,"%s%s"
							,batdn_alt[i]>0 && batdn_alt[i]<=cfg.altpaths
							? cfg.altpath[batdn_alt[i]-1]
							: cfg.dir[batdn_dir[i]]->path
							,tmp);
						mv(str,tmp2,1); /* copy the file to temp dir */
						getnodedat(cfg.node_num,&thisnode,1);
						thisnode.aux=0xfe;
						putnodedat(cfg.node_num,&thisnode);
						CRLF; 
					} 
				} 
			} 
		} 
	}

	if(!(*msgcnt) && !mailmsgs && !files && !netfiles && !batdn_total
		&& (prepack || !preqwk)) {
		bputs(text[QWKNoNewMessages]);
		return(false); 
	}

	if(!(useron.rest&FLAG('Q'))) {					/* Don't include in network */
		/***********************/					/* packets */
		/* Copy QWK Text files */
		/***********************/
		sprintf(str,"%sQWK/HELLO",cfg.text_dir);
		if(fexistcase(str)) {
			sprintf(tmp2,"%sHELLO",cfg.temp_dir);
			mv(str,tmp2,1); 
		}
		sprintf(str,"%sQWK/BBSNEWS",cfg.text_dir);
		if(fexistcase(str)) {
			sprintf(tmp2,"%sBBSNEWS",cfg.temp_dir);
			mv(str,tmp2,1); 
		}
		sprintf(str,"%sQWK/GOODBYE",cfg.text_dir);
		if(fexistcase(str)) {
			sprintf(tmp2,"%sGOODBYE",cfg.temp_dir);
			mv(str,tmp2,1); 
		}
		sprintf(str,"%sQWK/BLT-*",cfg.text_dir);
		glob(str,0,NULL,&g);
		for(i=0;i<(uint)g.gl_pathc;i++) { 			/* Copy BLT-*.* files */
			fname=getfname(g.gl_pathv[i]);
			padfname(fname,str);
			if(isdigit(str[4]) && isdigit(str[9])) {
				sprintf(str,"%sQWK/%s",cfg.text_dir,fname);
				sprintf(tmp2,"%s%s",cfg.temp_dir,fname);
				mv(str,tmp2,1); 
			}
		}
		globfree(&g);
	}

	if(prepack) {
		for(i=1;i<=cfg.sys_nodes;i++) {
			getnodedat(i,&node,0);
			if((node.status==NODE_INUSE || node.status==NODE_QUIET
				|| node.status==NODE_LOGON) && node.useron==useron.number)
				break; 
		}
		if(i<=cfg.sys_nodes)	/* Don't pre-pack with user online */
			return(false); 
	}

	/*******************/
	/* Compress Packet */
	/*******************/
	sprintf(tmp2,"%s%s",cfg.temp_dir,ALLFILES);
	i=external(cmdstr(temp_cmd(),packet,tmp2,NULL)
		,ex|EX_WILDCARD);
	if(!fexist(packet)) {
		bputs(text[QWKCompressionFailed]);
		if(i)
			errormsg(WHERE,ERR_EXEC,cmdstr(temp_cmd(),packet,tmp2,NULL),i);
		else
			errorlog("Couldn't compress QWK packet");
		return(false); 
	}

	if(prepack) 		/* Early return if pre-packing */
		return(true);

	l=flength(packet);
	sprintf(str,"%s.qwk",cfg.sys_id);
	bprintf(text[FiFilename],str);
	bprintf(text[FiFileSize],ultoac(l,tmp));
	if(l>0L && cur_cps)
		i=l/(ulong)cur_cps;
	else
		i=0;
	bprintf(text[FiTransferTime],sectostr(i,tmp));
	CRLF;
	if(!(useron.exempt&FLAG('T')) && i>timeleft) {
		bputs(text[NotEnoughTimeToDl]);
		return(false); 
	}

	if(useron.rest&FLAG('Q')) {
		sprintf(str,"%s.qwk",cfg.sys_id);
		dir=opendir(cfg.temp_dir);
		while(dir!=NULL && (dirent=readdir(dir))!=NULL) {
			if(!stricmp(str,dirent->d_name))	/* QWK packet */
				continue;
			sprintf(tmp,"%s%s",cfg.temp_dir,dirent->d_name);
			if(!isdir(tmp))
				remove(tmp); 
		}
		if(dir!=NULL)
			closedir(dir);
	}

	return(true);
}
Esempio n. 13
0
bool sbbs_t::answer()
{
	char	str[MAX_PATH+1],str2[MAX_PATH+1],c;
	char 	tmp[(MAX_PATH > CRYPT_MAX_TEXTSIZE ? MAX_PATH:CRYPT_MAX_TEXTSIZE)+1];
	char 	tmpname[CRYPT_MAX_TEXTSIZE+1];
	char 	path[MAX_PATH+1];
	int		i,l,in;
	struct tm tm;

	useron.number=0;
	answertime=logontime=starttime=now=time(NULL);
	/* Caller ID is IP address */
	SAFECOPY(cid,client_ipaddr);

	memset(&tm,0,sizeof(tm));
    localtime_r(&now,&tm); 

	safe_snprintf(str,sizeof(str),"%s  %s %s %02d %u            Node %3u"
		,hhmmtostr(&cfg,&tm,str2)
		,wday[tm.tm_wday]
        ,mon[tm.tm_mon],tm.tm_mday,tm.tm_year+1900,cfg.node_num);
	logline("@ ",str);

	safe_snprintf(str,sizeof(str),"%s  %s [%s]", connection, client_name, cid);
	logline("@+:",str);

	if(client_ident[0]) {
		safe_snprintf(str,sizeof(str),"Identity: %s",client_ident);
		logline("@*",str);
	}

	online=ON_REMOTE;

	if(sys_status&SS_RLOGIN) {
		if(incom(1000)==0) {
			for(i=0;i<(int)sizeof(str)-1;i++) {
				in=incom(1000);
				if(in==0 || in==NOINP)
					break;
				str[i]=in;
			}
			str[i]=0;
			for(i=0;i<(int)sizeof(str2)-1;i++) {
				in=incom(1000);
				if(in==0 || in==NOINP)
					break;
				str2[i]=in;
			}
			str2[i]=0;
			for(i=0;i<(int)sizeof(terminal)-1;i++) {
				in=incom(1000);
				if(in==0 || in==NOINP)
					break;
				terminal[i]=in;
			}
			terminal[i]=0;
			lprintf(LOG_DEBUG,"Node %d RLogin: '******' / '%.*s' / '%s'"
				,cfg.node_num
				,LEN_ALIAS*2,str
				,LEN_ALIAS*2,str2
				,terminal);
			SAFECOPY(rlogin_term, terminal);
			SAFECOPY(rlogin_name, str2);
			SAFECOPY(rlogin_pass, str);
			/* Truncate terminal speed (e.g. "/57600") from terminal-type string 
			   (but keep full terminal type/speed string in rlogin_term): */
			truncstr(terminal,"/");	
			useron.number=userdatdupe(0, U_ALIAS, LEN_ALIAS, rlogin_name);
			if(useron.number) {
				getuserdat(&cfg,&useron);
				useron.misc&=~TERM_FLAGS;
				SAFEPRINTF(path,"%srlogin.cfg",cfg.ctrl_dir);
				if(!findstr(client.addr,path)) {
					SAFECOPY(tmp, rlogin_pass);
					for(i=0;i<3;i++) {
						if(stricmp(tmp,useron.pass)) {
							badlogin(useron.alias, tmp);
							rioctl(IOFI);       /* flush input buffer */
							bputs(text[InvalidLogon]);
							if(cfg.sys_misc&SM_ECHO_PW)
								safe_snprintf(str,sizeof(str),"(%04u)  %-25s  FAILED Password attempt: '%s'"
									,0,useron.alias,tmp);
							else
								safe_snprintf(str,sizeof(str),"(%04u)  %-25s  FAILED Password attempt"
									,0,useron.alias);
							logline(LOG_NOTICE,"+!",str);
							bputs(text[PasswordPrompt]);
							console|=CON_R_ECHOX;
							getstr(tmp,LEN_PASS*2,K_UPPER|K_LOWPRIO|K_TAB);
							console&=~(CON_R_ECHOX|CON_L_ECHOX);
						}
						else {
							if(REALSYSOP) {
								rioctl(IOFI);       /* flush input buffer */
								if(!chksyspass())
									bputs(text[InvalidLogon]);
								else {
									i=0;
									break;
								}
							}
							else
								break;
						}
					}
					if(i) {
						if(stricmp(tmp,useron.pass)) {
							badlogin(useron.alias, tmp);
							bputs(text[InvalidLogon]);
							if(cfg.sys_misc&SM_ECHO_PW)
								safe_snprintf(str,sizeof(str),"(%04u)  %-25s  FAILED Password attempt: '%s'"
									,0,useron.alias,tmp);
							else
								safe_snprintf(str,sizeof(str),"(%04u)  %-25s  FAILED Password attempt"
									,0,useron.alias);
							logline(LOG_NOTICE,"+!",str);
						}
						lprintf(LOG_WARNING,"Node %d !CLIENT IP NOT LISTED in %s"
							,cfg.node_num,path);
						useron.number=0;
						hangup();
					}
				}
			}
			else
				lprintf(LOG_INFO,"Node %d RLogin: Unknown user: %s",cfg.node_num,rlogin_name);
		}
		if(rlogin_name[0]==0) {
			lprintf(LOG_NOTICE,"Node %d !RLogin: No user name received",cfg.node_num);
			sys_status&=~SS_RLOGIN;
		}
	}

	if(!(telnet_mode&TELNET_MODE_OFF)) {
		/* Disable Telnet Terminal Echo */
		request_telnet_opt(TELNET_WILL,TELNET_ECHO);
		/* Will suppress Go Ahead */
		request_telnet_opt(TELNET_WILL,TELNET_SUP_GA);
		/* Retrieve terminal type and speed from telnet client --RS */
		request_telnet_opt(TELNET_DO,TELNET_TERM_TYPE);
		request_telnet_opt(TELNET_DO,TELNET_TERM_SPEED);
		request_telnet_opt(TELNET_DO,TELNET_SEND_LOCATION);
		request_telnet_opt(TELNET_DO,TELNET_NEGOTIATE_WINDOW_SIZE);
		request_telnet_opt(TELNET_DO,TELNET_NEW_ENVIRON);
	}
#ifdef USE_CRYPTLIB
	if(sys_status&SS_SSH) {
		pthread_mutex_lock(&ssh_mutex);
		cryptGetAttributeString(ssh_session, CRYPT_SESSINFO_USERNAME, tmpname, &i);
		tmpname[i]=0;
		SAFECOPY(rlogin_name, tmpname);
		cryptGetAttributeString(ssh_session, CRYPT_SESSINFO_PASSWORD, tmp, &i);
		tmp[i]=0;
		SAFECOPY(rlogin_pass, tmp);
		pthread_mutex_unlock(&ssh_mutex);
		lprintf(LOG_DEBUG,"Node %d SSH login: '******'"
			,cfg.node_num, tmpname);
		useron.number=userdatdupe(0, U_ALIAS, LEN_ALIAS, tmpname);
		if(useron.number) {
			getuserdat(&cfg,&useron);
			useron.misc&=~TERM_FLAGS;
			for(i=0;i<3;i++) {
				if(stricmp(tmp,useron.pass)) {
					badlogin(useron.alias, tmp);
					rioctl(IOFI);       /* flush input buffer */
					bputs(text[InvalidLogon]);
					if(cfg.sys_misc&SM_ECHO_PW)
						safe_snprintf(str,sizeof(str),"(%04u)  %-25s  FAILED Password attempt: '%s'"
							,0,useron.alias,tmp);
					else
						safe_snprintf(str,sizeof(str),"(%04u)  %-25s  FAILED Password attempt"
							,0,useron.alias);
					/* crash here Sept-12-2010
					   str	0x06b3fc4c "(0000)  Guest                      FAILED Password attempt: '*****@*****.**'"

					   and Oct-6-2010
					   str	0x070ffc4c "(0000)  Woot903                    FAILED Password attempt: 'p67890pppsdsjhsdfhhfhnhnfhfhfdhjksdjkfdskw3902391=`'"	char [261]
					*/
					logline(LOG_NOTICE,"+!",str);
					bputs(text[PasswordPrompt]);
					console|=CON_R_ECHOX;
					getstr(tmp,LEN_PASS*2,K_UPPER|K_LOWPRIO|K_TAB);
					console&=~(CON_R_ECHOX|CON_L_ECHOX);
				}
				else {
					if(REALSYSOP) {
						rioctl(IOFI);       /* flush input buffer */
						if(!chksyspass())
							bputs(text[InvalidLogon]);
						else {
							i=0;
							break;
						}
					}
					else
						break;
				}
			}
			if(i) {
				if(stricmp(tmp,useron.pass)) {
					badlogin(useron.alias, tmp);
					bputs(text[InvalidLogon]);
					if(cfg.sys_misc&SM_ECHO_PW)
						safe_snprintf(str,sizeof(str),"(%04u)  %-25s  FAILED Password attempt: '%s'"
							,0,useron.alias,tmp);
					else
						safe_snprintf(str,sizeof(str),"(%04u)  %-25s  FAILED Password attempt"
							,0,useron.alias);
					logline(LOG_NOTICE,"+!",str);
				}
				useron.number=0;
				hangup();
			}
		}
		else
			lprintf(LOG_INFO,"Node %d SSH: Unknown user: %s",cfg.node_num,rlogin_name);
	}
#endif

	/* Detect terminal type */
    mswait(200);
	rioctl(IOFI);		/* flush input buffer */
	putcom( "\r\n"		/* locate cursor at column 1 */
			"\x1b[s"	/* save cursor position (necessary for HyperTerm auto-ANSI) */
    		"\x1b[255B"	/* locate cursor as far down as possible */
			"\x1b[255C"	/* locate cursor as far right as possible */
			"\b_"		/* need a printable at this location to actually move cursor */
			"\x1b[6n"	/* Get cursor position */
			"\x1b[u"	/* restore cursor position */
			"\x1b[!_"	/* RIP? */
			"\x1b[30;40m\xc2\x9f""Zuul.connection.write('\\x1b""Are you the gatekeeper?')\xc2\x9c"	/* ZuulTerm? */
			"\x1b[0m_"	/* "Normal" colors */
			"\x1b[2J"	/* clear screen */
			"\x1b[H"	/* home cursor */
			"\xC"		/* clear screen (in case not ANSI) */
			"\r"		/* Move cursor left (in case previous char printed) */
			);
	i=l=0;
	tos=1;
	lncntr=0;
	safe_snprintf(str, sizeof(str), "%s  %s", VERSION_NOTICE, COPYRIGHT_NOTICE);
	strip_ctrl(str, str);
	center(str);

	while(i++<50 && l<(int)sizeof(str)-1) { 	/* wait up to 5 seconds for response */
		c=incom(100)&0x7f;
		if(c==0)
			continue;
		i=0;
		if(l==0 && c!=ESC)	// response must begin with escape char
			continue;
		str[l++]=c;
		if(c=='R') {   /* break immediately if ANSI response */
			mswait(500);
			break; 
		}
	}

	while((c=(incom(100)&0x7f))!=0 && l<(int)sizeof(str)-1)
		str[l++]=c;
	str[l]=0;

    if(l) {
		c_escape_str(str,tmp,sizeof(tmp),TRUE);
		lprintf(LOG_DEBUG,"Node %d received terminal auto-detection response: '%s'"
			,cfg.node_num,tmp);
        if(str[0]==ESC && str[1]=='[' && str[l-1]=='R') {
			int	x,y;

			if(terminal[0]==0)
				SAFECOPY(terminal,"ANSI");
			autoterm|=(ANSI|COLOR);
			if(sscanf(str+2,"%u;%u",&y,&x)==2) {
				lprintf(LOG_DEBUG,"Node %d received ANSI cursor position report: %ux%u"
					,cfg.node_num, x, y);
				/* Sanity check the coordinates in the response: */
				if(x>=40 && x<=255) cols=x; 
				if(y>=10 && y<=255) rows=y;
			}
		}
		truncsp(str);
		if(strstr(str,"RIPSCRIP")) {
			if(terminal[0]==0)
				SAFECOPY(terminal,"RIP");
			logline("@R",strstr(str,"RIPSCRIP"));
			autoterm|=(RIP|COLOR|ANSI); }
		else if(strstr(str,"Are you the gatekeeper?"))  {
			if(terminal[0]==0)
				SAFECOPY(terminal,"HTML");
			logline("@H",strstr(str,"Are you the gatekeeper?"));
			autoterm|=HTML;
		} 
	}
	else if(terminal[0]==0)
		SAFECOPY(terminal,"DUMB");

	rioctl(IOFI); /* flush left-over or late response chars */

	if(!autoterm && str[0]) {
		c_escape_str(str,tmp,sizeof(tmp),TRUE);
		lprintf(LOG_NOTICE,"Node %d terminal auto-detection failed, response: '%s'"
			,cfg.node_num, tmp);
	}

	/* AutoLogon via IP or Caller ID here */
	if(!useron.number && !(sys_status&SS_RLOGIN)
		&& (startup->options&BBS_OPT_AUTO_LOGON) && cid[0]) {
		useron.number=userdatdupe(0, U_NOTE, LEN_NOTE, cid);
		if(useron.number) {
			getuserdat(&cfg, &useron);
			if(!(useron.misc&AUTOLOGON) || !(useron.exempt&FLAG('V')))
				useron.number=0;
		}
	}

	if(!online) 
		return(false); 

	if(stricmp(terminal,"sexpots")==0) {	/* dial-up connection (via SexPOTS) */
		SAFEPRINTF2(str,"%s connection detected at %lu bps", terminal, cur_rate);
		logline("@S",str);
		node_connection = (ushort)cur_rate;
		SAFEPRINTF(connection,"%lu",cur_rate);
		SAFECOPY(cid,"Unknown");
		SAFECOPY(client_name,"Unknown");
		if(telnet_location[0]) {			/* Caller-ID info provided */
			SAFEPRINTF(str, "CID: %s", telnet_location);
			logline("@*",str);
			SAFECOPY(cid,telnet_location);
			truncstr(cid," ");				/* Only include phone number in CID */
			char* p=telnet_location;
			FIND_WHITESPACE(p);
			SKIP_WHITESPACE(p);
			if(*p) {
				SAFECOPY(client_name,p);	/* CID name, if provided (maybe 'P' or 'O' if private or out-of-area) */
			}
		}
		SAFECOPY(client.addr,cid);
		SAFECOPY(client.host,client_name);
		client_on(client_socket,&client,TRUE /* update */);
	} else {
		if(telnet_location[0]) {			/* Telnet Location info provided */
			SAFEPRINTF(str, "Telnet Location: %s", telnet_location);
			logline("@*",str);
		}
	}


	useron.misc&=~TERM_FLAGS;
	useron.misc|=autoterm;
	SAFECOPY(useron.comp,client_name);

	if(!useron.number && rlogin_name[0]!=0 && !(cfg.sys_misc&SM_CLOSED) && !matchuser(&cfg, rlogin_name, /* Sysop alias: */FALSE)) {
		lprintf(LOG_INFO,"Node %d UNKNOWN %s-specified USERNAME: %s, starting new user signup",cfg.node_num,client.protocol,rlogin_name);
		bprintf("%s: %s\r\n", text[UNKNOWN_USER], rlogin_name);
		newuser();
	}

	if(!useron.number) {	/* manual/regular logon */

		/* Display ANSWER screen */
		rioctl(IOSM|PAUSE);
		sys_status|=SS_PAUSEON;
		SAFEPRINTF(str,"%sanswer",cfg.text_dir);
		SAFEPRINTF(path,"%s.rip",str);
		if((autoterm&RIP) && fexistcase(path))
			printfile(path,P_NOABORT);
		else {
			SAFEPRINTF(path,"%s.html",str);
			if((autoterm&HTML) && fexistcase(path))
				printfile(path,P_NOABORT);
			else {
				SAFEPRINTF(path,"%s.ans",str);
				if((autoterm&ANSI) && fexistcase(path))
					printfile(path,P_NOABORT);
				else {
					SAFEPRINTF(path,"%s.asc",str);
					if(fexistcase(path))
						printfile(path, P_NOABORT);
				}
			}
		}
		sys_status&=~SS_PAUSEON;
		exec_bin(cfg.login_mod,&main_csi);
	} else	/* auto logon here */
		if(logon()==false)
			return(false);


	if(!useron.number)
		hangup();

	/* Save the IP to the user's note */
	if(cid[0]) {
		SAFECOPY(useron.note,cid);
		putuserrec(&cfg,useron.number,U_NOTE,LEN_NOTE,useron.note);
	}

	/* Save host name to the user's computer description */
	if(client_name[0]) {
		SAFECOPY(useron.comp,client_name);
		putuserrec(&cfg,useron.number,U_COMP,LEN_COMP,useron.comp);
	}

	if(!online) 
		return(false); 

	if(!(sys_status&SS_USERON)) {
		errormsg(WHERE,ERR_CHK,"User not logged on",0);
		hangup();
		return(false); 
	}

	if(useron.pass[0])
		loginSuccess(startup->login_attempt_list, &client_addr);

	return(true);
}
Esempio n. 14
0
bool sbbs_t::inetmail(char *into, char *subj, long mode)
{
	char	str[256],str2[256],msgpath[256],title[256],name[256],ch
			,buf[SDT_BLOCK_LEN],*p,addr[256];
	char 	tmp[512];
	char	your_addr[128];
	ushort	xlat=XLAT_NONE,net=NET_INTERNET;
	int 	i,j,x,file;
	long	l;
	ulong	length,offset;
	FILE	*instream;
	smbmsg_t msg;

	if(useron.etoday>=cfg.level_emailperday[useron.level] && !SYSOP) {
		bputs(text[TooManyEmailsToday]);
		return(false); 
	}

	strcpy(name,into);
	strcpy(addr,into);
	strcpy(title,subj);

	if((!SYSOP && !(cfg.inetmail_misc&NMAIL_ALLOW)) || useron.rest&FLAG('M')) {
		bputs(text[NoNetMailAllowed]);
		return(false); }

	if(cfg.inetmail_cost && !(useron.exempt&FLAG('S'))) {
		if(useron.cdt+useron.freecdt<cfg.inetmail_cost) {
			bputs(text[NotEnoughCredits]);
			return(false); }
		sprintf(str,text[NetMailCostContinueQ],cfg.inetmail_cost);
		if(noyes(str))
			return(false); }

	/* Get destination user name */
	p=strrchr(name,'@');
	if(!p)
		p=strrchr(name,'!');
	if(p) {
		*p=0;
		truncsp(name); }

	/* Get this user's internet mailing address */
	usermailaddr(&cfg,your_addr
		,cfg.inetmail_misc&NMAIL_ALIAS ? useron.alias : useron.name);

	bprintf(text[InternetMailing],addr,your_addr);
	action=NODE_SMAL;
	nodesync();

	sprintf(msgpath,"%snetmail.msg",cfg.node_dir);
	if(!writemsg(msgpath,nulstr,title,mode,INVALID_SUB,into)) {
		bputs(text[Aborted]);
		return(false); }

	if(mode&WM_FILE) {
		sprintf(str2,"%sfile/%04u.out",cfg.data_dir,useron.number);
		MKDIR(str2);
		sprintf(str2,"%sfile/%04u.out/%s",cfg.data_dir,useron.number,title);
		if(fexistcase(str2)) {
			bputs(text[FileAlreadyThere]);
			remove(msgpath);
			return(false); }
#if 0	/* no such thing as local logon */
		if(online==ON_LOCAL) {		/* Local upload */
			bputs(text[EnterPath]);
			if(!getstr(str,60,K_LINE|K_UPPER)) {
				bputs(text[Aborted]);
				remove(msgpath);
				return(false); }
			backslash(str);
			strcat(str,title);
			mv(str,str2,1); }
		else 
#endif
		{ /* Remote */
			xfer_prot_menu(XFER_UPLOAD);
			mnemonics(text[ProtocolOrQuit]);
			strcpy(str,"Q");
			for(x=0;x<cfg.total_prots;x++)
				if(cfg.prot[x]->ulcmd[0] && chk_ar(cfg.prot[x]->ar,&useron)) {
					sprintf(tmp,"%c",cfg.prot[x]->mnemonic);
					strcat(str,tmp); }
			ch=(char)getkeys(str,0);
			if(ch=='Q' || sys_status&SS_ABORT) {
				bputs(text[Aborted]);
				remove(msgpath);
				return(false); }
			for(x=0;x<cfg.total_prots;x++)
				if(cfg.prot[x]->ulcmd[0] && cfg.prot[x]->mnemonic==ch
					&& chk_ar(cfg.prot[x]->ar,&useron))
					break;
			if(x<cfg.total_prots)	/* This should be always */
				protocol(cfg.prot[x],XFER_UPLOAD,str2,nulstr,true); 
		}
		sprintf(tmp,"%s%s",cfg.temp_dir,title);
		if(!fexistcase(str2) && fexistcase(tmp))
			mv(tmp,str2,0);
		l=flength(str2);
		if(l>0)
			bprintf(text[FileNBytesReceived],title,ultoac(l,tmp));
		else {
			bprintf(text[FileNotReceived],title);
			remove(msgpath);
			return(false); } }

	if((i=smb_stack(&smb,SMB_STACK_PUSH))!=SMB_SUCCESS) {
		errormsg(WHERE,ERR_OPEN,"MAIL",i);
		return(false); }
	sprintf(smb.file,"%smail",cfg.data_dir);
	smb.retry_time=cfg.smb_retry_time;
	smb.subnum=INVALID_SUB;
	if((i=smb_open(&smb))!=SMB_SUCCESS) {
		smb_stack(&smb,SMB_STACK_POP);
		errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
		return(false); }

	if(filelength(fileno(smb.shd_fp))<1) {	 /* Create it if it doesn't exist */
		smb.status.max_crcs=cfg.mail_maxcrcs;
		smb.status.max_age=cfg.mail_maxage;
		smb.status.max_msgs=0;
		smb.status.attr=SMB_EMAIL;
		if((i=smb_create(&smb))!=SMB_SUCCESS) {
			smb_close(&smb);
			smb_stack(&smb,SMB_STACK_POP);
			errormsg(WHERE,ERR_CREATE,smb.file,i);
			return(false); } }

	if((i=smb_locksmbhdr(&smb))!=SMB_SUCCESS) {
		smb_close(&smb);
		smb_stack(&smb,SMB_STACK_POP);
		errormsg(WHERE,ERR_LOCK,smb.file,i);
		return(false); }

	length=flength(msgpath)+2;	 /* +2 for translation string */

	if(length&0xfff00000UL) {
		smb_unlocksmbhdr(&smb);
		smb_close(&smb);
		smb_stack(&smb,SMB_STACK_POP);
		errormsg(WHERE,ERR_LEN,msgpath,length);
		return(false); }

	if((i=smb_open_da(&smb))!=SMB_SUCCESS) {
		smb_unlocksmbhdr(&smb);
		smb_close(&smb);
		smb_stack(&smb,SMB_STACK_POP);
		errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
		return(false); }
	if(cfg.sys_misc&SM_FASTMAIL)
		offset=smb_fallocdat(&smb,length,1);
	else
		offset=smb_allocdat(&smb,length,1);
	smb_close_da(&smb);

	if((file=open(msgpath,O_RDONLY|O_BINARY))==-1
		|| (instream=fdopen(file,"rb"))==NULL) {
		smb_freemsgdat(&smb,offset,length,1);
		smb_unlocksmbhdr(&smb);
		smb_close(&smb);
		smb_stack(&smb,SMB_STACK_POP);
		errormsg(WHERE,ERR_OPEN,msgpath,O_RDONLY|O_BINARY);
		return(false); }

	setvbuf(instream,NULL,_IOFBF,2*1024);
	fseek(smb.sdt_fp,offset,SEEK_SET);
	xlat=XLAT_NONE;
	fwrite(&xlat,2,1,smb.sdt_fp);
	x=SDT_BLOCK_LEN-2;				/* Don't read/write more than 255 */
	while(!feof(instream)) {
		memset(buf,0,x);
		j=fread(buf,1,x,instream);
		if(j<1)
			break;
		if(j>1 && (j!=x || feof(instream)) && buf[j-1]==LF && buf[j-2]==CR)
			buf[j-1]=buf[j-2]=0;
		fwrite(buf,j,1,smb.sdt_fp);
		x=SDT_BLOCK_LEN; }
	fflush(smb.sdt_fp);
	fclose(instream);

	memset(&msg,0,sizeof(smbmsg_t));
	msg.hdr.version=smb_ver();
	if(mode&WM_FILE)
		msg.hdr.auxattr|=MSG_FILEATTACH;
	msg.hdr.when_written.time=msg.hdr.when_imported.time=time(NULL);
	msg.hdr.when_written.zone=msg.hdr.when_imported.zone=sys_timezone(&cfg);

	msg.hdr.offset=offset;

	net=NET_INTERNET;
	smb_hfield_str(&msg,RECIPIENT,name);
	smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(net),&net);
	smb_hfield_str(&msg,RECIPIENTNETADDR,addr);

	strcpy(str,cfg.inetmail_misc&NMAIL_ALIAS ? useron.alias : useron.name);
	smb_hfield_str(&msg,SENDER,str);

	sprintf(str,"%u",useron.number);
	smb_hfield_str(&msg,SENDEREXT,str);

	/*
	smb_hfield(&msg,SENDERNETTYPE,sizeof(net),&net);
	smb_hfield(&msg,SENDERNETADDR,strlen(sys_inetaddr),sys_inetaddr);
	*/

	/* Security logging */
	msg_client_hfields(&msg,&client);

	smb_hfield_str(&msg,SUBJECT,title);
	strcpy(str,title);

	smb_dfield(&msg,TEXT_BODY,length);

	i=smb_addmsghdr(&smb,&msg,SMB_SELFPACK);	// calls smb_unlocksmbhdr() 
	smb_close(&smb);
	smb_stack(&smb,SMB_STACK_POP);

	smb_freemsgmem(&msg);
	if(i!=SMB_SUCCESS) {
		errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error);
		smb_freemsgdat(&smb,offset,length,1);
		return(false); 
	}

	if(mode&WM_FILE && online==ON_REMOTE)
		autohangup();

	if(cfg.inetmail_sem[0]) 	 /* update semaphore file */
		ftouch(cmdstr(cfg.inetmail_sem,nulstr,nulstr,NULL));
	if(!(useron.exempt&FLAG('S')))
		subtract_cdt(&cfg,&useron,cfg.inetmail_cost);

	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));

	sprintf(str,"%s sent Internet Mail to %s (%s)"
		,useron.alias
		,name,addr);
	logline("EN",str);
	return(true);
}
Esempio n. 15
0
int sbbs_t::exec_misc(csi_t* csi, char *path)
{
	char	str[512],tmp[512],buf[1025],ch,op,*p,**pp,**pp1,**pp2;
	ushort	w;
	uint 	i=0,j;
	long	l,*lp=NULL,*lp1=NULL,*lp2=NULL;
	void	*vp;
	struct	dirent *de;
    struct  tm tm;

	switch(*(csi->ip++)) {
		case CS_VAR_INSTRUCTION:
			switch(*(csi->ip++)) {	/* sub-op-code stored as next byte */
				case PRINT_VAR:
					pp=getstrvar(csi,*(long *)csi->ip);
					if(!pp || !*pp) {
						lp=getintvar(csi,*(long *)csi->ip);
						if(lp)
							bprintf("%ld",*lp); }
					else
						putmsg(cmdstr(*pp,path,csi->str,buf)
							,P_SAVEATR|P_NOABORT|P_NOATCODES);
					csi->ip+=4;
					return(0);
				case VAR_PRINTF:
				case VAR_PRINTF_LOCAL:
					op=*(csi->ip-1);
					p=format_string(this, csi);
					if(op==VAR_PRINTF)
						putmsg(cmdstr(p,path,csi->str,buf),P_SAVEATR|P_NOABORT|P_NOATCODES);
					else {
						if(online==ON_LOCAL)
							eprintf(LOG_INFO,"%s",cmdstr(p,path,csi->str,buf));
						else
							lputs(LOG_INFO,cmdstr(p,path,csi->str,buf));
					}
					free(p);
					return(0);
				case SHOW_VARS:
					bprintf("shell     str=(%08lX) %s\r\n"
						,csi->str,csi->str);
					for(i=0;i<csi->str_vars;i++)
						bprintf("local  str[%d]=(%08lX) (%08lX) %s\r\n"
							,i,csi->str_var_name[i]
							,csi->str_var[i]
							,csi->str_var[i]);
					for(i=0;i<csi->int_vars;i++)
						bprintf("local  int[%d]=(%08lX) (%08lX) %ld\r\n"
							,i,csi->int_var_name[i]
							,csi->int_var[i]
							,csi->int_var[i]);
					for(i=0;i<global_str_vars;i++)
						bprintf("global str[%d]=(%08lX) (%08lX) %s\r\n"
							,i,global_str_var_name[i]
							,global_str_var[i]
							,global_str_var[i]);
					for(i=0;i<global_int_vars;i++)
						bprintf("global int[%d]=(%08lX) (%08lX) %ld\r\n"
							,i,global_int_var_name[i]
							,global_int_var[i]
							,global_int_var[i]);
					return(0);
				case DEFINE_STR_VAR:
					if(getstrvar(csi,*(long *)csi->ip)) {
						csi->ip+=4;
						return(0); }
					csi->str_vars++;
					csi->str_var=(char **)realloc(csi->str_var
						,sizeof(char *)*csi->str_vars);
					csi->str_var_name=(long *)realloc(csi->str_var_name
						,sizeof(long)*csi->str_vars);
					if(csi->str_var==NULL
						|| csi->str_var_name==NULL) { /* REALLOC failed */
						errormsg(WHERE,ERR_ALLOC,"local str var"
							,sizeof(char *)*csi->str_vars);
						if(csi->str_var_name) {
							free(csi->str_var_name);
							csi->str_var_name=0; }
						if(csi->str_var) {
							free(csi->str_var);
							csi->str_var=0; }
						csi->str_vars=0; }
					else {
						csi->str_var_name[csi->str_vars-1]=*(long *)csi->ip;
						csi->str_var[csi->str_vars-1]=0; }
					csi->ip+=4; /* Skip variable name */
					return(0);
				case DEFINE_INT_VAR:
					if(getintvar(csi,*(long *)csi->ip)) {
						csi->ip+=4;
						return(0); }
					csi->int_vars++;
					csi->int_var=(long *)realloc(csi->int_var
						,sizeof(char *)*csi->int_vars);
					csi->int_var_name=(long *)realloc(csi->int_var_name
						,sizeof(long)*csi->int_vars);
					if(csi->int_var==NULL
						|| csi->int_var_name==NULL) { /* REALLOC failed */
						errormsg(WHERE,ERR_ALLOC,"local int var"
							,sizeof(char *)*csi->int_vars);
						if(csi->int_var_name) {
							free(csi->int_var_name);
							csi->int_var_name=0; }
						if(csi->int_var) {
							free(csi->int_var);
							csi->int_var=0; }
						csi->int_vars=0; }
					else {
						csi->int_var_name[csi->int_vars-1]=*(long *)csi->ip;
						csi->int_var[csi->int_vars-1]=0; }
					csi->ip+=4; /* Skip variable name */
					return(0);
				case DEFINE_GLOBAL_STR_VAR:
					if(getstrvar(csi,*(long *)csi->ip)) {
						csi->ip+=4;
						return(0); }
					global_str_vars++;
					global_str_var=(char **)realloc(global_str_var
						,sizeof(char *)*global_str_vars);
					global_str_var_name=(long *)realloc(global_str_var_name
						,sizeof(long)*global_str_vars);
					if(global_str_var==NULL
						|| global_str_var_name==NULL) { /* REALLOC failed */
						errormsg(WHERE,ERR_ALLOC,"global str var"
							,sizeof(char *)*global_str_vars);
						if(global_str_var_name) {
							free(global_str_var_name);
							global_str_var_name=0; }
						if(global_str_var) {
							free(global_str_var);
							global_str_var=0; }
						global_str_vars=0; }
					else {
						global_str_var_name[global_str_vars-1]=
							*(long *)csi->ip;
						global_str_var[global_str_vars-1]=0; }
					csi->ip+=4; /* Skip variable name */
					return(0);
				case DEFINE_GLOBAL_INT_VAR:
					if(getintvar(csi,*(long *)csi->ip)) {
						csi->ip+=4;
						return(0); }
					global_int_vars++;
					global_int_var=(long *)realloc(global_int_var
						,sizeof(char *)*global_int_vars);
					global_int_var_name=(long *)realloc(global_int_var_name
						,sizeof(long)*global_int_vars);
					if(global_int_var==NULL
						|| global_int_var_name==NULL) { /* REALLOC failed */
						errormsg(WHERE,ERR_ALLOC,"local int var"
							,sizeof(char *)*global_int_vars);
						if(global_int_var_name) {
							free(global_int_var_name);
							global_int_var_name=0; }
						if(global_int_var) {
							free(global_int_var);
							global_int_var=0; }
						global_int_vars=0; }
					else {
						global_int_var_name[global_int_vars-1]
							=*(long *)csi->ip;
						global_int_var[global_int_vars-1]=0; }
					csi->ip+=4; /* Skip variable name */
					return(0);

				case SET_STR_VAR:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip variable name */
					if(pp)
						*pp=copystrvar(csi,*pp
							,cmdstr((char *)csi->ip,path,csi->str,buf));
					while(*(csi->ip++));	 /* Find NULL */
					return(0);
				case SET_INT_VAR:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip variable name */
					if(lp)
						*lp=*(long *)csi->ip;
					csi->ip+=4; /* Skip value */
					return(0);
				case COMPARE_STR_VAR:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip variable name */
					if(pp && *pp)
						csi->logic=stricmp(*pp
							,cmdstr((char *)csi->ip,path,csi->str,buf));
					else {	/* Uninitialized str var */
						if(*(csi->ip)==0)	 /* Blank static str */
							csi->logic=LOGIC_TRUE;
						else
							csi->logic=LOGIC_FALSE; }
					while(*(csi->ip++));	 /* Find NULL */
					return(0);
				case STRSTR_VAR:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip variable name */
					if(pp && *pp && strstr(*pp
						,cmdstr((char *)csi->ip,path,csi->str,buf)))
						csi->logic=LOGIC_TRUE;
					else
						csi->logic=LOGIC_FALSE;
					while(*(csi->ip++));	 /* Find NULL */
					return(0);
				case STRNCMP_VAR:
					i=*csi->ip++;
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip variable name */
					if(pp && *pp)
						csi->logic=strnicmp(*pp
							,cmdstr((char *)csi->ip,path,csi->str,buf),i);
					else
						csi->logic=LOGIC_FALSE;
					while(*(csi->ip++));	 /* Find NULL */
					return(0);
				case STRNCMP_VARS:
					i=*csi->ip++;
					pp1=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip variable name */
					pp2=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(pp1 && *pp1 && pp2 && *pp2)
						csi->logic=strnicmp(*pp1,*pp2,i);
					else
						csi->logic=LOGIC_FALSE;
					return(0);
				case STRSTR_VARS:
					pp1=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip variable name */
					pp2=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(pp1 && *pp1 && pp2 && *pp2 && strstr(*pp1,*pp2))
						csi->logic=LOGIC_TRUE;
					else
						csi->logic=LOGIC_FALSE;
					return(0);
				case COMPARE_INT_VAR:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip variable name */
					l=*(long *)csi->ip;
					csi->ip+=4; /* Skip static value */
					if(!lp) {	/* Unknown variable */
						csi->logic=LOGIC_FALSE;
						return(0); }
					if(*lp>l)
						csi->logic=LOGIC_GREATER;
					else if(*lp<l)
						csi->logic=LOGIC_LESS;
					else
						csi->logic=LOGIC_EQUAL;
					return(0);
				case COMPARE_VARS:
					lp1=lp2=0;
					pp1=getstrvar(csi,*(long *)csi->ip);
					if(!pp1)
						lp1=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip variable name */
					pp2=getstrvar(csi,*(long *)csi->ip);
					if(!pp2)
						lp2=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip variable name */

					if(((!pp1 || !*pp1) && !lp1)
						|| ((!pp2 || !*pp2) && !lp2)) {
						if(pp1 && pp2)		/* Both unitialized or blank */
							csi->logic=LOGIC_TRUE;
						else
							csi->logic=LOGIC_FALSE;
						return(0); }

					if(pp1) { /* ASCII */
						if(!pp2) {
							ultoa(*lp2,tmp,10);
							csi->logic=stricmp(*pp1,tmp); }
						else
							csi->logic=stricmp(*pp1,*pp2);
						return(0); }

					/* Binary */
					if(!lp2) {
						l=strtol(*pp2,0,0);
						if(*lp1>l)
							csi->logic=LOGIC_GREATER;
						else if(*lp1<l)
							csi->logic=LOGIC_LESS;
						else
							csi->logic=LOGIC_EQUAL;
						return(0); }
					if(*lp1>*lp2)
						csi->logic=LOGIC_GREATER;
					else if(*lp1<*lp2)
						csi->logic=LOGIC_LESS;
					else
						csi->logic=LOGIC_EQUAL;
					return(0);
				case COPY_VAR:
					lp1=lp2=0;
					pp1=getstrvar(csi,*(long *)csi->ip);
					if(!pp1)
						lp1=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip variable name */
					pp2=getstrvar(csi,*(long *)csi->ip);
					if(!pp2)
						lp2=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip variable name */

					if((!pp1 && !lp1)
						|| ((!pp2 || !*pp2) && !lp2)) {
						csi->logic=LOGIC_FALSE;
						return(0); }
					csi->logic=LOGIC_TRUE;

					if(pp1) {	/* ASCII */
						if(!pp2)
							ultoa(*lp2,tmp,10);
						else
							strcpy(tmp,*pp2);
						*pp1=copystrvar(csi,*pp1,tmp);
						return(0); }
					if(!lp2)
						*lp1=strtol(*pp2,0,0);
					else
						*lp1=*lp2;
					return(0);
				case SWAP_VARS:
					lp1=lp2=0;
					pp1=getstrvar(csi,*(long *)csi->ip);
					if(!pp1)
						lp1=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip variable name */
					pp2=getstrvar(csi,*(long *)csi->ip);
					if(!pp2)
						lp2=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip variable name */

					if(((!pp1 || !*pp1) && !lp1)
						|| ((!pp2 || !*pp2) && !lp2)) {
						csi->logic=LOGIC_FALSE;
						return(0); }

					csi->logic=LOGIC_TRUE;

					if(pp1) {	/* ASCII */
						if(!pp2) {
							if(!strnicmp(*pp2,"0x",2)) {
								l=strtol((*pp1)+2,0,16);
								ultoa(*lp2,tmp,16); }
							else {
								l=atol(*pp1);
								ultoa(*lp2,tmp,10); }
							*pp1=copystrvar(csi,*pp1,tmp);
							*lp2=l; }
						else {
							p=*pp1;
							*pp1=*pp2;
							*pp2=p; }
						return(0); }

					/* Binary */
					if(!lp2) {
						if(!strnicmp(*pp2,"0x",2)) {
							l=strtol((*pp2)+2,0,16);
							ultoa(*lp1,tmp,16); }
						else {
							l=atol(*pp2);
							ultoa(*lp1,tmp,10); }
						*pp2=copystrvar(csi,*pp2,tmp);
						*lp1=l; }
					else {
						l=*lp1;
						*lp1=*lp2;
						*lp2=l; }
					return(0);
				case CAT_STR_VAR:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip variable name */
					strcpy(tmp,(char *)csi->ip);
					while(*(csi->ip++));
					if(pp && *pp)
						for(i=0;i<MAX_SYSVARS;i++)
							if(*pp==sysvar_p[i])
								break;
					if(pp && *pp!=csi->str && i==MAX_SYSVARS) {
						if(*pp)
							*pp=(char *)realloc(*pp,strlen(*pp)+strlen(tmp)+1);
						else
							*pp=(char *)realloc(*pp,strlen(tmp)+1); }
					if(pp && *pp)
						strcat(*pp,tmp);
					return(0);
				case CAT_STR_VARS:
					pp1=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip dest variable name */
					pp2=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip source variable name */

					/* Concatenate an int var to a str var (as char) */
					if(pp2==NULL) {
						lp=getintvar(csi,*(long *)(csi->ip-4));
						if(lp==NULL) {
							csi->logic=LOGIC_FALSE;
							return(0);
						}
						pp=pp1;
						tmp[0]=(uchar)*lp;
						tmp[1]=0;
						if(pp && *pp)
							for(i=0;i<MAX_SYSVARS;i++)
								if(*pp==sysvar_p[i])
									break;
						if(pp && *pp!=csi->str && i==MAX_SYSVARS) {
							if(*pp)
								*pp=(char *)realloc(*pp,strlen(*pp)+strlen(tmp)+1);
							else
								*pp=(char *)realloc(*pp,strlen(tmp)+1); }
						if(pp && *pp)
							strcat(*pp,tmp);
						return(0);
					}

					if(!pp1 || !pp2 || !*pp2) {
						csi->logic=LOGIC_FALSE;
						return(0); }
					csi->logic=LOGIC_TRUE;
					if(*pp1)
						for(i=0;i<MAX_SYSVARS;i++)
							if(*pp1==sysvar_p[i])
								break;
					if(*pp1!=csi->str && (!*pp1 || i==MAX_SYSVARS)) {
						if(*pp1)
							*pp1=(char *)realloc(*pp1,strlen(*pp1)+strlen(*pp2)+1);
						else
							*pp1=(char *)realloc(*pp1,strlen(*pp2)+1); }
					strcat(*pp1,*pp2);
					return(0);
				case FORMAT_STR_VAR:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip variable name */
					p=format_string(this, csi);
					cmdstr(p,path,csi->str,str);
					if(pp)
						*pp=copystrvar(csi,*pp,str);
					free(p);
					return(0);
				case FORMAT_TIME_STR:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip variable name */
					strcpy(str,(char *)csi->ip);
					while(*(csi->ip++));	/* Find NULL */
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(pp && lp) {
						if(localtime_r((time_t *)lp,&tm)!=NULL) {
							strftime(buf,128,str,&tm);
							*pp=copystrvar(csi,*pp,buf); 
						} 
					}
					return(0);
				case TIME_STR:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip str variable name */
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip int variable name */
					if(pp && lp) {
						strcpy(str,timestr((time_t *)lp));
						*pp=copystrvar(csi,*pp,str); }
					return(0);
				case DATE_STR:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip str variable name */
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip int variable name */
					if(pp && lp) {
						unixtodstr(&cfg,*lp,str);
						*pp=copystrvar(csi,*pp,str); }
					return(0);
				case SECOND_STR:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip str variable name */
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip int variable name */
					if(pp && lp) {
						sectostr(*lp,str);
						*pp=copystrvar(csi,*pp,str); }
					return(0);
				case STRUPR_VAR:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(pp && *pp)
						strupr(*pp);
					return(0);
				case STRLWR_VAR:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(pp && *pp)
						strlwr(*pp);
					return(0);
				case TRUNCSP_STR_VAR:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(pp && *pp)
						truncsp(*pp);
					return(0);
				case STRIP_CTRL_STR_VAR:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(pp && *pp)
						strip_ctrl(*pp);
					return(0);

				case ADD_INT_VAR:
				case SUB_INT_VAR:
				case MUL_INT_VAR:
				case DIV_INT_VAR:
				case MOD_INT_VAR:
				case AND_INT_VAR:
				case OR_INT_VAR:
				case NOT_INT_VAR:
				case XOR_INT_VAR:
					i=*(csi->ip-1);
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					l=*(long *)csi->ip;
					csi->ip+=4;
					if(!lp)
						return(0);
					switch(i) {
						case ADD_INT_VAR:
							*lp+=l;
							break;
						case SUB_INT_VAR:
							*lp-=l;
							break;
						case MUL_INT_VAR:
							*lp*=l;
							break;
						case DIV_INT_VAR:
							*lp/=l;
							break;
						case MOD_INT_VAR:
							*lp%=l;
							break;
						case AND_INT_VAR:
							*lp&=l;
							break;
						case OR_INT_VAR:
							*lp|=l;
							break;
						case NOT_INT_VAR:
							*lp&=~l;
							break;
						case XOR_INT_VAR:
							*lp^=l;
							break; }
					return(0);
				case COMPARE_ANY_BITS: 
				case COMPARE_ALL_BITS:
					i=*(csi->ip-1);
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					l=*(long *)csi->ip;
					csi->ip+=4;
					csi->logic=LOGIC_FALSE;
					if(!lp)
						return(0);

					if(i==COMPARE_ANY_BITS) {
						if(((*lp)&l)!=0)
							csi->logic=LOGIC_TRUE;
					} else {
						if(((*lp)&l)==l)
							csi->logic=LOGIC_TRUE;
					}
					return(0);
				case ADD_INT_VARS:
				case SUB_INT_VARS:
				case MUL_INT_VARS:
				case DIV_INT_VARS:
				case MOD_INT_VARS:
				case AND_INT_VARS:
				case OR_INT_VARS:
				case NOT_INT_VARS:
				case XOR_INT_VARS:
					i=*(csi->ip-1);
					lp1=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					lp2=getintvar(csi,*(long *)csi->ip);
					if(!lp2) {
						pp=getstrvar(csi,*(long *)csi->ip);
						if(!pp || !*pp)
							return(0);
						l=strtol(*pp,0,0); }
					else
						l=*lp2;
					csi->ip+=4;
					if(!lp1)
						return(0);
					switch(i) {
						case ADD_INT_VARS:
							*lp1+=l;
							break;
						case SUB_INT_VARS:
							*lp1-=l;
							break;
						case MUL_INT_VARS:
							*lp1*=l;
							break;
						case DIV_INT_VARS:
							*lp1/=l;
							break;
						case MOD_INT_VARS:
							*lp1%=l;
							break;
						case AND_INT_VARS:
							*lp1&=l;
							break;
						case OR_INT_VARS:
							*lp1|=l;
							break;
						case NOT_INT_VARS:
							*lp1&=~l;
							break;
						case XOR_INT_VARS:
							*lp1^=l;
							break; }
					return(0);
				case RANDOM_INT_VAR:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					l=*(long *)csi->ip;
					csi->ip+=4;
					if(lp)
						*lp=sbbs_random(l);
					return(0);
				case TIME_INT_VAR:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(lp)
						*lp=time(NULL);
					return(0);
				case DATE_STR_TO_INT:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(lp && pp && *pp)
						*lp=dstrtounix(&cfg,*pp);
					return(0);
				case STRLEN_INT_VAR:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(lp) {
						if(pp && *pp)
							*lp=strlen(*pp);
						else
							*lp=0; }
					return(0);
				case CRC16_TO_INT:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(lp) {
						if(pp && *pp)
							*lp=crc16(*pp,0);
						else
							*lp=0; }
					return(0);
				case CRC32_TO_INT:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(lp) {
						if(pp && *pp)
							*lp=crc32(*pp,0);
						else
							*lp=0; }
					return(0);
				case CHKSUM_TO_INT:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(lp) {
						*lp=0;
						if(pp && *pp) {
							i=0;
							while(*((*pp)+i))
								*lp+=(uchar)*((*pp)+(i++)); } }
					return(0);
				case FLENGTH_TO_INT:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(lp) {
						if(pp && *pp)
							*lp=flength(*pp);
						else
							*lp=0; }
					return(0);
				case FTIME_TO_INT:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(lp) {
						if(pp && *pp)
							*lp=fdate(*pp);
						else
							*lp=0; }
					return(0);
				case CHARVAL_TO_INT:
				case COPY_FIRST_CHAR:	// duplicate functionality - doh!
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(lp) {
						if(pp && *pp)
							*lp=**pp;
						else
							*lp=0; }
					return(0);
				case GETSTR_VAR:
				case GETLINE_VAR:
				case GETNAME_VAR:
				case GETSTRUPR_VAR:
				case GETSTR_MODE:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					i=*(csi->ip++);
					csi->logic=LOGIC_FALSE;
					switch(*(csi->ip-6)) {
						case GETNAME_VAR:
							getstr(buf,i,K_UPRLWR);
							break;
						case GETSTRUPR_VAR:
							getstr(buf,i,K_UPPER);
							break;
						case GETLINE_VAR:
							getstr(buf,i,K_LINE);
							break;
						case GETSTR_MODE:
							l=*(long *)csi->ip;
							csi->ip+=4;
							if(l&K_EDIT) {
								if(pp && *pp)
									strcpy(buf,*pp);
								else
									buf[0]=0; }
							getstr(buf,i,l);
							break;
						default:
							getstr(buf,i,0); }
					if(sys_status&SS_ABORT)
						return(0);
					if(pp) {
						*pp=copystrvar(csi,*pp,buf);
						csi->logic=LOGIC_TRUE; }
					return(0);
				case GETNUM_VAR:
					pp=getstrvar(csi,*(long *)csi->ip);
					if(!pp)
						lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					i=*(short *)csi->ip;
					csi->ip+=2;
					csi->logic=LOGIC_FALSE;
					l=getnum(i);
					if(!pp && !lp)
						return(0);
					if(pp) {
						if(l<=0)
							str[0]=0;
						else
							ultoa(l,str,10);
						*pp=copystrvar(csi,*pp,str);
						csi->logic=LOGIC_TRUE;
						return(0); }
					if(lp) {
						*lp=l;
						csi->logic=LOGIC_TRUE; }
					return(0);

				case SHIFT_STR_VAR:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					i=*(csi->ip++);
					if(!pp || !*pp)
						return(0);
					if(strlen(*pp)>=i)
						memmove(*pp,*pp+i,strlen(*pp)+1);
					return(0);

				case SHIFT_TO_FIRST_CHAR:
				case SHIFT_TO_LAST_CHAR:
					i=*(csi->ip-1);
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					ch=*(csi->ip++);
					csi->logic=LOGIC_FALSE;
					if(!pp || !*pp)
						return(0);
					if(i==SHIFT_TO_FIRST_CHAR)
						p=strchr(*pp,ch);
					else	/* _TO_LAST_CHAR */
						p=strrchr(*pp,ch);
					if(p==NULL)
						return(0);
					csi->logic=LOGIC_TRUE;
					i=p-*pp;
					if(i>0)
						memmove(*pp,*pp+i,strlen(p)+1);
					return(0);

				case CHKFILE_VAR:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(pp && *pp && fexistcase(cmdstr(*pp,path,csi->str,buf)))
						csi->logic=LOGIC_TRUE;
					else
						csi->logic=LOGIC_FALSE;
					return(0);
				case PRINTFILE_VAR_MODE:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					i=*(short *)(csi->ip);
					csi->ip+=2;
					if(pp && *pp)
						printfile(*pp,i);
					return(0);
				case PRINTTAIL_VAR_MODE:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					i=*(short *)(csi->ip);
					csi->ip+=2;
					j=*csi->ip;
					csi->ip++;
					if(pp && *pp)
						printtail(*pp,j,i);
					return(0);
				case TELNET_GATE_VAR:
					l=*(ulong *)(csi->ip);	// Mode
					csi->ip+=4;
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(pp && *pp)
						telnet_gate(*pp,l);
					return(0);
				case TELNET_GATE_STR:
					l=*(ulong *)(csi->ip);	// Mode
					csi->ip+=4;
					strcpy(str,(char *)csi->ip);
					while(*(csi->ip++));	/* Find NULL */
					telnet_gate(str,l);
					return(0);
				case COPY_CHAR:
					pp=getstrvar(csi,*(long *)csi->ip);
					if(pp==NULL)
						lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;

					if(pp==NULL && lp!=NULL)
						*lp=csi->cmd;
					else if(pp!=NULL) {
						sprintf(tmp,"%c",csi->cmd);
						*pp=copystrvar(csi,*pp,tmp);
					}
					return(0);
				case COMPARE_FIRST_CHAR:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					ch=*(csi->ip++);	/* char const */
					if(pp==NULL || *pp==NULL)
						csi->logic=LOGIC_FALSE;
					else {
						if(**pp==ch)
							csi->logic=LOGIC_EQUAL;
						else if(**pp>ch)
							csi->logic=LOGIC_GREATER;
						else 
							csi->logic=LOGIC_LESS;
					}
					return(0);

				case SEND_FILE_VIA:
				case RECEIVE_FILE_VIA:
					j=*(csi->ip-1);
					ch=*(csi->ip++);	/* Protocol */
					cmdstr((char *)csi->ip,csi->str,csi->str,str);
					while(*(csi->ip++));	/* Find NULL */
					for(i=0;i<cfg.total_prots;i++)
						if(cfg.prot[i]->mnemonic==ch && chk_ar(cfg.prot[i]->ar,&useron))
							break;
					csi->logic=LOGIC_FALSE;
					if(i<cfg.total_prots)
						if(protocol(cfg.prot[i],j==SEND_FILE_VIA ? XFER_DOWNLOAD : XFER_UPLOAD
							,str,str,true)==0)
							csi->logic=LOGIC_TRUE;
					return(0);
				case SEND_FILE_VIA_VAR:
				case RECEIVE_FILE_VIA_VAR:
					j=*(csi->ip-1);
					ch=*(csi->ip++);	/* Protocol */
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					for(i=0;i<cfg.total_prots;i++)
						if(cfg.prot[i]->mnemonic==ch && chk_ar(cfg.prot[i]->ar,&useron))
							break;
					csi->logic=LOGIC_FALSE;
					if(!pp || !(*pp))
						return(0);
					if(i<cfg.total_prots)
						if(protocol(cfg.prot[i]
							,j==SEND_FILE_VIA_VAR ? XFER_DOWNLOAD : XFER_UPLOAD
							,*pp,*pp,true)==0)
							csi->logic=LOGIC_TRUE;
					return(0);

				case MATCHUSER:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(lp) {
						if(pp && *pp)
							*lp=matchuser(&cfg, *pp, TRUE /*sysop_alias*/);
						else
							*lp=0; 
					}
					return(0);

				default:
					errormsg(WHERE,ERR_CHK,"var sub-instruction",*(csi->ip-1));
					return(0); }

		case CS_FIO_FUNCTION:
			switch(*(csi->ip++)) {	/* sub-op-code stored as next byte */
				case FIO_OPEN:
				case FIO_OPEN_VAR:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					w=*(ushort *)csi->ip;
					csi->ip+=2;
					csi->logic=LOGIC_FALSE;
					if(*(csi->ip-7)==FIO_OPEN) {
						cmdstr((char *)csi->ip,path,csi->str,str);
						while(*(csi->ip++)); }	 /* skip filename */
					else {
						pp=getstrvar(csi,*(long *)csi->ip);
						csi->ip+=4;
						if(!pp || !*pp)
							return(0);
						strcpy(str,*pp); }
					if(csi->files>=MAX_FOPENS)
						return(0);
					if(lp) {
						/* Access flags are not cross-platform, so convert */
						i=0;
						if(w&0x001) i|=O_RDONLY;
						if(w&0x002) i|=O_WRONLY;
						if(w&0x004) i|=O_RDWR;
						if(w&0x040) i|=O_DENYNONE;
						if(w&0x100) i|=O_CREAT;
						if(w&0x200) i|=O_TRUNC;
						if(w&0x400) i|=O_EXCL;
						if(w&0x800) i|=O_APPEND;
						*lp=(long)fnopen((int *)&j,str,i);
						if(*lp) {
							for(i=0;i<csi->files;i++)
								if(!csi->file[i])
									break;
							csi->file[i]=(FILE *)*lp;
							if(i==csi->files)
								csi->files++;
							csi->logic=LOGIC_TRUE; } }
					return(0);
				case FIO_CLOSE:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(lp && *lp) {
						csi->logic=fclose((FILE *)*lp);
						for(i=0;i<csi->files;i++)
							if(csi->file[i]==(FILE *)*lp)
								csi->file[i]=0; 
						*lp=0;
					}
					else
						csi->logic=LOGIC_FALSE;
					return(0);
				case FIO_FLUSH:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(lp && *lp)
						csi->logic=fflush((FILE *)*lp);
					else
						csi->logic=LOGIC_FALSE;
					return(0);
				case FIO_READ:
				case FIO_READ_VAR:
					lp1=getintvar(csi,*(long *)csi->ip);		/* Handle */
					csi->ip+=4;
					pp=getstrvar(csi,*(long *)csi->ip);
					if(!pp)
						lp2=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					csi->logic=LOGIC_FALSE;
					if(*(csi->ip-9)==FIO_READ) {
						i=*(short *)csi->ip;
						csi->ip+=2; /* Length */ }
					else {			/* FIO_READ_VAR */
						vp=getintvar(csi,*(long *)csi->ip);
						csi->ip+=4;
						if(!vp)
							return(0);
						i=*(short *)vp; }
					if(i>sizeof(buf)-1)
						i=sizeof(buf)-1;
					if(!lp1 || !(*lp1) || (!pp && !lp2))
						return(0);
					if(pp) {
						if(i<1) {
							if(*pp && **pp)
								i=strlen(*pp);
							else
								i=128; }
						if((j=fread(buf,1,i,(FILE *)*lp1))==i)
							csi->logic=LOGIC_TRUE;
						buf[j]=0;
						if(csi->etx) {
							p=strchr(buf,csi->etx);
							if(p) *p=0; }
						*pp=copystrvar(csi,*pp,buf); }
					else {
						*lp2=0;
						if(i>4 || i<1) i=4;
						if(fread(lp2,1,i,(FILE *)*lp1)==i)
							csi->logic=LOGIC_TRUE; }
					return(0);
				case FIO_READ_LINE:
					lp1=getintvar(csi,*(long *)csi->ip);		/* Handle */
					csi->ip+=4;
					pp=getstrvar(csi,*(long *)csi->ip);
					if(!pp)
						lp2=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					csi->logic=LOGIC_FALSE;
					if(!lp1 || !(*lp1) || feof((FILE *)*lp1) || (!pp && !lp2))
						return(0);
					csi->logic=LOGIC_TRUE;
					for(i=0;i<sizeof(buf)-1;i++) {
						if(!fread(buf+i,1,1,(FILE *)*lp1))
							break;
						if(*(buf+i)==LF) {
							i++;
							break; } }
					buf[i]=0;
					if(csi->etx) {
						p=strchr(buf,csi->etx);
						if(p) *p=0; }
					if(pp)
						*pp=copystrvar(csi,*pp,buf);
					else
						*lp2=strtol(buf,0,0);
					return(0);
				case FIO_WRITE:
				case FIO_WRITE_VAR:
					lp1=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					pp=getstrvar(csi,*(long *)csi->ip);
					if(!pp)
						lp2=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					csi->logic=LOGIC_FALSE;
					if(*(csi->ip-9)==FIO_WRITE) {
						i=*(short *)csi->ip;
						csi->ip+=2; /* Length */ }
					else {			/* FIO_WRITE_VAR */
						vp=getintvar(csi,*(long *)csi->ip);
						csi->ip+=4;
						if(!vp)
							return(0);
						i=*(short *)vp; }
					if(i>sizeof(buf)-1)
						i=sizeof(buf)-1;
					if(!lp1 || !(*lp1) || (!pp && !lp2) || (pp && !*pp))
						return(0);
					if(pp) {
						j=strlen(*pp);
						if(i<1) i=j;
						if(j>i) j=i;
						if(fwrite(*pp,1,j,(FILE *)*lp1)!=j)
							csi->logic=LOGIC_FALSE;
						else {
							if(j<i) {
								memset(buf,csi->etx,i-j);
								fwrite(buf,1,i-j,(FILE *)*lp1); 
							}
							csi->logic=LOGIC_TRUE; 
						}
					} else {
						if(i<1 || i>4) i=4;
						if(fwrite(lp2,1,i,(FILE *)*lp1)==i)
							csi->logic=LOGIC_TRUE; }
					return(0);
				case FIO_GET_LENGTH:
					lp1=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					lp2=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(lp1 && *lp1 && lp2)
						*lp2=filelength(fileno((FILE *)*lp1));
					return(0);
				case FIO_GET_TIME:
					lp1=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					lp2=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(lp1 && *lp1 && lp2) 
						*lp2=filetime(fileno((FILE *)*lp1));
					return(0);
				case FIO_SET_TIME:
					lp1=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					lp2=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
	#if 0 /* ftime */
					if(lp1 && *lp1 && lp2) {
						ft=unixtoftime(*lp2);
						setftime(fileno((FILE *)*lp1),&ft); }
	#endif
					return(0);
				case FIO_EOF:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					csi->logic=LOGIC_FALSE;
					if(lp && *lp)
						if(ftell((FILE *)*lp)>=filelength(fileno((FILE *)*lp)))
							csi->logic=LOGIC_TRUE;
					return(0);
				case FIO_GET_POS:
					lp1=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					lp2=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(lp1 && *lp1 && lp2)
						*lp2=ftell((FILE *)*lp1);
					return(0);
				case FIO_SEEK:
				case FIO_SEEK_VAR:
					lp1=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					csi->logic=LOGIC_FALSE;
					if(*(csi->ip-5)==FIO_SEEK) {
						l=*(long *)csi->ip;
						csi->ip+=4; }
					else {
						lp2=getintvar(csi,*(long *)csi->ip);
						csi->ip+=4;
						if(!lp2) {
							csi->ip+=2;
							return(0); }
						l=*lp2; }
					i=*(short *)csi->ip;
					csi->ip+=2;
					if(lp1 && *lp1)
						if(fseek((FILE *)*lp1,l,i)!=-1)
							csi->logic=LOGIC_TRUE;
					return(0);
				case FIO_LOCK:
				case FIO_LOCK_VAR:
					lp1=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					csi->logic=LOGIC_FALSE;
					if(*(csi->ip-5)==FIO_LOCK) {
						l=*(long *)csi->ip;
						csi->ip+=4; 
					} else {
						lp2=getintvar(csi,*(long *)csi->ip);
						csi->ip+=4;
						if(!lp2)
							return(0);
						l=*lp2; 
					}
					if(lp1 && *lp1) {
						fflush((FILE *)*lp1);
						csi->logic=!lock(fileno((FILE *)*lp1),ftell((FILE*)*lp1),l); 
					}
					return(0);
				case FIO_UNLOCK:
				case FIO_UNLOCK_VAR:
					lp1=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					csi->logic=LOGIC_FALSE;
					if(*(csi->ip-5)==FIO_UNLOCK) {
						l=*(long *)csi->ip;
						csi->ip+=4; 
					} else {
						lp2=getintvar(csi,*(long *)csi->ip);
						csi->ip+=4;
						if(!lp2)
							return(0);
						l=*lp2; 
					}
					if(lp1 && *lp1) {
						fflush((FILE *)*lp1);
						csi->logic=!unlock(fileno((FILE *)*lp1),ftell((FILE*)*lp1),l); 
					}
					return(0);
				case FIO_SET_LENGTH:
				case FIO_SET_LENGTH_VAR:
					lp1=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					csi->logic=LOGIC_FALSE;
					if(*(csi->ip-5)==FIO_SET_LENGTH) {
						l=*(long *)csi->ip;
						csi->ip+=4; 
					} else {
						lp2=getintvar(csi,*(long *)csi->ip);
						csi->ip+=4;
						if(!lp2)
							return(0);
						l=*lp2; }
					if(lp1 && *lp1)
						csi->logic=chsize(fileno((FILE *)*lp1),l);
					return(0);
				case FIO_PRINTF:
					lp1=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					p=format_string(this, csi);
					if(lp1 && *lp1) {
						cmdstr(p,path,csi->str,str);
						fwrite(str,1,strlen(str),(FILE *)*lp1); 
					}
					free(p);
					return(0);
				case FIO_SET_ETX:
					csi->etx=*(csi->ip++);
					return(0);
				case REMOVE_FILE:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(pp && *pp && remove(*pp)==0)
						csi->logic=LOGIC_TRUE;
					else
						csi->logic=LOGIC_FALSE;
					return(0);
				case RENAME_FILE:
				case COPY_FILE:
				case MOVE_FILE:
					pp1=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4; /* Skip variable name */
					pp2=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(pp1 && *pp1 && pp2 && *pp2)
						switch(*(csi->ip-9)) {
							case RENAME_FILE:
								csi->logic=rename(*pp1,*pp2);
								break;
							case COPY_FILE:
								csi->logic=mv(*pp1,*pp2,1);
								break;
							case MOVE_FILE:
								csi->logic=mv(*pp1,*pp2,0);
								break; }
					else
						csi->logic=LOGIC_FALSE;
					return(0);
				case GET_FILE_ATTRIB:
				case SET_FILE_ATTRIB:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(pp && *pp && lp) {
						if(*(csi->ip-9)==GET_FILE_ATTRIB)
							*lp=getfattr(*pp);
						else 
							*lp=CHMOD(*pp,(int)*lp); 
					}
					return(0);
				case MAKE_DIR:
				case REMOVE_DIR:
				case CHANGE_DIR:
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(pp && *pp)
						switch(*(csi->ip-5)) {
							case MAKE_DIR:
								csi->logic=MKDIR(*pp);
								break;
							case REMOVE_DIR:
								csi->logic=rmdir(*pp);
								break;
							case CHANGE_DIR:
								csi->logic=chdir(*pp);
								break; }
					else
						csi->logic=LOGIC_FALSE;
					return(0);

				case OPEN_DIR:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					csi->logic=LOGIC_FALSE;
					if(pp && *pp && lp) {
						*lp=(long)opendir((char *)*pp);
						if(*lp)
							csi->logic=LOGIC_TRUE; }
					return(0);
				case READ_DIR:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					pp=getstrvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					csi->logic=LOGIC_FALSE;
					if(pp && lp) {
						de=readdir((DIR *)(*lp));
						if(de!=NULL) {
							csi->logic=LOGIC_TRUE;
							*pp=copystrvar(csi,*pp,de->d_name); } }
					return(0);
				case REWIND_DIR:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(lp) {
						rewinddir((DIR *)(*lp));
						csi->logic=LOGIC_TRUE; }
					else
						csi->logic=LOGIC_FALSE;
					return(0);
				case CLOSE_DIR:
					lp=getintvar(csi,*(long *)csi->ip);
					csi->ip+=4;
					if(lp && closedir((DIR *)(*lp))==0)
						csi->logic=LOGIC_TRUE;
					else
						csi->logic=LOGIC_FALSE;
					return(0);

				default:
					errormsg(WHERE,ERR_CHK,"fio sub-instruction",*(csi->ip-1));
					return(0); }

		case CS_NET_FUNCTION:
			return(exec_net(csi));

		case CS_SWITCH:
			lp=getintvar(csi,*(long *)csi->ip);
			csi->ip+=4;
			if(!lp) {
				skipto(csi,CS_END_SWITCH);
				csi->ip++; }
			else {
				csi->misc|=CS_IN_SWITCH;
				csi->switch_val=*lp; }
			return(0);
		case CS_CASE:
			l=*(long *)csi->ip;
			csi->ip+=4;
			if(csi->misc&CS_IN_SWITCH && csi->switch_val!=l)
				skipto(csi,CS_NEXTCASE);
			else
				csi->misc&=~CS_IN_SWITCH;
			return(0);
		case CS_COMPARE_ARS:
			i=*(csi->ip++);  /* Length of ARS stored as byte before ARS */
			csi->logic=!chk_ar(csi->ip,&useron);
			csi->ip+=i;
			return(0);
		case CS_TOGGLE_USER_MISC:
			useron.misc^=*(ulong *)csi->ip;
			putuserrec(&cfg,useron.number,U_MISC,8,ultoa(useron.misc,tmp,16));
			csi->ip+=4;
			return(0);
		case CS_COMPARE_USER_MISC:
			if((useron.misc&*(ulong *)csi->ip)==*(ulong *)csi->ip)
				csi->logic=LOGIC_TRUE;
			else
				csi->logic=LOGIC_FALSE;
			csi->ip+=4;
			return(0);
		case CS_TOGGLE_USER_CHAT:
			useron.chat^=*(ulong *)csi->ip;
			putuserrec(&cfg,useron.number,U_CHAT,8,ultoa(useron.chat,tmp,16));
			csi->ip+=4;
			return(0);
		case CS_COMPARE_USER_CHAT:
			if((useron.chat&*(ulong *)csi->ip)==*(ulong *)csi->ip)
				csi->logic=LOGIC_TRUE;
			else
				csi->logic=LOGIC_FALSE;
			csi->ip+=4;
			return(0);
		case CS_TOGGLE_USER_QWK:
			useron.qwk^=*(ulong *)csi->ip;
			putuserrec(&cfg,useron.number,U_QWK,8,ultoa(useron.qwk,tmp,16));
			csi->ip+=4;
			return(0);
		case CS_COMPARE_USER_QWK:
			if((useron.qwk&*(ulong *)csi->ip)==*(ulong *)csi->ip)
				csi->logic=LOGIC_TRUE;
			else
				csi->logic=LOGIC_FALSE;
			csi->ip+=4;
			return(0);
		case CS_REPLACE_TEXT:
			i=*(ushort *)csi->ip;
			csi->ip+=2;
			i--;
			if(i>=TOTAL_TEXT) {
				errormsg(WHERE,ERR_CHK,"replace text #",i);
				while(*(csi->ip++));	 /* Find NULL */
				return(0); }
			if(text[i]!=text_sav[i] && text[i]!=nulstr)
				free(text[i]);
			j=strlen(cmdstr((char *)csi->ip,path,csi->str,buf));
			if(!j)
				text[i]=nulstr;
			else
				text[i]=(char *)malloc(j+1);
			if(!text[i]) {
				errormsg(WHERE,ERR_ALLOC,"replacement text",j);
				while(*(csi->ip++));	 /* Find NULL */
				text[i]=text_sav[i];
				return(0); }
			if(j)
				strcpy(text[i],buf);
			while(*(csi->ip++));	 /* Find NULL */
			return(0);
		case CS_USE_INT_VAR:	// Self-modifying code!
			pp=getstrvar(csi,*(long *)csi->ip);
			if(pp && *pp)
				l=strtol(*pp,0,0);
			else {
				lp=getintvar(csi,*(long *)csi->ip);
				if(lp)
					l=*lp;
				else
					l=0; }
			csi->ip+=4; 			// Variable
			i=*(csi->ip++); 		// Offset
			if(i<1 || csi->ip+1+i>=csi->cs+csi->length) {
				errormsg(WHERE,ERR_CHK,"offset",i);
				csi->ip++;
				return(0); }
			switch(*(csi->ip++)) {	// Length
				case sizeof(char):
					*(csi->ip+i)=(char)l;
					break;
				case sizeof(short):
					*((short *)(csi->ip+i))=(short)l;
					break;
				case sizeof(long):
					*((long *)(csi->ip+i))=l;
					break;
				default:
					errormsg(WHERE,ERR_CHK,"length",*(csi->ip-1));
					break; }
			return(0);
		default:
			errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1));
			return(0); }
}
Esempio n. 16
0
int main(int argc, char **argv)
{
	char	revision[16];
	char	error[512];
	char	*p,str[256],fname[256],ext,not[MAX_NOTS][9];
	uchar	*datbuf,*ixbbuf;
	int 	i,j,file,dirnum,libnum,desc_off,lines,nots=0
			,omode=O_WRONLY|O_CREAT|O_TRUNC;
	ulong	l,m,n,cdt,misc=0,total_cdt=0,total_files=0,dir_files,datbuflen;
	time32_t uld,dld,now;
	long	max_age=0;
	FILE	*in,*out=NULL;

	sscanf("$Revision$", "%*s %s", revision);

	fprintf(stderr,"\nFILELIST v%s-%s (rev %s) - Generate Synchronet File "
		"Directory Lists\n"
		,FILELIST_VER
		,PLATFORM_DESC
		,revision
		);

	if(argc<2 
		|| strcmp(argv[1],"-?")==0 
		|| strcmp(argv[1],"-help")==0 
		|| strcmp(argv[1],"--help")==0 
		|| strcmp(argv[1],"/?")==0
		) {
		printf("\n   usage: FILELIST <dir_code or - for ALL> [switches] [outfile]\n");
		printf("\n");
		printf("switches: -lib name All directories of specified library\n");
		printf("          -not code Exclude specific directory\n");
		printf("          -new days Include only new files in listing (days since upload)\n");
		printf("          -cat      Concatenate to existing outfile\n");
		printf("          -pad      Pad filename with spaces\n");
		printf("          -hdr      Include directory headers\n");
		printf("          -cdt      Include credit value\n");
		printf("          -tot      Include credit totals\n");
		printf("          -uln      Include uploader's name\n");
		printf("          -uld      Include upload date\n");
		printf("          -dfd      Include DOS file date\n");
		printf("          -dld      Include download date\n");
		printf("          -dls      Include total downloads\n");
		printf("          -nod      Exclude normal descriptions\n");
		printf("          -noe      Exclude normal descriptions, if extended "
			"exists\n");
		printf("          -ext      Include extended descriptions\n");
		printf("          -jst      Justify extended descriptions under normal\n");
		printf("          -+        Include extended description indicator (+)\n");
		printf("          --        Include offline file indicator (-)\n");
		printf("          -*        Short-hand for -pad -hdr -cdt -+ --\n");
		exit(0); }

	p=getenv("SBBSCTRL");
	if(p==NULL) {
		printf("\nSBBSCTRL environment variable not set.\n");
		printf("\nExample: SET SBBSCTRL=/sbbs/ctrl\n");
		exit(1); 
	}

	now=time32(NULL);

	memset(&scfg,0,sizeof(scfg));
	scfg.size=sizeof(scfg);
	SAFECOPY(scfg.ctrl_dir,p);

	if(chdir(scfg.ctrl_dir)!=0)
		fprintf(stderr,"!ERROR changing directory to: %s", scfg.ctrl_dir);

	printf("\nLoading configuration files from %s\n",scfg.ctrl_dir);
	if(!load_cfg(&scfg,NULL,TRUE,error)) {
		fprintf(stderr,"!ERROR loading configuration files: %s\n",error);
		exit(1);
	}
	SAFECOPY(scfg.temp_dir,"../temp");
	prep_dir(scfg.ctrl_dir, scfg.temp_dir, sizeof(scfg.temp_dir));

	dirnum=libnum=-1;
	if(argv[1][0]=='*' || strcmp(argv[1],"-")==0)
		misc|=ALL;
	else if(argv[1][0]!='-') {
		strupr(argv[1]);
		for(i=0;i<scfg.total_dirs;i++)
			if(!stricmp(argv[1],scfg.dir[i]->code))
				break;
		if(i>=scfg.total_dirs) {
			printf("\nDirectory code '%s' not found.\n",argv[1]);
			exit(1); }
		dirnum=i; }
	for(i=1;i<argc;i++) {
		if(!stricmp(argv[i],"-lib")) {
			if(dirnum!=-1) {
				printf("\nBoth directory code and -lib parameters were used.\n");
				exit(1); }
			i++;
			if(i>=argc) {
				printf("\nLibrary short name must follow -lib parameter.\n");
				exit(1); }
			strupr(argv[i]);
			for(j=0;j<scfg.total_libs;j++)
				if(!stricmp(scfg.lib[j]->sname,argv[i]))
					break;
			if(j>=scfg.total_libs) {
				printf("\nLibrary short name '%s' not found.\n",argv[i]);
				exit(1); }
			libnum=j; }
		else if(!stricmp(argv[i],"-not")) {
			if(nots>=MAX_NOTS) {
				printf("\nMaximum number of -not options (%u) exceeded.\n"
					,MAX_NOTS);
				exit(1); }
			i++;
			if(i>=argc) {
				printf("\nDirectory internal code must follow -not parameter.\n");
				exit(1); }
			sprintf(not[nots++],"%.8s",argv[i]); }
		else if(!stricmp(argv[i],"-all")) {
			if(dirnum!=-1) {
				printf("\nBoth directory code and -all parameters were used.\n");
				exit(1); }
			if(libnum!=-1) {
				printf("\nBoth library name and -all parameters were used.\n");
				exit(1); }
			misc|=ALL; }
		else if(!stricmp(argv[i],"-new")) {
			i++;
			if(i>=argc) {
				printf("\nDays since upload must follow -new parameter.\n");
				exit(1); 
			}
			max_age=strtol(argv[i],NULL,0);
		}
		else if(!stricmp(argv[i],"-pad"))
			misc|=PAD;
		else if(!stricmp(argv[i],"-cat"))
			omode=O_WRONLY|O_CREAT|O_APPEND;
		else if(!stricmp(argv[i],"-hdr"))
			misc|=HDR;
		else if(!stricmp(argv[i],"-cdt"))
			misc|=CDT_;
		else if(!stricmp(argv[i],"-tot"))
			misc|=TOT;
		else if(!stricmp(argv[i],"-ext"))
			misc|=EXT;
		else if(!stricmp(argv[i],"-uln"))
			misc|=ULN;
		else if(!stricmp(argv[i],"-uld"))
			misc|=ULD;
		else if(!stricmp(argv[i],"-dld"))
			misc|=DLD;
		else if(!stricmp(argv[i],"-dfd"))
			misc|=DFD;
		else if(!stricmp(argv[i],"-dls"))
			misc|=DLS;
		else if(!stricmp(argv[i],"-nod"))
			misc|=NOD;
		else if(!stricmp(argv[i],"-jst"))
			misc|=(EXT|JST);
		else if(!stricmp(argv[i],"-noe"))
			misc|=(EXT|NOE);
		else if(!stricmp(argv[i],"-+"))
			misc|=PLUS;
		else if(!stricmp(argv[i],"--"))
			misc|=MINUS;
		else if(!stricmp(argv[i],"-*"))
			misc|=(HDR|PAD|CDT_|PLUS|MINUS);

		else if(i!=1) {
			if(argv[i][0]=='*' || strcmp(argv[i],"-")==0) {
				misc|=AUTO;
				continue; }
			if((j=nopen(argv[i],omode))==-1) {
				printf("\nError opening/creating %s for output.\n",argv[i]);
				exit(1); }
			out=fdopen(j,"wb"); } }

	if(!out && !(misc&AUTO)) {
		printf("\nOutput file not specified, using FILES.BBS in each "
			"directory.\n");
		misc|=AUTO; }

	for(i=0;i<scfg.total_dirs;i++) {
		dir_files=0;
		if(!(misc&ALL) && i!=dirnum && scfg.dir[i]->lib!=libnum)
			continue;
		for(j=0;j<nots;j++)
			if(!stricmp(not[j],scfg.dir[i]->code))
				break;
		if(j<nots)
			continue;
		if(misc&AUTO && scfg.dir[i]->seqdev) 	/* CD-ROM */
			continue;
		printf("\n%-*s %s",LEN_GSNAME,scfg.lib[scfg.dir[i]->lib]->sname,scfg.dir[i]->lname);
		sprintf(str,"%s%s.ixb",scfg.dir[i]->data_dir,scfg.dir[i]->code);
		if((file=nopen(str,O_RDONLY))==-1)
			continue;
		l=filelength(file);
		if(misc&AUTO) {
			sprintf(str,"%sFILES.BBS",scfg.dir[i]->path);
			if((j=nopen(str,omode))==-1) {
				printf("\nError opening/creating %s for output.\n",str);
				exit(1); }
			out=fdopen(j,"wb"); }
		if(misc&HDR) {
			sprintf(fname,"%-*s      %-*s       Files: %4lu"
				,LEN_GSNAME,scfg.lib[scfg.dir[i]->lib]->sname
				,LEN_SLNAME,scfg.dir[i]->lname,l/F_IXBSIZE);
			fprintf(out,"%s\r\n",fname);
			memset(fname,'-',strlen(fname));
			fprintf(out,"%s\r\n",fname); }
		if(!l) {
			close(file);
			if(misc&AUTO) fclose(out);
			continue; }
		if((ixbbuf=(uchar *)malloc(l))==NULL) {
			close(file);
			if(misc&AUTO) fclose(out);
			printf("\7ERR_ALLOC %s %lu\n",str,l);
			continue; }
		if(read(file,ixbbuf,l)!=(int)l) {
			close(file);
			if(misc&AUTO) fclose(out);
			printf("\7ERR_READ %s %lu\n",str,l);
			free((char *)ixbbuf);
			continue; }
		close(file);
		sprintf(str,"%s%s.dat",scfg.dir[i]->data_dir,scfg.dir[i]->code);
		if((file=nopen(str,O_RDONLY))==-1) {
			printf("\7ERR_OPEN %s %u\n",str,O_RDONLY);
			free((char *)ixbbuf);
			if(misc&AUTO) fclose(out);
			continue; }
		datbuflen=filelength(file);
		if((datbuf=malloc(datbuflen))==NULL) {
			close(file);
			printf("\7ERR_ALLOC %s %lu\n",str,datbuflen);
			free((char *)ixbbuf);
			if(misc&AUTO) fclose(out);
			continue; }
		if(read(file,datbuf,datbuflen)!=(int)datbuflen) {
			close(file);
			printf("\7ERR_READ %s %lu\n",str,datbuflen);
			free((char *)datbuf);
			free((char *)ixbbuf);
			if(misc&AUTO) fclose(out);
			continue; }
		close(file);
		m=0L;
		while(m<l && !ferror(out)) {
			for(j=0;j<12 && m<l;j++)
				if(j==8)
					str[j]=ixbbuf[m]>' ' ? '.' : ' ';
				else
					str[j]=ixbbuf[m++]; /* Turns FILENAMEEXT into FILENAME.EXT */
			str[j]=0;
			unpadfname(str,fname);
			n=ixbbuf[m]|((long)ixbbuf[m+1]<<8)|((long)ixbbuf[m+2]<<16);
			uld=(ixbbuf[m+3]|((long)ixbbuf[m+4]<<8)|((long)ixbbuf[m+5]<<16)
				|((long)ixbbuf[m+6]<<24));
			dld=(ixbbuf[m+7]|((long)ixbbuf[m+8]<<8)|((long)ixbbuf[m+9]<<16)
				|((long)ixbbuf[m+10]<<24));
			m+=11;

			if(n>=datbuflen 							/* index out of bounds */
				|| datbuf[n+F_DESC+LEN_FDESC]!=CR) {	/* corrupted data */
				fprintf(stderr,"\n\7%s%s is corrupted!\n"
					,scfg.dir[i]->data_dir,scfg.dir[i]->code);
				exit(-1); }
			
			if(max_age && ((now - uld) / (24*60*60) > max_age))
				continue;

			fprintf(out,"%-12.12s",misc&PAD ? str : fname);

			total_files++;
			dir_files++;

			if(misc&PLUS && datbuf[n+F_MISC]!=ETX
				&& (datbuf[n+F_MISC]-' ')&FM_EXTDESC)
				fputc('+',out);
			else
				fputc(' ',out);

			desc_off=12;
			if(misc&(CDT_|TOT)) {
				getrec((char *)&datbuf[n],F_CDT,LEN_FCDT,str);
				cdt=atol(str);
				total_cdt+=cdt;
				if(misc&CDT_) {
					fprintf(out,"%7lu",cdt);
					desc_off+=7; } }

			if(misc&MINUS) {
				sprintf(str,"%s%s",scfg.dir[i]->path,fname);
				if(!fexistcase(str))
					fputc('-',out);
				else
					fputc(' ',out); }
			else
				fputc(' ',out);
			desc_off++;

			if(misc&DFD) {
				sprintf(str,"%s%s",scfg.dir[i]->path,fname);
				fprintf(out,"%s ",unixtodstr(&scfg,(time32_t)fdate(str),str));
				desc_off+=9; }

			if(misc&ULD) {
				fprintf(out,"%s ",unixtodstr(&scfg,uld,str));
				desc_off+=9; }

			if(misc&ULN) {
				getrec((char *)&datbuf[n],F_ULER,25,str);
				fprintf(out,"%-25s ",str);
				desc_off+=26; }

			if(misc&DLD) {
				fprintf(out,"%s ",unixtodstr(&scfg,dld,str));
				desc_off+=9; }

			if(misc&DLS) {
				getrec((char *)&datbuf[n],F_TIMESDLED,5,str);
				j=atoi(str);
				fprintf(out,"%5u ",j);
				desc_off+=6; }

			if(datbuf[n+F_MISC]!=ETX && (datbuf[n+F_MISC]-' ')&FM_EXTDESC)
				ext=1;	/* extended description exists */
			else
				ext=0;	/* it doesn't */

			if(!(misc&NOD) && !(misc&NOE && ext)) {
				getrec((char *)&datbuf[n],F_DESC,LEN_FDESC,str);
				fprintf(out,"%s",str); }

			if(misc&EXT && ext) {							/* Print ext desc */

				sprintf(str,"%s%s.exb",scfg.dir[i]->data_dir,scfg.dir[i]->code);
				if(!fexist(str))
					continue;
				if((j=nopen(str,O_RDONLY))==-1) {
					printf("\7ERR_OPEN %s %u\n",str,O_RDONLY);
					continue; }
				if((in=fdopen(j,"rb"))==NULL) {
					close(j);
					continue; }
				fseek(in,(n/F_LEN)*512L,SEEK_SET);
				lines=0;
				if(!(misc&NOE)) {
					fprintf(out,"\r\n");
					lines++; }
				while(!feof(in) && !ferror(in)
					&& ftell(in)<(long)((n/F_LEN)+1)*512L) {
					if(!fgets(str,128,in) || !str[0])
						break;
					stripctrlz(str);
					if(lines) {
						if(misc&JST)
							fprintf(out,"%*s",desc_off,"");
						fputc(' ',out);				/* indent one character */ }
					fprintf(out,"%s",str);
					lines++; }
				fclose(in); }
			fprintf(out,"\r\n"); }
		free((char *)datbuf);
		free((char *)ixbbuf);
		if(dir_files)
			fprintf(out,"\r\n"); /* blank line at end of dir */
		if(misc&AUTO) fclose(out); }

	if(misc&TOT && !(misc&AUTO))
		fprintf(out,"TOTALS\n------\n%lu credits/bytes in %lu files.\r\n"
			,total_cdt,total_files);
	printf("\nDone.\n");
	return(0);
}
Esempio n. 17
0
int main(int argc, char **argv)
{
	char str[256],dir[256]={""},*p;
    uchar *buf;
	int i,file,pause=0,lncntr=0;
    time_t timestamp;
    long l;
    ulong   length,
            logons,
            timeon,
            posts,
            emails,
            fbacks,
            ulb,
            uls,
            dlb,
            dls;
	time_t	yesterday;
	struct tm *curdate;


printf("\nSynchronet System/Node Statistics Log Viewer v1.02\n\n");

for(i=1;i<argc;i++)
	if(!stricmp(argv[i],"/P"))
		pause=1;
	else
		strcpy(dir,argv[1]);
if(!dir[0]) {
	p=getenv("SBBSCTRL");
	if(p!=NULL)
		strcpy(dir,p); }

backslash(dir);

sprintf(str,"%scsts.dab",dir);
if(!fexistcase(str)) {
	printf("%s does not exist\r\n",str);
	return(1); }
if((file=nopen(str,O_RDONLY))==-1) {
	printf("Error opening %s\r\n",str);
	return(1); }
length=filelength(file);
if(length<40) {
    close(file);
	return(1); }
if((buf=malloc(length))==0) {
    close(file);
	printf("error allocating %lu bytes\r\n",length);
	return(1); }
read(file,buf,length);
close(file);
l=length-4;
while(l>-1L) {
    fbacks=buf[l]|((long)buf[l+1]<<8)|((long)buf[l+2]<<16)
        |((long)buf[l+3]<<24);
    l-=4;
    emails=buf[l]|((long)buf[l+1]<<8)|((long)buf[l+2]<<16)
        |((long)buf[l+3]<<24);
    l-=4;
    posts=buf[l]|((long)buf[l+1]<<8)|((long)buf[l+2]<<16)
        |((long)buf[l+3]<<24);
    l-=4;
    dlb=buf[l]|((long)buf[l+1]<<8)|((long)buf[l+2]<<16)
        |((long)buf[l+3]<<24);
    l-=4;
    dls=buf[l]|((long)buf[l+1]<<8)|((long)buf[l+2]<<16)
        |((long)buf[l+3]<<24);
    l-=4;
    ulb=buf[l]|((long)buf[l+1]<<8)|((long)buf[l+2]<<16)
        |((long)buf[l+3]<<24);
    l-=4;
    uls=buf[l]|((long)buf[l+1]<<8)|((long)buf[l+2]<<16)
        |((long)buf[l+3]<<24);
    l-=4;
    timeon=buf[l]|((long)buf[l+1]<<8)|((long)buf[l+2]<<16)
        |((long)buf[l+3]<<24);
    l-=4;
    logons=buf[l]|((long)buf[l+1]<<8)|((long)buf[l+2]<<16)
        |((long)buf[l+3]<<24);
    l-=4;
    timestamp=buf[l]|((long)buf[l+1]<<8)|((long)buf[l+2]<<16)
        |((long)buf[l+3]<<24);
    l-=4;
	yesterday=timestamp-(24*60*60);	/* 1 day less than stamp */
	curdate=localtime(&yesterday);
	printf("%2.2d/%2.2d/%2.2d T:%5lu   L:%3lu   P:%3lu   "
		"E:%3lu   F:%3lu   U:%6luk %3lu  D:%6luk %3lu\n"
		,curdate->tm_mon+1,curdate->tm_mday,curdate->tm_year%100,timeon,logons,posts,emails
		,fbacks,ulb/1024,uls,dlb/1024,dls);
	lncntr++;
	if(pause && lncntr>=20) {
		printf("[Hit a key]");
		fflush(stdout);
		if(getchar()==3)
			break;
		printf("\r");
		lncntr=0; } }
free(buf);
return(0);
}
Esempio n. 18
0
bool sbbs_t::email(int usernumber, const char *top, const char *subj, long mode)
{
	char		str[256],str2[256],msgpath[256],title[LEN_TITLE+1],ch
				,buf[SDT_BLOCK_LEN];
	char 		tmp[512];
	char		pid[128];
	char*		editor=NULL;
	ushort		msgattr=0;
	uint16_t	xlat=XLAT_NONE;
	ushort		nettype;
	int 		i,j,x,file;
	long		l;
	long		length;
	ulong		offset;
	uint32_t	crc=0xffffffffUL;
	FILE*		instream;
	node_t		node;
	smbmsg_t	msg;

	SAFECOPY(title,subj);

	if(useron.etoday>=cfg.level_emailperday[useron.level] && !SYSOP && !(useron.exempt&FLAG('M'))) {
		bputs(text[TooManyEmailsToday]);
		return(false); 
	}

	if(usernumber==1 && useron.rest&FLAG('S')
		&& (cfg.node_valuser!=1 || useron.fbacks || useron.emails)) { /* ! val fback */
		bprintf(text[R_Feedback],cfg.sys_op);
		return(false); 
	}
	if(usernumber!=1 && useron.rest&FLAG('E')
		&& (cfg.node_valuser!=usernumber || useron.fbacks || useron.emails)) {
		bputs(text[R_Email]);
		return(false); 
	}
	if(!usernumber) {
		bputs(text[UnknownUser]);
		return(false); 
	}
	getuserrec(&cfg,usernumber,U_MISC,8,str);
	l=ahtoul(str);
	if(l&(DELETED|INACTIVE)) {              /* Deleted or Inactive User */
		bputs(text[UnknownUser]);
		return(false); 
	}
	if((l&NETMAIL) && (cfg.sys_misc&SM_FWDTONET)) {
		getuserrec(&cfg,usernumber,U_NETMAIL,LEN_NETMAIL,str);
		bprintf(text[UserNetMail],str);
		if((mode & WM_FORCEFWD) || text[ForwardMailQ][0]==0 || yesno(text[ForwardMailQ])) /* Forward to netmail address */
			return(netmail(str,subj,mode));
	}
	bprintf(text[Emailing],username(&cfg,usernumber,tmp),usernumber);
	action=NODE_SMAL;
	nodesync();

	sprintf(str,"%sfeedback.*", cfg.exec_dir);
	if(usernumber==cfg.node_valuser && useron.fbacks && fexist(str)) {
		exec_bin("feedback",&main_csi);
		if(main_csi.logic!=LOGIC_TRUE)
			return(false); 
	}

	if(cfg.sys_misc&SM_ANON_EM && useron.exempt&FLAG('A')
		&& !noyes(text[AnonymousQ]))
		msgattr|=MSG_ANONYMOUS;

	if(cfg.sys_misc&SM_DELREADM)
		msgattr|=MSG_KILLREAD;

	msg_tmp_fname(useron.xedit, msgpath, sizeof(msgpath));
	username(&cfg,usernumber,str2);
	if(!writemsg(msgpath,top,title,mode,INVALID_SUB,str2,&editor)) {
		bputs(text[Aborted]);
		return(false); 
	}

	if(mode&WM_FILE && !SYSOP && !(cfg.sys_misc&SM_FILE_EM))
		mode&=~WM_FILE;


	if(mode&WM_FILE) {
		sprintf(str2,"%sfile/%04u.in", cfg.data_dir,usernumber);
		MKDIR(str2);
		sprintf(str2,"%sfile/%04u.in/%s", cfg.data_dir,usernumber,title);
		if(fexistcase(str2)) {
			bputs(text[FileAlreadyThere]);
			remove(msgpath);
			return(false); 
		}
		{ /* Remote */
			xfer_prot_menu(XFER_UPLOAD);
			mnemonics(text[ProtocolOrQuit]);
			strcpy(str,"Q");
			for(x=0;x<cfg.total_prots;x++)
				if(cfg.prot[x]->ulcmd[0] && chk_ar(cfg.prot[x]->ar,&useron,&client)) {
					sprintf(tmp,"%c",cfg.prot[x]->mnemonic);
					strcat(str,tmp); 
				}
			ch=(char)getkeys(str,0);
			if(ch=='Q' || sys_status&SS_ABORT) {
				bputs(text[Aborted]);
				remove(msgpath);
				return(false); 
			}
			for(x=0;x<cfg.total_prots;x++)
				if(cfg.prot[x]->ulcmd[0] && cfg.prot[x]->mnemonic==ch
					&& chk_ar(cfg.prot[x]->ar,&useron,&client))
					break;
			if(x<cfg.total_prots)	/* This should be always */
				protocol(cfg.prot[x],XFER_UPLOAD,str2,nulstr,true); 
		}
		safe_snprintf(tmp,sizeof(tmp),"%s%s",cfg.temp_dir,title);
		if(!fexistcase(str2) && fexistcase(tmp))
			mv(tmp,str2,0);
		l=(long)flength(str2);
		if(l>0)
			bprintf(text[FileNBytesReceived],title,ultoac(l,tmp));
		else {
			bprintf(text[FileNotReceived],title);
			remove(msgpath);
			return(false); 
		} 
	}

	bputs(text[WritingIndx]);

	if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) {
		errormsg(WHERE,ERR_OPEN,"MAIL",i);
		return(false); 
	}
	sprintf(smb.file,"%smail", cfg.data_dir);
	smb.retry_time=cfg.smb_retry_time;
	smb.subnum=INVALID_SUB;
	if((i=smb_open(&smb))!=0) {
		smb_stack(&smb,SMB_STACK_POP);
		errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
		return(false); 
	}

	if(smb_fgetlength(smb.shd_fp)<1) {	 /* Create it if it doesn't exist */
		smb.status.max_crcs=cfg.mail_maxcrcs;
		smb.status.max_age=cfg.mail_maxage;
		smb.status.max_msgs=0;
		smb.status.attr=SMB_EMAIL;
		if((i=smb_create(&smb))!=0) {
			smb_close(&smb);
			smb_stack(&smb,SMB_STACK_POP);
			errormsg(WHERE,ERR_CREATE,smb.file,i,smb.last_error);
			return(false); 
		} 
	}

	if((i=smb_locksmbhdr(&smb))!=0) {
		smb_close(&smb);
		smb_stack(&smb,SMB_STACK_POP);
		errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error);
		return(false); 
	}

	length=(long)flength(msgpath)+2;	 /* +2 for translation string */

	if(length&0xfff00000UL) {
		smb_unlocksmbhdr(&smb);
		smb_close(&smb);
		smb_stack(&smb,SMB_STACK_POP);
		errormsg(WHERE,ERR_LEN,msgpath,length);
		return(false); 
	}

	if((i=smb_open_da(&smb))!=0) {
		smb_unlocksmbhdr(&smb);
		smb_close(&smb);
		smb_stack(&smb,SMB_STACK_POP);
		errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
		return(false); 
	}
	if(cfg.sys_misc&SM_FASTMAIL)
		offset=smb_fallocdat(&smb,length,1);
	else
		offset=smb_allocdat(&smb,length,1);
	smb_close_da(&smb);

	if((instream=fnopen(&file,msgpath,O_RDONLY|O_BINARY))==NULL) {
		smb_freemsgdat(&smb,offset,length,1);
		smb_unlocksmbhdr(&smb);
		smb_close(&smb);
		smb_stack(&smb,SMB_STACK_POP);
		errormsg(WHERE,ERR_OPEN,msgpath,O_RDONLY|O_BINARY);
		return(false); 
	}

	setvbuf(instream,NULL,_IOFBF,2*1024);
	smb_fseek(smb.sdt_fp,offset,SEEK_SET);
	xlat=XLAT_NONE;
	smb_fwrite(&smb,&xlat,2,smb.sdt_fp);
	x=SDT_BLOCK_LEN-2;				/* Don't read/write more than 255 */
	while(!feof(instream)) {
		memset(buf,0,x);
		j=fread(buf,1,x,instream);
		if(j<1)
			break;
		if(j>1 && (j!=x || feof(instream)) && buf[j-1]==LF && buf[j-2]==CR)
			buf[j-1]=buf[j-2]=0;
		if(cfg.mail_maxcrcs) {
			for(i=0;i<j;i++)
				crc=ucrc32(buf[i],crc); 
		}
		smb_fwrite(&smb,buf,j,smb.sdt_fp);
		x=SDT_BLOCK_LEN; 
	}
	smb_fflush(smb.sdt_fp);
	fclose(instream);
	crc=~crc;

	memset(&msg,0,sizeof(smbmsg_t));
	msg.hdr.version=smb_ver();
	msg.hdr.attr=msgattr;
	if(mode&WM_FILE)
		msg.hdr.auxattr|=MSG_FILEATTACH;
	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);

	if(cfg.mail_maxcrcs) {
		i=smb_addcrc(&smb,crc);
		if(i) {
			smb_freemsgdat(&smb,offset,length,1);
			smb_unlocksmbhdr(&smb);
			smb_close(&smb);
			smb_stack(&smb,SMB_STACK_POP);
			attr(cfg.color[clr_err]);
			bputs(text[CantPostMsg]);
			return(false); 
		} 
	}

	msg.hdr.offset=offset;

	username(&cfg,usernumber,str);
	smb_hfield_str(&msg,RECIPIENT,str);

	sprintf(str,"%u",usernumber);
	smb_hfield_str(&msg,RECIPIENTEXT,str);

	SAFECOPY(str,useron.alias);
	smb_hfield_str(&msg,SENDER,str);

	sprintf(str,"%u",useron.number);
	smb_hfield_str(&msg,SENDEREXT,str);

	if(useron.misc&NETMAIL) {
		if(useron.rest&FLAG('G'))
			smb_hfield_str(&msg,REPLYTO,useron.name);
		nettype=smb_netaddr_type(useron.netmail);
		if(nettype!=NET_NONE && nettype!=NET_UNKNOWN) {
			smb_hfield(&msg,REPLYTONETTYPE,sizeof(nettype),&nettype);
			smb_hfield_str(&msg,REPLYTONETADDR,useron.netmail);
		}
	}

	/* Security logging */
	msg_client_hfields(&msg,&client);
	smb_hfield_str(&msg,SENDERSERVER,startup->host_name);

	smb_hfield_str(&msg,SUBJECT,title);

	/* Generate FidoNet Program Identifier */
	smb_hfield_str(&msg,FIDOPID,msg_program_id(pid));

	if(editor!=NULL)
		smb_hfield_str(&msg,SMB_EDITOR,editor);

	smb_dfield(&msg,TEXT_BODY,length);

	i=smb_addmsghdr(&smb,&msg,SMB_SELFPACK); // calls smb_unlocksmbhdr() 
	smb_close(&smb);
	smb_stack(&smb,SMB_STACK_POP);

	smb_freemsgmem(&msg);
	if(i!=SMB_SUCCESS) {
		smb_freemsgdat(&smb,offset,length,1);
		errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error);
		return(false); 
	}

	if(usernumber==1)
		logon_fbacks++;
	else
		logon_emails++;
	user_sent_email(&cfg, &useron, 1, usernumber==1);
	bprintf(text[Emailed],username(&cfg,usernumber,tmp),usernumber);
	safe_snprintf(str,sizeof(str),"%s sent e-mail to %s #%d"
		,useron.alias,username(&cfg,usernumber,tmp),usernumber);
	logline("E+",str);
	if(mode&WM_FILE && online==ON_REMOTE)
		autohangup();
	if(msgattr&MSG_ANONYMOUS)				/* Don't tell user if anonymous */
		return(true);
	for(i=1;i<=cfg.sys_nodes;i++) { /* Tell user, if online */
		getnodedat(i,&node,0);
		if(node.useron==usernumber && !(node.misc&NODE_POFF)
			&& (node.status==NODE_INUSE || node.status==NODE_QUIET)) {
			safe_snprintf(str,sizeof(str),text[EmailNodeMsg],cfg.node_num,useron.alias);
			putnmsg(&cfg,i,str);
			break; 
		} 
	}
	if(i>cfg.sys_nodes) {	/* User wasn't online, so leave short msg */
		safe_snprintf(str,sizeof(str),text[UserSentYouMail],useron.alias);
		putsmsg(&cfg,usernumber,str); 
	}
	return(true);
}
Esempio n. 19
0
int sbbs_t::text_sec()
{
	char	str[256],usemenu
			,*file[MAX_TXTFILES],addpath[83],addstr[83],*buf,ch;
	char 	tmp[512];
	long	i,j,usrsec[MAX_TXTSECS],usrsecs,cursec;
    long    l,length;
    FILE    *stream;

	for(i=j=0;i<cfg.total_txtsecs;i++) {
		if(!chk_ar(cfg.txtsec[i]->ar,&useron,&client))
			continue;
		usrsec[j++]=i; 
	}
	usrsecs=j;
	if(!usrsecs) {
		bputs(text[NoTextSections]);
		return(1); 
	}
	action=NODE_RTXT;
	while(online) {
		sprintf(str,"%smenu/text_sec.*",cfg.text_dir);
		if(fexist(str))
			menu("text_sec");
		else {
			bputs(text[TextSectionLstHdr]);
			for(i=0;i<usrsecs && !msgabort();i++) {
				sprintf(str,text[TextSectionLstFmt],i+1,cfg.txtsec[usrsec[i]]->name);
				if(i<9) outchar(' ');
				bputs(str); 
			}
		}
		ASYNC;
		mnemonics(text[WhichTextSection]);
		if((cursec=getnum(usrsecs))<1)
			break;
		cursec--;
		while(online) {
			sprintf(str,"%smenu/text%lu.*",cfg.text_dir,cursec+1);
			if(fexist(str)) {
				sprintf(str,"text%lu",cursec+1);
				menu(str);
				usemenu=1; 
			}
			else {
				bprintf(text[TextFilesLstHdr],cfg.txtsec[usrsec[cursec]]->name);
				usemenu=0; 
			}
			sprintf(str,"%stext/%s.ixt",cfg.data_dir,cfg.txtsec[usrsec[cursec]]->code);
			j=0;
			if(fexist(str)) {
				if((stream=fnopen((int *)&i,str,O_RDONLY))==NULL) {
					errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
					return(0); 
				}
				while(!ferror(stream) && !msgabort()) {  /* file open too long */
					if(!fgets(str,81,stream))
						break;
					str[strlen(str)-2]=0;   /* chop off CRLF */
					if((file[j]=(char *)malloc(strlen(str)+1))==NULL) {
						errormsg(WHERE,ERR_ALLOC,nulstr,strlen(str)+1);
						continue; 
					}
					strcpy(file[j],str);
					fgets(str,81,stream);
					if(!usemenu) bprintf(text[TextFilesLstFmt],j+1,str);
					j++; 
				}
				fclose(stream); 
			}
			ASYNC;
			if(SYSOP) {
				strcpy(str,"QARE?");
				mnemonics(text[WhichTextFileSysop]); 
			}
			else {
				strcpy(str,"Q?");
				mnemonics(text[WhichTextFile]); 
			}
			i=getkeys(str,j);
			if(!(i&0x80000000L)) {		  /* no file number */
				for(l=0;l<j;l++)
					free(file[l]);
				if((i=='E' || i=='R') && !j)
					continue; 
			}
			if(i=='Q' || !i)
				break;
			if(i==-1) {  /* ctrl-c */
				for(i=0;i<j;i++)
					free(file[i]);
				return(0); 
			}
			if(i=='?')  /* ? means re-list */
				continue;
			if(i=='A') {    /* Add text file */
				if(j) {
					bputs(text[AddTextFileBeforeWhich]);
					i=getnum(j+1);
					if(i<1)
						continue;
					i--;    /* number of file entries to skip */ }
				else
					i=0;
				bprintf(text[AddTextFilePath]
					,cfg.data_dir,cfg.txtsec[usrsec[cursec]]->code);
				if(!getstr(addpath,80,0))
					continue;
				strcat(addpath,crlf);
				bputs(text[AddTextFileDesc]);
				if(!getstr(addstr,74,0))
					continue;
				strcat(addstr,crlf);
				sprintf(str,"%stext/%s.ixt"
					,cfg.data_dir,cfg.txtsec[usrsec[cursec]]->code);
				if(i==j) {  /* just add to end */
					if((i=nopen(str,O_WRONLY|O_APPEND|O_CREAT))==-1) {
						errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_APPEND|O_CREAT);
						return(0); 
					}
					write(i,addpath,strlen(addpath));
					write(i,addstr,strlen(addstr));
					close(i);
					continue; 
				}
				j=i; /* inserting in middle of file */
				if((stream=fnopen((int *)&i,str,O_RDWR))==NULL) {
					errormsg(WHERE,ERR_OPEN,str,O_RDWR);
					return(0); 
				}
				length=(long)filelength(i);
				for(i=0;i<j;i++) {  /* skip two lines for each entry */
					fgets(tmp,81,stream);
					fgets(tmp,81,stream); 
				}
				l=(long)ftell(stream);
				if((buf=(char *)malloc(length-l))==NULL) {
					fclose(stream);
					errormsg(WHERE,ERR_ALLOC,str,length-l);
					return(0); 
				}
				fread(buf,1,length-l,stream);
				fseek(stream,l,SEEK_SET); /* go back to where we need to insert */
				fputs(addpath,stream);
				fputs(addstr,stream);
				fwrite(buf,1,length-l,stream);
				fclose(stream);
				free(buf);
				continue; 
			}
			if(i=='R' || i=='E') {   /* Remove or Edit text file */
				ch=(char)i;
				if(ch=='R')
					bputs(text[RemoveWhichTextFile]);
				else
					bputs(text[EditWhichTextFile]);
				i=getnum(j);
				if(i<1)
					continue;
				sprintf(str,"%stext/%s.ixt"
					,cfg.data_dir,cfg.txtsec[usrsec[cursec]]->code);
				j=i-1;
				if((stream=fnopen(NULL,str,O_RDONLY))==NULL) {
					errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
					return(0); 
				}
				for(i=0;i<j;i++) {  /* skip two lines for each entry */
					fgets(tmp,81,stream);
					fgets(tmp,81,stream); 
				}
				fgets(addpath,81,stream);
				truncsp(addpath);
				fclose(stream);
				if(!strchr(addpath,'\\') && !strchr(addpath,'/'))
					sprintf(tmp,"%stext/%s/%s"
						,cfg.data_dir,cfg.txtsec[usrsec[cursec]]->code,addpath);
				else
					strcpy(tmp,addpath);
				if(ch=='R') {               /* Remove */
					if(fexist(tmp)) {
						sprintf(str,text[DeleteTextFileQ],tmp);
						if(!noyes(str))
							if(remove(tmp)) errormsg(WHERE,ERR_REMOVE,tmp,0); 
					}
					sprintf(str,"%stext/%s.ixt"
						,cfg.data_dir,cfg.txtsec[usrsec[cursec]]->code);
					removeline(str,addpath,2,0); 
				}
				else {                      /* Edit */
					strcpy(str,tmp);
					editfile(str); 
				}
				continue; 
			}
			i=(i&~0x80000000L)-1;
			if(!strchr(file[i],'\\') && !strchr(file[i],'/'))
				sprintf(str,"%stext/%s/%s"
					,cfg.data_dir,cfg.txtsec[usrsec[cursec]]->code,file[i]);
			else
				strcpy(str,file[i]);
			fexistcase(str);
			attr(LIGHTGRAY);
			printfile(str,0);
			sprintf(str,"%s read text file: %s"
				,useron.alias,file[i]);
			logline("T-",str);
			pause();
			sys_status&=~SS_ABORT;
			for(i=0;i<j;i++)
				free(file[i]); 
		} 
	}
	return(0);
}
Esempio n. 20
0
bool sbbs_t::pack_rep(uint hubnum)
{
	char		str[MAX_PATH+1];
	char 		tmp[MAX_PATH+1],tmp2[MAX_PATH+1];
	char		hubid_upper[LEN_QWKID+1];
	char		hubid_lower[LEN_QWKID+1];
	int 		file,mode;
	uint		i,j,k;
	long		msgcnt,submsgs,packedmail,netfiles=0,deleted;
	uint32_t	u;
	uint32_t	posts;
	uint32_t	mailmsgs;
	ulong		msgs;
	uint32_t	last;
	post_t*		post;
	mail_t*		mail;
	FILE*		rep;
	FILE*		hdrs=NULL;
	DIR*		dir;
	DIRENT*		dirent;
	smbmsg_t	msg;

	msgcnt=0L;
	delfiles(cfg.temp_dir,ALLFILES);

	SAFECOPY(hubid_upper,cfg.qhub[hubnum]->id);
	strupr(hubid_upper);
	SAFECOPY(hubid_lower,cfg.qhub[hubnum]->id);
	strlwr(hubid_lower);

	SAFEPRINTF2(str,"%s%s.REP",cfg.data_dir,hubid_upper);
	if(fexistcase(str)) {
		eprintf(LOG_INFO,"Updating %s", str);
		external(cmdstr(cfg.qhub[hubnum]->unpack,str,ALLFILES,NULL),EX_OFFLINE);
	} else
		eprintf(LOG_INFO,"Creating %s", str);
	/*************************************************/
	/* Create SYSID.MSG, write header and leave open */
	/*************************************************/
	SAFEPRINTF2(str,"%s%s.MSG",cfg.temp_dir,hubid_upper);
	fexistcase(str);
	if((rep=fnopen(&file,str,O_CREAT|O_WRONLY|O_TRUNC))==NULL) {
		errormsg(WHERE,ERR_CREATE,str,O_CREAT|O_WRONLY|O_TRUNC);
		return(false);
	}
	if(filelength(file)<1) { 							/* New REP packet */
		SAFEPRINTF2(str,"%-*s"
			,QWK_BLOCK_LEN,hubid_upper);		/* So write header */
		fwrite(str,QWK_BLOCK_LEN,1,rep); 
	}
	fseek(rep,0L,SEEK_END);

	/* Always includes HEADERS.DAT in .REP packets which are only for QWKnet hubs */
	/* And *usually* a Synchronet system */
	SAFEPRINTF(str,"%sHEADERS.DAT",cfg.temp_dir);
	fexistcase(str);
	if((hdrs=fopen(str,"a"))==NULL)
		errormsg(WHERE,ERR_CREATE,str,0);

	/*********************/
	/* Pack new messages */
	/*********************/
	SAFEPRINTF(smb.file,"%smail",cfg.data_dir);
	smb.retry_time=cfg.smb_retry_time;
	smb.subnum=INVALID_SUB;
	if((i=smb_open(&smb))!=0) {
		fclose(rep);
		if(hdrs!=NULL)
			fclose(hdrs);
		errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
		return(false); 
	}

	/***********************/
	/* Pack E-mail, if any */
	/***********************/
	qwkmail_last=0;
	mail=loadmail(&smb,&mailmsgs,0,MAIL_YOUR,0);
	packedmail=0;
	if(mailmsgs) {
		eprintf(LOG_INFO,"Packing NetMail for %s", cfg.qhub[hubnum]->id);
		for(u=0;u<mailmsgs;u++) {
	//		bprintf("\b\b\b\b\b%-5lu",u+1);

			memset(&msg,0,sizeof(msg));
			msg.idx=mail[u];
			if(msg.idx.number>qwkmail_last)
				qwkmail_last=msg.idx.number;
			if(!loadmsg(&msg,mail[u].number))
				continue;

			SAFEPRINTF(str,"%s/",cfg.qhub[hubnum]->id);
			if(msg.to_net.type!=NET_QWK
				|| (strcmp((char *)msg.to_net.addr,cfg.qhub[hubnum]->id)
				&& strncmp((char *)msg.to_net.addr,str,strlen(str)))) {
				smb_unlockmsghdr(&smb,&msg);
				smb_freemsgmem(&msg);
				continue; 
			}

			msgtoqwk(&msg,rep,QM_TO_QNET|QM_REP|A_LEAVE,INVALID_SUB,0,hdrs);
			packedmail++;
			smb_unlockmsghdr(&smb,&msg);
			smb_freemsgmem(&msg); 
			YIELD();	/* yield */
		}
		eprintf(LOG_INFO,"Packed %d NetMail messages",packedmail); 
	}
	smb_close(&smb);					/* Close the e-mail */
	if(mailmsgs)
		free(mail);

	for(i=0;i<cfg.qhub[hubnum]->subs;i++) {
		j=cfg.qhub[hubnum]->sub[i]; 			/* j now equals the real sub num */
		msgs=getlastmsg(j,&last,0);
		lncntr=0;						/* defeat pause */
		if(!msgs || last<=subscan[j].ptr) {
			if(subscan[j].ptr>last) {
				subscan[j].ptr=last;
				subscan[j].last=last; 
			}
			eprintf(LOG_INFO,remove_ctrl_a(text[NScanStatusFmt],tmp)
				,cfg.grp[cfg.sub[j]->grp]->sname
				,cfg.sub[j]->lname,0L,msgs);
			continue; 
		}

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

		post=loadposts(&posts,j,subscan[j].ptr,LP_BYSELF|LP_OTHERS|LP_PRIVATE|LP_REP,NULL);
		eprintf(LOG_INFO,remove_ctrl_a(text[NScanStatusFmt],tmp)
			,cfg.grp[cfg.sub[j]->grp]->sname
			,cfg.sub[j]->lname,posts,msgs);
		if(!posts)	{ /* no new messages */
			smb_close(&smb);
			continue; 
		}

		subscan[j].ptr=last;                   /* set pointer */
		eprintf(LOG_INFO,"%s",remove_ctrl_a(text[QWKPackingSubboard],tmp));	/* ptr to last msg	*/
		submsgs=0;
		for(u=0;u<posts;u++) {
	//		bprintf("\b\b\b\b\b%-5lu",u+1);

			memset(&msg,0,sizeof(msg));
			msg.idx=post[u];
			if(!loadmsg(&msg,post[u].number))
				continue;

			if(msg.from_net.type && msg.from_net.type!=NET_QWK &&
				!(cfg.sub[j]->misc&SUB_GATE)) {
				smb_freemsgmem(&msg);
				smb_unlockmsghdr(&smb,&msg);
				continue; 
			}

			if(!strnicmp(msg.subj,"NE:",3) || (msg.from_net.type==NET_QWK &&
				route_circ((char *)msg.from_net.addr,cfg.qhub[hubnum]->id))) {
				smb_freemsgmem(&msg);
				smb_unlockmsghdr(&smb,&msg);
				continue; 
			}

			mode=cfg.qhub[hubnum]->mode[i]|QM_TO_QNET|QM_REP;
			if(mode&A_LEAVE) mode|=(QM_VIA|QM_TZ|QM_MSGID);
			if(msg.from_net.type!=NET_QWK)
				mode|=QM_TAGLINE;

			msgtoqwk(&msg,rep,mode,j,cfg.qhub[hubnum]->conf[i],hdrs);

			smb_freemsgmem(&msg);
			smb_unlockmsghdr(&smb,&msg);
			msgcnt++;
			submsgs++; 
			if(!(u%50))
				YIELD(); /* yield */
		}
		eprintf(LOG_INFO,remove_ctrl_a(text[QWKPackedSubboard],tmp),submsgs,msgcnt);
		free(post);
		smb_close(&smb); 
		YIELD();	/* yield */
	}

	if(hdrs!=NULL)
		fclose(hdrs);
	fclose(rep);			/* close HUB_ID.MSG */
	CRLF;
							/* Look for extra files to send out */
	SAFEPRINTF2(str,"%sqnet/%s.out",cfg.data_dir,hubid_lower);
	dir=opendir(str);
	while(dir!=NULL && (dirent=readdir(dir))!=NULL) {
		SAFEPRINTF3(str,"%sqnet/%s.out/%s",cfg.data_dir,hubid_lower,dirent->d_name);
		if(isdir(str))
			continue;
		SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,dirent->d_name);
		eprintf(LOG_INFO,remove_ctrl_a(text[RetrievingFile],tmp),str);
		if(!mv(str,tmp2,/* copy: */TRUE))
			netfiles++;
	}
	if(dir!=NULL)
		closedir(dir);
	if(netfiles)
		CRLF;

	if(!msgcnt && !netfiles && !packedmail) {
		eprintf(LOG_INFO,remove_ctrl_a(text[QWKNoNewMessages],tmp));
		return(true);	// Changed from false Mar-11-2005 (needs to be true to save updated ptrs)
	}

	/*******************/
	/* Compress Packet */
	/*******************/
	SAFEPRINTF2(str,"%s%s.REP",cfg.data_dir,hubid_upper);
	SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,ALLFILES);
	i=external(cmdstr(cfg.qhub[hubnum]->pack,str,tmp2,NULL)
		,EX_OFFLINE|EX_WILDCARD);
	if(!fexistcase(str)) {
		eprintf(LOG_WARNING,"%s",remove_ctrl_a(text[QWKCompressionFailed],tmp));
		if(i)
			errormsg(WHERE,ERR_EXEC,cmdstr(cfg.qhub[hubnum]->pack,str,tmp2,NULL),i);
		else
			lprintf(LOG_ERR, "Couldn't compress REP packet");
		return(false); 
	}
	SAFEPRINTF2(str,"%sqnet/%s.out/",cfg.data_dir,hubid_lower);
	delfiles(str,ALLFILES);

	if(packedmail) {						/* Delete NetMail */
		SAFEPRINTF(smb.file,"%smail",cfg.data_dir);
		smb.retry_time=cfg.smb_retry_time;
		smb.subnum=INVALID_SUB;
		if((i=smb_open(&smb))!=0) {
			errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
			return(true); 
		}

		mail=loadmail(&smb,&mailmsgs,0,MAIL_YOUR,0);

		if((i=smb_locksmbhdr(&smb))!=0) {			  /* Lock the base, so nobody */
			if(mailmsgs)
				free(mail);
			smb_close(&smb);
			errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error);	/* messes with the index */
			return(true); 
		}

		if((i=smb_getstatus(&smb))!=0) {
			if(mailmsgs)
				free(mail);
			smb_close(&smb);
			errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error);
			return(true); 
		}

		deleted=0;
		/* Mark as READ and DELETE */
		for(u=0;u<mailmsgs;u++) {
			if(mail[u].number>qwkmail_last)
				continue;
			memset(&msg,0,sizeof(msg));
			/* !IMPORTANT: search by number (do not initialize msg.idx.offset) */
			if(!loadmsg(&msg,mail[u].number))
				continue;

			SAFEPRINTF(str,"%s/",cfg.qhub[hubnum]->id);
			if(msg.to_net.type!=NET_QWK
				|| (strcmp((char *)msg.to_net.addr,cfg.qhub[hubnum]->id)
				&& strncmp((char *)msg.to_net.addr,str,strlen(str)))) {
				smb_unlockmsghdr(&smb,&msg);
				smb_freemsgmem(&msg);
				continue; 
			}

			msg.hdr.attr|=MSG_DELETE;
			msg.idx.attr=msg.hdr.attr;
			if((i=smb_putmsg(&smb,&msg))!=0)
				errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error);
			else
				deleted++;
			smb_unlockmsghdr(&smb,&msg);
			smb_freemsgmem(&msg); 
		}

		if(deleted && cfg.sys_misc&SM_DELEMAIL)
			delmail(0,MAIL_YOUR);
		smb_close(&smb);
		if(mailmsgs)
			free(mail); 
		eprintf(LOG_INFO,"Deleted %d sent NetMail messages",deleted); 
	}

	return(true);
}
Esempio n. 21
0
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);
}