Пример #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;
}
Пример #2
0
void sbbs_t::viewfilecontents(file_t* f)
{
	char	cmd[128];
	char	path[MAX_PATH+1];
	char* 	ext;
	int		i;

	getfilepath(&cfg, f, path);

	if(f->size<=0L) {
		bprintf(text[FileDoesNotExist],path);
		return; 
	}
	if((ext=getfext(path))!=NULL) {
		ext++;
		for(i=0;i<cfg.total_fviews;i++) {
			if(!stricmp(ext,cfg.fview[i]->ext)
				&& chk_ar(cfg.fview[i]->ar,&useron,&client)) {
				strcpy(cmd,cfg.fview[i]->cmd);
				break; 
			} 
		}
	}
	if(ext==NULL || i==cfg.total_fviews)
		bprintf(text[NonviewableFile],ext);
	else
		if((i=external(cmdstr(cmd,path,path,NULL),EX_STDIO))!=0)
			errormsg(WHERE,ERR_EXEC,cmdstr(cmd,path,path,NULL),i);
}
Пример #3
0
void sbbs_t::viewfiles(uint dirnum, char *fspec)
{
    char	viewcmd[256];
	char 	tmp[512];
    int		i;

	curdirnum=dirnum;	/* for ARS */
	sprintf(viewcmd,"%s%s",cfg.dir[dirnum]->path,fspec);
	if(!fexist(viewcmd)) {
		bputs(text[FileNotFound]);
		return; 
	}
	padfname(fspec,tmp);
	truncsp(tmp);
	for(i=0;i<cfg.total_fviews;i++)
		if(!stricmp(tmp+9,cfg.fview[i]->ext) && chk_ar(cfg.fview[i]->ar,&useron,&client)) {
			strcpy(viewcmd,cfg.fview[i]->cmd);
			break; 
		}
	if(i==cfg.total_fviews) {
		bprintf(text[NonviewableFile],tmp+9);
		return; 
	}
	sprintf(tmp,"%s%s",cfg.dir[dirnum]->path,fspec);
	if((i=external(cmdstr(viewcmd,tmp,tmp,NULL),EX_STDIO|EX_SH))!=0)
		errormsg(WHERE,ERR_EXEC,viewcmd,i);    /* must have EX_SH to ^C */
}
Пример #4
0
int sbbs_t::uselect(int add, uint n, const char *title, const char *item, const uchar *ar)
{
	char	str[128];
	int		i;
	uint	t,u;

	if(uselect_total>=sizeof(uselect_num)/sizeof(uselect_num[0]))	/* out of bounds */
		uselect_total=0;

	if(add) {
		if(ar && !chk_ar(ar,&useron,&client))
			return(0);
		if(!uselect_total)
			bprintf(text[SelectItemHdr],title);
		uselect_num[uselect_total++]=n;
		bprintf(text[SelectItemFmt],uselect_total,item);
		return(0); 
	}

	if(!uselect_total)
		return(-1);

	for(u=0;u<uselect_total;u++)
		if(uselect_num[u]==n)
			break;
	if(u==uselect_total)
		u=0;
	sprintf(str,text[SelectItemWhich],u+1);
	mnemonics(str);
	i=getnum(uselect_total);
	t=uselect_total;
	uselect_total=0;
	if(i<0)
		return(-1);
	if(!i) {					/* User hit ENTER, use default */
		for(u=0;u<t;u++)
			if(uselect_num[u]==n)
				return(uselect_num[u]);
		if(n<t)
			return(uselect_num[n]);
		return(-1); 
	}
	return(uselect_num[i-1]);
}
Пример #5
0
void update_userlist_item(GtkListStore *lstore, GtkTreeIter *curr, int usernum)
{
	char			sex[2];
	char			first[9];
	char			last[9];
	user_t			user;

	user.number=usernum;
	getuserdat(&cfg, &user);
	if(arbuf) {
		if(!chk_ar(&cfg, arbuf, &user, /* client: */NULL)) {
			gtk_list_store_remove(lstore, curr);
			return;
		}
	}
	sex[0]=user.sex;
	sex[1]=0;
	unixtodstr(&cfg, user.firston, first);
	unixtodstr(&cfg, user.laston, last);
	gtk_list_store_set(lstore, curr
		,0,user.number
		,1,user.alias
		,2,user.name
		,3,user.level
		,4,getage(&cfg, user.birth)
		,5,sex
		,6,user.location
		,7,user.modem
		,8,user.note
		,9,user.comp
		,10,user.phone
		,11,user.netmail
		,12,user.logons
		,13,first
		,14,last
		,15,user.firston
		,16,user.laston
		,-1);
}
Пример #6
0
static JSBool
js_chk_ar(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
	uchar*		ar;
	private_t*	p;
	jsrefcount	rc;
	char		*ars;
	scfg_t*		scfg;

	scfg=JS_GetRuntimePrivate(JS_GetRuntime(cx));

	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
		return JS_FALSE;

	JSVALUE_TO_MSTRING(cx,argv[0], ars, NULL);
	HANDLE_PENDING(cx);
	if(ars==NULL)
		return JS_FALSE;

	rc=JS_SUSPENDREQUEST(cx);
	ar = arstr(NULL,ars,scfg);
	free(ars);

	js_getuserdat(scfg,p);

	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(chk_ar(scfg,ar,p->user,p->client)));

	if(ar!=NULL && ar!=nular)
		free(ar);
	JS_RESUMEREQUEST(cx, rc);

	return JS_TRUE;
}
Пример #7
0
bool sbbs_t::logon()
{
	char	str[256],c;
	char 	tmp[512];
	int 	file;
	uint	i,j,mailw;
	long	kmode;
	ulong	totallogons;
	node_t	node;
	struct	tm	tm;

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

	if(!useron.number)
		return(false);

	client.user=useron.alias;
	client_on(client_socket,&client,TRUE /* update */);

#ifdef JAVASCRIPT
	js_create_user_objects();
#endif

	if(useron.rest&FLAG('Q'))
		qwklogon=1;
	if(SYSOP && !(cfg.sys_misc&SM_R_SYSOP))
		return(false);

	if(useron.rest&FLAG('G')) {     /* Guest account */
		useron.misc=(cfg.new_misc&(~ASK_NSCAN));
		useron.rows=0;
		useron.misc&=~(ANSI|RIP|WIP|NO_EXASCII|COLOR|HTML);
		useron.misc|=autoterm;
		if(!(useron.misc&ANSI) && text[AnsiTerminalQ][0] && yesno(text[AnsiTerminalQ]))
			useron.misc|=ANSI;
		if(useron.misc&(RIP|WIP|HTML)
			|| (useron.misc&ANSI && text[ColorTerminalQ][0] && yesno(text[ColorTerminalQ])))
			useron.misc|=COLOR;
		if(text[ExAsciiTerminalQ][0] && !yesno(text[ExAsciiTerminalQ]))
			useron.misc|=NO_EXASCII;
		for(i=0;i<cfg.total_xedits;i++)
			if(!stricmp(cfg.xedit[i]->code,cfg.new_xedit)
				&& chk_ar(cfg.xedit[i]->ar,&useron,&client))
				break;
		if(i<cfg.total_xedits)
			useron.xedit=i+1;
		else
			useron.xedit=0;
		useron.prot=cfg.new_prot;
		useron.shell=cfg.new_shell; 
	}

	if(!chk_ar(cfg.node_ar,&useron,&client)) {
		bputs(text[NoNodeAccess]);
		sprintf(str,"(%04u)  %-25s  Insufficient node access"
			,useron.number,useron.alias);
		logline(LOG_NOTICE,"+!",str);
		return(false); 
	}

	getnodedat(cfg.node_num,&thisnode,1);
	if(thisnode.misc&NODE_LOCK) {
		putnodedat(cfg.node_num,&thisnode);	/* must unlock! */
		if(!SYSOP && !(useron.exempt&FLAG('N'))) {
			bputs(text[NodeLocked]);
			sprintf(str,"(%04u)  %-25s  Locked node logon attempt"
				,useron.number,useron.alias);
			logline(LOG_NOTICE,"+!",str);
			return(false); 
		}
		if(yesno(text[RemoveNodeLockQ])) {
			getnodedat(cfg.node_num,&thisnode,1);
			logline("S-","Removed Node Lock");
			thisnode.misc&=~NODE_LOCK; 
		}
		else
			getnodedat(cfg.node_num,&thisnode,1); 
	}

	if(useron.exempt&FLAG('H'))
		console|=CON_NO_INACT;

	if((useron.exempt&FLAG('Q') && useron.misc&QUIET))
		thisnode.status=NODE_QUIET;
	else
		thisnode.status=NODE_INUSE;
	action=thisnode.action=NODE_LOGN;
	thisnode.connection=node_connection;
	thisnode.misc&=~(NODE_ANON|NODE_INTR|NODE_MSGW|NODE_POFF|NODE_AOFF);
	if(useron.chat&CHAT_NOACT)
		thisnode.misc|=NODE_AOFF;
	if(useron.chat&CHAT_NOPAGE)
		thisnode.misc|=NODE_POFF;
	thisnode.useron=useron.number;
	putnodedat(cfg.node_num,&thisnode);

	getusrsubs();
	getusrdirs();

	if(useron.misc&CURSUB && !(useron.rest&FLAG('G'))) {
		for(i=0;i<usrgrps;i++) {
			for(j=0;j<usrsubs[i];j++) {
				if(!strcmp(cfg.sub[usrsub[i][j]]->code,useron.cursub))
					break; 
			}
			if(j<usrsubs[i]) {
				curgrp=i;
				cursub[i]=j;
				break; 
			} 
		}
		for(i=0;i<usrlibs;i++) {
			for(j=0;j<usrdirs[i];j++)
				if(!strcmp(cfg.dir[usrdir[i][j]]->code,useron.curdir))
					break;
			if(j<usrdirs[i]) {
				curlib=i;
				curdir[i]=j;
				break; 
			} 
		} 
	}


	if(useron.misc&AUTOTERM) {
		useron.misc&=~(ANSI|RIP|WIP|HTML);
		useron.misc|=autoterm; 
	}

	if(!chk_ar(cfg.shell[useron.shell]->ar,&useron,&client)) {
		useron.shell=cfg.new_shell;
		if(!chk_ar(cfg.shell[useron.shell]->ar,&useron,&client)) {
			for(i=0;i<cfg.total_shells;i++)
				if(chk_ar(cfg.shell[i]->ar,&useron,&client))
					break;
			if(i==cfg.total_shells)
				useron.shell=0; 
		} 
	}

	logon_ml=useron.level;
	logontime=time(NULL);
	starttime=logontime;
	useron.logontime=(time32_t)logontime;
	last_ns_time=ns_time=useron.ns_time;
	// ns_time-=(useron.tlast*60); /* file newscan time == last logon time */
	delfiles(cfg.temp_dir,ALLFILES);
	sprintf(str,"%smsgs/n%3.3u.msg",cfg.data_dir,cfg.node_num);
	remove(str);            /* remove any pending node messages */
	sprintf(str,"%smsgs/n%3.3u.ixb",cfg.data_dir,cfg.node_num);
	remove(str);			/* remove any pending node message indices */

	if(!SYSOP && online==ON_REMOTE && !qwklogon) {
		rioctl(IOCM|ABORT);	/* users can't abort anything */
		rioctl(IOCS|ABORT); 
	}

	CLS;
	if(useron.rows)
		rows=useron.rows;
	unixtodstr(&cfg,(time32_t)logontime,str);
	if(!strncmp(str,useron.birth,5) && !(useron.rest&FLAG('Q'))) {
		bputs(text[HappyBirthday]);
		pause();
		CLS;
		user_event(EVENT_BIRTHDAY); 
	}
	useron.ltoday++;

	gettimeleft();
	sprintf(str,"%sfile/%04u.dwn",cfg.data_dir,useron.number);
	batch_add_list(str);
	if(!qwklogon) { 	 /* QWK Nodes don't go through this */

		if(cfg.sys_pwdays
			&& (ulong)logontime>(useron.pwmod+((ulong)cfg.sys_pwdays*24UL*60UL*60UL))) {
			bprintf(text[TimeToChangePw],cfg.sys_pwdays);

			c=0;
			while(c<LEN_PASS) { 				/* Create random password */
				str[c]=sbbs_random(43)+'0';
				if(isalnum(str[c]))
					c++; 
			}
			str[c]=0;
			bprintf(text[YourPasswordIs],str);

			if(cfg.sys_misc&SM_PWEDIT && yesno(text[NewPasswordQ]))
				while(online) {
					bputs(text[NewPassword]);
					getstr(str,LEN_PASS,K_UPPER|K_LINE);
					truncsp(str);
					if(chkpass(str,&useron,true))
						break;
					CRLF; 
				}

			while(online) {
				if(cfg.sys_misc&SM_PWEDIT) {
					CRLF;
					bputs(text[VerifyPassword]); 
				}
				else
					bputs(text[NewUserPasswordVerify]);
				console|=CON_R_ECHOX;
				getstr(tmp,LEN_PASS*2,K_UPPER);
				console&=~(CON_R_ECHOX|CON_L_ECHOX);
				if(strcmp(str,tmp)) {
					bputs(text[Wrong]);
					continue; 
				}
				break; 
			}
			strcpy(useron.pass,str);
			useron.pwmod=time32(NULL);
			putuserrec(&cfg,useron.number,U_PWMOD,8,ultoa((ulong)useron.pwmod,str,16));
			bputs(text[PasswordChanged]);
			pause(); 
		}
		if(useron.ltoday>cfg.level_callsperday[useron.level]
			&& !(useron.exempt&FLAG('L'))) {
			bputs(text[NoMoreLogons]);
			sprintf(str,"(%04u)  %-25s  Out of logons"
				,useron.number,useron.alias);
			logline(LOG_NOTICE,"+!",str);
			hangup();
			return(false); 
		}
		if(useron.rest&FLAG('L') && useron.ltoday>1) {
			bputs(text[R_Logons]);
			sprintf(str,"(%04u)  %-25s  Out of logons"
				,useron.number,useron.alias);
			logline(LOG_NOTICE,"+!",str);
			hangup();
			return(false); 
		}
		kmode=(cfg.uq&UQ_NOEXASC);
		if(!(cfg.uq&UQ_NOUPRLWR))
			kmode|=K_UPRLWR;

		if(!(useron.rest&FLAG('G'))) {
			if(!useron.name[0] && ((cfg.uq&UQ_ALIASES && cfg.uq&UQ_REALNAME)
				|| cfg.uq&UQ_COMPANY))
				while(online) {
					if(cfg.uq&UQ_ALIASES && cfg.uq&UQ_REALNAME)
						bputs(text[EnterYourRealName]);
					else
						bputs(text[EnterYourCompany]);
					getstr(useron.name,LEN_NAME,kmode);
					if(cfg.uq&UQ_ALIASES && cfg.uq&UQ_REALNAME) {
						if(trashcan(useron.name,"name") || !useron.name[0]
							|| !strchr(useron.name,' ')
							|| strchr(useron.name,0xff)
							|| (cfg.uq&UQ_DUPREAL
								&& userdatdupe(useron.number,U_NAME,LEN_NAME
								,useron.name,0,0)))
							bputs(text[YouCantUseThatName]);
						else
							break; 
					}
					else
						break; 
				}
			if(cfg.uq&UQ_HANDLE && !useron.handle[0]) {
				sprintf(useron.handle,"%.*s",LEN_HANDLE,useron.alias);
				while(online) {
					bputs(text[EnterYourHandle]);
					if(!getstr(useron.handle,LEN_HANDLE
						,K_LINE|K_EDIT|K_AUTODEL|(cfg.uq&UQ_NOEXASC))
						|| strchr(useron.handle,0xff)
						|| (cfg.uq&UQ_DUPHAND
							&& userdatdupe(useron.number,U_HANDLE,LEN_HANDLE
							,useron.handle,0,0))
						|| trashcan(useron.handle,"name"))
						bputs(text[YouCantUseThatName]);
					else
						break; 
				} 
			}
			if(cfg.uq&UQ_LOCATION && !useron.location[0])
				while(online) {
					bputs(text[EnterYourCityState]);
					if(getstr(useron.location,LEN_LOCATION,kmode))
						break; 
				}
			if(cfg.uq&UQ_ADDRESS && !useron.address[0])
				while(online) {
					bputs(text[EnterYourAddress]);
					if(getstr(useron.address,LEN_ADDRESS,kmode))
						break; 
				}
			if(cfg.uq&UQ_ADDRESS && !useron.zipcode[0])
				while(online) {
					bputs(text[EnterYourZipCode]);
					if(getstr(useron.zipcode,LEN_ZIPCODE,K_UPPER|(cfg.uq&UQ_NOEXASC)))
						break; 
				}
			if(cfg.uq&UQ_PHONE && !useron.phone[0]) {
				if(text[CallingFromNorthAmericaQ][0])
					i=yesno(text[CallingFromNorthAmericaQ]);
				else
					i=0;
				while(online) {
					bputs(text[EnterYourPhoneNumber]);
					if(i) {
						if(gettmplt(useron.phone,cfg.sys_phonefmt
							,K_LINE|(cfg.uq&UQ_NOEXASC))<strlen(cfg.sys_phonefmt))
							 continue; 
					} else {
						if(getstr(useron.phone,LEN_PHONE
							,K_UPPER|(cfg.uq&UQ_NOEXASC))<5)
							continue; 
					}
					if(!trashcan(useron.phone,"phone"))
						break; 
				} 
			}
			if(!(cfg.uq&UQ_NONETMAIL) && !useron.netmail[0]) {
				while(online) {
					bputs(text[EnterNetMailAddress]);
					if(getstr(useron.netmail,LEN_NETMAIL,K_EDIT|K_AUTODEL|K_LINE)
						&& !trashcan(useron.netmail,"email"))
						break;
				}
				if(useron.netmail[0] && cfg.sys_misc&SM_FWDTONET && !noyes(text[ForwardMailQ]))
					useron.misc|=NETMAIL;
				else 
					useron.misc&=~NETMAIL;
			}
			if(cfg.new_sif[0]) {
				sprintf(str,"%suser/%4.4u.dat",cfg.data_dir,useron.number);
				if(flength(str)<1L)
					create_sif_dat(cfg.new_sif,str); 
			} 
		}
	}	
	if(!online) {
		sprintf(str,"(%04u)  %-25s  Unsuccessful logon"
			,useron.number,useron.alias);
		logline(LOG_NOTICE,"+!",str);
		return(false); 
	}
	SAFECOPY(useron.modem,connection);
	useron.logons++;
	putuserdat(&cfg,&useron);
	getmsgptrs();
	sys_status|=SS_USERON;          /* moved from further down */

	if(useron.rest&FLAG('Q')) {
		sprintf(str,"(%04u)  %-25s  QWK Network Connection"
			,useron.number,useron.alias);
		logline("++",str);
		return(true); 
	}

	/********************/
	/* SUCCESSFUL LOGON */
	/********************/
	totallogons=logonstats();
	sprintf(str,"(%04u)  %-25s  Logon %lu - %u"
		,useron.number,useron.alias,totallogons,useron.ltoday);
	logline("++",str);

	if(!qwklogon && cfg.logon_mod[0])
		exec_bin(cfg.logon_mod,&main_csi);

	if(thisnode.status!=NODE_QUIET && (!REALSYSOP || cfg.sys_misc&SM_SYSSTAT)) {
		sprintf(str,"%slogon.lst",cfg.data_dir);
		if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) {
			errormsg(WHERE,ERR_OPEN,str,O_RDWR|O_CREAT|O_APPEND);
			return(false); 
		}
		getuserrec(&cfg,useron.number,U_NOTE,LEN_NOTE,useron.note);
		getuserrec(&cfg,useron.number,U_LOCATION,LEN_LOCATION,useron.location);
		sprintf(str,text[LastFewCallersFmt],cfg.node_num
			,totallogons,useron.alias
			,cfg.sys_misc&SM_LISTLOC ? useron.location : useron.note
			,tm.tm_hour,tm.tm_min
			,connection,useron.ltoday > 999 ? 999 : useron.ltoday);
		write(file,str,strlen(str));
		close(file); 
	}

	if(cfg.sys_logon[0])				/* execute system logon event */
		external(cmdstr(cfg.sys_logon,nulstr,nulstr,NULL),EX_STDOUT); /* EX_SH */

	if(qwklogon)
		return(true);

	sys_status|=SS_PAUSEON;	/* always force pause on during this section */
	mailw=getmail(&cfg,useron.number,0);

	if(!(cfg.sys_misc&SM_NOSYSINFO)) {
		bprintf(text[SiSysName],cfg.sys_name);
		//bprintf(text[SiNodeNumberName],cfg.node_num,cfg.node_name);
		bprintf(text[LiUserNumberName],useron.number,useron.alias);
		bprintf(text[LiLogonsToday],useron.ltoday
			,cfg.level_callsperday[useron.level]);
		bprintf(text[LiTimeonToday],useron.ttoday
			,cfg.level_timeperday[useron.level]+useron.min);
		bprintf(text[LiMailWaiting],mailw);
		strcpy(str,text[LiSysopIs]);
		if(startup->options&BBS_OPT_SYSOP_AVAILABLE 
			|| (cfg.sys_chat_ar[0] && chk_ar(cfg.sys_chat_ar,&useron,&client)))
			strcat(str,text[LiSysopAvailable]);
		else
			strcat(str,text[LiSysopNotAvailable]);
		bprintf("%s\r\n\r\n",str);
	}

	if(sys_status&SS_EVENT)
		bprintf(text[ReducedTime],timestr(event_time));
	getnodedat(cfg.node_num,&thisnode,1);
	thisnode.misc&=~(NODE_AOFF|NODE_POFF);
	if(useron.chat&CHAT_NOACT)
		thisnode.misc|=NODE_AOFF;
	if(useron.chat&CHAT_NOPAGE)
		thisnode.misc|=NODE_POFF;
	putnodedat(cfg.node_num,&thisnode);

	getsmsg(useron.number); 		/* Moved from further down */
	SYNC;
	c=0;
	for(i=1;i<=cfg.sys_nodes;i++)
		if(i!=cfg.node_num) {
			getnodedat(i,&node,0);
			if(!(cfg.sys_misc&SM_NONODELIST)
				&& (node.status==NODE_INUSE
					|| ((node.status==NODE_QUIET || node.errors) && SYSOP))) {
				if(!c)
					bputs(text[NodeLstHdr]);
				printnodedat(i,&node);
				c=1; 
			}
			if(node.status==NODE_INUSE && i!=cfg.node_num && node.useron==useron.number
				&& !SYSOP && !(useron.exempt&FLAG('G'))) {
				SAFEPRINTF2(str,"(%04u)  %-25s  On two nodes at the same time"
					,useron.number,useron.alias);
				logline(LOG_NOTICE,"+!",str);
				bputs(text[UserOnTwoNodes]);
				hangup();
				return(false); 
			}
			if(thisnode.status!=NODE_QUIET
				&& (node.status==NODE_INUSE || node.status==NODE_QUIET)
				&& !(node.misc&NODE_AOFF) && node.useron!=useron.number) {
				sprintf(str,text[NodeLoggedOnAtNbps]
					,cfg.node_num
					,thisnode.misc&NODE_ANON ? text[UNKNOWN_USER] : useron.alias
					,connection);
				putnmsg(&cfg,i,str); 
			} 
		}

	if(cfg.sys_exp_warn && useron.expire && useron.expire>now /* Warn user of coming */
		&& (useron.expire-now)/(1440L*60L)<=cfg.sys_exp_warn) /* expiration */
		bprintf(text[AccountWillExpireInNDays],(useron.expire-now)/(1440L*60L));

	if(criterrs && SYSOP)
		bprintf(text[CriticalErrors],criterrs);
	if((i=getuserxfers(0,useron.number,0))!=0)
		bprintf(text[UserXferForYou],i,i>1 ? "s" : nulstr); 
	if((i=getuserxfers(useron.number,0,0))!=0)
		bprintf(text[UnreceivedUserXfer],i,i>1 ? "s" : nulstr);
	SYNC;
	sys_status&=~SS_PAUSEON;	/* Turn off the pause override flag */
	if(online==ON_REMOTE)
		rioctl(IOSM|ABORT);		/* Turn abort ability on */
	if(text[ReadYourMailNowQ][0] && mailw) {
		if(yesno(text[ReadYourMailNowQ]))
			readmail(useron.number,MAIL_YOUR); 
	}
	if(usrgrps && useron.misc&ASK_NSCAN && text[NScanAllGrpsQ][0] && yesno(text[NScanAllGrpsQ]))
		scanallsubs(SCAN_NEW);
	if(usrgrps && useron.misc&ASK_SSCAN && text[SScanAllGrpsQ][0] && yesno(text[SScanAllGrpsQ]))
		scanallsubs(SCAN_TOYOU);
	return(true);
}
Пример #8
0
BOOL sbbs_t::newuser()
{
	char	c,str[512];
	char 	tmp[512];
	uint	i;
	long	kmode;
	bool	usa;

	bputs(text[StartingNewUserRegistration]);
	getnodedat(cfg.node_num,&thisnode,0);
	if(thisnode.misc&NODE_LOCK) {
		bputs(text[NodeLocked]);
		logline(LOG_WARNING,"N!","New user locked node logon attempt");
		hangup();
		return(FALSE); 
	}

	if(cfg.sys_misc&SM_CLOSED) {
		bputs(text[NoNewUsers]);
		hangup();
		return(FALSE); 
	}
	getnodedat(cfg.node_num,&thisnode,1);
	thisnode.status=NODE_NEWUSER;
	thisnode.connection=node_connection;
	putnodedat(cfg.node_num,&thisnode);
	memset(&useron,0,sizeof(user_t));	  /* Initialize user info to null */
	if(cfg.new_pass[0] && online==ON_REMOTE) {
		c=0;
		while(++c<4) {
			bputs(text[NewUserPasswordPrompt]);
			getstr(str,40,K_UPPER);
			if(!strcmp(str,cfg.new_pass))
				break;
			SAFEPRINTF(tmp,"NUP Attempted: '%s'",str);
			logline(LOG_NOTICE,"N!",tmp); 
		}
		if(c==4) {
			SAFEPRINTF(str,"%snupguess.msg",cfg.text_dir);
			if(fexist(str))
				printfile(str,P_NOABORT);
			hangup();
			return(FALSE); 
		} 
	}

	/* Sets defaults per sysop config */
	useron.misc|=(cfg.new_misc&~(DELETED|INACTIVE|QUIET|NETMAIL));
	useron.qwk=QWK_DEFAULT;
	useron.firston=useron.laston=useron.pwmod=time32(NULL);
	if(cfg.new_expire) {
		now=time(NULL);
		useron.expire=(time32_t)(now+((long)cfg.new_expire*24L*60L*60L)); 
	} else
		useron.expire=0;
	useron.sex=' ';
	useron.prot=cfg.new_prot;
	SAFECOPY(useron.comp,client_name);	/* hostname or CID name */
	SAFECOPY(useron.note,cid);			/* IP address or CID number */
	if((i=userdatdupe(0,U_NOTE,LEN_NOTE,cid, /* del */true))!=0) {	/* Duplicate IP address */
		SAFEPRINTF2(useron.comment,"Warning: same IP address as user #%d %s"
			,i,username(&cfg,i,str));
		logline(LOG_NOTICE,"N!",useron.comment); 
	}

	SAFECOPY(useron.alias,"New");     /* just for status line */
	SAFECOPY(useron.modem,connection);
	if(!lastuser(&cfg)) {	/* Automatic sysop access for first user */
		bprintf("Creating sysop account... System password required.\r\n");
		if(!chksyspass())
			return(FALSE); 
		useron.level=99;
		useron.exempt=useron.flags1=useron.flags2=0xffffffffUL;
		useron.flags3=useron.flags4=0xffffffffUL;
		useron.rest=0L; 
	} else {
		useron.level=cfg.new_level;
		useron.flags1=cfg.new_flags1;
		useron.flags2=cfg.new_flags2;
		useron.flags3=cfg.new_flags3;
		useron.flags4=cfg.new_flags4;
		useron.rest=cfg.new_rest;
		useron.exempt=cfg.new_exempt; 
	}

	useron.cdt=cfg.new_cdt;
	useron.min=cfg.new_min;
	useron.freecdt=cfg.level_freecdtperday[useron.level];

	if(cfg.total_fcomps)
		SAFECOPY(useron.tmpext,cfg.fcomp[0]->ext);
	else
		SAFECOPY(useron.tmpext,"ZIP");

	useron.shell=cfg.new_shell;

	useron.alias[0]=0;

	kmode=(cfg.uq&UQ_NOEXASC)|K_EDIT|K_AUTODEL;
	if(!(cfg.uq&UQ_NOUPRLWR))
		kmode|=K_UPRLWR;

	while(online) {

		if(autoterm || (text[AutoTerminalQ][0] && yesno(text[AutoTerminalQ]))) {
			useron.misc|=AUTOTERM;
			useron.misc|=autoterm; 
		} else
			useron.misc&=~AUTOTERM;

		if(!(useron.misc&AUTOTERM)) {
			if(text[AnsiTerminalQ][0] && yesno(text[AnsiTerminalQ]))
				useron.misc|=ANSI; 
			else
				useron.misc&=~ANSI;
		}

		if(useron.misc&ANSI) {
			useron.rows=0;	/* Auto-rows */
			if(!(cfg.uq&UQ_COLORTERM) || useron.misc&(RIP|WIP|HTML) || text[ColorTerminalQ][0]==0 || yesno(text[ColorTerminalQ]))
				useron.misc|=COLOR; 
			else
				useron.misc&=~COLOR;
		}
		else
			useron.rows=24;
		if(text[ExAsciiTerminalQ][0] && !yesno(text[ExAsciiTerminalQ]))
			useron.misc|=NO_EXASCII;
		else
			useron.misc&=~NO_EXASCII;

		if(rlogin_name[0])
			SAFECOPY(useron.alias,rlogin_name);

		while(online) {
			if(cfg.uq&UQ_ALIASES)
				bputs(text[EnterYourAlias]);
			else
				bputs(text[EnterYourRealName]);
			getstr(useron.alias,LEN_ALIAS,kmode);
			truncsp(useron.alias);
			if (!check_name(&cfg,useron.alias)
				|| (!(cfg.uq&UQ_ALIASES) && !strchr(useron.alias,' '))) {
				bputs(text[YouCantUseThatName]);
				if(text[ContinueQ][0] && !yesno(text[ContinueQ]))
					return(FALSE);
				continue;
			}
			break; 
		}
		if(!online) return(FALSE);
		if((cfg.uq&UQ_ALIASES) && (cfg.uq&UQ_REALNAME)) {
			while(online) {
				bputs(text[EnterYourRealName]);
				getstr(useron.name,LEN_NAME,kmode);
				if (!check_name(&cfg,useron.name)
					|| !strchr(useron.name,' ')
					|| ((cfg.uq&UQ_DUPREAL)
						&& userdatdupe(useron.number,U_NAME,LEN_NAME,useron.name)))
					bputs(text[YouCantUseThatName]);
				else
					break; 
				if(text[ContinueQ][0] && !yesno(text[ContinueQ]))
					return(FALSE);
			} 
		}
		else if(cfg.uq&UQ_COMPANY) {
				bputs(text[EnterYourCompany]);
				getstr(useron.name,LEN_NAME,(cfg.uq&UQ_NOEXASC)|K_EDIT|K_AUTODEL); 
		}
		if(!useron.name[0])
			SAFECOPY(useron.name,useron.alias);
		if(!online) return(FALSE);
		if(!useron.handle[0])
			SAFECOPY(useron.handle,useron.alias);
		while((cfg.uq&UQ_HANDLE) && online) {
			bputs(text[EnterYourHandle]);
			if(!getstr(useron.handle,LEN_HANDLE
				,K_LINE|K_EDIT|K_AUTODEL|(cfg.uq&UQ_NOEXASC))
				|| strchr(useron.handle,0xff)
				|| ((cfg.uq&UQ_DUPHAND)
					&& userdatdupe(0,U_HANDLE,LEN_HANDLE,useron.handle))
				|| trashcan(useron.handle,"name"))
				bputs(text[YouCantUseThatName]);
			else
				break; 
			if(text[ContinueQ][0] && !yesno(text[ContinueQ]))
				return(FALSE);
		}
		if(!online) return(FALSE);
		if(cfg.uq&UQ_ADDRESS)
			while(online) { 	   /* Get address and zip code */
				bputs(text[EnterYourAddress]);
				if(getstr(useron.address,LEN_ADDRESS,kmode))
					break; 
			}
		if(!online) return(FALSE);
		while((cfg.uq&UQ_LOCATION) && online) {
			bputs(text[EnterYourCityState]);
			if(getstr(useron.location,LEN_LOCATION,kmode)
				&& ((cfg.uq&UQ_NOCOMMAS) || strchr(useron.location,',')))
				break;
			bputs(text[CommaInLocationRequired]);
			useron.location[0]=0; 
		}
		if(cfg.uq&UQ_ADDRESS)
			while(online) {
				bputs(text[EnterYourZipCode]);
				if(getstr(useron.zipcode,LEN_ZIPCODE
					,K_UPPER|(cfg.uq&UQ_NOEXASC)|K_EDIT|K_AUTODEL))
					break; 
			}
		if(!online) return(FALSE);
		if(cfg.uq&UQ_PHONE) {
			if(text[CallingFromNorthAmericaQ][0])
				usa=yesno(text[CallingFromNorthAmericaQ]);
			else
				usa=false;
			while(online && text[EnterYourPhoneNumber][0]) {
				bputs(text[EnterYourPhoneNumber]);
				if(!usa) {
					if(getstr(useron.phone,LEN_PHONE
						,K_UPPER|K_LINE|(cfg.uq&UQ_NOEXASC)|K_EDIT|K_AUTODEL)<5)
						continue; 
				}
				else {
					if(gettmplt(useron.phone,cfg.sys_phonefmt
						,K_LINE|(cfg.uq&UQ_NOEXASC)|K_EDIT)<strlen(cfg.sys_phonefmt))
						continue; 
				}
				if(!trashcan(useron.phone,"phone"))
					break; 
			} 
		}
		if(!online) return(FALSE);
		if(cfg.uq&UQ_SEX) {
			bputs(text[EnterYourSex]);
			useron.sex=(char)getkeys("MF",0); 
		}
		while((cfg.uq&UQ_BIRTH) && online) {
			bprintf(text[EnterYourBirthday]
				,cfg.sys_misc&SM_EURODATE ? "DD/MM/YY" : "MM/DD/YY");
			if(gettmplt(useron.birth,"nn/nn/nn",K_EDIT)==8 && getage(&cfg,useron.birth))
				break; 
		}
		if(!online) return(FALSE);
		while(!(cfg.uq&UQ_NONETMAIL) && online) {
			bputs(text[EnterNetMailAddress]);
			if(getstr(useron.netmail,LEN_NETMAIL,K_EDIT|K_AUTODEL|K_LINE)
				&& !trashcan(useron.netmail,"email"))
				break;
		}
		if(useron.netmail[0] && cfg.sys_misc&SM_FWDTONET && text[ForwardMailQ][0] && yesno(text[ForwardMailQ]))
			useron.misc|=NETMAIL;
		else 
			useron.misc&=~NETMAIL;
		if(text[UserInfoCorrectQ][0]==0 || yesno(text[UserInfoCorrectQ]))
			break; 
	}
	if(!online) return(FALSE);
	SAFEPRINTF(str,"New user: %s",useron.alias);
	logline("N",str);
	if(!online) return(FALSE);
	CLS;
	SAFEPRINTF(str,"%ssbbs.msg",cfg.text_dir);
	printfile(str,P_NOABORT);
	if(lncntr)
		pause();
	CLS;
	SAFEPRINTF(str,"%ssystem.msg",cfg.text_dir);
	printfile(str,P_NOABORT);
	if(lncntr)
		pause();
	CLS;
	SAFEPRINTF(str,"%snewuser.msg",cfg.text_dir);
	printfile(str,P_NOABORT);
	if(lncntr)
		pause();
	CLS;
	answertime=time(NULL);		/* could take 10 minutes to get this far */

	/* Default editor (moved here, after terminal type setup Jan-2003) */
	for(i=0;i<cfg.total_xedits;i++)
		if(!stricmp(cfg.xedit[i]->code,cfg.new_xedit) && chk_ar(cfg.xedit[i]->ar,&useron,&client))
			break;
	if(i<cfg.total_xedits)
		useron.xedit=i+1;

	if(cfg.total_xedits && (cfg.uq&UQ_XEDIT) && text[UseExternalEditorQ][0]) {
		if(yesno(text[UseExternalEditorQ])) {
			for(i=0;i<cfg.total_xedits;i++)
				uselect(1,i,text[ExternalEditorHeading],cfg.xedit[i]->name,cfg.xedit[i]->ar);
			if((int)(i=uselect(0,useron.xedit ? useron.xedit-1 : 0,0,0,0))>=0)
				useron.xedit=i+1; 
		} else
			useron.xedit=0;
	}

	if(cfg.total_shells>1 && (cfg.uq&UQ_CMDSHELL)) {
		for(i=0;i<cfg.total_shells;i++)
			uselect(1,i,text[CommandShellHeading],cfg.shell[i]->name,cfg.shell[i]->ar);
		if((int)(i=uselect(0,useron.shell,0,0,0))>=0)
			useron.shell=i; 
	}

	if(rlogin_pass[0] && chkpass(rlogin_pass,&useron,true)) {
		CRLF;
		SAFECOPY(useron.pass, rlogin_pass);
		strupr(useron.pass);	/* passwords are case insensitive, but assumed (in some places) to be uppercase in the user database */
	}
	else {
		c=0;
		while(c<LEN_PASS) { 				/* Create random password */
			useron.pass[c]=sbbs_random(43)+'0';
			if(isalnum(useron.pass[c]))
				c++; 
		}
		useron.pass[c]=0;

		bprintf(text[YourPasswordIs],useron.pass);

		if(cfg.sys_misc&SM_PWEDIT && text[NewPasswordQ][0] && yesno(text[NewPasswordQ]))
			while(online) {
				bputs(text[NewPassword]);
				getstr(str,LEN_PASS,K_UPPER|K_LINE);
				truncsp(str);
				if(chkpass(str,&useron,true)) {
					SAFECOPY(useron.pass,str);
					CRLF;
					bprintf(text[YourPasswordIs],useron.pass);
					break; 
				}
				CRLF; 
			}

		c=0;
		while(online) {
			bprintf(text[NewUserPasswordVerify]);
			console|=CON_R_ECHOX;
			str[0]=0;
			getstr(str,LEN_PASS*2,K_UPPER);
			console&=~(CON_R_ECHOX|CON_L_ECHOX);
			if(!strcmp(str,useron.pass)) break;
			if(cfg.sys_misc&SM_ECHO_PW) 
				SAFEPRINTF3(tmp,"%s FAILED Password verification: '%s' instead of '%s'"
					,useron.alias
					,str
					,useron.pass);
			else
				SAFEPRINTF(tmp,"%s FAILED Password verification"
					,useron.alias);
			logline(LOG_NOTICE,nulstr,tmp);
			if(++c==4) {
				logline(LOG_NOTICE,"N!","Couldn't figure out password.");
				hangup(); 
			}
			bputs(text[IncorrectPassword]);
			bprintf(text[YourPasswordIs],useron.pass); 
		}
	}

	if(!online) return(FALSE);
	if(cfg.new_magic[0]) {
		bputs(text[MagicWordPrompt]);
		str[0]=0;
		getstr(str,50,K_UPPER);
		if(strcmp(str,cfg.new_magic)) {
			bputs(text[FailedMagicWord]);
			SAFEPRINTF2(tmp,"%s failed magic word: '%s'",useron.alias,str);
			logline("N!",tmp);
			hangup(); 
		}
		if(!online) return(FALSE); 
	}

	bputs(text[CheckingSlots]);

	if((i=newuserdat(&cfg,&useron))!=0) {
		SAFEPRINTF(str,"user record #%u",useron.number);
		errormsg(WHERE,ERR_CREATE,str,i);
		hangup();
		return(FALSE); 
	}
	SAFEPRINTF2(str,"Created user record #%u: %s",useron.number,useron.alias);
	logline(nulstr,str);
	if(cfg.new_sif[0]) {
		SAFEPRINTF2(str,"%suser/%4.4u.dat",cfg.data_dir,useron.number);
		create_sif_dat(cfg.new_sif,str); 
	}
	if(!(cfg.uq&UQ_NODEF))
		maindflts(&useron);

	delallmail(useron.number, MAIL_ANY);

	if(useron.number!=1 && cfg.node_valuser) {
		SAFEPRINTF(str,"%sfeedback.msg",cfg.text_dir);
		CLS;
		printfile(str,P_NOABORT);
		safe_snprintf(str,sizeof(str),text[NewUserFeedbackHdr]
			,nulstr,getage(&cfg,useron.birth),useron.sex,useron.birth
			,useron.name,useron.phone,useron.comp,useron.modem);
		email(cfg.node_valuser,str,"New User Validation",WM_EMAIL|WM_SUBJ_RO|WM_FORCEFWD);
		if(!useron.fbacks && !useron.emails) {
			if(online) {						/* didn't hang up */
				bprintf(text[NoFeedbackWarning],username(&cfg,cfg.node_valuser,tmp));
				email(cfg.node_valuser,str,"New User Validation",WM_EMAIL|WM_SUBJ_RO|WM_FORCEFWD);
				} /* give 'em a 2nd try */
			if(!useron.fbacks && !useron.emails) {
        		bprintf(text[NoFeedbackWarning],username(&cfg,cfg.node_valuser,tmp));
				logline(LOG_NOTICE,"N!","Aborted feedback");
				hangup();
				putuserrec(&cfg,useron.number,U_COMMENT,60,"Didn't leave feedback");
				putuserrec(&cfg,useron.number,U_MISC,8
					,ultoa(useron.misc|DELETED,tmp,16));
				putusername(&cfg,useron.number,nulstr);
				return(FALSE); 
			} 
		} 
	}

	answertime=starttime=time(NULL);	  /* set answertime to now */

#ifdef JAVASCRIPT
	js_create_user_objects();
#endif

	if(cfg.newuser_mod[0])
		exec_bin(cfg.newuser_mod,&main_csi);
	user_event(EVENT_NEWUSER);
	getuserdat(&cfg,&useron);	// In case event(s) modified user data
	logline("N+","Successful new user logon");
	sys_status|=SS_NEWUSER;

	return(TRUE);
}
Пример #9
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);
}
Пример #10
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);
}
Пример #11
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);
}
Пример #12
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);
}
Пример #13
0
bool sbbs_t::qwktomsg(FILE *qwk_fp, char *hdrblk, char fromhub, uint subnum
	, uint touser)
{
	char*		body;
	char*		tail;
	char*		header;
	char		str[256],col=0,lastch=0,*p,qwkbuf[QWK_BLOCK_LEN+1];
	uint 		i,j,k,lzh=0,skip=0;
	long		bodylen,taillen;
	bool		header_cont=false;
	bool		success=false;
	ulong		block,blocks;
	smbmsg_t	msg;
	struct		tm tm;
	ushort		xlat=XLAT_NONE;
	int			storage=SMB_SELFPACK;
	long		dupechk_hashes=SMB_HASH_SOURCE_ALL;

	memset(&msg,0,sizeof(smbmsg_t));		/* Initialize message header */
	msg.hdr.version=smb_ver();

	blocks=atol(hdrblk+116);
	if(blocks<2) {
		errormsg(WHERE,ERR_CHK,"QWK packet header blocks",blocks);
		return(false);
	}

	if(subnum!=INVALID_SUB
		&& (hdrblk[0]=='*' || hdrblk[0]=='+' || cfg.sub[subnum]->misc&SUB_PONLY))
		msg.hdr.attr|=MSG_PRIVATE;
	if(subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_AONLY)
		msg.hdr.attr|=MSG_ANONYMOUS;
	if(subnum==INVALID_SUB && cfg.sys_misc&SM_DELREADM)
		msg.hdr.attr|=MSG_KILLREAD;
	if((fromhub || useron.rest&FLAG('Q')) &&
		(hdrblk[0]=='*' || hdrblk[0]=='-' || hdrblk[0]=='`'))
		msg.hdr.attr|=MSG_READ;

	if(subnum!=INVALID_SUB && !fromhub && cfg.sub[subnum]->mod_ar[0]
		&& chk_ar(cfg.sub[subnum]->mod_ar,&useron))
		msg.hdr.attr|=MSG_MODERATED;
	if(subnum!=INVALID_SUB && !fromhub && cfg.sub[subnum]->misc&SUB_SYSPERM
		&& sub_op(subnum))
		msg.hdr.attr|=MSG_PERMANENT;

	memset(&tm,0,sizeof(tm));
	tm.tm_mon = ((hdrblk[8]&0xf)*10)+(hdrblk[9]&0xf);
	if(tm.tm_mon>0) tm.tm_mon--;	/* zero based */
	tm.tm_mday=((hdrblk[11]&0xf)*10)+(hdrblk[12]&0xf);
	tm.tm_year=((hdrblk[14]&0xf)*10)+(hdrblk[15]&0xf);
	if(tm.tm_year<Y2K_2DIGIT_WINDOW)
		tm.tm_year+=100;
	tm.tm_hour=((hdrblk[16]&0xf)*10)+(hdrblk[17]&0xf);
	tm.tm_min=((hdrblk[19]&0xf)*10)+(hdrblk[20]&0xf);
	tm.tm_sec=0;
	tm.tm_isdst=-1;	/* Do not adjust for DST */

	msg.hdr.when_written.time=mktime(&tm);
	if(!(useron.rest&FLAG('Q')) && !fromhub)
		msg.hdr.when_written.zone=sys_timezone(&cfg);
	msg.hdr.when_imported.time=time(NULL);
	msg.hdr.when_imported.zone=sys_timezone(&cfg);

	hdrblk[116]=0;	// don't include number of blocks in "re: msg number"
	if(!(useron.rest&FLAG('Q')) && !fromhub)
		msg.hdr.thread_back=atol((char *)hdrblk+108);

	if(subnum==INVALID_SUB) { 		/* E-mail */
		if(cfg.sys_misc&SM_FASTMAIL)
			storage=SMB_FASTALLOC;

		/* duplicate message-IDs must be allowed in mail database */
		dupechk_hashes&=~(1<<SMB_HASH_SOURCE_MSG_ID);

		username(&cfg,touser,str);
		smb_hfield_str(&msg,RECIPIENT,str);
		sprintf(str,"%u",touser);
		smb_hfield_str(&msg,RECIPIENTEXT,str); 
	} else {
		if(cfg.sub[subnum]->misc&SUB_HYPER)
			storage = SMB_HYPERALLOC;
		else if(cfg.sub[subnum]->misc&SUB_FAST)
			storage = SMB_FASTALLOC;

		if(cfg.sub[subnum]->misc&SUB_LZH)
			xlat=XLAT_LZH;

		sprintf(str,"%25.25s",(char *)hdrblk+21);     /* To user */
		truncsp(str);
		smb_hfield_str(&msg,RECIPIENT,str);
		if(cfg.sub[subnum]->misc&SUB_LZH)
			xlat=XLAT_LZH;
	}

	sprintf(str,"%25.25s",hdrblk+71);   /* Subject */
	truncsp(str);
	smb_hfield_str(&msg,SUBJECT,str);

	/********************************/
	/* Convert the QWK message text */
	/********************************/

	if((header=(char *)calloc((blocks-1L)*QWK_BLOCK_LEN*2L,sizeof(char)))==NULL) {
		smb_freemsgmem(&msg);
		errormsg(WHERE,ERR_ALLOC,"QWK msg header",(blocks-1L)*QWK_BLOCK_LEN*2L);
		return(false); 
	}

	bodylen=0;
	if((body=(char *)malloc((blocks-1L)*QWK_BLOCK_LEN*2L))==NULL) {
		free(header);
		smb_freemsgmem(&msg);
		errormsg(WHERE,ERR_ALLOC,"QWK msg body",(blocks-1L)*QWK_BLOCK_LEN*2L);
		return(false); 
	}

	taillen=0;
	if((tail=(char *)malloc((blocks-1L)*QWK_BLOCK_LEN*2L))==NULL) {
		free(header);
		free(body);
		smb_freemsgmem(&msg);
		errormsg(WHERE,ERR_ALLOC,"QWK msg tail",(blocks-1L)*QWK_BLOCK_LEN*2L);
		return(false); 
	}

	memset(qwkbuf,0,sizeof(qwkbuf));

	for(block=1;block<blocks;block++) {
		if(!fread(qwkbuf,1,QWK_BLOCK_LEN,qwk_fp))
			break;
		for(k=0;k<QWK_BLOCK_LEN;k++) {
			if(qwkbuf[k]==0)
				continue;
			if(bodylen==0 && (qwkbuf[k]=='@' || header_cont)) {
				if((p=strchr(qwkbuf+k, QWK_NEWLINE))!=NULL)
					*p=0;
				strcat(header, qwkbuf+k);
				strcat(header, "\n");
				if(p==NULL) {
					header_cont=true;
					break;
				}
				k+=strlen(qwkbuf+k);
				header_cont=false;
				continue;
			}
			if(!taillen && qwkbuf[k]==' ' && col==3 && bodylen>=3
				&& body[bodylen-3]=='-' && body[bodylen-2]=='-'
				&& body[bodylen-1]=='-') {
				bodylen-=3;
				strcpy(tail,"--- ");
				taillen=4;
				col++;
				continue; 
			}
			if(qwkbuf[k]==QWK_NEWLINE) {		/* expand QWK_NEWLINE to crlf */
				if(!taillen && col==3 && bodylen>=3 && body[bodylen-3]=='-'
					&& body[bodylen-2]=='-' && body[bodylen-1]=='-') {
					bodylen-=3;
					strcpy(tail,"---");
					taillen=3; 
				}
				col=0;
				if(taillen) {
					tail[taillen++]=CR;
					tail[taillen++]=LF; 
				}
				else {
					body[bodylen++]=CR;
					body[bodylen++]=LF; 
				}
				continue; 
			}
			/* beep restrict */
			if(!fromhub && qwkbuf[k]==BEL && useron.rest&FLAG('B'))   
				continue;
			/* ANSI restriction */
			if(!fromhub && (qwkbuf[k]==1 || qwkbuf[k]==ESC)
				&& useron.rest&FLAG('A'))
				continue;
			if(qwkbuf[k]!=1 && lastch!=1)
				col++;
			if(lastch==CTRL_A && !validattr(qwkbuf[k])) {
				if(taillen) taillen--;
				else		bodylen--;
				lastch=0;
				continue; 
			}
			lastch=qwkbuf[k];
			if(taillen)
				tail[taillen++]=qwkbuf[k];
			else
				body[bodylen++]=qwkbuf[k]; 
		} 
	}

	while(bodylen && body[bodylen-1]==' ') bodylen--; /* remove trailing spaces */
	if(bodylen>=2 && body[bodylen-2]==CR && body[bodylen-1]==LF)
		bodylen-=2;

	while(taillen && tail[taillen-1]<=' ') taillen--; /* remove trailing garbage */

	skip=0;
	if(useron.rest&FLAG('Q') || fromhub) {      /* QWK Net */
		if(!strnicmp(header,"@VIA:",5)) {
			if(!fromhub)
				set_qwk_flag(QWK_VIA);
			p=strchr(header, '\n');
			if(p) {
				*p=0;
				skip=strlen(header)+1; 
			}
			truncsp(header);
			p=header+5; 					/* Skip "@VIA:" */
			while(*p && *p<=' ') p++;		/* Skip any spaces */
			if(route_circ(p,cfg.sys_id)) {
				free(header);
				free(body);
				free(tail);
				smb_freemsgmem(&msg);
				bprintf("\r\nCircular message path: %s\r\n",p);
				sprintf(str,"Circular message path: %s from %s"
					,p,fromhub ? cfg.qhub[fromhub-1]->id:useron.alias);
				errorlog(str);
				return(false); 
			}
			sprintf(str,"%s/%s"
				,fromhub ? cfg.qhub[fromhub-1]->id : useron.alias,p);
			strupr(str);
			update_qwkroute(str); 
		}
		else {
			if(fromhub)
				strcpy(str,cfg.qhub[fromhub-1]->id);
			else
				strcpy(str,useron.alias); 
		}
		strupr(str);
		j=NET_QWK;
		smb_hfield(&msg,SENDERNETTYPE,2,&j);
		smb_hfield_str(&msg,SENDERNETADDR,str);
		sprintf(str,"%25.25s",hdrblk+46);  /* From user */
		truncsp(str);
	} else {
		sprintf(str,"%u",useron.number);
		smb_hfield_str(&msg,SENDEREXT,str);
		if((uint)subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_NAME)
			strcpy(str,useron.name);
		else
			strcpy(str,useron.alias);
	}
	smb_hfield_str(&msg,SENDER,str);

	if(!strnicmp(header+skip,"@MSGID:",7)) {
		if(!fromhub)
			set_qwk_flag(QWK_MSGID);
		p=strchr(header+skip, '\n');
		i=skip;
		if(p) {
			*p=0;
			skip+=strlen(header+i)+1; 
		}
		p=header+i+7;					/* Skip "@MSGID:" */
		while(*p && *p<=' ') p++;		/* Skip any spaces */
		truncstr(p," ");				/* Truncate at first space char */
		smb_hfield_str(&msg,RFC822MSGID,p);
	}
	if(!strnicmp(header+skip,"@REPLY:",7)) {
		if(!fromhub)
			set_qwk_flag(QWK_MSGID);
		p=strchr(header+skip, '\n');
		i=skip;
		if(p) {
			*p=0;
			skip+=strlen(header+i)+1; 
		}
		p=header+i+7;					/* Skip "@REPLY:" */
		while(*p && *p<=' ') p++;		/* Skip any spaces */
		truncstr(p," ");				/* Truncate at first space char */
		smb_hfield_str(&msg,RFC822REPLYID,p);
	}
	if(!strnicmp(header+skip,"@TZ:",4)) {
		if(!fromhub)
			set_qwk_flag(QWK_TZ);
		p=strchr(header+skip, '\n');
		i=skip;
		if(p) {
			*p=0;
			skip+=strlen(header+i)+1; 
		}
		p=header+i+4;					/* Skip "@TZ:" */
		while(*p && *p<=' ') p++;		/* Skip any spaces */
		msg.hdr.when_written.zone=(short)ahtoul(p); 
	}
	if(!strnicmp(header+skip,"@REPLYTO:",9)) {
		p=strchr(header+skip, '\n');
		i=skip;
		if(p) {
			*p=0;
			skip+=strlen(header+i)+1; 
		}
		p=header+i+9;					/* Skip "@REPLYTO:" */
		while(*p && *p<=' ') p++;		/* Skip any spaces */
		smb_hfield_str(&msg,REPLYTO,p);
	}
	free(header);

	/* smb_addmsg required ASCIIZ strings */
	body[bodylen]=0;
	tail[taillen]=0;

	if(online==ON_REMOTE)
		bputs(text[WritingIndx]);

	if(smb.status.max_crcs==0)	/* no CRC checking means no body text dupe checking */
		dupechk_hashes&=~(1<<SMB_HASH_SOURCE_BODY);

	if((i=smb_addmsg(&smb,&msg,storage,dupechk_hashes,xlat,(uchar*)body,(uchar*)tail))==SMB_SUCCESS)
		success=true;
	else if(i==SMB_DUPE_MSG) {
		bprintf("\r\n!%s\r\n",smb.last_error);
		if(!fromhub) {
			if(subnum==INVALID_SUB) {
				sprintf(str,"%s duplicate e-mail attempt (%s)",useron.alias,smb.last_error);
				logline("E!",str); 
			} else {
				sprintf(str,"%s duplicate message attempt in %s %s (%s)"
					,useron.alias
					,cfg.grp[cfg.sub[subnum]->grp]->sname
					,cfg.sub[subnum]->lname
					,smb.last_error);
				logline("P!",str); 
			}
		}
	}
	else 
		errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error);

	smb_freemsgmem(&msg);

	free(body);
	free(tail);

	return(success);
}
Пример #14
0
void sbbs_t::readmail(uint usernumber, int which)
{
	char	str[256],str2[256],str3[256],done=0,domsg=1
			,*p,*tp,*sp,ch;
	char 	tmp[512];
	int		i,j;
	int		error;
	int		mismatches=0,act;
    long    length,l,lm_mode;
	ulong	last;
	bool	replied;
	file_t	fd;
	mail_t	*mail;
	smbmsg_t msg;

	if(which==MAIL_SENT && useron.rest&FLAG('K')) {
		bputs(text[R_ReadSentMail]);
		return;
	}

	msg.total_hfields=0;			/* init to NULL, cause not allocated yet */

	fd.dir=cfg.total_dirs+1;			/* temp dir for file attachments */

	if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) {
		errormsg(WHERE,ERR_OPEN,"MAIL",i);
		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);
		return; }

	if(cfg.sys_misc&SM_SYSVDELM && (SYSOP || cfg.sys_misc&SM_USRVDELM))
		lm_mode=LM_INCDEL;
	else
		lm_mode=0;
	mail=loadmail(&smb,&smb.msgs,usernumber,which,lm_mode);
	if(!smb.msgs) {
		if(which==MAIL_SENT)
			bputs(text[NoMailSent]);
		else if(which==MAIL_ALL)
			bputs(text[NoMailOnSystem]);
		else
			bputs(text[NoMailWaiting]);
		smb_close(&smb);
		smb_stack(&smb,SMB_STACK_POP);
		return; }

	last=smb.status.last_msg;

	if(which==MAIL_SENT)
		act=NODE_RSML;
	else if(which==MAIL_ALL)
		act=NODE_SYSP;
	else
		act=NODE_RMAL;
	action=act;
	if(smb.msgs>1 && which!=MAIL_ALL) {
		if(which==MAIL_SENT)
			bputs(text[MailSentLstHdr]);
		else
			bputs(text[MailWaitingLstHdr]);

		for(smb.curmsg=0;smb.curmsg<smb.msgs && !msgabort();smb.curmsg++) {
			if(msg.total_hfields)
				smb_freemsgmem(&msg);
			msg.total_hfields=0;
			msg.idx.offset=mail[smb.curmsg].offset;
			if(!loadmsg(&msg,mail[smb.curmsg].number))
				continue;
			smb_unlockmsghdr(&smb,&msg);
			bprintf(text[MailWaitingLstFmt],smb.curmsg+1
				,which==MAIL_SENT ? msg.to
				: (msg.hdr.attr&MSG_ANONYMOUS) && !SYSOP ? text[Anonymous]
				: msg.from
				,msg.hdr.attr&MSG_DELETE ? '-' : msg.hdr.attr&MSG_REPLIED ? 'R'
					: msg.hdr.attr&MSG_READ ? ' '
					: msg.from_net.type || msg.to_net.type ? 'N':'*'
				,msg.subj);
			smb_freemsgmem(&msg);
			msg.total_hfields=0; }

		ASYNC;
		if(!(sys_status&SS_ABORT)) {
			bprintf(text[StartWithN],1L);
			if((long)(smb.curmsg=getnum(smb.msgs))>0)
				smb.curmsg--;
			else if((long)smb.curmsg==-1) {
				free(mail);
				smb_close(&smb);
				smb_stack(&smb,SMB_STACK_POP);
				return; } }
		sys_status&=~SS_ABORT; }
	else {
		smb.curmsg=0;
		if(which==MAIL_ALL)
			domsg=0; }
	if(which==MAIL_SENT) {
		sprintf(str,"%s read sent mail",useron.alias);
		logline("E",str);
	} else if(which==MAIL_ALL) {
		sprintf(str,"%s read all mail",useron.alias);
		logline("S+",str);
	} else {
		sprintf(str,"%s read mail",useron.alias);
		logline("E",str);
	}
	if(useron.misc&RIP) {
		strcpy(str,which==MAIL_YOUR ? "mailread" : which==MAIL_ALL ?
			"allmail" : "sentmail");
		menu(str); }
	while(online && !done) {
		action=act;

		if(msg.total_hfields)
			smb_freemsgmem(&msg);
		msg.total_hfields=0;

		msg.idx.offset=mail[smb.curmsg].offset;
		msg.idx.number=mail[smb.curmsg].number;
		msg.idx.to=mail[smb.curmsg].to;
		msg.idx.from=mail[smb.curmsg].from;
		msg.idx.subj=mail[smb.curmsg].subj;

		if((i=smb_locksmbhdr(&smb))!=0) {
			errormsg(WHERE,ERR_LOCK,smb.file,i);
			break; }

		if((i=smb_getstatus(&smb))!=0) {
			smb_unlocksmbhdr(&smb);
			errormsg(WHERE,ERR_READ,smb.file,i);
			break; }
		smb_unlocksmbhdr(&smb);

		if(smb.status.last_msg!=last) { 	/* New messages */
			last=smb.status.last_msg;
			free(mail);
			mail=loadmail(&smb,&smb.msgs,usernumber,which,lm_mode);   /* So re-load */
			if(!smb.msgs)
				break;
			for(smb.curmsg=0;smb.curmsg<smb.msgs;smb.curmsg++)
				if(mail[smb.curmsg].number==msg.idx.number)
					break;
			if(smb.curmsg>=smb.msgs)
				smb.curmsg=(smb.msgs-1);
			continue; }

		if(!loadmsg(&msg,mail[smb.curmsg].number)) {	/* Message header gone */
			if(mismatches>5) {	/* We can't do this too many times in a row */
				errormsg(WHERE,ERR_CHK,"message number",mail[smb.curmsg].number);
				break; }
			free(mail);
			mail=loadmail(&smb,&smb.msgs,usernumber,which,lm_mode);
			if(!smb.msgs)
				break;
			if(smb.curmsg>(smb.msgs-1))
				smb.curmsg=(smb.msgs-1);
			mismatches++;
			continue; }
		smb_unlockmsghdr(&smb,&msg);
		msg.idx.attr=msg.hdr.attr;

		mismatches=0;

		if(domsg && !(sys_status&SS_ABORT)) {

			show_msg(&msg
				,msg.from_ext && msg.idx.from==1 && !msg.from_net.type
					? 0:P_NOATCODES);

			if(msg.hdr.auxattr&MSG_FILEATTACH) {  /* Attached file */
				smb_getmsgidx(&smb,&msg);
				strcpy(str,msg.subj);					/* filenames in title */
//				strupr(str);
				tp=str;
				while(online) {
					p=strchr(tp,' ');
					if(p) *p=0;
					sp=strrchr(tp,'/');              /* sp is slash pointer */
					if(!sp) sp=strrchr(tp,'\\');
					if(sp) tp=sp+1;
					padfname(tp,fd.name);
					sprintf(str2,"%sfile/%04u.in/%s"  /* str2 is path/fname */
						,cfg.data_dir,msg.idx.to,tp);
					length=flength(str2);
					if(length<1)
						bputs(text[FileNotFound]);
					else if(!(useron.exempt&FLAG('T')) && cur_cps && !SYSOP
						&& length/(long)cur_cps>(time_t)timeleft)
						bputs(text[NotEnoughTimeToDl]);
					else {
						sprintf(str3,text[DownloadAttachedFileQ]
							,tp,ultoac(length,tmp));
						if(length>0L && yesno(str3)) {
#if 0	/* no such thing as local logon */
							if(online==ON_LOCAL) {
								bputs(text[EnterPath]);
								if(getstr(str3,60,K_LINE)) {
									backslashcolon(str3);
									sprintf(tmp,"%s%s",str3,tp);
									if(!mv(str2,tmp,which!=MAIL_YOUR)) {
										logon_dlb+=length;
										logon_dls++;
										useron.dls=(ushort)adjustuserrec(&cfg,useron.number
											,U_DLS,5,1);
										useron.dlb=adjustuserrec(&cfg,useron.number
											,U_DLB,10,length);
										bprintf(text[FileNBytesSent]
											,fd.name,ultoac(length,tmp)); } } }

							else 
#endif
							{	/* Remote User */
								xfer_prot_menu(XFER_DOWNLOAD);
								mnemonics(text[ProtocolOrQuit]);
								strcpy(str3,"Q");
								for(i=0;i<cfg.total_prots;i++)
									if(cfg.prot[i]->dlcmd[0]
										&& chk_ar(cfg.prot[i]->ar,&useron)) {
										sprintf(tmp,"%c",cfg.prot[i]->mnemonic);
										strcat(str3,tmp); }
								ch=(char)getkeys(str3,0);
								for(i=0;i<cfg.total_prots;i++)
									if(cfg.prot[i]->dlcmd[0] && ch==cfg.prot[i]->mnemonic
										&& chk_ar(cfg.prot[i]->ar,&useron))
										break;
								if(i<cfg.total_prots) {
									error=protocol(cfg.prot[i],XFER_DOWNLOAD,str2,nulstr,false);
									if(checkprotresult(cfg.prot[i],error,&fd)) {
										if(which==MAIL_YOUR)
											remove(str2);
										logon_dlb+=length;	/* Update stats */
										logon_dls++;
										useron.dls=(ushort)adjustuserrec(&cfg,useron.number
											,U_DLS,5,1);
										useron.dlb=adjustuserrec(&cfg,useron.number
											,U_DLB,10,length);
										bprintf(text[FileNBytesSent]
											,fd.name,ultoac(length,tmp));
										sprintf(str3
											,"%s downloaded attached file: %s"
											,useron.alias
											,fd.name);
										logline("D-",str3); 
									}
									autohangup(); 
								} 
							} 
						} 
					}
					if(!p)
						break;
					tp=p+1;
					while(*tp==' ') tp++; 
				}
				sprintf(str,"%sfile/%04u.in",cfg.data_dir,usernumber);
				rmdir(str); }
			if(which==MAIL_YOUR && !(msg.hdr.attr&MSG_READ)) {
				mail[smb.curmsg].attr|=MSG_READ;
				if(thisnode.status==NODE_INUSE)
					telluser(&msg);
				if(msg.total_hfields)
					smb_freemsgmem(&msg);
				msg.total_hfields=0;
				msg.idx.offset=0;						/* Search by number */
				if(smb_locksmbhdr(&smb)==SMB_SUCCESS) {	/* Lock the entire base */
					if(loadmsg(&msg,msg.idx.number)) {
						msg.hdr.attr|=MSG_READ;
						msg.idx.attr=msg.hdr.attr;
						if((i=smb_putmsg(&smb,&msg))!=0)
							errormsg(WHERE,ERR_WRITE,smb.file,i);
						smb_unlockmsghdr(&smb,&msg); }
					smb_unlocksmbhdr(&smb); }
				if(!msg.total_hfields) {				/* unsuccessful reload */
					domsg=0;
					continue; } }
			}
		else domsg=1;

		if(useron.misc&WIP) {
			strcpy(str,which==MAIL_YOUR ? "mailread" : which==MAIL_ALL ?
				"allmail" : "sentmail");
			menu(str); }

		ASYNC;
		if(which==MAIL_SENT)
			bprintf(text[ReadingSentMail],smb.curmsg+1,smb.msgs);
		else if(which==MAIL_ALL)
			bprintf(text[ReadingAllMail],smb.curmsg+1,smb.msgs);
		else
			bprintf(text[ReadingMail],smb.curmsg+1,smb.msgs);
		sprintf(str,"ADFLNQRT?<>[]{}-+");
		if(SYSOP)
			strcat(str,"CUSPH");
		if(which!=MAIL_YOUR)
			strcat(str,"E");
		l=getkeys(str,smb.msgs);
		if(l&0x80000000L) {
			if(l==-1)	/* ctrl-c */
				break;
			smb.curmsg=(l&~0x80000000L)-1;
			continue; }
		switch(l) {
			case 'A':   /* Auto-reply to last piece */
			case 'R':
				if(l==(cfg.sys_misc&SM_RA_EMU ? 'A' : 'R'))  /* re-read last message */
					break;

				if(which==MAIL_SENT)
					break;
				if((msg.hdr.attr&MSG_ANONYMOUS) && !SYSOP) {
					bputs(text[CantReplyToAnonMsg]);
					break; }

				quotemsg(&msg,1);

				if(msg.from_net.addr==NULL)
					SAFECOPY(str,msg.from);
				else if(msg.from_net.type==NET_FIDO) 	/* FidoNet type */
					SAFEPRINTF2(str,"%s@%s",msg.from
						,smb_faddrtoa((faddr_t *)msg.from_net.addr,tmp));
				else if(msg.from_net.type==NET_INTERNET) {
					if(msg.replyto_net.type==NET_INTERNET)
						SAFECOPY(str,(char *)msg.replyto_net.addr);
					else
						SAFECOPY(str,(char *)msg.from_net.addr);
				} else
					SAFEPRINTF2(str,"%s@%s",msg.from,(char*)msg.from_net.addr);

				SAFECOPY(str2,str);

				bputs(text[Email]);
				if(!getstr(str,64,K_EDIT|K_AUTODEL))
					break;
				msg.hdr.number=msg.idx.number;
				smb_getmsgidx(&smb,&msg);

				if(!stricmp(str2,str))		/* Reply to sender */
					sprintf(str2,text[Regarding],msg.subj);
				else						/* Reply to other */
					sprintf(str2,text[RegardingByOn],msg.subj,msg.from
						,timestr((time_t *)&msg.hdr.when_written.time));

				p=strrchr(str,'@');
				if(p) { 							/* name @addr */
					replied=netmail(str,msg.subj,WM_QUOTE);
					sprintf(str2,text[DeleteMailQ],msg.from); }
				else {
					if(!msg.from_net.type && !stricmp(str,msg.from))
						replied=email(msg.idx.from,str2,msg.subj,WM_EMAIL|WM_QUOTE);
					else if(!stricmp(str,"SYSOP"))
						replied=email(1,str2,msg.subj,WM_EMAIL|WM_QUOTE);
					else if((i=finduser(str))!=0)
						replied=email(i,str2,msg.subj,WM_EMAIL|WM_QUOTE);
					else
						replied=false;
					sprintf(str2,text[DeleteMailQ],msg.from); }

				if(replied==true && !(msg.hdr.attr&MSG_REPLIED)) {
					if(msg.total_hfields)
						smb_freemsgmem(&msg);
					msg.total_hfields=0;
					msg.idx.offset=0;
					if(smb_locksmbhdr(&smb)==SMB_SUCCESS) {	/* Lock the entire base */
						if(loadmsg(&msg,msg.idx.number)) {
							msg.hdr.attr|=MSG_REPLIED;
							msg.idx.attr=msg.hdr.attr;
							if((i=smb_putmsg(&smb,&msg))!=0)
								errormsg(WHERE,ERR_WRITE,smb.file,i);
							smb_unlockmsghdr(&smb,&msg); 
						}
						smb_unlocksmbhdr(&smb);
					}
				}

				if(msg.hdr.attr&MSG_DELETE || !yesno(str2)) {
					if(smb.curmsg<smb.msgs-1) smb.curmsg++;
					else done=1;
					break;	}
				/* Case 'D': must follow! */
			case 'D':   /* Delete last piece (toggle) */
				if(msg.hdr.attr&MSG_PERMANENT) {
					bputs("\r\nPermanent message.\r\n");
					domsg=0;
					break; }
				if(msg.total_hfields)
					smb_freemsgmem(&msg);
				msg.total_hfields=0;
				msg.idx.offset=0;
				if(smb_locksmbhdr(&smb)==SMB_SUCCESS) {	/* Lock the entire base */
					if(loadmsg(&msg,msg.idx.number)) {
						msg.hdr.attr^=MSG_DELETE;
						msg.idx.attr=msg.hdr.attr;
		//				  mail[smb.curmsg].attr=msg.hdr.attr;
						if((i=smb_putmsg(&smb,&msg))!=0)
							errormsg(WHERE,ERR_WRITE,smb.file,i);
						smb_unlockmsghdr(&smb,&msg); 
					}
					smb_unlocksmbhdr(&smb);
				}
				if(smb.curmsg<smb.msgs-1) smb.curmsg++;
				else done=1;
				break;
			case 'F':  /* Forward last piece */
				domsg=0;
				bputs(text[ForwardMailTo]);
				if(!getstr(str,LEN_ALIAS,cfg.uq&UQ_NOUPRLWR ? K_NONE:K_UPRLWR))
					break;
				i=finduser(str);
				if(!i)
					break;
				domsg=1;
				if(smb.curmsg<smb.msgs-1) smb.curmsg++;
				else done=1;
				smb_getmsgidx(&smb,&msg);
				forwardmail(&msg,i);
				if(msg.hdr.attr&MSG_PERMANENT)
					break;
				sprintf(str2,text[DeleteMailQ],msg.from);
				if(!yesno(str2))
					break;
				if(msg.total_hfields)
					smb_freemsgmem(&msg);
				msg.total_hfields=0;
				msg.idx.offset=0;
				if(smb_locksmbhdr(&smb)==SMB_SUCCESS) {	/* Lock the entire base */
					if(loadmsg(&msg,msg.idx.number)) {
						msg.hdr.attr|=MSG_DELETE;
						msg.idx.attr=msg.hdr.attr;
		//				  mail[smb.curmsg].attr=msg.hdr.attr;
						if((i=smb_putmsg(&smb,&msg))!=0)
							errormsg(WHERE,ERR_WRITE,smb.file,i);
						smb_unlockmsghdr(&smb,&msg); 
					}
					smb_unlocksmbhdr(&smb);
				}

				break;
			case 'H':
				domsg=0;
				msghdr(&msg);
				break;
			case 'L':     /* List mail */
				domsg=0;
				bprintf(text[StartWithN],(long)smb.curmsg+1);
				if((i=getnum(smb.msgs))>0)
					i--;
				else if(i==-1)
					break;
				else
					i=smb.curmsg;
				if(which==MAIL_SENT)
					bputs(text[MailSentLstHdr]);
				else if(which==MAIL_ALL)
					bputs(text[MailOnSystemLstHdr]);
				else
					bputs(text[MailWaitingLstHdr]);
				for(;i<smb.msgs && !msgabort();i++) {
					if(msg.total_hfields)
						smb_freemsgmem(&msg);
					msg.total_hfields=0;
					msg.idx.offset=mail[i].offset;
					if(!loadmsg(&msg,mail[i].number))
						continue;
					smb_unlockmsghdr(&smb,&msg);
					if(which==MAIL_ALL)
						bprintf(text[MailOnSystemLstFmt]
							,i+1,msg.from,msg.to
							,msg.hdr.attr&MSG_DELETE ? '-' : msg.hdr.attr&MSG_REPLIED ? 'R'
								: msg.hdr.attr&MSG_READ ? ' '
								: msg.from_net.type || msg.to_net.type ? 'N':'*'
							,msg.subj);
					else
						bprintf(text[MailWaitingLstFmt],i+1
							,which==MAIL_SENT ? msg.to
							: (msg.hdr.attr&MSG_ANONYMOUS) && !SYSOP
							? text[Anonymous] : msg.from
							,msg.hdr.attr&MSG_DELETE ? '-' : msg.hdr.attr&MSG_REPLIED ? 'R'
								: msg.hdr.attr&MSG_READ ? ' '
								: msg.from_net.type || msg.to_net.type ? 'N':'*'
							,msg.subj);
					smb_freemsgmem(&msg);
					msg.total_hfields=0; }
				break;
			case 'Q':
				done=1;
				break;
			case 'C':   /* Change attributes of last piece */
				i=chmsgattr(msg.hdr.attr);
				if(msg.hdr.attr==i)
					break;
				if(msg.total_hfields)
					smb_freemsgmem(&msg);
				msg.total_hfields=0;
				msg.idx.offset=0;
				if(smb_locksmbhdr(&smb)==SMB_SUCCESS) {	/* Lock the entire base */
					if(loadmsg(&msg,msg.idx.number)) {
						msg.hdr.attr=msg.idx.attr=(ushort)i;
						if((i=smb_putmsg(&smb,&msg))!=0)
							errormsg(WHERE,ERR_WRITE,smb.file,i);
						smb_unlockmsghdr(&smb,&msg); 
					}
					smb_unlocksmbhdr(&smb);
				}
				break;
			case '>':
				for(i=smb.curmsg+1;i<smb.msgs;i++)
					if(mail[i].subj==msg.idx.subj)
						break;
				if(i<smb.msgs)
					smb.curmsg=i;
				else
					domsg=0;
				break;
			case '<':   /* Search Title backward */
				for(i=smb.curmsg-1;i>-1;i--)
					if(mail[i].subj==msg.idx.subj)
						break;
				if(i>-1)
					smb.curmsg=i;
				else
					domsg=0;
				break;
			case '}':   /* Search Author forward */
				strcpy(str,msg.from);
				for(i=smb.curmsg+1;i<smb.msgs;i++)
					if(mail[i].from==msg.idx.from)
						break;
				if(i<smb.msgs)
					smb.curmsg=i;
				else
					domsg=0;
				break;
			case 'N':   /* Got to next un-read message */
				for(i=smb.curmsg+1;i<smb.msgs;i++)
					if(!(mail[i].attr&MSG_READ))
						break;
				if(i<smb.msgs)
					smb.curmsg=i;
				else
					domsg=0;
				break;
			case '{':   /* Search Author backward */
				strcpy(str,msg.from);
				for(i=smb.curmsg-1;i>-1;i--)
					if(mail[i].from==msg.idx.from)
						break;
				if(i>-1)
					smb.curmsg=i;
				else
					domsg=0;
				break;
			case ']':   /* Search To User forward */
				strcpy(str,msg.to);
				for(i=smb.curmsg+1;i<smb.msgs;i++)
					if(mail[i].to==msg.idx.to)
						break;
				if(i<smb.msgs)
					smb.curmsg=i;
				else
					domsg=0;
				break;
			case '[':   /* Search To User backward */
				strcpy(str,msg.to);
				for(i=smb.curmsg-1;i>-1;i--)
					if(mail[i].to==msg.idx.to)
						break;
				if(i>-1)
					smb.curmsg=i;
				else
					domsg=0;
				break;
			case 0:
			case '+':
				if(smb.curmsg<smb.msgs-1) smb.curmsg++;
				else done=1;
				break;
			case '-':
				if(smb.curmsg>0) smb.curmsg--;
				break;
			case 'S':
				domsg=0;
	/*
				if(!yesno(text[SaveMsgToFile]))
					break;
	*/
				bputs(text[FileToWriteTo]);
				if(getstr(str,40,K_LINE))
					msgtotxt(&msg,str,1,1);
				break;
			case 'E':
				editmsg(&msg,INVALID_SUB);
				break;
			case 'T':
				domsg=0;
				i=smb.curmsg;
				if(i) i++;
				j=i+10;
				if(j>smb.msgs)
					j=smb.msgs;

				if(which==MAIL_SENT)
					bputs(text[MailSentLstHdr]);
				else if(which==MAIL_ALL)
					bputs(text[MailOnSystemLstHdr]);
				else
					bputs(text[MailWaitingLstHdr]);
				for(;i<j;i++) {
					if(msg.total_hfields)
						smb_freemsgmem(&msg);
					msg.total_hfields=0;
					msg.idx.offset=mail[i].offset;
					if(!loadmsg(&msg,mail[i].number))
						continue;
					smb_unlockmsghdr(&smb,&msg);
					if(which==MAIL_ALL)
						bprintf(text[MailOnSystemLstFmt]
							,i+1,msg.from,msg.to
							,msg.hdr.attr&MSG_DELETE ? '-' : msg.hdr.attr&MSG_REPLIED ? 'R'
								: msg.hdr.attr&MSG_READ ? ' ' 
								: msg.from_net.type || msg.to_net.type ? 'N':'*'
							,msg.subj);
					else
						bprintf(text[MailWaitingLstFmt],i+1
							,which==MAIL_SENT ? msg.to
							: (msg.hdr.attr&MSG_ANONYMOUS) && !SYSOP
							? text[Anonymous] : msg.from
							,msg.hdr.attr&MSG_DELETE ? '-' : msg.hdr.attr&MSG_REPLIED ? 'R'
								: msg.hdr.attr&MSG_READ ? ' '
								: msg.from_net.type || msg.to_net.type ? 'N':'*'
							,msg.subj);
					smb_freemsgmem(&msg);
					msg.total_hfields=0; }
				smb.curmsg=(i-1);
				break;
			case 'U':   /* user edit */
				msg.hdr.number=msg.idx.number;
				smb_getmsgidx(&smb,&msg);
				useredit(which==MAIL_SENT ? msg.idx.to : msg.idx.from);
				break;
			case 'P':   /* Purge author and all mail to/from */
				if(noyes(text[AreYouSureQ]))
					break;
				msg.hdr.number=msg.idx.number;
				smb_getmsgidx(&smb,&msg);
				purgeuser(msg.idx.from);
				if(smb.curmsg<smb.msgs-1) smb.curmsg++;
				break;
			case '?':
				strcpy(str,which==MAIL_YOUR ? "mailread" : which==MAIL_ALL
						? "allmail" : "sentmail");
				menu(str);
				if(SYSOP && which==MAIL_SENT)
					menu("syssmail");
				else if(SYSOP && which==MAIL_YOUR)
					menu("sysmailr");   /* Sysop Mail Read */
				domsg=0;
				break;
				} }

	if(msg.total_hfields)
		smb_freemsgmem(&msg);

	if(smb.msgs)
		free(mail);

	/***************************************/
	/* Delete messages marked for deletion */
	/***************************************/

	if(cfg.sys_misc&SM_DELEMAIL) {
		if((i=smb_locksmbhdr(&smb))!=0) 			/* Lock the base, so nobody */
			errormsg(WHERE,ERR_LOCK,smb.file,i);	/* messes with the index */
		else
			delmail(usernumber,which); }

	smb_close(&smb);
	smb_stack(&smb,SMB_STACK_POP);
}
Пример #15
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);
}
Пример #16
0
bool sbbs_t::qwk_import_msg(FILE *qwk_fp, char *hdrblk, ulong blocks
							,char fromhub, uint subnum
							,uint touser, smbmsg_t* msg)
{
	char*		body;
	char*		tail;
	char*		qwkbuf;
	char		str[256],col=0,lastch=0,*p;
	char		from[128];
	uint 		i,k;
	long		bodylen,taillen;
	bool		success=false;
	uint16_t	net_type;
	ushort		xlat=XLAT_NONE;
	int			storage=SMB_SELFPACK;
	long		dupechk_hashes=SMB_HASH_SOURCE_DUPE;
	str_list_t	kludges;

	if(subnum!=INVALID_SUB
		&& (hdrblk[0]=='*' || hdrblk[0]=='+' || cfg.sub[subnum]->misc&SUB_PONLY))
		msg->hdr.attr|=MSG_PRIVATE;
	if(subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_AONLY)
		msg->hdr.attr|=MSG_ANONYMOUS;
	if(subnum==INVALID_SUB && cfg.sys_misc&SM_DELREADM)
		msg->hdr.attr|=MSG_KILLREAD;
	if((fromhub || useron.rest&FLAG('Q')) &&
		(hdrblk[0]=='*' || hdrblk[0]=='-' || hdrblk[0]=='`'))
		msg->hdr.attr|=MSG_READ;

	if(subnum!=INVALID_SUB && !fromhub && cfg.sub[subnum]->mod_ar[0]
		&& chk_ar(cfg.sub[subnum]->mod_ar,&useron,&client))
		msg->hdr.attr|=MSG_MODERATED;
	if(subnum!=INVALID_SUB && !fromhub && cfg.sub[subnum]->misc&SUB_SYSPERM
		&& sub_op(subnum))
		msg->hdr.attr|=MSG_PERMANENT;

	if(!(useron.rest&FLAG('Q')) && !fromhub && msg->hdr.when_written.zone==0)
		msg->hdr.when_written.zone=sys_timezone(&cfg);

	msg->hdr.when_imported.time=time32(NULL);
	msg->hdr.when_imported.zone=sys_timezone(&cfg);

	hdrblk[116]=0;	// don't include number of blocks in "re: msg number"
	if(!(useron.rest&FLAG('Q')) && !fromhub)
		msg->hdr.thread_back=atol((char *)hdrblk+108);

	if(subnum==INVALID_SUB) { 		/* E-mail */
		if(cfg.sys_misc&SM_FASTMAIL)
			storage=SMB_FASTALLOC;

		/* duplicate message-IDs must be allowed in mail database */
		dupechk_hashes&=~(1<<SMB_HASH_SOURCE_MSG_ID);

		sprintf(str,"%u",touser);
		smb_hfield_str(msg,RECIPIENTEXT,str); 
	} else {
		if(cfg.sub[subnum]->misc&SUB_HYPER)
			storage = SMB_HYPERALLOC;
		else if(cfg.sub[subnum]->misc&SUB_FAST)
			storage = SMB_FASTALLOC;

		if(cfg.sub[subnum]->misc&SUB_LZH)
			xlat=XLAT_LZH;
	}

	/********************************/
	/* Convert the QWK message text */
	/********************************/

	if((qwkbuf=(char *)malloc((blocks-1)*QWK_BLOCK_LEN))==NULL) {
		errormsg(WHERE,ERR_ALLOC,"QWK msg buf",(blocks-1)*QWK_BLOCK_LEN);
		return(false); 
	}

	if(fread(qwkbuf,QWK_BLOCK_LEN,blocks-1,qwk_fp) != blocks-1) {
		free(qwkbuf);
		errormsg(WHERE,ERR_READ,"QWK msg blocks",(blocks-1)*QWK_BLOCK_LEN);
	}

	bodylen=0;
	if((body=(char *)malloc((blocks-1L)*QWK_BLOCK_LEN*2L))==NULL) {
		free(qwkbuf);
		errormsg(WHERE,ERR_ALLOC,"QWK msg body",(blocks-1L)*QWK_BLOCK_LEN*2L);
		return(false); 
	}

	taillen=0;
	if((tail=(char *)malloc((blocks-1L)*QWK_BLOCK_LEN*2L))==NULL) {
		free(qwkbuf);
		free(body);
		errormsg(WHERE,ERR_ALLOC,"QWK msg tail",(blocks-1L)*QWK_BLOCK_LEN*2L);
		return(false); 
	}

	kludges=strListInit();

	for(k=0;k<(blocks-1)*QWK_BLOCK_LEN;k++) {
		if(qwkbuf[k]==0)
			continue;
		if(bodylen==0 
			&& (qwkbuf[k]=='@' 
				|| (((useron.qwk&QWK_EXT) || subnum==INVALID_SUB)
					&& (strnicmp(qwkbuf+k,"To:",3)==0 
					||  strnicmp(qwkbuf+k,"From:",5)==0 
					||  strnicmp(qwkbuf+k,"Subject:",8)==0)))) {
			if((p=strchr(qwkbuf+k, QWK_NEWLINE))==NULL) {
				body[bodylen++]=qwkbuf[k];
				continue;
			}
			*p=0;	/* Converts QWK_NEWLINE to NUL */
			strListPush(&kludges, qwkbuf+k);
			k+=strlen(qwkbuf+k);
			continue;
		}
		if(!taillen && qwkbuf[k]==' ' && col==3 && bodylen>=3
			&& body[bodylen-3]=='-' && body[bodylen-2]=='-'
			&& body[bodylen-1]=='-') {
			bodylen-=3;
			strcpy(tail,"--- ");	/* DO NOT USE SAFECOPY */
			taillen=4;
			col++;
			continue; 
		}
		if(qwkbuf[k]==QWK_NEWLINE) {		/* expand QWK_NEWLINE to crlf */
			if(!bodylen && !taillen)		/* Ignore blank lines at top of message */
				continue;
			if(!taillen && col==3 && bodylen>=3 && body[bodylen-3]=='-'
				&& body[bodylen-2]=='-' && body[bodylen-1]=='-') {
				bodylen-=3;
				strcpy(tail,"---");	/* DO NOT USE SAFECOPY */
				taillen=3; 
			}
			col=0;
			if(taillen) {
				tail[taillen++]=CR;
				tail[taillen++]=LF; 
			}
			else {
				body[bodylen++]=CR;
				body[bodylen++]=LF; 
			}
			continue; 
		}
		/* beep restrict */
		if(!fromhub && qwkbuf[k]==BEL && useron.rest&FLAG('B'))   
			continue;
		/* ANSI restriction */
		if(!fromhub && (qwkbuf[k]==CTRL_A || qwkbuf[k]==ESC)
			&& useron.rest&FLAG('A'))
			continue;
		if(qwkbuf[k]!=CTRL_A && lastch!=CTRL_A)
			col++;
		if(lastch==CTRL_A && !valid_ctrl_a_code(qwkbuf[k])) {
			if(taillen) taillen--;
			else		bodylen--;
			lastch=0;
			continue; 
		}
		lastch=qwkbuf[k];
		if(taillen)
			tail[taillen++]=qwkbuf[k];
		else
			body[bodylen++]=qwkbuf[k]; 
	} 
	free(qwkbuf);

	while(bodylen && body[bodylen-1]==' ') bodylen--; /* remove trailing spaces */
	if(bodylen>=2 && body[bodylen-2]==CR && body[bodylen-1]==LF)
		bodylen-=2;

	while(taillen && tail[taillen-1]<=' ') taillen--; /* remove trailing garbage */

	/* Parse QWK Kludges (QWKE standard and SyncQNET legacy) here: */
	if(useron.rest&FLAG('Q') || fromhub) {      /* QWK Net */
		if((p=iniGetString(kludges,ROOT_SECTION,"@VIA",NULL,NULL)) != NULL) {
			if(!fromhub)
				set_qwk_flag(QWK_VIA);
			if(route_circ(p,cfg.sys_id)) {
				bprintf("\r\nCircular message path: %s\r\n",p);
				lprintf(LOG_ERR,"Circular message path: %s from %s"
					,p,fromhub ? cfg.qhub[fromhub-1]->id:useron.alias);
				strListFree(&kludges);
				free(body);
				free(tail);
				return(false); 
			}
			SAFEPRINTF2(str,"%s/%s"
				,fromhub ? cfg.qhub[fromhub-1]->id : useron.alias,p);
			strupr(str);
			update_qwkroute(str); 
		}
		else {
			if(fromhub)
				SAFECOPY(str,cfg.qhub[fromhub-1]->id);
			else
				SAFECOPY(str,useron.alias); 
		}
		/* From network type & address: */
		strupr(str);
		net_type=NET_QWK;
		smb_hfield_netaddr(msg, SENDERNETADDR, str, &net_type);
		smb_hfield_bin(msg,SENDERNETTYPE,net_type);

	} else {
		sprintf(str,"%u",useron.number);
		smb_hfield_str(msg,SENDEREXT,str);
		if((uint)subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_NAME)
			SAFECOPY(from,useron.name);
		else
			SAFECOPY(from,useron.alias);
		smb_hfield_str(msg,SENDER,from);
	}
	if((p=iniGetString(kludges,ROOT_SECTION,"@MSGID",NULL,NULL)) != NULL) {
		if(!fromhub)
			set_qwk_flag(QWK_MSGID);
		truncstr(p," ");				/* Truncate at first space char */
		if(msg->id==NULL)
			smb_hfield_str(msg,RFC822MSGID,p);
	}
	if((p=iniGetString(kludges,ROOT_SECTION,"@REPLY",NULL,NULL)) != NULL) {
		if(!fromhub)
			set_qwk_flag(QWK_MSGID);
		truncstr(p," ");				/* Truncate at first space char */
		if(msg->reply_id==NULL)
			smb_hfield_str(msg,RFC822REPLYID,p);
	}
	if((p=iniGetString(kludges,ROOT_SECTION,"@TZ",NULL,NULL)) != NULL) {
		if(!fromhub)
			set_qwk_flag(QWK_TZ);
		msg->hdr.when_written.zone=(short)ahtoul(p); 
	}
	if((p=iniGetString(kludges,ROOT_SECTION,"@REPLYTO",NULL,NULL)) != NULL) {
		if(msg->replyto==NULL)
			smb_hfield_str(msg,REPLYTO,p);
	}
	/* QWKE standard: */
	if((p=iniGetString(kludges,ROOT_SECTION,"Subject",NULL,NULL)) != NULL)
		smb_hfield_replace_str(msg,SUBJECT,p);
	if((p=iniGetString(kludges,ROOT_SECTION,"To",NULL,NULL)) != NULL)
		smb_hfield_replace_str(msg,RECIPIENT,p);
	if((useron.rest&FLAG('Q'))
		&& (p=iniGetString(kludges,ROOT_SECTION,"From",NULL,NULL)) != NULL)
		smb_hfield_replace_str(msg,SENDER,p);

	strListFree(&kludges);

	/* smb_addmsg requires ASCIIZ strings */
	body[bodylen]=0;
	tail[taillen]=0;

	if(online==ON_REMOTE)
		bputs(text[WritingIndx]);

	if(smb.status.max_crcs==0)	/* no CRC checking means no body text dupe checking */
		dupechk_hashes&=~(1<<SMB_HASH_SOURCE_BODY);

	if((i=smb_addmsg(&smb,msg,storage,dupechk_hashes,xlat,(uchar*)body,(uchar*)tail))==SMB_SUCCESS)
		success=true;
	else if(i==SMB_DUPE_MSG) {
		bprintf("\r\n!%s\r\n",smb.last_error);
		if(!fromhub) {
			if(subnum==INVALID_SUB) {
				SAFEPRINTF2(str,"%s duplicate e-mail attempt (%s)",useron.alias,smb.last_error);
				logline(LOG_NOTICE,"E!",str); 
			} else {
				SAFEPRINTF4(str,"%s duplicate message attempt in %s %s (%s)"
					,useron.alias
					,cfg.grp[cfg.sub[subnum]->grp]->sname
					,cfg.sub[subnum]->lname
					,smb.last_error);
				logline(LOG_NOTICE,"P!",str); 
			}
		}
	}
	else 
		errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error);

	free(body);
	free(tail);

	return(success);
}
Пример #17
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); }
}
Пример #18
0
JSObject* DLLCALL js_CreateXtrnAreaObject(JSContext* cx, JSObject* parent, scfg_t* cfg
										  ,user_t* user, client_t* client)
{
	JSObject*	areaobj;
	JSObject*	allsec;
	JSObject*	allprog;
	JSObject*	secobj;
	JSObject*	progobj;
	JSObject*	eventobj;
	JSObject*	event_array;
	JSObject*	xeditobj;
	JSObject*	xedit_array;
	JSObject*	sec_list;
	JSObject*	prog_list;
	JSString*	js_str;
	jsval		val;
	jsuint		sec_index;
	jsuint		prog_index;
	uint		l,d;

	/* Return existing object if it's already been created */
	if(JS_GetProperty(cx,parent,"xtrn_area",&val) && val!=JSVAL_VOID)
		areaobj = JSVAL_TO_OBJECT(val);
	else
		areaobj = JS_DefineObject(cx, parent, "xtrn_area", NULL
									, NULL, JSPROP_ENUMERATE|JSPROP_READONLY);

	if(areaobj==NULL)
		return(NULL);

#ifdef BUILD_JSDOCS
	js_DescribeSyncObject(cx,areaobj,"External Program Areas",310);
#endif

	/* xtrn_area.sec[] */
	if((allsec=JS_NewObject(cx,NULL,NULL,areaobj))==NULL)
		return(NULL);

	val=OBJECT_TO_JSVAL(allsec);
	if(!JS_SetProperty(cx, areaobj, "sec", &val))
		return(NULL);

	/* xtrn_area.prog[] */
	if((allprog=JS_NewObject(cx,NULL,NULL,areaobj))==NULL)
		return(NULL);

	val=OBJECT_TO_JSVAL(allprog);
	if(!JS_SetProperty(cx, areaobj, "prog", &val))
		return(NULL);

	/* xtrn_area.sec_list[] */
	if((sec_list=JS_NewArrayObject(cx, 0, NULL))==NULL) 
		return(NULL);

	val=OBJECT_TO_JSVAL(sec_list);
	if(!JS_SetProperty(cx, areaobj, "sec_list", &val)) 
		return(NULL);

	for(l=0;l<cfg->total_xtrnsecs;l++) {

		if((secobj=JS_NewObject(cx, NULL, NULL, NULL))==NULL)
			return(NULL);

		sec_index=-1;
		if(user==NULL || chk_ar(cfg,cfg->xtrnsec[l]->ar,user,client)) {

			if(!JS_GetArrayLength(cx, sec_list, &sec_index))
				return(NULL);

			val=OBJECT_TO_JSVAL(secobj);
			if(!JS_SetElement(cx, sec_list, sec_index, &val))
				return(NULL);
		}

		/* Add as property (associative array element) */
		if(!JS_DefineProperty(cx, allsec, cfg->xtrnsec[l]->code, val
			,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE))
			return(NULL);

		val=INT_TO_JSVAL(sec_index);
		if(!JS_SetProperty(cx, secobj, "index", &val))
			return(NULL);

		val=INT_TO_JSVAL(l);
		if(!JS_SetProperty(cx, secobj, "number", &val))
			return(NULL);

		if((js_str=JS_NewStringCopyZ(cx, cfg->xtrnsec[l]->code))==NULL)
			return(NULL);
		val=STRING_TO_JSVAL(js_str);
		if(!JS_SetProperty(cx, secobj, "code", &val))
			return(NULL);

		if((js_str=JS_NewStringCopyZ(cx, cfg->xtrnsec[l]->name))==NULL)
			return(NULL);
		val=STRING_TO_JSVAL(js_str);
		if(!JS_SetProperty(cx, secobj, "name", &val))
			return(NULL);

		if((js_str=JS_NewStringCopyZ(cx, cfg->xtrnsec[l]->arstr))==NULL)
			return(NULL);
		val=STRING_TO_JSVAL(js_str);
		if(!JS_SetProperty(cx, secobj, "ars", &val))
			return(NULL);

		if(user==NULL || chk_ar(cfg,cfg->xtrnsec[l]->ar,user,client))
			val=JSVAL_TRUE;
		else
			val=JSVAL_FALSE;
		if(!JS_SetProperty(cx, secobj, "can_access", &val))
			return(NULL);

		/* prog_list[] */
		if((prog_list=JS_NewArrayObject(cx, 0, NULL))==NULL) 
			return(NULL);

		val=OBJECT_TO_JSVAL(prog_list);
		if(!JS_SetProperty(cx, secobj, "prog_list", &val)) 
			return(NULL);

#ifdef BUILD_JSDOCS
		js_DescribeSyncObject(cx,secobj,"Online Program (door) Sections (current user has access to)",310);
#endif

		for(d=0;d<cfg->total_xtrns;d++) {
			if(cfg->xtrn[d]->sec!=l)
				continue;

			if((progobj=JS_NewObject(cx, NULL, NULL, NULL))==NULL)
				return(NULL);

			prog_index=-1;
			if((user==NULL || chk_ar(cfg,cfg->xtrn[d]->ar,user,client))
				&& !(cfg->xtrn[d]->event && cfg->xtrn[d]->misc&EVENTONLY)) {

				if(!JS_GetArrayLength(cx, prog_list, &prog_index))
					return(NULL);							

				val=OBJECT_TO_JSVAL(progobj);
				if(!JS_SetElement(cx, prog_list, prog_index, &val))
					return(NULL);
			}

			/* Add as property (associative array element) */
			if(!JS_DefineProperty(cx, allprog, cfg->xtrn[d]->code, val
				,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE))
				return(NULL);

			val=INT_TO_JSVAL(prog_index);
			if(!JS_SetProperty(cx, progobj, "index", &val))
				return(NULL);

			val=INT_TO_JSVAL(d);
			if(!JS_SetProperty(cx, progobj, "number", &val))
				return(NULL);

			val=INT_TO_JSVAL(sec_index);
			if(!JS_SetProperty(cx, progobj, "sec_index", &val))
				return(NULL);

			val=INT_TO_JSVAL(l);
			if(!JS_SetProperty(cx, progobj, "sec_number", &val))
				return(NULL);

			val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,cfg->xtrnsec[l]->code));
			if(!JS_SetProperty(cx, progobj, "sec_code", &val))
				return(NULL);

			if(!js_CreateXtrnProgProperties(cx, progobj, cfg->xtrn[d]))
				return(NULL);

			if(user==NULL || chk_ar(cfg,cfg->xtrn[d]->ar,user,client))
				val=JSVAL_TRUE;
			else
				val=JSVAL_FALSE;
			if(!JS_SetProperty(cx, progobj, "can_access", &val))
				return(NULL);

			if(user==NULL || chk_ar(cfg,cfg->xtrn[d]->run_ar,user,client))
				val=JSVAL_TRUE;
			else
				val=JSVAL_FALSE;
			if(!JS_SetProperty(cx, progobj, "can_run", &val))
				return(NULL);

#ifdef BUILD_JSDOCS
			js_DescribeSyncObject(cx,progobj,"Online External Programs (doors) (current user has access to)",310);
#endif
		}

