Example #1
0
bool sbbs_t::lookup_netuser(char *into)
{
	char to[128],name[26],str[256],q[128];
	int i;
	FILE *stream;

	if(strchr(into,'@'))
		return(false);
	strcpy(to,into);
	strupr(to);
	sprintf(str,"%sqnet/users.dat", cfg.data_dir);
	if((stream=fnopen(&i,str,O_RDONLY))==NULL)
		return(false);
	while(!feof(stream)) {
		if(!fgets(str,sizeof(str),stream))
			break;
		str[25]=0;
		truncsp(str);
		strcpy(name,str);
		strupr(name);
		str[35]=0;
		truncsp(str+27);
		sprintf(q,"Do you mean %s @%s",str,str+27);
		if(strstr(name,to) && yesno(q)) {
			fclose(stream);
			sprintf(into,"%s@%s",str,str+27);
			return(true); 
		}
		if(sys_status&SS_ABORT)
			break; 
	}
	fclose(stream);
	return(false);
}
Example #2
0
void sbbs_t::qwk_new_msg(smbmsg_t* msg, char* hdrblk, long offset, str_list_t all_headers, bool parse_sender_hfields)
{
	char str[128];
	char to[128];
	str_list_t	msg_headers;

	smb_freemsgmem(msg);

	sprintf(str,"%lx",offset);
	msg_headers=iniGetSection(all_headers,str);

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

	sprintf(to,"%25.25s",(char *)hdrblk+21);     /* To user */
	truncsp(to);

	if(msg_headers!=NULL)
		qwk_parse_header_list(msg, &msg_headers, parse_sender_hfields, stricmp(to,"NETMAIL")!=0);

	/* Parse the QWK message header: */
	if(msg->hdr.when_written.time==0) {
		struct		tm tm;
		memset(&tm,0,sizeof(tm));
		tm.tm_mon = ((hdrblk[8]&0xf)*10)+(hdrblk[9]&0xf);
		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);

		msg->hdr.when_written.time=(uint32_t)sane_mktime(&tm);
	}

	if(msg->to==NULL)
		smb_hfield_str(msg,RECIPIENT,to);

	if(parse_sender_hfields && msg->from==NULL) {
		sprintf(str,"%25.25s",hdrblk+46);  
		truncsp(str);
		smb_hfield_str(msg,SENDER,str);
	}

	if(msg->subj==NULL) {
		sprintf(str,"%25.25s",hdrblk+71);   /* Subject */
		truncsp(str);
		smb_hfield_str(msg,SUBJECT,str);
	}

	iniFreeStringList(msg_headers);
}
Example #3
0
str_list_t csvLineParser(const char* line)
{
	char*		p;
	char*		buf;
	char*		tmp;
	size_t		count=0;
	str_list_t	list;

	if((list=strListInit())==NULL)
		return(NULL);

	if((buf=strdup(line))==NULL) {
		strListFree(&list);
		return(NULL);
	}

	truncsp(buf);

	for(p=strtok_r(buf,",",&tmp);p;p=strtok_r(NULL,",",&tmp))
		strListAppend(&list,p,count++);

	free(buf);

	return(list);
}
Example #4
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 */
}
Example #5
0
BOOL DLLCALL findstr_in_string(const char* insearchof, char* string)
{
	char*	p;
	char	str[256];
	char	search[81];
	int		c;
	int		i;
	BOOL	found=FALSE;

	if(string==NULL || insearchof==NULL)
		return(FALSE);

	SAFECOPY(search,insearchof);
	strupr(search);
	SAFECOPY(str,string);

	p=str;	
	SKIP_WHITESPACE(p);

	if(*p==';')		/* comment */
		return(FALSE);

	if(*p=='!')	{	/* !match */
		found=TRUE;
		p++;
	}

	truncsp(p);
	c=strlen(p);
	if(c) {
		c--;
		strupr(p);
		if(p[c]=='~') {
			p[c]=0;
			if(strstr(search,p))
				found=!found; 
		}

		else if(p[c]=='^' || p[c]=='*') {
			p[c]=0;
			if(!strncmp(p,search,c))
				found=!found; 
		}

		else if(p[0]=='*') {
			i=strlen(search);
			if(i<c)
				return(found);
			if(!strncmp(p+1,search+(i-c),c))
				found=!found; 
		}

		else if(!strcmp(p,search))
			found=!found; 
	} 
	return(found);
}
Example #6
0
char *readline(long *offset, char *outstr, int maxlen, FILE *instream)
{
	char str[257];

	if(fgets(str,256,instream)==NULL)
		return(NULL);
	sprintf(outstr,"%.*s",maxlen,str);
	truncsp(outstr);
	(*offset)+=maxlen;
	return(outstr);
}
Example #7
0
void sbbs_t::center(char *instr)
{
	char str[256];
	int i,j;

	SAFECOPY(str,instr);
	truncsp(str);
	j=bstrlen(str);
	for(i=0;i<(cols-j)/2;i++)
		outchar(' ');
	bputs(str);
	CRLF;
}
Example #8
0
int lprintf(int level, char *fmat, ...)
{
	va_list argptr;
	char sbuf[512];
	int chcount;

	va_start(argptr,fmat);
	chcount=vsprintf(sbuf,fmat,argptr);
	va_end(argptr);
	truncsp(sbuf);
	printf("%s\n",sbuf);
	return(chcount);
}
Example #9
0
str_list_t DLLCALL getNameServerList(void)
{
#ifdef __unix__	/* Look up DNS server address */
	FILE*	fp;
	char*	p;
	char	str[128];
	str_list_t	list;

	if((list=strListInit())==NULL)
		return(NULL);
	if((fp=fopen("/etc/resolv.conf","r"))!=NULL) {
		while(!feof(fp)) {
			if(fgets(str,sizeof(str),fp)==NULL)
				break;
			truncsp(str);
			p=str;
			SKIP_WHITESPACE(p);
			if(strnicmp(p,"nameserver",10)!=0) /* no match */
				continue;
			FIND_WHITESPACE(p);	/* skip "nameserver" */
			SKIP_WHITESPACE(p);	/* skip more white-space */
			strListPush(&list,p);
		}
		fclose(fp);
	}
	return(list);

#elif defined(_WIN32)
	FIXED_INFO* FixedInfo=NULL;
	ULONG    	FixedInfoLen=0;
	IP_ADDR_STRING* ip;
	str_list_t	list;

	if((list=strListInit())==NULL)
		return(NULL);
	if(GetNetworkParams(FixedInfo,&FixedInfoLen) == ERROR_BUFFER_OVERFLOW) {
        FixedInfo=(FIXED_INFO*)malloc(FixedInfoLen);
		if(GetNetworkParams(FixedInfo,&FixedInfoLen) == ERROR_SUCCESS) {
			ip=&FixedInfo->DnsServerList;
			for(; ip!=NULL; ip=ip->Next)
				strListPush(&list,ip->IpAddress.String);
		}
        if(FixedInfo!=NULL)
            free(FixedInfo);
    }
	return(list);
#else
	#error "Need a get_nameserver() implementation for this platform"
#endif
}
Example #10
0
static char *binstr(uchar *buf, ushort length)
{
	static char str[512];
	int i;

	str[0]=0;
	for(i=0;i<length;i++)
		if(buf[i] && (buf[i]<' ' || buf[i]>=0x7f) 
			&& buf[i]!='\r' && buf[i]!='\n' && buf[i]!='\t')
			break;
	if(i==length)		/* not binary */
		return((char*)buf);
	for(i=0;i<length;i++) {
		sprintf(str+strlen(str),"%02X ",buf[i]);
		if(i>=100) {
			strcat(str,"...");
			break;
		}
	}
	truncsp(str);
	return(str);
}
Example #11
0
int main(int argc, char **argv)
{
	char	str[MAX_PATH+1];
	char	fname[MAX_PATH+1];
	char	ini_fname[MAX_PATH+1];
	char*	p;
	char*	arg;
	int 	i;
	int		retval;
	uint	fnames=0;
	FILE*	fp;
	BOOL	tcp_nodelay;
	char	compiler[32];
	str_list_t fname_list;

	fname_list=strListInit();

	DESCRIBE_COMPILER(compiler);

	errfp=stderr;
#ifdef __unix__
	statfp=stderr;
#else
	statfp=stdout;
#endif

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

	fprintf(statfp,"\nSynchronet External X/Y/Zmodem  v%s-%s"
		"  Copyright %s Rob Swindell\n\n"
		,revision
		,PLATFORM_DESC
		,__DATE__+7
		);

	xmodem_init(&xm,NULL,&mode,lputs,xmodem_progress,send_byte,recv_byte,is_connected,NULL);
	zmodem_init(&zm,NULL,lputs,zmodem_progress,send_byte,recv_byte,is_connected,NULL,data_waiting);

	/* Generate path/sexyz[.host].ini from path/sexyz[.exe] */
	SAFECOPY(str,argv[0]);
	p=getfname(str);
	SAFECOPY(fname,p);
	*p=0;
	if((p=getfext(fname))!=NULL) 
		*p=0;
	strcat(fname,".ini");
	
	iniFileName(ini_fname,sizeof(ini_fname),str,fname);
	if((fp=fopen(ini_fname,"r"))!=NULL)
		fprintf(statfp,"Reading %s\n",ini_fname);

	tcp_nodelay				=iniReadBool(fp,ROOT_SECTION,"TCP_NODELAY",TRUE);

	telnet					=iniReadBool(fp,ROOT_SECTION,"Telnet",TRUE);
	debug_tx				=iniReadBool(fp,ROOT_SECTION,"DebugTx",FALSE);
	debug_rx				=iniReadBool(fp,ROOT_SECTION,"DebugRx",FALSE);
	debug_telnet			=iniReadBool(fp,ROOT_SECTION,"DebugTelnet",FALSE);

	pause_on_exit			=iniReadBool(fp,ROOT_SECTION,"PauseOnExit",FALSE);
	pause_on_abend			=iniReadBool(fp,ROOT_SECTION,"PauseOnAbend",FALSE);

	log_level				=iniReadLogLevel(fp,ROOT_SECTION,"LogLevel",log_level);

	outbuf.highwater_mark	=iniReadInteger(fp,ROOT_SECTION,"OutbufHighwaterMark",1100);
	outbuf_drain_timeout	=iniReadInteger(fp,ROOT_SECTION,"OutbufDrainTimeout",10);
	outbuf_size				=iniReadInteger(fp,ROOT_SECTION,"OutbufSize",16*1024);

	progress_interval		=iniReadInteger(fp,ROOT_SECTION,"ProgressInterval",1);

	if(iniReadBool(fp,ROOT_SECTION,"Debug",FALSE))
		log_level=LOG_DEBUG;

	xm.send_timeout			=iniReadInteger(fp,"Xmodem","SendTimeout",xm.send_timeout);	/* seconds */
	xm.recv_timeout			=iniReadInteger(fp,"Xmodem","RecvTimeout",xm.recv_timeout);	/* seconds */
	xm.byte_timeout			=iniReadInteger(fp,"Xmodem","ByteTimeout",xm.byte_timeout);	/* seconds */
	xm.ack_timeout			=iniReadInteger(fp,"Xmodem","AckTimeout",xm.ack_timeout);	/* seconds */
	xm.block_size			=iniReadInteger(fp,"Xmodem","BlockSize",xm.block_size);		/* 128 or 1024 */
	xm.max_errors			=iniReadInteger(fp,"Xmodem","MaxErrors",xm.max_errors);
	xm.g_delay				=iniReadInteger(fp,"Xmodem","G_Delay",xm.g_delay);

	zm.init_timeout			=iniReadInteger(fp,"Zmodem","InitTimeout",zm.init_timeout);	/* seconds */
	zm.send_timeout			=iniReadInteger(fp,"Zmodem","SendTimeout",zm.send_timeout);	/* seconds */
	zm.recv_timeout			=iniReadInteger(fp,"Zmodem","RecvTimeout",zm.recv_timeout);	/* seconds */
	zm.crc_timeout			=iniReadInteger(fp,"Zmodem","CrcTimeout",zm.crc_timeout);	/* seconds */
	zm.block_size			=iniReadInteger(fp,"Zmodem","BlockSize",zm.block_size);			/* 1024  */
	zm.max_block_size		=iniReadInteger(fp,"Zmodem","MaxBlockSize",zm.max_block_size);	/* 1024 or 8192 */
	zm.max_errors			=iniReadInteger(fp,"Zmodem","MaxErrors",zm.max_errors);
	zm.recv_bufsize			=iniReadInteger(fp,"Zmodem","RecvBufSize",0);
	zm.no_streaming			=!iniReadBool(fp,"Zmodem","Streaming",TRUE);
	zm.want_fcs_16			=!iniReadBool(fp,"Zmodem","CRC32",TRUE);
	zm.escape_telnet_iac	=iniReadBool(fp,"Zmodem","EscapeTelnetIAC",TRUE);
	zm.escape_8th_bit		=iniReadBool(fp,"Zmodem","Escape8thBit",FALSE);
	zm.escape_ctrl_chars	=iniReadBool(fp,"Zmodem","EscapeCtrlChars",FALSE);

	dszlog_path				=iniReadBool(fp,"DSZLOG","Path",TRUE);
	dszlog_short			=iniReadBool(fp,"DSZLOG","Short",FALSE);
	dszlog_quotes			=iniReadBool(fp,"DSZLOG","Quotes",FALSE);

	if(fp!=NULL)
		fclose(fp);

	if(zm.recv_bufsize > 0xffff)
		zm.recv_bufsize = 0xffff;

	if(outbuf_size < MIN_OUTBUF_SIZE)
		outbuf_size = MIN_OUTBUF_SIZE;
	else if(outbuf_size > MAX_OUTBUF_SIZE)
		outbuf_size = MAX_OUTBUF_SIZE;
	
	fprintf(statfp,"Output buffer size: %u\n", outbuf_size);
	RingBufInit(&outbuf, outbuf_size);

#if !defined(RINGBUF_EVENT)
	outbuf_empty=CreateEvent(NULL,/* ManualReset */TRUE, /*InitialState */TRUE,NULL);
#endif

#if 0
	if(argc>1) {
		fprintf(statfp,"Command line: ");
		for(i=1;i<argc;i++)
			fprintf(statfp,"%s ",argv[i]);
		fprintf(statfp,"\n",statfp);
	}
#endif


	for(i=1;i<argc;i++) {

		if(sock==INVALID_SOCKET && isdigit(argv[i][0])) {
			sock=atoi(argv[i]);
			continue;
		}

		if(!(mode&(SEND|RECV))) {
			if(toupper(argv[i][0])=='S' || toupper(argv[i][0])=='R') { /* cmd */
				if(toupper(argv[i][0])=='R')
					mode|=RECV;
				else
					mode|=SEND;

				switch(argv[i][1]) {
					case 'c':
					case 'C':
						mode|=XMODEM|CRC;
						break;
					case 'x':
						xm.block_size=128;
					case 'X':
						mode|=XMODEM;
						break;
					case 'b':	/* sz/rz compatible */
					case 'B':
					case 'y':
						xm.block_size=128;
					case 'Y':
						mode|=(YMODEM|CRC);
						break;
					case 'g':
					case 'G':
						mode|=(YMODEM|CRC|GMODE);
						break;
					case 'z':
					case 'Z':
						mode|=(ZMODEM|CRC);
						break;
					default:
						fprintf(statfp,"Unrecognized command '%s'\n\n",argv[i]);
						fprintf(statfp,usage);
						bail(1); 
				} 
				continue;
			}

			if(toupper(argv[i][0])=='V') {

				fprintf(statfp,"%-8s %s\n",getfname(__FILE__)		,revision);
				fprintf(statfp,"%-8s %s\n",getfname(xmodem_source()),xmodem_ver(str));
				fprintf(statfp,"%-8s %s\n",getfname(zmodem_source()),zmodem_ver(str));
#ifdef _DEBUG
				fprintf(statfp,"Debug\n");
#endif
				fprintf(statfp,"Compiled %s %.5s with %s\n",__DATE__,__TIME__,compiler);
				fprintf(statfp,"%s\n",os_version(str));
				bail(0);
			}

			arg=argv[i];
			if(*arg=='-') {
				while(*arg=='-')
					arg++;
				if(stricmp(arg,"telnet")==0) {
					telnet=TRUE;
					continue;
				}
				if(stricmp(arg,"rlogin")==0 || stricmp(arg,"ssh")==0 || stricmp(arg,"raw")==0) {
					telnet=FALSE;
					continue;
				}
				if(stricmp(arg,"debug")==0) {
					log_level=LOG_DEBUG;
					continue;
				}
				if(stricmp(arg,"quotes")==0) {
					dszlog_quotes=TRUE;
					continue;
				}
				switch(toupper(*arg)) {
					case 'K':	/* sz/rz compatible */
						xm.block_size=1024;
						break;
					case 'C':	/* sz/rz compatible */
						mode|=CRC;
						break;
					case '2':
						zm.max_block_size=2048;
						break;
					case '4':
						zm.max_block_size=4096;
						break;
					case '8':	/* ZedZap */
						zm.max_block_size=8192;
						break;
					case 'O':	/* disable Zmodem CRC-32 */
						zm.want_fcs_16=TRUE;
						break;
					case 'S':	/* disable Zmodem streaming */
						zm.no_streaming=TRUE;
						break;
					case 'G':	/* Ymodem-G */
						mode|=GMODE;
						break;
					case 'Y':
						mode|=OVERWRITE;
						break;
					case '!':
						pause_on_abend=TRUE;
						break;
				}
			}
		}

		else if((argv[i][0]=='+' || argv[i][0]=='@') && fexist(argv[i]+1)) {
			if(mode&RECVDIR) {
				fprintf(statfp,"!Cannot specify both directory and filename\n");
				bail(1); 
			}
			sprintf(str,"%s",argv[i]+1);
			if((fp=fopen(str,"r"))==NULL) {
				fprintf(statfp,"!Error %d opening filelist: %s\n",errno,str);
				bail(1); 
			}
			while(!feof(fp) && !ferror(fp)) {
				if(!fgets(str,sizeof(str),fp))
					break;
				truncsp(str);
				strListAppend(&fname_list,strdup(str),fnames++);
			}
			fclose(fp); 
		}

		else if(mode&(SEND|RECV)){
			if(isdir(argv[i])) { /* is a directory */
				if(mode&RECVDIR) {
					fprintf(statfp,"!Only one directory can be specified\n");
					bail(1); 
				}
				if(fnames) {
					fprintf(statfp,"!Cannot specify both directory and filename\n");
					bail(1); 
				}
				if(mode&SEND) {
					fprintf(statfp,"!Cannot send directory '%s'\n",argv[i]);
					bail(1);
				}
				mode|=RECVDIR; 
			}
			strListAppend(&fname_list,argv[i],fnames++);
		} 
	}

	if(!telnet)
		zm.escape_telnet_iac = FALSE;

	if(sock==INVALID_SOCKET || sock<1) {
#ifdef __unix__
		if(STDOUT_FILENO > STDIN_FILENO)
			sock=STDOUT_FILENO;
		else
			sock=STDIN_FILENO;
		stdio=TRUE;
		
		fprintf(statfp,"No socket descriptor specified, using STDIO\n");
		telnet=FALSE;
#else
		fprintf(statfp,"!No socket descriptor specified\n\n");
		fprintf(errfp,usage);
		bail(1);
#endif
	}
#ifdef __unix__
	else
		statfp=stdout;
#endif

	if(!(mode&(SEND|RECV))) {
		fprintf(statfp,"!No command specified\n\n");
		fprintf(statfp,usage);
		bail(1); 
	}

	if(mode&(SEND|XMODEM) && !fnames) { /* Sending with any or recv w/Xmodem */
		fprintf(statfp,"!Must specify filename or filelist\n\n");
		fprintf(statfp,usage);
		bail(1); 
	}

#ifdef __unix__
	if(stdio) {
		struct termios term;
		memset(&term,0,sizeof(term));
		cfsetispeed(&term,B19200);
		cfsetospeed(&term,B19200);
		term.c_iflag &= ~(IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
		term.c_oflag &= ~OPOST;
		term.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
		term.c_cflag &= ~(CSIZE|PARENB);
		term.c_cflag |= CS8;
		atexit(resetterm);
		tcgetattr(STDOUT_FILENO, &origterm);
		tcsetattr(STDOUT_FILENO, TCSADRAIN, &term);
	}
#endif

	/* Code disabled.  Why?  ToDo */
/*	if(mode&RECVDIR)
		backslash(fname[0]); */

	if(!winsock_startup())
		bail(-1);

	/* Enable the Nagle Algorithm */
#ifdef __unix__
	if(!stdio) {
#endif
		lprintf(LOG_DEBUG,"Setting TCP_NODELAY to %d",tcp_nodelay);
		setsockopt(sock,IPPROTO_TCP,TCP_NODELAY,(char*)&tcp_nodelay,sizeof(tcp_nodelay));
#ifdef __unix__
	}
#endif

	if(!socket_check(sock, NULL, NULL, 0)) {
		lprintf(LOG_WARNING,"No socket connection");
		bail(-1); 
	}

	if((dszlog=getenv("DSZLOG"))!=NULL) {
		if((logfp=fopen(dszlog,"w"))==NULL) {
			lprintf(LOG_WARNING,"Error %d opening DSZLOG file: %s",errno,dszlog);
			bail(-1); 
		}
	}

	/* Install Ctrl-C/Break signal handler here */
#if defined(_WIN32)
	SetConsoleCtrlHandler(ControlHandler, TRUE /* Add */);
#elif defined(__unix__)
	signal(SIGQUIT,break_handler);
	signal(SIGINT,break_handler);
	signal(SIGTERM,break_handler);

	signal(SIGHUP,SIG_IGN);

	/* Don't die on SIGPIPE  */
	signal(SIGPIPE,SIG_IGN);
#endif

#if !SINGLE_THREADED
	_beginthread(output_thread,0,NULL);
#endif

	if(mode&RECV)
		retval=receive_files(fname_list, fnames);
	else
		retval=send_files(fname_list, fnames);

#if !SINGLE_THREADED
	lprintf(LOG_DEBUG,"Waiting for output buffer to empty... ");
	if(WaitForEvent(outbuf_empty,5000)!=WAIT_OBJECT_0)
		lprintf(LOG_DEBUG,"FAILURE");
#endif

	terminate=TRUE;	/* stop output thread */
	/* Code disabled.  Why?  ToDo */
/*	sem_post(outbuf.sem);
	sem_post(outbuf.highwater_sem); */

	fprintf(statfp,"Exiting - Error level: %d, flows: %u, select_errors=%u"
		,retval, flows, select_errors);
	fprintf(statfp,"\n");

	bail(retval);
}
Example #12
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);
}
Example #13
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);
}
Example #14
0
void sbbs_t::qwktonetmail(FILE *rep, char *block, char *into, uchar fromhub)
{
	char	*qwkbuf,to[129],name[129],sender[129],senderaddr[129]
			   ,str[256],*p,*cp,*addr,fulladdr[129],ch;
	char 	tmp[512];
	int 	i,fido,inet=0,qnet=0;
	ushort	net;
	uint16_t xlat;
	long	l,offset,length,m,n;
	faddr_t fidoaddr;
    fmsghdr_t hdr;
	smbmsg_t msg;
	struct	tm tm;

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

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

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

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

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

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

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


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


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

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

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

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

	if(qnet || inet) {

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

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

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

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

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

	if(qnet) {

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

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

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

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

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

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

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

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

	if(qnet || inet) {

		bputs(text[WritingIndx]);

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

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

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


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

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

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

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

		msg.hdr.offset=offset;

		smb_dfield(&msg,TEXT_BODY,length);

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

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

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

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

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


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

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

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

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

	SAFECOPY(hdr.to,to);

	/* Look-up in nodelist? */

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

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

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

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

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

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

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

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

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

	SAFECOPY(hdr.subj,p);

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

	pt_zone_kludge(hdr,fido);

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

	l=QWK_BLOCK_LEN;

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

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

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

	sprintf(str,"%s sent NetMail to %s @%s via QWK"
		,useron.alias
		,hdr.to,smb_faddrtoa(&fidoaddr,tmp));
	logline("EN",str);
}
Example #15
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);
}
Example #16
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);
}
Example #17
0
const char* sbbs_t::atcode(char* sp, char* str, size_t maxlen)
{
	char*	tp;
	uint	i;
	uint	ugrp;
	uint	usub;
	long	l;
    stats_t stats;
    node_t  node;
	struct	tm tm;

	str[0]=0;

	if(!strcmp(sp,"VER"))
		return(VERSION);

	if(!strcmp(sp,"REV")) {
		safe_snprintf(str,maxlen,"%c",REVISION);
		return(str);
	}

	if(!strcmp(sp,"FULL_VER")) {
		safe_snprintf(str,maxlen,"%s%c%s",VERSION,REVISION,beta_version);
		truncsp(str);
#if defined(_DEBUG)
		strcat(str," Debug");
#endif
		return(str);
	}

	if(!strcmp(sp,"VER_NOTICE"))
		return(VERSION_NOTICE);

	if(!strcmp(sp,"OS_VER"))
		return(os_version(str));

#ifdef JAVASCRIPT
	if(!strcmp(sp,"JS_VER"))
		return((char *)JS_GetImplementationVersion());
#endif

	if(!strcmp(sp,"PLATFORM"))
		return(PLATFORM_DESC);

	if(!strcmp(sp,"COPYRIGHT"))
		return(COPYRIGHT_NOTICE);

	if(!strcmp(sp,"COMPILER")) {
		DESCRIBE_COMPILER(str);
		return(str);
	}

	if(!strcmp(sp,"UPTIME")) {
		extern volatile time_t uptime;
		time_t up=time(NULL)-uptime;
		if(up<0)
			up=0;
		char   days[64]="";
		if((up/(24*60*60))>=2) {
	        sprintf(days,"%lu days ",(ulong)(up/(24L*60L*60L)));
			up%=(24*60*60);
		}
		safe_snprintf(str,maxlen,"%s%lu:%02lu"
	        ,days
			,(ulong)(up/(60L*60L))
			,(ulong)((up/60L)%60L)
			);
		return(str);
	}

	if(!strcmp(sp,"SERVED")) {
		extern volatile ulong served;
		safe_snprintf(str,maxlen,"%lu",served);
		return(str);
	}

	if(!strcmp(sp,"SOCKET_LIB"))
		return(socklib_version(str,SOCKLIB_DESC));

	if(!strcmp(sp,"MSG_LIB")) {
		safe_snprintf(str,maxlen,"SMBLIB %s",smb_lib_ver());
		return(str);
	}

	if(!strcmp(sp,"BBS") || !strcmp(sp,"BOARDNAME"))
		return(cfg.sys_name);

	if(!strcmp(sp,"BAUD") || !strcmp(sp,"BPS")) {
		safe_snprintf(str,maxlen,"%lu",cur_rate);
		return(str);
	}

	if(!strcmp(sp,"CONN"))
		return(connection);

	if(!strcmp(sp,"SYSOP"))
		return(cfg.sys_op);

	if(!strcmp(sp,"LOCATION"))
		return(cfg.sys_location);

	if(!strcmp(sp,"NODE")) {
		safe_snprintf(str,maxlen,"%u",cfg.node_num);
		return(str);
	}

	if(!strcmp(sp,"TNODE")) {
		safe_snprintf(str,maxlen,"%u",cfg.sys_nodes);
		return(str);
	}

	if(!strcmp(sp,"INETADDR"))
		return(cfg.sys_inetaddr);

	if(!strcmp(sp,"HOSTNAME"))
		return(startup->host_name);

	if(!strcmp(sp,"FIDOADDR")) {
		if(cfg.total_faddrs)
			return(smb_faddrtoa(&cfg.faddr[0],str));
		return(nulstr);
	}

	if(!strcmp(sp,"EMAILADDR"))
		return(usermailaddr(&cfg, str
			,cfg.inetmail_misc&NMAIL_ALIAS ? useron.alias : useron.name));

	if(!strcmp(sp,"QWKID"))
		return(cfg.sys_id);

	if(!strcmp(sp,"TIME") || !strcmp(sp,"SYSTIME")) {
		now=time(NULL);
		memset(&tm,0,sizeof(tm));
		localtime_r(&now,&tm);
		if(cfg.sys_misc&SM_MILITARY)
			safe_snprintf(str,maxlen,"%02d:%02d:%02d"
		        	,tm.tm_hour,tm.tm_min,tm.tm_sec);
		else
			safe_snprintf(str,maxlen,"%02d:%02d %s"
				,tm.tm_hour==0 ? 12
				: tm.tm_hour>12 ? tm.tm_hour-12
				: tm.tm_hour, tm.tm_min, tm.tm_hour>11 ? "pm":"am");
		return(str);
	}

	if(!strcmp(sp,"TIMEZONE"))
		return(smb_zonestr(sys_timezone(&cfg),str));

	if(!strcmp(sp,"DATE") || !strcmp(sp,"SYSDATE")) {
		return(unixtodstr(&cfg,time32(NULL),str));
	}

	if(!strcmp(sp,"DATETIME"))
		return(timestr(time(NULL)));

	if(!strcmp(sp,"TMSG")) {
		l=0;
		for(i=0;i<cfg.total_subs;i++)
			l+=getposts(&cfg,i); 		/* l=total posts */
		safe_snprintf(str,maxlen,"%lu",l);
		return(str);
	}

	if(!strcmp(sp,"TUSER")) {
		safe_snprintf(str,maxlen,"%u",total_users(&cfg));
		return(str);
	}

	if(!strcmp(sp,"TFILE")) {
		l=0;
		for(i=0;i<cfg.total_dirs;i++)
			l+=getfiles(&cfg,i);
		safe_snprintf(str,maxlen,"%lu",l);
		return(str);
	}

	if(!strcmp(sp,"TCALLS") || !strcmp(sp,"NUMCALLS")) {
		getstats(&cfg,0,&stats);
		safe_snprintf(str,maxlen,"%lu",stats.logons);
		return(str);
	}

	if(!strcmp(sp,"PREVON") || !strcmp(sp,"LASTCALLERNODE")
		|| !strcmp(sp,"LASTCALLERSYSTEM"))
		return(lastuseron);

	if(!strcmp(sp,"CLS")) {
		CLS;
		return(nulstr);
	}

	if(!strcmp(sp,"PAUSE") || !strcmp(sp,"MORE")) {
		pause();
		return(nulstr);
	}

	if(!strcmp(sp,"RESETPAUSE")) {
		lncntr=0;
		return(nulstr);
	}

	if(!strcmp(sp,"NOPAUSE") || !strcmp(sp,"POFF")) {
		sys_status^=SS_PAUSEOFF;
		return(nulstr);
	}

	if(!strcmp(sp,"PON") || !strcmp(sp,"AUTOMORE")) {
		sys_status^=SS_PAUSEON;
		return(nulstr);
	}

	/* NOSTOP */

	/* STOP */

	if(!strcmp(sp,"BELL") || !strcmp(sp,"BEEP"))
		return("\a");

	if(!strcmp(sp,"EVENT")) {
		if(event_time==0)
			return("<none>");
		return(timestr(event_time));
	}

	/* LASTCALL */

	if(!strncmp(sp,"NODE",4)) {
		i=atoi(sp+4);
		if(i && i<=cfg.sys_nodes) {
			getnodedat(i,&node,0);
			printnodedat(i,&node);
		}
		return(nulstr);
	}

	if(!strcmp(sp,"WHO")) {
		whos_online(true);
		return(nulstr);
	}

	/* User Codes */

	if(!strcmp(sp,"USER") || !strcmp(sp,"ALIAS") || !strcmp(sp,"NAME"))
		return(useron.alias);

	if(!strcmp(sp,"FIRST")) {
		safe_snprintf(str,maxlen,"%s",useron.alias);
		tp=strchr(str,' ');
		if(tp) *tp=0;
		return(str);
	}

	if(!strcmp(sp,"USERNUM")) {
		safe_snprintf(str,maxlen,"%u",useron.number);
		return(str);
	}

	if(!strcmp(sp,"PHONE") || !strcmp(sp,"HOMEPHONE")
		|| !strcmp(sp,"DATAPHONE") || !strcmp(sp,"DATA"))
		return(useron.phone);

	if(!strcmp(sp,"ADDR1"))
		return(useron.address);

	if(!strcmp(sp,"FROM"))
		return(useron.location);

	if(!strcmp(sp,"CITY")) {
		safe_snprintf(str,maxlen,"%s",useron.location);
		char* p=strchr(str,',');
		if(p) {
			*p=0;
			return(str);
		}
		return(nulstr);
	}

	if(!strcmp(sp,"STATE")) {
		char* p=strchr(useron.location,',');
		if(p) {
			p++;
			if(*p==' ')
				p++;
			return(p);
		}
		return(nulstr);
	}

	if(!strcmp(sp,"CPU"))
		return(useron.comp);

	if(!strcmp(sp,"HOST"))
		return(client_name);

	if(!strcmp(sp,"BDATE"))
		return(useron.birth);

	if(!strcmp(sp,"AGE")) {
		safe_snprintf(str,maxlen,"%u",getage(&cfg,useron.birth));
		return(str);
	}

	if(!strcmp(sp,"CALLS") || !strcmp(sp,"NUMTIMESON")) {
		safe_snprintf(str,maxlen,"%u",useron.logons);
		return(str);
	}

	if(!strcmp(sp,"MEMO"))
		return(unixtodstr(&cfg,useron.pwmod,str));

	if(!strcmp(sp,"SEC") || !strcmp(sp,"SECURITY")) {
		safe_snprintf(str,maxlen,"%u",useron.level);
		return(str);
	}

	if(!strcmp(sp,"SINCE"))
		return(unixtodstr(&cfg,useron.firston,str));

	if(!strcmp(sp,"TIMEON") || !strcmp(sp,"TIMEUSED")) {
		now=time(NULL);
		safe_snprintf(str,maxlen,"%lu",(ulong)(now-logontime)/60L);
		return(str);
	}

	if(!strcmp(sp,"TUSED")) {              /* Synchronet only */
		now=time(NULL);
		return(sectostr((uint)(now-logontime),str)+1);
	}

	if(!strcmp(sp,"TLEFT")) {              /* Synchronet only */
		gettimeleft();
		return(sectostr(timeleft,str)+1);
	}

	if(!strcmp(sp,"TPERD"))                /* Synchronet only */
		return(sectostr(cfg.level_timeperday[useron.level],str)+1);

	if(!strcmp(sp,"TPERC"))                /* Synchronet only */
		return(sectostr(cfg.level_timepercall[useron.level],str)+1);

	if(!strcmp(sp,"TIMELIMIT")) {
		safe_snprintf(str,maxlen,"%u",cfg.level_timepercall[useron.level]);
		return(str);
	}

	if(!strcmp(sp,"MINLEFT") || !strcmp(sp,"LEFT") || !strcmp(sp,"TIMELEFT")) {
		gettimeleft();
		safe_snprintf(str,maxlen,"%lu",timeleft/60);
		return(str);
	}

	if(!strcmp(sp,"LASTON"))
		return(timestr(useron.laston));

	if(!strcmp(sp,"LASTDATEON"))
		return(unixtodstr(&cfg,useron.laston,str));

	if(!strcmp(sp,"LASTTIMEON")) {
		memset(&tm,0,sizeof(tm));
		localtime32(&useron.laston,&tm);
		if(cfg.sys_misc&SM_MILITARY)
			safe_snprintf(str,maxlen,"%02d:%02d:%02d"
				,tm.tm_hour, tm.tm_min, tm.tm_sec);
		else
			safe_snprintf(str,maxlen,"%02d:%02d %s"
				,tm.tm_hour==0 ? 12
				: tm.tm_hour>12 ? tm.tm_hour-12
				: tm.tm_hour, tm.tm_min, tm.tm_hour>11 ? "pm":"am");
		return(str);
	}

	if(!strcmp(sp,"MSGLEFT") || !strcmp(sp,"MSGSLEFT")) {
		safe_snprintf(str,maxlen,"%u",useron.posts);
		return(str);
	}

	if(!strcmp(sp,"MSGREAD")) {
		safe_snprintf(str,maxlen,"%lu",posts_read);
		return(str);
	}

	if(!strcmp(sp,"FREESPACE")) {
		safe_snprintf(str,maxlen,"%lu",getfreediskspace(cfg.temp_dir,0));
		return(str);
	}

	if(!strcmp(sp,"FREESPACEK")) {
		safe_snprintf(str,maxlen,"%lu",getfreediskspace(cfg.temp_dir,1024));
		return(str);
	}

	if(!strcmp(sp,"UPBYTES")) {
		safe_snprintf(str,maxlen,"%lu",useron.ulb);
		return(str);
	}

	if(!strcmp(sp,"UPK")) {
		safe_snprintf(str,maxlen,"%lu",useron.ulb/1024L);
		return(str);
	}

	if(!strcmp(sp,"UPS") || !strcmp(sp,"UPFILES")) {
		safe_snprintf(str,maxlen,"%u",useron.uls);
		return(str);
	}

	if(!strcmp(sp,"DLBYTES")) {
		safe_snprintf(str,maxlen,"%lu",useron.dlb);
		return(str);
	}

	if(!strcmp(sp,"DOWNK")) {
		safe_snprintf(str,maxlen,"%lu",useron.dlb/1024L);
		return(str);
	}

	if(!strcmp(sp,"DOWNS") || !strcmp(sp,"DLFILES")) {
		safe_snprintf(str,maxlen,"%u",useron.dls);
		return(str);
	}

	if(!strcmp(sp,"LASTNEW"))
		return(unixtodstr(&cfg,(time32_t)ns_time,str));

	if(!strcmp(sp,"NEWFILETIME"))
		return(timestr(ns_time));

	/* MAXDL */

	if(!strcmp(sp,"MAXDK") || !strcmp(sp,"DLKLIMIT") || !strcmp(sp,"KBLIMIT")) {
		safe_snprintf(str,maxlen,"%lu",cfg.level_freecdtperday[useron.level]/1024L);
		return(str);
	}

	if(!strcmp(sp,"DAYBYTES")) {    /* amt of free cdts used today */
		safe_snprintf(str,maxlen,"%lu",cfg.level_freecdtperday[useron.level]-useron.freecdt);
		return(str);
	}

	if(!strcmp(sp,"BYTELIMIT")) {
		safe_snprintf(str,maxlen,"%lu",cfg.level_freecdtperday[useron.level]);
		return(str);
	}

	if(!strcmp(sp,"KBLEFT")) {
		safe_snprintf(str,maxlen,"%lu",(useron.cdt+useron.freecdt)/1024L);
		return(str);
	}

	if(!strcmp(sp,"BYTESLEFT")) {
		safe_snprintf(str,maxlen,"%lu",useron.cdt+useron.freecdt);
		return(str);
	}

	if(!strcmp(sp,"CONF")) {
		safe_snprintf(str,maxlen,"%s %s"
			,usrgrps ? cfg.grp[usrgrp[curgrp]]->sname :nulstr
			,usrgrps ? cfg.sub[usrsub[curgrp][cursub[curgrp]]]->sname : nulstr);
		return(str);
	}

	if(!strcmp(sp,"CONFNUM")) {
		safe_snprintf(str,maxlen,"%u %u",curgrp+1,cursub[curgrp]+1);
		return(str);
	}

	if(!strcmp(sp,"NUMDIR")) {
		safe_snprintf(str,maxlen,"%u %u",usrlibs ? curlib+1 : 0,usrlibs ? curdir[curlib]+1 : 0);
		return(str);
	}

	if(!strcmp(sp,"EXDATE") || !strcmp(sp,"EXPDATE"))
		return(unixtodstr(&cfg,useron.expire,str));

	if(!strcmp(sp,"EXPDAYS")) {
		now=time(NULL);
		l=(long)(useron.expire-now);
		if(l<0)
			l=0;
		safe_snprintf(str,maxlen,"%lu",l/(1440L*60L));
		return(str);
	}

	if(!strcmp(sp,"MEMO1"))
		return(useron.note);

	if(!strcmp(sp,"MEMO2") || !strcmp(sp,"COMPANY"))
		return(useron.name);

	if(!strcmp(sp,"ZIP"))
		return(useron.zipcode);

	if(!strcmp(sp,"HANGUP")) {
		hangup();
		return(nulstr);
	}

	/* Synchronet Specific */

	if(!strncmp(sp,"SETSTR:",7)) {
		strcpy(main_csi.str,sp+7);
		return(nulstr);
	}

	if(!strncmp(sp,"EXEC:",5)) {
		exec_bin(sp+5,&main_csi);
		return(nulstr);
	}

	if(!strncmp(sp,"EXEC_XTRN:",10)) {
		for(i=0;i<cfg.total_xtrns;i++)
			if(!stricmp(cfg.xtrn[i]->code,sp+10))
				break;
		if(i<cfg.total_xtrns)
			exec_xtrn(i);
		return(nulstr);
	}

	if(!strncmp(sp,"MENU:",5)) {
		menu(sp+5);
		return(nulstr);
	}

	if(!strncmp(sp,"TYPE:",5)) {
		printfile(cmdstr(sp+5,nulstr,nulstr,str),0);
		return(nulstr);
	}

	if(!strncmp(sp,"INCLUDE:",8)) {
		printfile(cmdstr(sp+8,nulstr,nulstr,str),P_NOCRLF|P_SAVEATR);
		return(nulstr);
	}

	if(!strcmp(sp,"QUESTION"))
		return(question);

	if(!strcmp(sp,"HANDLE"))
		return(useron.handle);

	if(!strcmp(sp,"CID") || !strcmp(sp,"IP"))
		return(cid);

	if(!strcmp(sp,"LOCAL-IP"))
		return(local_addr);

	if(!strcmp(sp,"CRLF"))
		return("\r\n");

	if(!strcmp(sp,"PUSHXY")) {
		ansi_save();
		return(nulstr);
	}

	if(!strcmp(sp,"POPXY")) {
		ansi_restore();
		return(nulstr);
	}

	if(!strncmp(sp,"UP:",3)) {
		cursor_up(atoi(sp+3));
		return(str);
	}

	if(!strncmp(sp,"DOWN:",5)) {
		cursor_down(atoi(sp+5));
		return(str);
	}

	if(!strncmp(sp,"LEFT:",5)) {
		cursor_left(atoi(sp+5));
		return(str);
	}

	if(!strncmp(sp,"RIGHT:",6)) {
		cursor_right(atoi(sp+6));
		return(str);
	}

	if(!strncmp(sp,"GOTOXY:",7)) {
		tp=strchr(sp,',');
		if(tp!=NULL) {
			tp++;
			ansi_gotoxy(atoi(sp+7),atoi(tp));
		}
		return(nulstr);
	}

	if(!strcmp(sp,"GRP")) {
		if(SMB_IS_OPEN(&smb)) {
			if(smb.subnum==INVALID_SUB)
				return("Local");
			if(smb.subnum<cfg.total_subs)
				return(cfg.grp[cfg.sub[smb.subnum]->grp]->sname);
		}
		return(usrgrps ? cfg.grp[usrgrp[curgrp]]->sname : nulstr);
	}

	if(!strcmp(sp,"GRPL")) {
		if(SMB_IS_OPEN(&smb)) {
			if(smb.subnum==INVALID_SUB)
				return("Local");
			if(smb.subnum<cfg.total_subs)
				return(cfg.grp[cfg.sub[smb.subnum]->grp]->lname);
		}
		return(usrgrps ? cfg.grp[usrgrp[curgrp]]->lname : nulstr);
	}

	if(!strcmp(sp,"GN")) {
		if(SMB_IS_OPEN(&smb))
			ugrp=getusrgrp(smb.subnum);
		else
			ugrp=usrgrps ? curgrp+1 : 0;
		safe_snprintf(str,maxlen,"%u",ugrp);
		return(str);
	}

	if(!strcmp(sp,"GL")) {
		if(SMB_IS_OPEN(&smb))
			ugrp=getusrgrp(smb.subnum);
		else
			ugrp=usrgrps ? curgrp+1 : 0;
		safe_snprintf(str,maxlen,"%-4u",ugrp);
		return(str);
	}

	if(!strcmp(sp,"GR")) {
		if(SMB_IS_OPEN(&smb))
			ugrp=getusrgrp(smb.subnum);
		else
			ugrp=usrgrps ? curgrp+1 : 0;
		safe_snprintf(str,maxlen,"%4u",ugrp);
		return(str);
	}

	if(!strcmp(sp,"SUB")) {
		if(SMB_IS_OPEN(&smb)) {
			if(smb.subnum==INVALID_SUB)
				return("Mail");
			else if(smb.subnum<cfg.total_subs)
				return(cfg.sub[smb.subnum]->sname);
		}
		return(usrgrps ? cfg.sub[usrsub[curgrp][cursub[curgrp]]]->sname : nulstr);
	}

	if(!strcmp(sp,"SUBL")) {
		if(SMB_IS_OPEN(&smb)) {
			if(smb.subnum==INVALID_SUB)
				return("Mail");
			else if(smb.subnum<cfg.total_subs)
				return(cfg.sub[smb.subnum]->lname);
		}
		return(usrgrps  ? cfg.sub[usrsub[curgrp][cursub[curgrp]]]->lname : nulstr);
	}

	if(!strcmp(sp,"SN")) {
		if(SMB_IS_OPEN(&smb))
			usub=getusrsub(smb.subnum);
		else
			usub=usrgrps ? cursub[curgrp]+1 : 0;
		safe_snprintf(str,maxlen,"%u",usub);
		return(str);
	}

	if(!strcmp(sp,"SL")) {
		if(SMB_IS_OPEN(&smb))
			usub=getusrsub(smb.subnum);
		else
			usub=usrgrps ? cursub[curgrp]+1 : 0;
		safe_snprintf(str,maxlen,"%-4u",usub);
		return(str);
	}

	if(!strcmp(sp,"SR")) {
		if(SMB_IS_OPEN(&smb))
			usub=getusrsub(smb.subnum);
		else
			usub=usrgrps ? cursub[curgrp]+1 : 0;
		safe_snprintf(str,maxlen,"%4u",usub);
		return(str);
	}

	if(!strcmp(sp,"LIB"))
		return(usrlibs ? cfg.lib[usrlib[curlib]]->sname : nulstr);

	if(!strcmp(sp,"LIBL"))
		return(usrlibs ? cfg.lib[usrlib[curlib]]->lname : nulstr);

	if(!strcmp(sp,"LN")) {
		safe_snprintf(str,maxlen,"%u",usrlibs ? curlib+1 : 0);
		return(str);
	}

	if(!strcmp(sp,"LL")) {
		safe_snprintf(str,maxlen,"%-4u",usrlibs ? curlib+1 : 0);
		return(str);
	}

	if(!strcmp(sp,"LR")) {
		safe_snprintf(str,maxlen,"%4u",usrlibs  ? curlib+1 : 0);
		return(str);
	}

	if(!strcmp(sp,"DIR"))
		return(usrlibs ? cfg.dir[usrdir[curlib][curdir[curlib]]]->sname :nulstr);

	if(!strcmp(sp,"DIRL"))
		return(usrlibs ? cfg.dir[usrdir[curlib][curdir[curlib]]]->lname : nulstr);

	if(!strcmp(sp,"DN")) {
		safe_snprintf(str,maxlen,"%u",usrlibs ? curdir[curlib]+1 : 0);
		return(str);
	}

	if(!strcmp(sp,"DL")) {
		safe_snprintf(str,maxlen,"%-4u",usrlibs ? curdir[curlib]+1 : 0);
		return(str);
	}

	if(!strcmp(sp,"DR")) {
		safe_snprintf(str,maxlen,"%4u",usrlibs ? curdir[curlib]+1 : 0);
		return(str);
	}

	if(!strcmp(sp,"NOACCESS")) {
		if(noaccess_str==text[NoAccessTime])
			safe_snprintf(str,maxlen,noaccess_str,noaccess_val/60,noaccess_val%60);
		else if(noaccess_str==text[NoAccessDay])
			safe_snprintf(str,maxlen,noaccess_str,wday[noaccess_val]);
		else
			safe_snprintf(str,maxlen,noaccess_str,noaccess_val);
		return(str);
	}

	if(!strcmp(sp,"LAST")) {
		tp=strrchr(useron.alias,' ');
		if(tp) tp++;
		else tp=useron.alias;
		return(tp);
	}

	if(!strcmp(sp,"REAL") || !strcmp(sp,"FIRSTREAL")) {
		safe_snprintf(str,maxlen,"%s",useron.name);
		tp=strchr(str,' ');
		if(tp) *tp=0;
		return(str);
	}

	if(!strcmp(sp,"LASTREAL")) {
		tp=strrchr(useron.name,' ');
		if(tp) tp++;
		else tp=useron.name;
		return(tp);
	}

	if(!strcmp(sp,"MAILW")) {
		safe_snprintf(str,maxlen,"%u",getmail(&cfg,useron.number,0));
		return(str);
	}

	if(!strcmp(sp,"MAILP")) {
		safe_snprintf(str,maxlen,"%u",getmail(&cfg,useron.number,1));
		return(str);
	}

	if(!strncmp(sp,"MAILW:",6)) {
		safe_snprintf(str,maxlen,"%u",getmail(&cfg,atoi(sp+6),0));
		return(str);
	}

	if(!strncmp(sp,"MAILP:",6)) {
		safe_snprintf(str,maxlen,"%u",getmail(&cfg,atoi(sp+6),1));
		return(str);
	}

	if(!strcmp(sp,"MSGREPLY")) {
		safe_snprintf(str,maxlen,"%c",cfg.sys_misc&SM_RA_EMU ? 'R' : 'A');
		return(str);
	}

	if(!strcmp(sp,"MSGREREAD")) {
		safe_snprintf(str,maxlen,"%c",cfg.sys_misc&SM_RA_EMU ? 'A' : 'R');
		return(str);
	}

	if(!strncmp(sp,"STATS.",6)) {
		getstats(&cfg,0,&stats);
		sp+=6;
		if(!strcmp(sp,"LOGONS"))
			safe_snprintf(str,maxlen,"%lu",stats.logons);
		else if(!strcmp(sp,"LTODAY"))
			safe_snprintf(str,maxlen,"%lu",stats.ltoday);
		else if(!strcmp(sp,"TIMEON"))
			safe_snprintf(str,maxlen,"%lu",stats.timeon);
		else if(!strcmp(sp,"TTODAY"))
			safe_snprintf(str,maxlen,"%lu",stats.ttoday);
		else if(!strcmp(sp,"ULS"))
			safe_snprintf(str,maxlen,"%lu",stats.uls);
		else if(!strcmp(sp,"ULB"))
			safe_snprintf(str,maxlen,"%lu",stats.ulb);
		else if(!strcmp(sp,"DLS"))
			safe_snprintf(str,maxlen,"%lu",stats.dls);
		else if(!strcmp(sp,"DLB"))
			safe_snprintf(str,maxlen,"%lu",stats.dlb);
		else if(!strcmp(sp,"PTODAY"))
			safe_snprintf(str,maxlen,"%lu",stats.ptoday);
		else if(!strcmp(sp,"ETODAY"))
			safe_snprintf(str,maxlen,"%lu",stats.etoday);
		else if(!strcmp(sp,"FTODAY"))
			safe_snprintf(str,maxlen,"%lu",stats.ftoday);
		else if(!strcmp(sp,"NUSERS"))
			safe_snprintf(str,maxlen,"%u",stats.nusers);
		return(str);
	}

	/* Message header codes */
	if(!strcmp(sp,"MSG_TO") && current_msg!=NULL) {
		if(current_msg->to==NULL)
			return(nulstr);
		if(current_msg->to_ext!=NULL)
			safe_snprintf(str,maxlen,"%s #%s",current_msg->to,current_msg->to_ext);
		else if(current_msg->to_net.type!=NET_NONE) {
			char tmp[128];
			safe_snprintf(str,maxlen,"%s (%s)",current_msg->to
				,smb_netaddrstr(&current_msg->to_net,tmp));
		} else
			return(current_msg->to);
		return(str);
	}
	if(!strcmp(sp,"MSG_TO_NAME") && current_msg!=NULL)
		return(current_msg->to==NULL ? nulstr : current_msg->to);
	if(!strcmp(sp,"MSG_TO_EXT") && current_msg!=NULL) {
		if(current_msg->to_ext==NULL)
			return(nulstr);
		return(current_msg->to_ext);
	}
	if(!strcmp(sp,"MSG_TO_NET") && current_msg!=NULL)
		return(smb_netaddrstr(&current_msg->to_net,str));
	if(!strcmp(sp,"MSG_FROM") && current_msg!=NULL) {
		if(current_msg->from==NULL)
			return(nulstr);
		if(current_msg->hdr.attr&MSG_ANONYMOUS && !SYSOP)
			return(text[Anonymous]);
		if(current_msg->from_ext!=NULL)
			safe_snprintf(str,maxlen,"%s #%s",current_msg->from,current_msg->from_ext);
		else if(current_msg->from_net.type!=NET_NONE) {
			char tmp[128];
			safe_snprintf(str,maxlen,"%s (%s)",current_msg->from
				,smb_netaddrstr(&current_msg->from_net,tmp));
		} else
			return(current_msg->from);
		return(str);
	}
	if(!strcmp(sp,"MSG_FROM_NAME") && current_msg!=NULL) {
		if(current_msg->from==NULL)
			return(nulstr);
		if(current_msg->hdr.attr&MSG_ANONYMOUS && !SYSOP)
			return(text[Anonymous]);
		return(current_msg->from);
	}
	if(!strcmp(sp,"MSG_FROM_EXT") && current_msg!=NULL) {
		if(!(current_msg->hdr.attr&MSG_ANONYMOUS) || SYSOP)
			if(current_msg->from_ext!=NULL)
				return(current_msg->from_ext);
		return(nulstr);
	}
	if(!strcmp(sp,"MSG_FROM_NET") && current_msg!=NULL) {
		if(current_msg->from_net.type!=NET_NONE
			&& (!(current_msg->hdr.attr&MSG_ANONYMOUS) || SYSOP))
			return(smb_netaddrstr(&current_msg->from_net,str));
		return(nulstr);
	}
	if(!strcmp(sp,"MSG_SUBJECT") && current_msg!=NULL)
		return(current_msg->subj==NULL ? nulstr : current_msg->subj);
	if(!strcmp(sp,"MSG_DATE") && current_msg!=NULL)
		return(timestr(current_msg->hdr.when_written.time));
	if(!strcmp(sp,"MSG_TIMEZONE") && current_msg!=NULL)
		return(smb_zonestr(current_msg->hdr.when_written.zone,NULL));
	if(!strcmp(sp,"MSG_ATTR") && current_msg!=NULL) {
		safe_snprintf(str,maxlen,"%s%s%s%s%s%s%s%s%s%s%s"
			,current_msg->hdr.attr&MSG_PRIVATE		? "Private  "   :nulstr
			,current_msg->hdr.attr&MSG_READ			? "Read  "      :nulstr
			,current_msg->hdr.attr&MSG_DELETE		? "Deleted  "   :nulstr
			,current_msg->hdr.attr&MSG_KILLREAD		? "Kill  "      :nulstr
			,current_msg->hdr.attr&MSG_ANONYMOUS	? "Anonymous  " :nulstr
			,current_msg->hdr.attr&MSG_LOCKED		? "Locked  "    :nulstr
			,current_msg->hdr.attr&MSG_PERMANENT	? "Permanent  " :nulstr
			,current_msg->hdr.attr&MSG_MODERATED	? "Moderated  " :nulstr
			,current_msg->hdr.attr&MSG_VALIDATED	? "Validated  " :nulstr
			,current_msg->hdr.attr&MSG_REPLIED		? "Replied  "	:nulstr
			,current_msg->hdr.attr&MSG_NOREPLY		? "NoReply  "	:nulstr
			);
		return(str);
	}
	if(!strcmp(sp,"MSG_ID") && current_msg!=NULL)
		return(current_msg->id==NULL ? nulstr : current_msg->id);
	if(!strcmp(sp,"MSG_REPLY_ID") && current_msg!=NULL)
		return(current_msg->reply_id==NULL ? nulstr : current_msg->reply_id);
	if(!strcmp(sp,"MSG_NUM") && current_msg!=NULL) {
		safe_snprintf(str,maxlen,"%lu",current_msg->hdr.number);
		return(str);
	}

	if(!strcmp(sp,"SMB_AREA")) {
		if(smb.subnum!=INVALID_SUB && smb.subnum<cfg.total_subs)
			safe_snprintf(str,maxlen,"%s %s"
				,cfg.grp[cfg.sub[smb.subnum]->grp]->sname
				,cfg.sub[smb.subnum]->sname);
		return(str);
	}
	if(!strcmp(sp,"SMB_AREA_DESC")) {
		if(smb.subnum!=INVALID_SUB && smb.subnum<cfg.total_subs)
			safe_snprintf(str,maxlen,"%s %s"
				,cfg.grp[cfg.sub[smb.subnum]->grp]->lname
				,cfg.sub[smb.subnum]->lname);
		return(str);
	}
	if(!strcmp(sp,"SMB_GROUP")) {
		if(smb.subnum!=INVALID_SUB && smb.subnum<cfg.total_subs)
			return(cfg.grp[cfg.sub[smb.subnum]->grp]->sname);
		return(nulstr);
	}
	if(!strcmp(sp,"SMB_GROUP_DESC")) {
		if(smb.subnum!=INVALID_SUB && smb.subnum<cfg.total_subs)
			return(cfg.grp[cfg.sub[smb.subnum]->grp]->lname);
		return(nulstr);
	}
	if(!strcmp(sp,"SMB_GROUP_NUM")) {
		if(smb.subnum!=INVALID_SUB && smb.subnum<cfg.total_subs)
			safe_snprintf(str,maxlen,"%u",getusrgrp(smb.subnum));
		return(str);
	}
	if(!strcmp(sp,"SMB_SUB")) {
		if(smb.subnum==INVALID_SUB)
			return("Mail");
		else if(smb.subnum<cfg.total_subs)
			return(cfg.sub[smb.subnum]->sname);
		return(nulstr);
	}
	if(!strcmp(sp,"SMB_SUB_DESC")) {
		if(smb.subnum==INVALID_SUB)
			return("Mail");
		else if(smb.subnum<cfg.total_subs)
			return(cfg.sub[smb.subnum]->lname);
		return(nulstr);
	}
	if(!strcmp(sp,"SMB_SUB_CODE")) {
		if(smb.subnum==INVALID_SUB)
			return("MAIL");
		else if(smb.subnum<cfg.total_subs)
			return(cfg.sub[smb.subnum]->code);
		return(nulstr);
	}
	if(!strcmp(sp,"SMB_SUB_NUM")) {
		if(smb.subnum!=INVALID_SUB && smb.subnum<cfg.total_subs)
			safe_snprintf(str,maxlen,"%u",getusrsub(smb.subnum));
		return(str);
	}
	if(!strcmp(sp,"SMB_MSGS")) {
		safe_snprintf(str,maxlen,"%ld",smb.msgs);
		return(str);
	}
	if(!strcmp(sp,"SMB_CURMSG")) {
		safe_snprintf(str,maxlen,"%ld",smb.curmsg+1);
		return(str);
	}
	if(!strcmp(sp,"SMB_LAST_MSG")) {
		safe_snprintf(str,maxlen,"%lu",smb.status.last_msg);
		return(str);
	}
	if(!strcmp(sp,"SMB_MAX_MSGS")) {
		safe_snprintf(str,maxlen,"%lu",smb.status.max_msgs);
		return(str);
	}
	if(!strcmp(sp,"SMB_MAX_CRCS")) {
		safe_snprintf(str,maxlen,"%lu",smb.status.max_crcs);
		return(str);
	}
	if(!strcmp(sp,"SMB_MAX_AGE")) {
		safe_snprintf(str,maxlen,"%hu",smb.status.max_age);
		return(str);
	}
	if(!strcmp(sp,"SMB_TOTAL_MSGS")) {
		safe_snprintf(str,maxlen,"%lu",smb.status.total_msgs);
		return(str);
	}

	return(NULL);
}
Example #18
0
void msgs_cfg()
{
	static int dflt,msgs_dflt,bar;
	char	str[256],str2[256],done=0;
	char*	p;
	char*	tp;
    char	tmp[128];
	char	tmp_code[32];
	int		j,k,q,s;
	int		i,file,ptridx,n;
	unsigned total_subs;
	long	ported;
	sub_t	tmpsub;
	static grp_t savgrp;
	FILE*	stream;

while(1) {
	for(i=0;i<cfg.total_grps && i<MAX_OPTS;i++)
		sprintf(opt[i],"%-25s",cfg.grp[i]->lname);
	opt[i][0]=0;
	j=WIN_ORG|WIN_ACT|WIN_CHE;
	if(cfg.total_grps)
		j|=WIN_DEL|WIN_DELACT|WIN_GET;
	if(cfg.total_grps<MAX_OPTS)
		j|=WIN_INS|WIN_INSACT|WIN_XTR;
	if(savgrp.sname[0])
		j|=WIN_PUT;
	uifc.helpbuf=
		"`Message Groups:`\n"
		"\n"
		"This is a listing of message groups for your BBS. Message groups are\n"
		"used to logically separate your message `sub-boards` into groups. Every\n"
		"sub-board belongs to a message group. You must have at least one message\n"
		"group and one sub-board configured.\n"
		"\n"
		"One popular use for message groups is to separate local sub-boards and\n"
		"networked sub-boards. One might have a `Local` message group that contains\n"
		"non-networked sub-boards of various topics and also have a `FidoNet`\n"
		"message group that contains sub-boards that are echoed across FidoNet.\n"
		"Some sysops separate sub-boards into more specific areas such as `Main`,\n"
		"`Technical`, or `Adult`. If you have many sub-boards that have a common\n"
		"subject denominator, you may want to have a separate message group for\n"
		"those sub-boards for a more organized message structure.\n"
	;
	i=uifc.list(j,0,0,45,&msgs_dflt,&bar,"Message Groups",opt);
	if(i==-1) {
		j=save_changes(WIN_MID);
		if(j==-1)
		   continue;
		if(!j) {
			write_msgs_cfg(&cfg,backup_level);
            refresh_cfg(&cfg);
        }
		return;
    }
	if((i&MSK_ON)==MSK_INS) {
		i&=MSK_OFF;
		uifc.helpbuf=
			"`Group Long Name:`\n"
			"\n"
			"This is a description of the message group which is displayed when a\n"
			"user of the system uses the `/*` command from the main menu.\n"
		;
		strcpy(str,"Main");
		if(uifc.input(WIN_MID|WIN_SAV,0,0,"Group Long Name",str,LEN_GLNAME
			,K_EDIT)<1)
			continue;
		uifc.helpbuf=
			"`Group Short Name:`\n"
			"\n"
			"This is a short description of the message group which is used for the\n"
			"main menu and reading message prompts.\n"
		;
		sprintf(str2,"%.*s",LEN_GSNAME,str);
		if(uifc.input(WIN_MID,0,0,"Group Short Name",str2,LEN_GSNAME,K_EDIT)<1)
			continue;
		if((cfg.grp=(grp_t **)realloc(cfg.grp,sizeof(grp_t *)*(cfg.total_grps+1)))==NULL) {
            errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_grps+1);
			cfg.total_grps=0;
			bail(1);
            continue; 
		}

		if(cfg.total_grps) {	/* was cfg.total_subs (?) */
            for(j=cfg.total_grps;j>i;j--)   /* insert above */
                cfg.grp[j]=cfg.grp[j-1];
            for(j=0;j<cfg.total_subs;j++)   /* move sub group numbers */
                if(cfg.sub[j]->grp>=i)
                    cfg.sub[j]->grp++; 
		}

		if((cfg.grp[i]=(grp_t *)malloc(sizeof(grp_t)))==NULL) {
			errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(grp_t));
			continue; 
		}
		memset((grp_t *)cfg.grp[i],0,sizeof(grp_t));
		strcpy(cfg.grp[i]->lname,str);
		strcpy(cfg.grp[i]->sname,str2);
		cfg.total_grps++;
		uifc.changes=1;
		continue; 
	}
	if((i&MSK_ON)==MSK_DEL) {
		i&=MSK_OFF;
		uifc.helpbuf=
			"`Delete All Data in Group:`\n"
			"\n"
			"If you wish to delete the messages in all the sub-boards in this group,\n"
			"select `Yes`.\n"
		;
		j=1;
		strcpy(opt[0],"Yes");
		strcpy(opt[1],"No");
		opt[2][0]=0;
		j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0,"Delete All Data in Group",opt);
		if(j==-1)
			continue;
		if(j==0)
			for(j=0;j<cfg.total_subs;j++)
				if(cfg.sub[j]->grp==i) {
					sprintf(str,"%s%s.s*"
						,cfg.grp[cfg.sub[j]->grp]->code_prefix
						,cfg.sub[j]->code_suffix);
					strlwr(str);
					if(!cfg.sub[j]->data_dir[0])
						sprintf(tmp,"%ssubs/",cfg.data_dir);
					else
						strcpy(tmp,cfg.sub[j]->data_dir);
					delfiles(tmp,str);
					clearptrs(j); 
				}
		free(cfg.grp[i]);
		for(j=0;j<cfg.total_subs;) {
			if(cfg.sub[j]->grp==i) {	/* delete subs of this group */
				free(cfg.sub[j]);
				cfg.total_subs--;
				k=j;
				while(k<cfg.total_subs) {	/* move all subs down */
					cfg.sub[k]=cfg.sub[k+1];
					for(q=0;q<cfg.total_qhubs;q++)
						for(s=0;s<cfg.qhub[q]->subs;s++)
							if(cfg.qhub[q]->sub[s]==k)
								cfg.qhub[q]->sub[s]--;
					k++; 
				} 
			}
			else j++; 
		}
		for(j=0;j<cfg.total_subs;j++)	/* move sub group numbers down */
			if(cfg.sub[j]->grp>i)
				cfg.sub[j]->grp--;
		cfg.total_grps--;
		while(i<cfg.total_grps) {
			cfg.grp[i]=cfg.grp[i+1];
			i++; 
		}
		uifc.changes=1;
		continue; 
	}
	if((i&MSK_ON)==MSK_GET) {
		i&=MSK_OFF;
		savgrp=*cfg.grp[i];
		continue; 
	}
	if((i&MSK_ON)==MSK_PUT) {
		i&=MSK_OFF;
		*cfg.grp[i]=savgrp;
		uifc.changes=1;
		continue; 
	}
	done=0;
	while(!done) {
		j=0;
		sprintf(opt[j++],"%-27.27s%s","Long Name",cfg.grp[i]->lname);
		sprintf(opt[j++],"%-27.27s%s","Short Name",cfg.grp[i]->sname);
		sprintf(opt[j++],"%-27.27s%s","Internal Code Prefix",cfg.grp[i]->code_prefix);
		sprintf(opt[j++],"%-27.27s%.40s","Access Requirements"
			,cfg.grp[i]->arstr);
		strcpy(opt[j++],"Clone Options");
		strcpy(opt[j++],"Export Areas...");
		strcpy(opt[j++],"Import Areas...");
		strcpy(opt[j++],"Message Sub-boards...");
		opt[j][0]=0;
		sprintf(str,"%s Group",cfg.grp[i]->sname);
		uifc.helpbuf=
			"`Message Group Configuration:`\n"
			"\n"
			"This menu allows you to configure the security requirements for access\n"
			"to this message group. You can also add, delete, and configure the\n"
			"sub-boards of this group by selecting the `Messages Sub-boards...` option.\n"
		;
		switch(uifc.list(WIN_ACT,6,4,60,&dflt,0,str,opt)) {
			case -1:
				done=1;
				break;
			case 0:
				uifc.helpbuf=
					"`Group Long Name:`\n"
					"\n"
					"This is a description of the message group which is displayed when a\n"
					"user of the system uses the `/*` command from the main menu.\n"
				;
				strcpy(str,cfg.grp[i]->lname);	/* save incase setting to null */
				if(!uifc.input(WIN_MID|WIN_SAV,0,17,"Name to use for Listings"
					,cfg.grp[i]->lname,LEN_GLNAME,K_EDIT))
					strcpy(cfg.grp[i]->lname,str);
				break;
			case 1:
				uifc.helpbuf=
					"`Group Short Name:`\n"
					"\n"
					"This is a short description of the message group which is used for\n"
					"main menu and reading messages prompts.\n"
				;
				uifc.input(WIN_MID|WIN_SAV,0,17,"Name to use for Prompts"
					,cfg.grp[i]->sname,LEN_GSNAME,K_EDIT);
				break;
			case 2:
				uifc.helpbuf=
					"`Internal Code Prefix:`\n"
					"\n"
					"This is an `optional` code prefix used to help generate unique internal\n"
					"codes for the sub-boards in this message group. If this option\n"
					"is used, sub-board internal codes will be constructed from this prefix\n"
					"and the specified code suffix for each sub-board.\n"
				;
				uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code Prefix"
					,cfg.grp[i]->code_prefix,LEN_CODE,K_EDIT|K_UPPER);
				break;
			case 3:
				sprintf(str,"%s Group",cfg.grp[i]->sname);
				getar(str,cfg.grp[i]->arstr);
				break;
			case 4: 	/* Clone Options */
				j=0;
				strcpy(opt[0],"Yes");
				strcpy(opt[1],"No");
				opt[2][0]=0;
				uifc.helpbuf=
					"`Clone Sub-board Options:`\n"
					"\n"
					"If you want to clone the options of the first sub-board of this group\n"
					"into all sub-boards of this group, select `Yes`.\n"
					"\n"
					"The options cloned are posting requirements, reading requirements,\n"
					"operator requirments, moderated user requirments, toggle options,\n"
					"network options (including EchoMail origin line, EchoMail address,\n"
					"and QWK Network tagline), maximum number of messages, maximum number\n"
					"of CRCs, maximum age of messages, storage method, and data directory.\n"
				;
				j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0
					,"Clone Options of First Sub-board into All of Group",opt);
				if(j==0) {
					k=-1;
					for(j=0;j<cfg.total_subs;j++)
						if(cfg.sub[j]->grp==i) {
							if(k==-1)
								k=j;
							else {
								uifc.changes=1;
								cfg.sub[j]->misc=(cfg.sub[k]->misc|SUB_HDRMOD);
								strcpy(cfg.sub[j]->post_arstr,cfg.sub[k]->post_arstr);
								strcpy(cfg.sub[j]->read_arstr,cfg.sub[k]->read_arstr);
								strcpy(cfg.sub[j]->op_arstr,cfg.sub[k]->op_arstr);
								strcpy(cfg.sub[j]->mod_arstr,cfg.sub[k]->mod_arstr);
								strcpy(cfg.sub[j]->origline,cfg.sub[k]->origline);
								strcpy(cfg.sub[j]->tagline,cfg.sub[k]->tagline);
								strcpy(cfg.sub[j]->data_dir,cfg.sub[k]->data_dir);
								strcpy(cfg.sub[j]->post_sem,cfg.sub[k]->post_sem);
								cfg.sub[j]->maxmsgs=cfg.sub[k]->maxmsgs;
								cfg.sub[j]->maxcrcs=cfg.sub[k]->maxcrcs;
								cfg.sub[j]->maxage=cfg.sub[k]->maxage;

								cfg.sub[j]->faddr=cfg.sub[k]->faddr; 
							} 
						} 
				}
				break;
			case 5:
				k=0;
				ported=0;
				q=uifc.changes;
				strcpy(opt[k++],"SUBS.TXT    (Synchronet)");
				strcpy(opt[k++],"AREAS.BBS   (MSG)");
				strcpy(opt[k++],"AREAS.BBS   (SBBSecho)");
				strcpy(opt[k++],"FIDONET.NA  (Fido)");
				opt[k][0]=0;
				uifc.helpbuf=
					"`Export Area File Format:`\n"
					"\n"
					"This menu allows you to choose the format of the area file you wish to\n"
					"export the current message group into.\n"
				;
				k=0;
				k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
					,"Export Area File Format",opt);
				if(k==-1)
					break;
				if(k==0)
					sprintf(str,"%sSUBS.TXT",cfg.ctrl_dir);
				else if(k==1)
					sprintf(str,"AREAS.BBS");
				else if(k==2)
					sprintf(str,"%sAREAS.BBS",cfg.data_dir);
				else if(k==3)
					sprintf(str,"FIDONET.NA");
				if(k && k<3)
					if(uifc.input(WIN_MID|WIN_SAV,0,0,"Uplinks"
						,str2,sizeof(str2)-1,0)<=0) {
						uifc.changes=q;
						break; 
					}
				if(uifc.input(WIN_MID|WIN_SAV,0,0,"Filename"
					,str,sizeof(str)-1,K_EDIT)<=0) {
					uifc.changes=q;
					break; 
				}
				if(fexist(str)) {
					strcpy(opt[0],"Overwrite");
					strcpy(opt[1],"Append");
					opt[2][0]=0;
					j=0;
					j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0
						,"File Exists",opt);
					if(j==-1)
						break;
					if(j==0) j=O_WRONLY|O_TRUNC;
					else	 j=O_WRONLY|O_APPEND; 
				}
				else
					j=O_WRONLY|O_CREAT;
				if((stream=fnopen(&file,str,j))==NULL) {
					sprintf(str,"Open Failure: %d (%s)"
						,errno,strerror(errno));
					uifc.msg(str);
					uifc.changes=q;
					break; 
				}
				uifc.pop("Exporting Areas...");
				for(j=0;j<cfg.total_subs;j++) {
					if(cfg.sub[j]->grp!=i)
						continue;
					ported++;
					if(k==1) {		/* AREAS.BBS *.MSG */
						sprintf(str,"%s%s%s/"
							,cfg.echomail_dir
							,cfg.grp[cfg.sub[j]->grp]->code_prefix
							,cfg.sub[j]->code_suffix);
						fprintf(stream,"%-30s %-20s %s\r\n"
							,str,stou(cfg.sub[j]->sname),str2);
						continue; 
					}
					if(k==2) {		/* AREAS.BBS SBBSecho */
						fprintf(stream,"%s%-30s %-20s %s\r\n"
							,cfg.grp[cfg.sub[j]->grp]->code_prefix
							,cfg.sub[j]->code_suffix
							,stou(cfg.sub[j]->sname)
							,str2);
						continue; 
					}
					if(k==3) {		/* FIDONET.NA */
						fprintf(stream,"%-20s %s\r\n"
							,stou(cfg.sub[j]->sname),cfg.sub[j]->lname);
						continue; 
					}
					fprintf(stream,"%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n"
							"%s\r\n%s\r\n%s\r\n"
						,cfg.sub[j]->lname
						,cfg.sub[j]->sname
						,cfg.sub[j]->qwkname
						,cfg.sub[j]->code_suffix
						,cfg.sub[j]->data_dir
						,cfg.sub[j]->arstr
						,cfg.sub[j]->read_arstr
						,cfg.sub[j]->post_arstr
						,cfg.sub[j]->op_arstr
						);
					fprintf(stream,"%"PRIX32"\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n"
						,cfg.sub[j]->misc
						,cfg.sub[j]->tagline
						,cfg.sub[j]->origline
						,cfg.sub[j]->post_sem
						,cfg.sub[j]->newsgroup
						,smb_faddrtoa(&cfg.sub[j]->faddr,tmp)
						);
					fprintf(stream,"%"PRIu32"\r\n%"PRIu32"\r\n%u\r\n%u\r\n%s\r\n"
						,cfg.sub[j]->maxmsgs
						,cfg.sub[j]->maxcrcs
						,cfg.sub[j]->maxage
						,cfg.sub[j]->ptridx
						,cfg.sub[j]->mod_arstr
						);
					fprintf(stream,"***END-OF-SUB***\r\n\r\n"); 
				}
				fclose(stream);
				uifc.pop(0);
				sprintf(str,"%lu Message Areas Exported Successfully",ported);
				uifc.msg(str);
				uifc.changes=q;
				break;
			case 6:
				ported=0;
				k=0;
				strcpy(opt[k++],"SUBS.TXT    (Synchronet)");
				strcpy(opt[k++],"AREAS.BBS   (Generic)");
				strcpy(opt[k++],"AREAS.BBS   (SBBSecho)");
				strcpy(opt[k++],"FIDONET.NA  (Fido)");
				opt[k][0]=0;
				uifc.helpbuf=
					"`Import Area File Format:`\n"
					"\n"
					"This menu allows you to choose the format of the area file you wish to\n"
					"import into the current message group.\n"
				;
				k=0;
				k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
					,"Import Area File Format",opt);
				if(k==-1)
					break;
				if(k==0)
					sprintf(str,"%sSUBS.TXT",cfg.ctrl_dir);
				else if(k==1)
					sprintf(str,"AREAS.BBS");
				else if(k==2)
					sprintf(str,"%sAREAS.BBS",cfg.data_dir);
				else if(k==3)
					sprintf(str,"FIDONET.NA");
				if(uifc.input(WIN_MID|WIN_SAV,0,0,"Filename"
					,str,sizeof(str)-1,K_EDIT)<=0)
                    break;
				if((stream=fnopen(&file,str,O_RDONLY))==NULL) {
					uifc.msg("Open Failure");
                    break; 
				}
				uifc.pop("Importing Areas...");
				total_subs = cfg.total_subs;	 /* Save original number of subs */
				ptridx = 0;
				while(!feof(stream)) {
					if(!fgets(str,sizeof(str),stream)) break;
					truncsp(str);
					if(!str[0])
						continue;
					if(k) {
						p=str;
						while(*p && *p<=' ') p++;
						if(!*p || *p==';')
							continue;
						memset(&tmpsub,0,sizeof(sub_t));
						tmpsub.misc|=
							(SUB_FIDO|SUB_NAME|SUB_TOUSER|SUB_QUOTE|SUB_HYPER);
						if(k==1) {		/* AREAS.BBS Generic/*.MSG */
							p=str;
							SKIP_WHITESPACE(p);			/* Find path	*/
							FIND_WHITESPACE(p);			/* Skip path	*/
							SKIP_WHITESPACE(p);			/* Find tag		*/
							truncstr(p," \t");			/* Truncate tag */
							SAFECOPY(tmp_code,p);		/* Copy tag to internal code */
							SAFECOPY(tmpsub.lname,utos(p));
							SAFECOPY(tmpsub.sname,tmpsub.lname);
							SAFECOPY(tmpsub.qwkname,tmpsub.qwkname);
						}
						else if(k==2) { /* AREAS.BBS SBBSecho */
							p=str;
							SKIP_WHITESPACE(p);			/* Find internal code */
							tp=p;
							FIND_WHITESPACE(tp);
							*tp=0;						/* Truncate internal code */
							SAFECOPY(tmp_code,p);		/* Copy internal code suffix */
							p=tp+1;
							SKIP_WHITESPACE(p);			/* Find echo tag */
							truncstr(p," \t");			/* Truncate tag */
							SAFECOPY(tmpsub.lname,utos(p));
							SAFECOPY(tmpsub.sname,tmpsub.lname);
							SAFECOPY(tmpsub.qwkname,tmpsub.sname);
						}
						else if(k==3) { /* FIDONET.NA */
                            p=str;
							SKIP_WHITESPACE(p);			/* Find echo tag */
							tp=p;
							FIND_WHITESPACE(tp);		/* Find end of tag */
							*tp=0;						/* Truncate echo tag */
							SAFECOPY(tmp_code,p);		/* Copy tag to internal code suffix */
							SAFECOPY(tmpsub.sname,utos(p));	/* ... to short name, converting underscores to spaces */
							SAFECOPY(tmpsub.qwkname,tmpsub.sname);	/* ... to QWK name .... */
							p=tp+1;
							SKIP_WHITESPACE(p);			/* Find description */
							SAFECOPY(tmpsub.lname,p);	/* Copy description to long name */
						}
					}
					else {
						memset(&tmpsub,0,sizeof(sub_t));
						tmpsub.grp=i;
						sprintf(tmpsub.lname,"%.*s",LEN_SLNAME,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.sname,"%.*s",LEN_SSNAME,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.qwkname,"%.*s",10,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						SAFECOPY(tmp_code,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.data_dir,"%.*s",LEN_DIR,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.arstr,"%.*s",LEN_ARSTR,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.read_arstr,"%.*s",LEN_ARSTR,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.post_arstr,"%.*s",LEN_ARSTR,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.op_arstr,"%.*s",LEN_ARSTR,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						tmpsub.misc=ahtoul(str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.tagline,"%.*s",80,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.origline,"%.*s",50,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.post_sem,"%.*s",LEN_DIR,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						SAFECOPY(tmpsub.newsgroup,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						tmpsub.faddr=atofaddr(str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						tmpsub.maxmsgs=atol(str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						tmpsub.maxcrcs=atol(str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						tmpsub.maxage=atoi(str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						tmpsub.ptridx=atoi(str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.mod_arstr,"%.*s",LEN_ARSTR,str);

						while(!feof(stream)
							&& strcmp(str,"***END-OF-SUB***")) {
							if(!fgets(str,128,stream)) break;
							truncsp(str); 
						} 
					}

                    SAFECOPY(tmpsub.code_suffix, prep_code(tmp_code,cfg.grp[i]->code_prefix));
					truncsp(tmpsub.sname);
					truncsp(tmpsub.lname);
					truncsp(tmpsub.qwkname);

					if(tmpsub.code_suffix[0]==0
						|| tmpsub.sname[0]==0
						|| tmpsub.lname[0]==0
						|| tmpsub.qwkname[0]==0)
						continue;

					for(j=0;j<total_subs;j++) {
						if(cfg.sub[j]->grp!=i)
							continue;
						if(!stricmp(cfg.sub[j]->code_suffix,tmpsub.code_suffix))
							break; 
					}
					if(j==total_subs) {
						j=cfg.total_subs;
						if((cfg.sub=(sub_t **)realloc(cfg.sub
							,sizeof(sub_t *)*(cfg.total_subs+1)))==NULL) {
							errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_subs+1);
							cfg.total_subs=0;
							bail(1);
							break; 
						}

						if((cfg.sub[j]=(sub_t *)malloc(sizeof(sub_t)))
							==NULL) {
							errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(sub_t));
							break; 
						}
						memset(cfg.sub[j],0,sizeof(sub_t)); 
					}
					if(!k) {
						n=cfg.sub[j]->ptridx;	/* save original ptridx */
						memcpy(cfg.sub[j],&tmpsub,sizeof(sub_t));
						cfg.sub[j]->ptridx=n;	/* restore original ptridx */
					} else {
                        cfg.sub[j]->grp=i;
						if(cfg.total_faddrs)
							cfg.sub[j]->faddr=cfg.faddr[0];
						strcpy(cfg.sub[j]->code_suffix,tmpsub.code_suffix);
						strcpy(cfg.sub[j]->sname,tmpsub.sname);
						strcpy(cfg.sub[j]->lname,tmpsub.lname);
						strcpy(cfg.sub[j]->qwkname,tmpsub.qwkname);
						strcpy(cfg.sub[j]->data_dir,tmpsub.data_dir);
						if(j==cfg.total_subs)
							cfg.sub[j]->maxmsgs=1000;
					}
					if(j==cfg.total_subs) {	/* adding new sub-board */
						for(;ptridx<USHRT_MAX;ptridx++) {
							for(n=0;n<total_subs;n++)
								if(cfg.sub[n]->ptridx==ptridx)
									break;
							if(n==total_subs)
								break; 
						}
						cfg.sub[j]->ptridx=ptridx;	/* use new ptridx */
						cfg.sub[j]->misc=tmpsub.misc;
						cfg.total_subs++; 
						ptridx++;	/* don't use the same ptridx for next sub */
					}
					uifc.changes=1; 
					ported++;
				}
				fclose(stream);
				uifc.pop(0);
				sprintf(str,"%lu Message Areas Imported Successfully",ported);
                uifc.msg(str);
				break;

			case 7:
                sub_cfg(i);
				break; 
			} 
		} 
	}
}
Example #19
0
void ident_server_thread(void* arg)
{
	int				result;
	SOCKET			sock;
	SOCKADDR_IN		server_addr={0};
	fd_set			socket_set;
	struct timeval tv;

	lprintf(LOG_DEBUG,"Ident server thread started");

	if((sock=socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == INVALID_SOCKET) {
		lprintf(LOG_ERR,"ERROR %u creating socket", ERROR_VALUE);
		return;
	}
	
    memset(&server_addr, 0, sizeof(server_addr));

	server_addr.sin_addr.s_addr = htonl(ident_interface);
    server_addr.sin_family = AF_INET;
    server_addr.sin_port   = htons(ident_port);

    if(bind(sock,(struct sockaddr *)&server_addr,sizeof(server_addr))!=0) {
		lprintf(LOG_ERR,"ERROR %u binding ident server socket", ERROR_VALUE);
		close_socket(&sock);
		return;
	}

    if(listen(sock, 1)) {
		lprintf(LOG_ERR,"!ERROR %u listening on ident server socket", ERROR_VALUE);
		close_socket(&sock);
		return;
	}

	while(!terminated) {
		/* now wait for connection */

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

		tv.tv_sec=5;
		tv.tv_usec=0;

		if((result=select(sock+1,&socket_set,NULL,NULL,&tv))<1) {
			if(result==0)
				continue;
			if(ERROR_VALUE==EINTR)
				lprintf(LOG_DEBUG,"Ident Server listening interrupted");
			else if(ERROR_VALUE == ENOTSOCK)
            	lprintf(LOG_NOTICE,"Ident Server sockets closed");
			else
				lprintf(LOG_WARNING,"!ERROR %d selecting ident socket",ERROR_VALUE);
			continue;
		}

		if(FD_ISSET(sock,&socket_set)) {
			SOCKADDR_IN		client_addr;
			socklen_t		client_addr_len;
			SOCKET			client_socket=INVALID_SOCKET;
			char			request[128];
			char			response[256];
			int				rd;

			client_addr_len = sizeof(client_addr);
			client_socket = accept(sock, (struct sockaddr *)&client_addr, &client_addr_len);
			if(client_socket != INVALID_SOCKET) {
				lprintf(LOG_INFO,"Ident request from %s : %u"
					,inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
				FD_ZERO(&socket_set);
				FD_SET(client_socket,&socket_set);
				tv.tv_sec=5;
				tv.tv_usec=0;
				if(select(client_socket+1,&socket_set,NULL,NULL,&tv)==1) {
					lprintf(LOG_DEBUG,"Ident select");
					if((rd=recv(client_socket, request, sizeof(request), 0)) > 0) {
						request[rd]=0;
						truncsp(request);
						lprintf(LOG_INFO,"Ident request: %s", request);
						/* example response: "40931,23:USERID:UNIX:cyan" */
						SAFEPRINTF4(response,"%s:%s:%s %s\r\n"
							,request, ident_response, cid_number, cid_name);
						sendsocket(client_socket,response,strlen(response));
					} else
						lprintf(LOG_DEBUG,"ident recv=%d %d", rd, ERROR_VALUE);
				}
				close_socket(&client_socket);
			}
		}
	}

	close_socket(&sock);
	lprintf(LOG_DEBUG,"Ident server thread terminated");
}
Example #20
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);
}
Example #21
0
void node_menu()
{
	char	str[81],savnode=0;
	int 	i,j;
	static int node_menu_dflt, node_bar;

while(1) {
	for(i=0;i<cfg.sys_nodes;i++)
		sprintf(opt[i],"Node %d",i+1);
	opt[i][0]=0;
	j=WIN_ORG|WIN_ACT|WIN_INSACT|WIN_DELACT;
	if(cfg.sys_nodes>1)
		j|=WIN_DEL|WIN_GET;
	if(cfg.sys_nodes<MAX_NODES && cfg.sys_nodes<MAX_OPTS)
		j|=WIN_INS;
	if(savnode)
		j|=WIN_PUT;
uifc.helpbuf=
	"Node List:\n"
	"\n"
	"This is the list of configured nodes in your system.\n"
	"\n"
	"To add a node, hit  INS .\n"
	"\n"
	"To delete a node, hit  DEL .\n"
	"\n"
	"To configure a node, select it using the arrow keys and hit  ENTER .\n"
	"\n"
	"To copy a node's configuration to another node, first select the source\n"
	"node with the arrow keys and hit  F5 . Then select the destination\n"
	"node and hit  F6 .\n"
;

	i=uifc.list(j,0,0,13,&node_menu_dflt,&node_bar,"Nodes",opt);
	if(i==-1) {
		if(savnode) {
			free_node_cfg(&cfg);
			savnode=0; }
		return; }

	if((i&MSK_ON)==MSK_DEL) {
		strcpy(opt[0],"Yes");
		strcpy(opt[1],"No");
		opt[2][0]=0;
		sprintf(str,"Delete Node %d",cfg.sys_nodes);
		i=1;
uifc.helpbuf=
	"Delete Node:\n"
	"\n"
	"If you are positive you want to delete this node, select Yes. Otherwise,\n"
	"select No or hit  ESC .\n"
;
		i=uifc.list(WIN_MID,0,0,0,&i,0,str,opt);
		if(!i) {
			--cfg.sys_nodes;
/*			free(cfg.node_path[cfg.sys_nodes]); */
			cfg.new_install=new_install;
			write_main_cfg(&cfg,backup_level);
            refresh_cfg(&cfg);
        }
		continue; }
	if((i&MSK_ON)==MSK_INS) {
		strcpy(cfg.node_dir,cfg.node_path[cfg.sys_nodes-1]);
		i=cfg.sys_nodes+1;
		uifc.pop("Reading NODE.CNF...");
		read_node_cfg(&cfg,error);
		uifc.pop(0);
		sprintf(str,"../node%d/",i);
		sprintf(tmp,"Node %d Path",i);
uifc.helpbuf=
	"Node Path:\n"
	"\n"
	"This is the path to this node's private directory where its separate\n"
	"configuration and data files are stored.\n"
	"\n"
	"The drive and directory of this path can be set to any valid DOS\n"
	"directory that can be accessed by ALL nodes and MUST NOT be on a RAM disk\n"
	"or other volatile media.\n"
	"\n"
	"If you want to abort the creation of this new node, hit  ESC .\n"
;
		j=uifc.input(WIN_MID,0,0,tmp,str,50,K_EDIT);
		uifc.changes=0;
		if(j<2)
			continue;
		truncsp(str);
		strcpy(cfg.node_path[i-1],str);
		if(str[strlen(str)-1]=='\\' || str[strlen(str)-1]=='/')
			str[strlen(str)-1]=0;
		MKDIR(str);
		cfg.node_num=++cfg.sys_nodes;
		SAFEPRINTF(cfg.node_name,"Node %u",cfg.node_num);
		SAFECOPY(cfg.node_phone,"N/A");
		cfg.new_install=new_install;
		write_node_cfg(&cfg,backup_level);
		write_main_cfg(&cfg,backup_level);
		free_node_cfg(&cfg);
        refresh_cfg(&cfg);
		continue;
    }
	if((i&MSK_ON)==MSK_GET) {
		if(savnode)
			free_node_cfg(&cfg);
		i&=MSK_OFF;
		strcpy(cfg.node_dir,cfg.node_path[i]);
		uifc.pop("Reading NODE.CNF...");
		read_node_cfg(&cfg,error);
		uifc.pop(0);
		savnode=1;
		continue; }
	if((i&MSK_ON)==MSK_PUT) {
		i&=MSK_OFF;
		strcpy(cfg.node_dir,cfg.node_path[i]);
		cfg.node_num=i+1;
		write_node_cfg(&cfg,backup_level);
        refresh_cfg(&cfg);
		uifc.changes=1;
		continue;
    }

	if(savnode) {
		free_node_cfg(&cfg);
		savnode=0; }
	strcpy(cfg.node_dir,cfg.node_path[i]);
	prep_dir(cfg.ctrl_dir, cfg.node_dir, sizeof(cfg.node_dir));

	uifc.pop("Reading NODE.CNF...");
	read_node_cfg(&cfg,error);
	uifc.pop(0);
	if(cfg.node_num!=i+1) { 	/* Node number isn't right? */
		cfg.node_num=i+1;		/* so fix it */
		write_node_cfg(&cfg,backup_level); } /* and write it back */
	node_cfg();

	free_node_cfg(&cfg); }
}
Example #22
0
void postmsg(char type, char* to, char* to_number, char* to_address, 
			 char* from, char* from_number, char* subject, FILE* fp)
{
	char		str[128];
	char		buf[1024];
	uchar*		msgtxt=NULL;
	uchar*		newtxt;
	long		msgtxtlen;
	ushort		net;
	int 		i;
	ushort		agent=AGENT_SMBUTIL;
	smbmsg_t	msg;
	long		dupechk_hashes=SMB_HASH_SOURCE_DUPE;

	/* Read message text from stream (file or stdin) */
	msgtxtlen=0;
	while(!feof(fp)) {
		i=fread(buf,1,sizeof(buf),fp);
		if(i<1)
			break;
		if((msgtxt=(uchar*)realloc(msgtxt,msgtxtlen+i+1))==NULL) {
			fprintf(errfp,"\n%s!realloc(%ld) failure\n",beep,msgtxtlen+i+1);
			bail(1);
		}
		memcpy(msgtxt+msgtxtlen,buf,i);
		msgtxtlen+=i;
	}

	if(msgtxt!=NULL) {

		msgtxt[msgtxtlen]=0;	/* Must be NULL-terminated */

		if((newtxt=(uchar*)malloc((msgtxtlen*2)+1))==NULL) {
			fprintf(errfp,"\n%s!malloc(%ld) failure\n",beep,(msgtxtlen*2)+1);
			bail(1);
		}

		/* Expand LFs to CRLFs */
		msgtxtlen=lf_expand(msgtxt, newtxt);
		free(msgtxt);
		msgtxt=newtxt;
	}

	memset(&msg,0,sizeof(smbmsg_t));
	msg.hdr.when_written.time=(uint32_t)time(NULL);
	msg.hdr.when_written.zone=tzone;
	msg.hdr.when_imported=msg.hdr.when_written;

	if((to==NULL || stricmp(to,"All")==0) && to_address!=NULL)
		to=to_address;
	if(to==NULL) {
		printf("To User Name: ");
		fgets(str,sizeof(str),stdin); 
	} else
		SAFECOPY(str,to);
	truncsp(str);

	if((i=smb_hfield_str(&msg,RECIPIENT,str))!=SMB_SUCCESS) {
		fprintf(errfp,"\n%s!smb_hfield_str(0x%02X) returned %d: %s\n"
			,beep,RECIPIENT,i,smb.last_error);
		bail(1); 
	}
	if(type=='E' || type=='N')
		smb.status.attr|=SMB_EMAIL;
	if(smb.status.attr&SMB_EMAIL) {
		if(to_address==NULL) {
			if(to_number==NULL) {
				printf("To User Number: ");
				gets(str);
			} else
				SAFECOPY(str,to_number);
			truncsp(str);
			if((i=smb_hfield_str(&msg,RECIPIENTEXT,str))!=SMB_SUCCESS) {
				fprintf(errfp,"\n%s!smb_hfield_str(0x%02X) returned %d: %s\n"
					,beep,RECIPIENTEXT,i,smb.last_error);
				bail(1); 
			}
		}
	}

	if(smb.status.attr&SMB_EMAIL && (type=='N' || to_address!=NULL)) {
		if(to_address==NULL) {
			printf("To Address (e.g. user@host): ");
			gets(str);
		} else
			SAFECOPY(str,to_address);
		truncsp(str);
		if(*str) {
			net=smb_netaddr_type(str);
			if((i=smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(net),&net))!=SMB_SUCCESS) {
				fprintf(errfp,"\n%s!smb_hfield(0x%02X) returned %d: %s\n"
					,beep,RECIPIENTNETTYPE,i,smb.last_error);
				bail(1); 
			}
			if((i=smb_hfield_str(&msg,RECIPIENTNETADDR,str))!=SMB_SUCCESS) {
				fprintf(errfp,"\n%s!smb_hfield_str(0x%02X) returned %d: %s\n"
					,beep,RECIPIENTNETADDR,i,smb.last_error);
				bail(1); 
			} 
		} 
	}

	if(from==NULL) {
		printf("From User Name: ");
		gets(str);
	} else
		SAFECOPY(str,from);
	truncsp(str);
	if((i=smb_hfield_str(&msg,SENDER,str))!=SMB_SUCCESS) {
		fprintf(errfp,"\n%s!smb_hfield_str(0x%02X) returned %d: %s\n"
			,beep,SENDER,i,smb.last_error);
		bail(1); 
	}
	if(smb.status.attr&SMB_EMAIL) {
		if(from_number==NULL) {
			printf("From User Number: ");
			gets(str);
		} else
			SAFECOPY(str,from_number);
		truncsp(str);
		if((i=smb_hfield_str(&msg,SENDEREXT,str))!=SMB_SUCCESS) {
			fprintf(errfp,"\n%s!smb_hfield_str(0x%02X) returned %d: %s\n"
				,beep,SENDEREXT,i,smb.last_error);
			bail(1); 
		}
	}
	if((i=smb_hfield(&msg, SENDERAGENT, sizeof(agent), &agent))!=SMB_SUCCESS) {
		fprintf(errfp,"\n%s!smb_hfield(0x%02X) returned %d: %s\n"
			,beep,SENDERAGENT,i,smb.last_error);
		bail(1);
	}

	if(subject==NULL) {
		printf("Subject: ");
		gets(str);
	} else
		SAFECOPY(str,subject);
	truncsp(str);
	if((i=smb_hfield_str(&msg,SUBJECT,str))!=SMB_SUCCESS) {
		fprintf(errfp,"\n%s!smb_hfield_str(0x%02X) returned %d: %s\n"
			,beep,SUBJECT,i,smb.last_error);
		bail(1); 
	}

	safe_snprintf(str,sizeof(str),"SMBUTIL %s-%s r%s %s %s"
		,SMBUTIL_VER
		,PLATFORM_DESC
		,revision
		,__DATE__
		,compiler
		);
	if((i=smb_hfield_str(&msg,FIDOPID,str))!=SMB_SUCCESS) {
		fprintf(errfp,"\n%s!smb_hfield_str(0x%02X) returned %d: %s\n"
			,beep,FIDOPID,i,smb.last_error);
		bail(1); 
	}

	if(mode&NOCRC || 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,smb.status.attr&SMB_HYPERALLOC
		,dupechk_hashes,xlat,msgtxt,NULL))!=SMB_SUCCESS) {
		fprintf(errfp,"\n%s!smb_addmsg returned %d: %s\n"
			,beep,i,smb.last_error);
		bail(1); 
	}
	smb_freemsgmem(&msg);

	FREE_AND_NULL(msgtxt);
}
Example #23
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); }
}
Example #24
0
bool sbbs_t::answer()
{
	char	str[MAX_PATH+1],str2[MAX_PATH+1],c;
	char 	tmp[(MAX_PATH > CRYPT_MAX_TEXTSIZE ? MAX_PATH:CRYPT_MAX_TEXTSIZE)+1];
	char 	tmpname[CRYPT_MAX_TEXTSIZE+1];
	char 	path[MAX_PATH+1];
	int		i,l,in;
	struct tm tm;

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

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

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

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

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

	online=ON_REMOTE;

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

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

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

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

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

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

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

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

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

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

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

	if(!online) 
		return(false); 

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


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

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

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

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


	if(!useron.number)
		hangup();

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

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

	if(!online) 
		return(false); 

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

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

	return(true);
}
Example #25
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);
}
Example #26
0
BOOL wait_for_call(COM_HANDLE com_handle)
{
	char		str[128];
	char*		p;
	BOOL		result=TRUE;
	DWORD		events=0;
	time_t		start=time(NULL);

	ZERO_VAR(cid_name);
	ZERO_VAR(cid_number);

	if(!comRaiseDTR(com_handle))
		lprintf(LOG_ERR,"ERROR %u raising DTR", COM_ERROR_VALUE);

	if(com_alreadyconnected)
		return TRUE;

	if(!mdm_null) {
		if(mdm_init[0]) {
			lprintf(LOG_INFO,"Initializing modem:");
			if(!modem_command(com_handle, mdm_init))
				return FALSE;
		}
		if(!mdm_manswer && mdm_autoans[0]) {
			lprintf(LOG_INFO,"Setting modem to auto-answer:");
			if(!modem_command(com_handle, mdm_autoans))
				return FALSE;
		}
		if(mdm_cid[0]) {
			lprintf(LOG_INFO,"Enabling modem Caller-ID:");
			if(!modem_command(com_handle, mdm_cid))
				return FALSE;
		}
	}

	lprintf(LOG_INFO,"Waiting for incoming call (%s) ...", mdm_manswer ? "Ring Indication" : "Carrier Detect");
	while(1) {
		if(terminated)
			return FALSE;
		if(comReadLine(com_handle, str, sizeof(str), /* timeout (ms): */250) > 0) {
			truncsp(str);
			if(str[0]==0)
				continue;
			lprintf(LOG_DEBUG,"Received from modem: '%s'", str);
			p=str;
			SKIP_WHITESPACE(p);
			if(*p) {
				lprintf(LOG_INFO, "Modem Message: %s", p);
				if(strncmp(p,"CONNECT ",8)==0) {
					long rate=atoi(p+8);
					if(rate)
						SAFEPRINTF2(termspeed,"%u,%u", rate, rate);
				}
				else if(strncmp(p,"NMBR",4)==0 || strncmp(p,"MESG",4)==0) {
					p+=4;
					FIND_CHAR(p,'=');
					SKIP_CHAR(p,'=');
					SKIP_WHITESPACE(p);
					if(cid_number[0]==0)	/* Don't overwrite, if multiple messages received */
						SAFECOPY(cid_number, p);
				}
				else if(strncmp(p,"NAME",4)==0) {
					p+=4;
					FIND_CHAR(p,'=');
					SKIP_CHAR(p,'=');
					SKIP_WHITESPACE(p);
					SAFECOPY(cid_name, p);
				}
				else if(strcmp(p,"NO CARRIER")==0) {
					ZERO_VAR(cid_name);
					ZERO_VAR(cid_number);
				}
				else if(mdm_ring[0] && strcmp(p,mdm_ring)==0 && mdm_manswer && mdm_answer[0]) {
					if(!modem_send(com_handle, mdm_answer)) {
						lprintf(LOG_ERR,"ERROR %u sending modem command (%s) on %s"
							,COM_ERROR_VALUE, mdm_answer, com_dev);
					}
				}
			}
			continue;	/* don't check DCD until we've received all the modem msgs */
		}
		if(carrier_detect(com_handle))
			break;
		if(mdm_reinit && (time(NULL)-start)/60 >= mdm_reinit) {
			lprintf(LOG_INFO,"Re-initialization timer elapsed: %u minutes", mdm_reinit);
			return TRUE;
		}
	}

	if(strcmp(cid_name,"P")==0)
		SAFECOPY(cid_name,"Private");
	else if(strcmp(cid_name,"O")==0)
		SAFECOPY(cid_name,"Out-of-area");

	if(strcmp(cid_number,"P")==0)
		SAFECOPY(cid_number,"Private");
	else if(strcmp(cid_number,"O")==0)
		SAFECOPY(cid_number,"Out-of-area");

	lprintf(LOG_INFO,"Carrier detected");
	return TRUE;
}
Example #27
0
bool sbbs_t::qnetmail(char *into, char *subj, long mode)
{
	char	str[256],msgpath[128],title[128],to[128],fulladdr[128]
			,buf[SDT_BLOCK_LEN],*addr;
	char 	tmp[512];
	ushort	xlat=XLAT_NONE,net=NET_QWK,touser;
	int 	i,j,x,file;
	ulong	length,offset;
	FILE	*instream;
	smbmsg_t msg;

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

	strcpy(to,into);
	strcpy(title,subj);

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

	addr=strrchr(to,'@');
	if(!addr) {
		bputs(text[InvalidNetMailAddr]);
		return(false); 
	}
	*addr=0;
	addr++;
	strupr(addr);
	truncsp(addr);
	touser=qwk_route(addr,fulladdr);
	if(!fulladdr[0]) {
		bputs(text[InvalidNetMailAddr]);
		return(false); 
	}

	truncsp(to);
	if(!stricmp(to,"SBBS") && !SYSOP) {
		bputs(text[InvalidNetMailAddr]);
		return(false); 
	}
	bprintf(text[NetMailing],to,fulladdr
		,useron.alias,cfg.sys_id);
	action=NODE_SMAL;
	nodesync();

	sprintf(msgpath,"%snetmail.msg",cfg.node_dir);
	if(!writemsg(msgpath,nulstr,title,mode|WM_QWKNET,INVALID_SUB,to)) {
		bputs(text[Aborted]);
		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_msgs=0;
		smb.status.max_age=cfg.mail_maxage;
		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,smb.last_error);
			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,smb.last_error);
		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_QWK;
	smb_hfield_str(&msg,RECIPIENT,to);
	sprintf(str,"%u",touser);
	smb_hfield_str(&msg,RECIPIENTEXT,str);
	smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(net),&net);
	smb_hfield_str(&msg,RECIPIENTNETADDR,fulladdr);

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

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

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

	smb_hfield_str(&msg,SUBJECT,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); 
	}

	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 QWK NetMail to %s (%s)"
		,useron.alias
		,to,fulladdr);
	logline("EN",str);
	return(true);
}
Example #28
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);
}
Example #29
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);
}