#ifdef BUILD_JSDOCS
		js_CreateArrayOfStrings(cx, secobj, "_property_desc_list", xtrn_sec_prop_desc, JSPROP_READONLY);
#endif

	}

#ifdef BUILD_JSDOCS

	js_DescribeSyncObject(cx,allsec,"Associative array of all external program sections (use internal code as index)",312);
	JS_DefineProperty(cx,allsec,"_dont_document",JSVAL_TRUE,NULL,NULL,JSPROP_READONLY);

	js_DescribeSyncObject(cx,allprog,"Associative array of all external programs (use internal code as index)",311);
	JS_DefineProperty(cx,allprog,"_dont_document",JSVAL_TRUE,NULL,NULL,JSPROP_READONLY);
#endif

	/* Create event property */
	if((event_array=JS_NewObject(cx,NULL,NULL,areaobj))==NULL)
		return(NULL);

	val=OBJECT_TO_JSVAL(event_array);
	if(!JS_SetProperty(cx, areaobj, "event", &val))
		return(NULL);

	for(l=0;l<cfg->total_events;l++) {

		if((eventobj=JS_NewObject(cx, NULL, NULL, NULL))==NULL)
			return(NULL);

		if(!JS_DefineProperty(cx, event_array, cfg->event[l]->code, OBJECT_TO_JSVAL(eventobj)
			,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE))
			return(NULL);

		if((js_str=JS_NewStringCopyZ(cx, cfg->event[l]->cmd))==NULL)
			return(NULL);
		if(!JS_DefineProperty(cx, eventobj, "cmd", STRING_TO_JSVAL(js_str)
			,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY))
			return(NULL);

		if((js_str=JS_NewStringCopyZ(cx, cfg->event[l]->dir))==NULL)
			return(NULL);
		if(!JS_DefineProperty(cx, eventobj, "startup_dir", STRING_TO_JSVAL(js_str)
			,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY))
			return(NULL);

		if(!JS_DefineProperty(cx, eventobj, "node_num", INT_TO_JSVAL(cfg->event[l]->node)
			,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY))
			return(NULL);

		if(!JS_DefineProperty(cx, eventobj, "time", INT_TO_JSVAL(cfg->event[l]->time)
			,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY))
			return(NULL);

		if(!JS_DefineProperty(cx, eventobj, "freq", INT_TO_JSVAL(cfg->event[l]->freq)
			,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY))
			return(NULL);

		if(!JS_DefineProperty(cx, eventobj, "days", INT_TO_JSVAL(cfg->event[l]->days)
			,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY))
			return(NULL);

		if(!JS_DefineProperty(cx, eventobj, "mdays", INT_TO_JSVAL(cfg->event[l]->mdays)
			,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY))
			return(NULL);

		if(!JS_DefineProperty(cx, eventobj, "months", INT_TO_JSVAL(cfg->event[l]->months)
			,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY))
			return(NULL);

		if(!JS_DefineProperty(cx, eventobj, "last_run", INT_TO_JSVAL(cfg->event[l]->last)
			,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY))
			return(NULL);

		if(!JS_DefineProperty(cx, eventobj, "settings", INT_TO_JSVAL(cfg->event[l]->misc)
			,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY))
			return(NULL);

#ifdef BUILD_JSDOCS
		js_CreateArrayOfStrings(cx, eventobj, "_property_desc_list", event_prop_desc, JSPROP_READONLY);
#endif
	}

#ifdef BUILD_JSDOCS
	js_DescribeSyncObject(cx,event_array,"Associative array of all timed events (use internal code as index)",311);
	JS_DefineProperty(cx,event_array,"_assoc_array",JSVAL_TRUE,NULL,NULL,JSPROP_READONLY);
#endif

	/* Create editor property */
	if((xedit_array=JS_NewObject(cx,NULL,NULL,areaobj))==NULL)
		return(NULL);

	val=OBJECT_TO_JSVAL(xedit_array);
	if(!JS_SetProperty(cx, areaobj, "editor", &val))
		return(NULL);

	for(l=0;l<cfg->total_xedits;l++) {

		if(user!=NULL && !chk_ar(cfg,cfg->xedit[l]->ar,user,client))
			continue;

		if((xeditobj=JS_NewObject(cx, NULL, NULL, NULL))==NULL)
			return(NULL);

		if(!JS_DefineProperty(cx, xedit_array, cfg->xedit[l]->code, OBJECT_TO_JSVAL(xeditobj)
			,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE))
			return(NULL);

		if((js_str=JS_NewStringCopyZ(cx, cfg->xedit[l]->name))==NULL)
			return(NULL);
		if(!JS_DefineProperty(cx, xeditobj, "name", STRING_TO_JSVAL(js_str)
			,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY))
			return(NULL);

		if((js_str=JS_NewStringCopyZ(cx, cfg->xedit[l]->rcmd))==NULL)
			return(NULL);
		if(!JS_DefineProperty(cx, xeditobj, "cmd", STRING_TO_JSVAL(js_str)
			,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY))
			return(NULL);

		if((js_str=JS_NewStringCopyZ(cx, cfg->xedit[l]->arstr))==NULL)
			return(NULL);
		if(!JS_DefineProperty(cx, xeditobj, "ars", STRING_TO_JSVAL(js_str)
			,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY))
			return(NULL);

		if(!JS_DefineProperty(cx, xeditobj, "settings", INT_TO_JSVAL(cfg->xedit[l]->misc)
			,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY))
			return(NULL);

		if(!JS_DefineProperty(cx, xeditobj, "type", INT_TO_JSVAL(cfg->xedit[l]->type)
			,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY))
			return(NULL);

#ifdef BUILD_JSDOCS
		js_CreateArrayOfStrings(cx, xeditobj, "_property_desc_list", xedit_prop_desc, JSPROP_READONLY);
#endif
	}

#ifdef BUILD_JSDOCS
	js_DescribeSyncObject(cx,xedit_array,"Associative array of all external editors (use internal code as index)",311);
	JS_DefineProperty(cx,xedit_array,"_assoc_array",JSVAL_TRUE,NULL,NULL,JSPROP_READONLY);
#endif

	return(areaobj);
}
Пример #19
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); 
	}
}
Пример #20
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);
}
Пример #21
0
bool sbbs_t::postmsg(uint subnum, smbmsg_t *remsg, long wm_mode)
{
	char	str[256],title[LEN_TITLE+1],top[256];
	char	msg_id[256];
	char	touser[64];
	char	from[64];
	char	pid[128];
	char*	editor=NULL;
	char*	msgbuf=NULL;
	uint16_t xlat;
	ushort	msgattr;
	int 	i,storage;
	long	dupechk_hashes;
	long	length;
	FILE*	fp;
	smbmsg_t msg;
	uint	reason;

	if(remsg) {
		sprintf(title,"%.*s",LEN_TITLE,remsg->subj);
		if(remsg->hdr.attr&MSG_ANONYMOUS)
			SAFECOPY(from,text[Anonymous]);
		else
			SAFECOPY(from,remsg->from);
		// If user posted this message, reply to the original recipient again
		if((remsg->from_ext!=NULL && atoi(remsg->from_ext)==useron.number)
			|| stricmp(useron.alias,remsg->from)==0 || stricmp(useron.name,remsg->from)==0)
			SAFECOPY(touser,remsg->to);
		else
			SAFECOPY(touser,from);
		msgattr=(ushort)(remsg->hdr.attr&MSG_PRIVATE);
		sprintf(top,text[RegardingByToOn],title,from,remsg->to
			,timestr(remsg->hdr.when_written.time)
			,smb_zonestr(remsg->hdr.when_written.zone,NULL)); 
	} else {
		title[0]=0;
		touser[0]=0;
		top[0]=0;
		msgattr=0; 
	}

	/* Security checks */
	if(!can_user_post(&cfg,subnum,&useron,&client,&reason)) {
		bputs(text[reason]);
		return false;
	}

	bprintf(text[Posting],cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname);
	action=NODE_PMSG;
	nodesync();

	if(!(msgattr&MSG_PRIVATE) && (cfg.sub[subnum]->misc&SUB_PONLY
		|| (cfg.sub[subnum]->misc&SUB_PRIV && !noyes(text[PrivatePostQ]))))
		msgattr|=MSG_PRIVATE;

	if(sys_status&SS_ABORT)
		return(false);

	if(
#if 0	/* we *do* support internet posts to specific people July-11-2002 */
		!(cfg.sub[subnum]->misc&SUB_INET) &&	// Prompt for TO: user
#endif
		(cfg.sub[subnum]->misc&SUB_TOUSER || msgattr&MSG_PRIVATE || touser[0])) {
		if(!touser[0] && !(msgattr&MSG_PRIVATE))
			SAFECOPY(touser,"All");
		bputs(text[PostTo]);
		i=LEN_ALIAS;
		if(cfg.sub[subnum]->misc&SUB_QNET)
			i=25;
		if(cfg.sub[subnum]->misc&SUB_FIDO)
			i=FIDO_NAME_LEN-1;
		if(cfg.sub[subnum]->misc&(SUB_PNET|SUB_INET))
			i=60;
		getstr(touser,i,K_UPRLWR|K_LINE|K_EDIT|K_AUTODEL);
		if(stricmp(touser,"ALL")
		&& !(cfg.sub[subnum]->misc&(SUB_PNET|SUB_FIDO|SUB_QNET|SUB_INET|SUB_ANON))) {
			if(cfg.sub[subnum]->misc&SUB_NAME) {
				if(!userdatdupe(useron.number,U_NAME,LEN_NAME,touser)) {
					bputs(text[UnknownUser]);
					return(false); 
				} 
			}
			else {
				if((i=finduser(touser))==0)
					return(false);
				username(&cfg,i,touser); 
			} 
		}
		if(sys_status&SS_ABORT)
			return(false); 
	}

	if(!touser[0])
		SAFECOPY(touser,"All");       // Default to ALL

	if(!stricmp(touser,"SYSOP") && !SYSOP)  // Change SYSOP to user #1
		username(&cfg,1,touser);

	if(msgattr&MSG_PRIVATE && !stricmp(touser,"ALL")) {
		bputs(text[NoToUser]);
		return(false); 
	}
	if(msgattr&MSG_PRIVATE)
		wm_mode|=WM_PRIVATE;

	if(cfg.sub[subnum]->misc&SUB_AONLY
		|| (cfg.sub[subnum]->misc&SUB_ANON && useron.exempt&FLAG('A')
			&& !noyes(text[AnonymousQ])))
		msgattr|=MSG_ANONYMOUS;

	if(cfg.sub[subnum]->mod_ar[0] && chk_ar(cfg.sub[subnum]->mod_ar,&useron,&client))
		msgattr|=MSG_MODERATED;

	if(cfg.sub[subnum]->misc&SUB_SYSPERM && sub_op(subnum))
		msgattr|=MSG_PERMANENT;

	if(msgattr&MSG_PRIVATE)
		bputs(text[PostingPrivately]);

	if(msgattr&MSG_ANONYMOUS)
		bputs(text[PostingAnonymously]);

	if(cfg.sub[subnum]->misc&SUB_NAME)
		bputs(text[UsingRealName]);

	msg_tmp_fname(useron.xedit, str, sizeof(str));
	if(!writemsg(str,top,title,wm_mode,subnum,touser,&editor)
		|| (length=(long)flength(str))<1) {	/* Bugfix Aug-20-2003: Reject negative length */
		bputs(text[Aborted]);
		return(false); 
	}

	bputs(text[WritingIndx]);

	if((i=smb_stack(&smb,SMB_STACK_PUSH))!=SMB_SUCCESS) {
		errormsg(WHERE,ERR_OPEN,cfg.sub[subnum]->code,i,smb.last_error);
		return(false); 
	}

	smb.subnum=subnum;
	if((i=msgbase_open(&cfg,&smb,&storage,&dupechk_hashes,&xlat))!=SMB_SUCCESS) {
		errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
		smb_stack(&smb,SMB_STACK_POP);
		return(false); 
	}

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

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

	if((msgbuf=(char*)calloc(length+1,sizeof(char))) == NULL) {
		smb_close(&smb);
		errormsg(WHERE,ERR_ALLOC,"msgbuf",length+1);
		smb_stack(&smb,SMB_STACK_POP);
		return(false);
	}

	if((fp=fopen(str,"rb"))==NULL) {
		free(msgbuf);
		smb_close(&smb);
		errormsg(WHERE,ERR_OPEN,str,O_RDONLY|O_BINARY);
		smb_stack(&smb,SMB_STACK_POP);
		return(false); 
	}

	i=fread(msgbuf,1,length,fp);
	fclose(fp);
	if(i != length) {
		free(msgbuf);
		smb_close(&smb);
		errormsg(WHERE,ERR_READ,str,length);
		smb_stack(&smb,SMB_STACK_POP);
		return(false);
	}
	truncsp(msgbuf);

	/* ToDo: split body/tail */

	memset(&msg,0,sizeof(msg));
	msg.hdr.attr=msgattr;
	msg.hdr.when_written.time=msg.hdr.when_imported.time=time32(NULL);
	msg.hdr.when_written.zone=msg.hdr.when_imported.zone=sys_timezone(&cfg);

	msg.hdr.number=smb.status.last_msg+1; /* this *should* be the new message number */

	if(remsg) {

		msg.hdr.thread_back=remsg->hdr.number;	/* needed for threading backward */

		if((msg.hdr.thread_id=remsg->hdr.thread_id) == 0)
			msg.hdr.thread_id=remsg->hdr.number;

		/* Add RFC-822 Reply-ID (generate if necessary) */
		if(remsg->id!=NULL)
			smb_hfield_str(&msg,RFC822REPLYID,remsg->id);

		/* Add FidoNet Reply if original message has FidoNet MSGID */
		if(remsg->ftn_msgid!=NULL)
			smb_hfield_str(&msg,FIDOREPLYID,remsg->ftn_msgid);

		if((i=smb_updatethread(&smb, remsg, smb.status.last_msg+1))!=SMB_SUCCESS)
			errormsg(WHERE,"updating thread",smb.file,i,smb.last_error); 
	}

	smb_hfield_str(&msg,RECIPIENT,touser);

	SAFECOPY(str,cfg.sub[subnum]->misc&SUB_NAME ? useron.name : useron.alias);
	smb_hfield_str(&msg,SENDER,str);

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

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

	smb_hfield_str(&msg,SUBJECT,title);

	/* Generate default (RFC822) message-id (always) */
	get_msgid(&cfg,subnum,&msg,msg_id,sizeof(msg_id));
	smb_hfield_str(&msg,RFC822MSGID,msg_id);

	/* Generate FTN (FTS-9) MSGID */
	if(cfg.sub[subnum]->misc&SUB_FIDO) {
		ftn_msgid(cfg.sub[subnum],&msg,msg_id,sizeof(msg_id));
		smb_hfield_str(&msg,FIDOMSGID,msg_id);
	}

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

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

	i=smb_addmsg(&smb,&msg,storage,dupechk_hashes,xlat,(uchar*)msgbuf,NULL);
	free(msgbuf);

	if(i==SMB_DUPE_MSG) {
		attr(cfg.color[clr_err]);
		bprintf(text[CantPostMsg], smb.last_error);
	} else if(i!=SMB_SUCCESS)
		errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error);

	smb_close(&smb);
	smb_stack(&smb,SMB_STACK_POP);
	smb_freemsgmem(&msg);
	if(i!=SMB_SUCCESS)
		return(false); 

	logon_posts++;
	user_posted_msg(&cfg, &useron, 1);
	bprintf(text[Posted],cfg.grp[cfg.sub[subnum]->grp]->sname
		,cfg.sub[subnum]->lname);
	sprintf(str,"%s posted on %s %s"
		,useron.alias,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname);
	logline("P+",str);

	signal_sub_sem(&cfg,subnum);

	user_event(EVENT_POST);

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

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

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

		case CS_FILE_GET_DIR_NUM:

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

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

		case CS_FILE_GET_LIB_NUM:

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

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

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

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

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

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

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

	errormsg(WHERE,ERR_CHK,"shell function",*(csi->ip-1));
	return(0);
}
Пример #23
0
bool sbbs_t::bulkmail(uchar *ar)
{
	char		str[256],title[LEN_TITLE+1];
	char		msgpath[MAX_PATH+1];
	char*		msgbuf;
	char*		editor=NULL;
	char 		tmp[512];
	int 		i,j,x;
	long		msgs=0;
	long		length;
	FILE*		fp;
	smb_t		smb;
	smbmsg_t	msg;
	user_t		user;

	memset(&msg,0,sizeof(msg));
	
	title[0]=0;
	action=NODE_SMAL;
	nodesync();

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

	msg_tmp_fname(useron.xedit, msgpath, sizeof(msgpath));
	if(!writemsg(msgpath,nulstr,title,WM_EMAIL,INVALID_SUB,"Bulk Mailing",&editor)) {
		bputs(text[Aborted]);
		return(false); 
	}

	if((fp=fopen(msgpath,"r"))==NULL) {
		errormsg(WHERE,ERR_OPEN,msgpath,O_RDONLY);
		return(false); 
	}

	if((length=(long)filelength(fileno(fp)))<=0) {
		fclose(fp);
		return(false);
	}

	bputs(text[WritingIndx]);
	CRLF;

	if((msgbuf=(char*)malloc(length+1))==NULL) {
		errormsg(WHERE,ERR_ALLOC,msgpath,length+1);
		return(false);
	}
	length=fread(msgbuf,sizeof(char),length,fp);
	fclose(fp);
	if(length<0) {
		free(msgbuf);
		errormsg(WHERE,ERR_READ,msgpath,length);
		return(false);
	}
	msgbuf[length]=0;	/* ASCIIZ */

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

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

	smb_hfield_str(&msg,SUBJECT,title);

	msg.hdr.when_written.time=time32(NULL);
	msg.hdr.when_written.zone=sys_timezone(&cfg);

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

	memset(&smb,0,sizeof(smb));
	smb.subnum=INVALID_SUB;	/* mail database */
	i=savemsg(&cfg, &smb, &msg, &client, startup->host_name, msgbuf);
	free(msgbuf);
	if(i!=0) {
		smb_close(&smb);
		smb_freemsgmem(&msg);
		return(false);
	}

	j=lastuser(&cfg);

	if(*ar)
		for(i=1;i<=j;i++) {
			user.number=i;
			if(getuserdat(&cfg, &user)!=0)
				continue;
			if(user.misc&(DELETED|INACTIVE))
				continue;
			if(chk_ar(ar,&user,/* client: */NULL)) {
				if((x=bulkmailhdr(&smb, &msg, i))!=SMB_SUCCESS) {
					errormsg(WHERE,ERR_WRITE,smb.file,x);
					break;
				}
				msgs++;
			} 
		}
	else
		while(online) {
			bputs(text[EnterAfterLastDestUser]);
			if(!getstr(str,LEN_ALIAS,cfg.uq&UQ_NOUPRLWR ? K_NONE:K_UPRLWR))
				break;
			if((i=finduser(str))!=0) {
				if((x=bulkmailhdr(&smb, &msg, i))!=SMB_SUCCESS) {
					errormsg(WHERE,ERR_WRITE,smb.file,x);
					break;
				}
				msgs++; 
			}
		}

	if((i=smb_open_da(&smb))==SMB_SUCCESS) {
		if(!msgs)
			smb_freemsg_dfields(&smb,&msg,SMB_ALL_REFS);
		else if(msgs>1)
			smb_incmsg_dfields(&smb,&msg,(ushort)msgs-1);
		smb_close_da(&smb);
	}

	smb_close(&smb);
	smb_freemsgmem(&msg);

	if(i!=SMB_SUCCESS) {
		errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
		return(false);
	}

	putuserrec(&cfg,useron.number,U_EMAILS,5,ultoa(useron.emails,tmp,10));
	putuserrec(&cfg,useron.number,U_ETODAY,5,ultoa(useron.etoday,tmp,10));

	return(true);
}
Пример #24
0
void sbbs_t::userlist(long mode)
{
	char	name[256],sort=0;
	char 	tmp[512];
	int		i,j,k,users=0;
	char *	line[2500];
	user_t	user;

	if(lastuser(&cfg)<=(sizeof(line)/sizeof(line[0])))
		sort=yesno(text[SortAlphaQ]);
	if(sort) {
		bputs(text[CheckingSlots]); 
	}
	else {
		CRLF; 
	}
	j=0;
	k=lastuser(&cfg);
	for(i=1;i<=k && !msgabort();i++) {
		if(sort && (online==ON_LOCAL || !rioctl(TXBC)))
			bprintf("%-4d\b\b\b\b",i);
		user.number=i;
		getuserdat(&cfg,&user);
		if(user.misc&(DELETED|INACTIVE))
			continue;
		users++;
		if(mode==UL_SUB) {
			if(!usrgrps)
				continue;
			if(!chk_ar(cfg.grp[usrgrp[curgrp]]->ar,&user))
				continue;
			if(!chk_ar(cfg.sub[usrsub[curgrp][cursub[curgrp]]]->ar,&user)
				|| (cfg.sub[usrsub[curgrp][cursub[curgrp]]]->read_ar[0]
				&& !chk_ar(cfg.sub[usrsub[curgrp][cursub[curgrp]]]->read_ar,&user)))
				continue; 
		}
		else if(mode==UL_DIR) {
			if(user.rest&FLAG('T'))
				continue;
			if(!usrlibs)
				continue;
			if(!chk_ar(cfg.lib[usrlib[curlib]]->ar,&user))
				continue;
			if(!chk_ar(cfg.dir[usrdir[curlib][curdir[curlib]]]->ar,&user))
				continue; 
		}
		if(sort) {
			if((line[j]=(char *)malloc(128))==0) {
				errormsg(WHERE,ERR_ALLOC,nulstr,83);
				for(i=0;i<j;i++)
					free(line[i]);
				return; 
			}
			sprintf(name,"%s #%d",user.alias,i);
			sprintf(line[j],text[UserListFmt],name
				,cfg.sys_misc&SM_LISTLOC ? user.location : user.note
				,unixtodstr(&cfg,user.laston,tmp)
				,user.modem); 
		}
		else {
			sprintf(name,"%s #%u",user.alias,i);
			bprintf(text[UserListFmt],name
				,cfg.sys_misc&SM_LISTLOC ? user.location : user.note
				,unixtodstr(&cfg,user.laston,tmp)
				,user.modem); 
		}
		j++; 
	}
	if(i<=k) {	/* aborted */
		if(sort)
			for(i=0;i<j;i++)
				free(line[i]);
		return; 
	}
	if(!sort) {
		CRLF; 
	}
	bprintf(text[NTotalUsers],users);
	if(mode==UL_SUB)
		bprintf(text[NUsersOnCurSub],j);
	else if(mode==UL_DIR)
		bprintf(text[NUsersOnCurDir],j);
	if(!sort)
		return;
	CRLF;
	qsort((void *)line,j,sizeof(line[0])
		,(int(*)(const void*, const void*))pstrcmp);
	for(i=0;i<j && !msgabort();i++)
		bputs(line[i]);
	for(i=0;i<j;i++)
		free(line[i]);
}