Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

sbbs.h 46.9 KB
Newer Older
1 2 3 4 5 6 7 8
/* Synchronet class (sbbs_t) definition and exported function prototypes */

/* $Id$ */

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
9
 * Copyright Rob Swindell - http://www.synchro.net/copyright.html			*
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
 *																			*
 * This program is free software; you can redistribute it and/or			*
 * modify it under the terms of the GNU General Public License				*
 * as published by the Free Software Foundation; either version 2			*
 * of the License, or (at your option) any later version.					*
 * See the GNU General Public License for more details: gpl.txt or			*
 * http://www.fsf.org/copyleft/gpl.html										*
 *																			*
 * Anonymous FTP access to the most recent released source is available at	*
 * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net	*
 *																			*
 * Anonymous CVS access to the development source and modification history	*
 * is available at cvs.synchro.net:/cvsroot/sbbs, example:					*
 * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login			*
 *     (just hit return, no password is necessary)							*
 * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src		*
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * You are encouraged to submit any modifications (preferably in Unix diff	*
 * format) via e-mail to mods@synchro.net									*
 *																			*
 * Note: If this box doesn't appear square, then you need to fix your tabs.	*
 ****************************************************************************/

#ifndef _SBBS_H
#define _SBBS_H

/****************************/
/* Standard library headers */
/****************************/

rswindell's avatar
rswindell committed
43 44 45
/***************/
/* OS-specific */
/***************/
46
#if defined(_WIN32)			/* Windows */
47

deuce's avatar
deuce committed
48 49 50
	#define NOCRYPT     /* Stop windows.h from loading wincrypt.h */
                    /* Is windows.h REALLY necessary?!?! */
	#define WIN32_LEAN_AND_MEAN
51 52 53 54 55 56
	#include <io.h>
	#include <share.h>
	#include <windows.h>
	#include <process.h>	/* _beginthread() prototype */
	#include <direct.h>		/* _mkdir() prototype */
	#include <mmsystem.h>	/* SND_ASYNC */
57

58
	#if defined(_DEBUG) && defined(_MSC_VER)
59 60 61
		#include <crtdbg.h> /* Windows debug macros and stuff */
	#endif

62
#if defined(__cplusplus)
63
	extern "C"
64
#endif
deuce's avatar
deuce committed
65
	HINSTANCE hK32;
66

67
#elif defined(__unix__)		/* Unix-variant */
68

69
	#include <unistd.h>		/* close */
70 71 72

#endif

73 74 75 76 77 78
#ifdef _THREAD_SUID_BROKEN
extern int	thread_suid_broken;			/* NPTL is no longer broken */
#else
#define thread_suid_broken FALSE
#endif

rswindell's avatar
rswindell committed
79 80 81
/******************/
/* ANSI C Library */
/******************/
82 83 84 85
#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
86
#include <fcntl.h>			/* open */
87 88 89
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
90

91
#ifndef __unix__
92 93 94 95 96

	#include <malloc.h>

#endif

97 98
#include <sys/stat.h>

deuce's avatar
deuce committed
99 100 101 102 103 104
#ifdef __unix__
	#define XP_UNIX
#else
	#define XP_PC
	#define XP_WIN
#endif
rswindell's avatar
rswindell committed
105 106 107

#if defined(JAVASCRIPT)
#include "comio.h"			/* needed for COM_HANDLE definition only */
deuce's avatar
deuce committed
108 109 110
#include <jsversion.h>
#include <jsapi.h>
#define JS_DestroyScript(cx,script)
111

112 113
#define JSSTRING_TO_RASTRING(cx, str, ret, sizeptr, lenptr) \
{ \
114
	size_t			*JSSTSlenptr=(lenptr); \
115 116 117 118 119 120 121 122 123
	size_t			JSSTSlen; \
	size_t			JSSTSpos; \
	const jschar	*JSSTSstrval; \
	char			*JSSTStmpptr; \
\
	if(JSSTSlenptr==NULL) \
		JSSTSlenptr=&JSSTSlen; \
	if((str) != NULL) { \
		if((JSSTSstrval=JS_GetStringCharsAndLength((cx), (str), JSSTSlenptr))) { \
124 125 126
			if((*(sizeptr) < (*JSSTSlenptr+1 )) || (ret)==NULL) { \
				*(sizeptr) = *JSSTSlenptr+1; \
				if((JSSTStmpptr=(char *)realloc((ret), *(sizeptr)))==NULL) { \
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
					JS_ReportError(cx, "Error reallocating %lu bytes at %s:%d", (*JSSTSlenptr)+1, getfname(__FILE__), __LINE__); \
					(ret)=NULL; \
					free(ret); \
				} \
				else { \
					(ret)=JSSTStmpptr; \
				} \
			} \
			if(ret) { \
				for(JSSTSpos=0; JSSTSpos<*JSSTSlenptr; JSSTSpos++) \
					(ret)[JSSTSpos]=(char)JSSTSstrval[JSSTSpos]; \
				(ret)[*JSSTSlenptr]=0; \
			} \
		} \
	} \
deuce's avatar
deuce committed
142 143
	else { \
		if(ret) \
144
			*(ret)=0; \
deuce's avatar
deuce committed
145
	} \
146 147 148 149 150 151 152 153
}

#define JSVALUE_TO_RASTRING(cx, val, ret, sizeptr, lenptr) \
{ \
	JSString	*JSVTSstr=JS_ValueToString((cx), (val)); \
	JSSTRING_TO_RASTRING((cx), JSVTSstr, (ret), (sizeptr), (lenptr)); \
}

154 155
#define JSSTRING_TO_MSTRING(cx, str, ret, lenptr) \
{ \
156
	size_t			*JSSTSlenptr=(lenptr); \
157 158 159 160 161 162 163 164 165 166 167 168 169 170
	size_t			JSSTSlen; \
	size_t			JSSTSpos; \
	const jschar	*JSSTSstrval; \
\
	if(JSSTSlenptr==NULL) \
		JSSTSlenptr=&JSSTSlen; \
	(ret)=NULL; \
	if((str) != NULL) { \
		if((JSSTSstrval=JS_GetStringCharsAndLength((cx), (str), JSSTSlenptr))) { \
			if(((ret)=(char *)malloc(*JSSTSlenptr+1))) { \
				for(JSSTSpos=0; JSSTSpos<*JSSTSlenptr; JSSTSpos++) \
					(ret)[JSSTSpos]=(char)JSSTSstrval[JSSTSpos]; \
				(ret)[*JSSTSlenptr]=0; \
			} \
171
			else JS_ReportError((cx), "Error allocating %lu bytes at %s:%d", (*JSSTSlenptr)+1, getfname(__FILE__), __LINE__); \
172 173 174 175 176 177 178 179 180 181
		} \
	} \
}

#define JSVALUE_TO_MSTRING(cx, val, ret, lenptr) \
{ \
	JSString	*JSVTSstr=JS_ValueToString((cx), (val)); \
	JSSTRING_TO_MSTRING((cx), JSVTSstr, (ret), lenptr); \
}

182 183
#define JSSTRING_TO_STRBUF(cx, str, ret, bufsize, lenptr) \
{ \
184
	size_t			*JSSTSlenptr=(lenptr); \
185 186 187 188 189 190
	size_t			JSSTSlen; \
	size_t			JSSTSpos; \
	const jschar	*JSSTSstrval; \
\
	if(JSSTSlenptr==NULL) \
		JSSTSlenptr=&JSSTSlen; \
191
	if((bufsize) < 1 || (str)==NULL) \
192 193 194
		*JSSTSlenptr = 0; \
	else { \
		if((JSSTSstrval=JS_GetStringCharsAndLength((cx), (str), JSSTSlenptr))) { \
195 196
			if(*JSSTSlenptr >= (bufsize)) \
				*JSSTSlenptr = (bufsize)-1; \
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
			for(JSSTSpos=0; JSSTSpos<*JSSTSlenptr; JSSTSpos++) \
				(ret)[JSSTSpos]=(char)JSSTSstrval[JSSTSpos]; \
		} \
		else \
			*JSSTSlenptr=0; \
	} \
	(ret)[*JSSTSlenptr]=0; \
}

#define JSVALUE_TO_STRBUF(cx, val, ret, bufsize, lenptr) \
{ \
	JSString	*JSVTSstr=JS_ValueToString((cx), (val)); \
	JSSTRING_TO_STRBUF((cx), JSVTSstr, (ret), (bufsize), lenptr); \
}

#define HANDLE_PENDING(cx) \
	if(JS_IsExceptionPending(cx)) \
		return JS_FALSE;

216 217
#define JSSTRING_TO_ASTRING(cx, str, ret, maxsize, lenptr) \
{ \
218
	size_t			*JSSTSlenptr=(lenptr); \
219 220 221 222 223 224 225 226 227
	size_t			JSSTSlen; \
	size_t			JSSTSpos; \
	const jschar	*JSSTSstrval; \
\
	if(JSSTSlenptr==NULL) \
		JSSTSlenptr=&JSSTSlen; \
	(ret)=NULL; \
	if((str) != NULL) { \
		if((JSSTSstrval=JS_GetStringCharsAndLength((cx), (str), JSSTSlenptr))) { \
228 229 230
			if(*JSSTSlenptr >= (maxsize)) { \
				*JSSTSlenptr = (maxsize)-1; \
			} \
231
			if(((ret)=(char *)alloca(*JSSTSlenptr+1))) { \
232
				for(JSSTSpos=0; JSSTSpos<*JSSTSlenptr; JSSTSpos++) { \
233
					(ret)[JSSTSpos]=(char)JSSTSstrval[JSSTSpos]; \
234
				} \
235 236
				(ret)[*JSSTSlenptr]=0; \
			} \
237
			else JS_ReportError((cx), "Error allocating %lu bytes on stack at %s:%d", (*JSSTSlenptr)+1, getfname(__FILE__), __LINE__); \
238 239 240 241 242 243 244 245 246 247
		} \
	} \
}

#define JSVALUE_TO_ASTRING(cx, val, ret, maxsize, lenptr) \
{ \
	JSString	*JSVTSstr=JS_ValueToString((cx), (val)); \
	JSSTRING_TO_ASTRING((cx), JSVTSstr, (ret), (maxsize), (lenptr)); \
}

rswindell's avatar
rswindell committed
248 249
#endif

250 251 252 253
#ifdef USE_CRYPTLIB
#include <cryptlib.h>
#endif

254
/* xpdev */
255 256 257
#ifndef LINK_LIST_THREADSAFE
 #define LINK_LIST_THREADSAFE
#endif
258
#include "genwrap.h"
rswindell's avatar
rswindell committed
259
#include "semfile.h"
260
#include "netwrap.h"
261 262
#include "dirwrap.h"
#include "filewrap.h"
263
#include "datewrap.h"
264
#include "sockwrap.h"
deuce's avatar
deuce committed
265
#include "multisock.h"
266
#include "eventwrap.h"
267
#include "link_list.h"
268
#include "msg_queue.h"
269
#include "xpdatetime.h"
270

271 272 273 274 275 276 277 278
/***********************/
/* Synchronet-specific */
/***********************/
#include "startup.h"
#ifdef __cplusplus
	#include "threadwrap.h"	/* pthread_mutex_t */
#endif

279 280 281 282 283 284 285 286 287
#include "smblib.h"
#include "ars_defs.h"
#include "scfgdefs.h"
#include "scfglib.h"
#include "userdat.h"
#include "riodefs.h"
#include "cmdshell.h"
#include "ringbuf.h"    /* RingBuf definition */
#include "client.h"		/* client_t definition */
288 289
#include "crc16.h"
#include "crc32.h"
290
#include "telnet.h"
291
#include "nopen.h"
292
#include "text.h"
293

294
/* Synchronet Node Instance class definition */
295 296 297 298 299 300
#ifdef __cplusplus
class sbbs_t
{

public:

deuce's avatar
deuce committed
301
	sbbs_t(ushort node_num, union xp_sockaddr *addr, size_t addr_len, const char* host_name, SOCKET
302
		,scfg_t*, char* text[], client_t* client_info);
303 304
	~sbbs_t();

305 306
	bbs_startup_t*	startup;

307
	bool	init(void);
308
	BOOL	terminated;
309 310 311 312

	client_t client;
	SOCKET	client_socket;
	SOCKET	client_socket_dup;
deuce's avatar
deuce committed
313
	union xp_sockaddr	client_addr;
314
	char	client_name[128];
rswindell's avatar
rswindell committed
315
	char	client_ident[128];
deuce's avatar
deuce committed
316 317
	char	client_ipaddr[INET6_ADDRSTRLEN];
	char	local_addr[INET6_ADDRSTRLEN];
318 319 320
#ifdef USE_CRYPTLIB
	CRYPT_SESSION	ssh_session;
	bool	ssh_mode;
321
	SOCKET	passthru_socket;
322 323
    bool	passthru_output_thread_running;
    bool	passthru_input_thread_running;
324
#endif
325 326 327 328 329 330 331 332 333 334 335

	scfg_t	cfg;

	int		outchar_esc;		   // track ANSI escape seq output

	int 	rioctl(ushort action); // remote i/o control
	bool	rio_abortable;

    RingBuf	inbuf;
    RingBuf	outbuf;
	HANDLE	input_thread;
336
	pthread_mutex_t	input_thread_mutex;
337
	bool	input_thread_mutex_locked;	// by someone other than the input_thread
338
	bool	input_thread_mutex_created;
339
	pthread_mutex_t	ssh_mutex;
340
	bool	ssh_mutex_created;
341 342

	int 	outcom(uchar ch); 	   // send character
343
	int 	incom(unsigned long timeout=0);		   // receive character
344

345
	void	spymsg(const char *msg);		// send message to active spies
346

347
	int		putcom(const char *str, size_t len=0);  // Send string
348 349
	void	hangup(void);		   // Hangup modem

350 351
	uchar	telnet_local_option[0x100];
	uchar	telnet_remote_option[0x100];
rswindell's avatar
rswindell committed
352
	void	send_telnet_cmd(uchar cmd, uchar opt);
353
	bool	request_telnet_opt(uchar cmd, uchar opt, unsigned waitforack=0);
354

355
    uchar	telnet_cmd[64];
rswindell's avatar
rswindell committed
356
    uint	telnet_cmdlen;
357 358
	ulong	telnet_mode;
	uchar	telnet_last_rxch;
359
	char	telnet_location[128];
360
	char	terminal[TELNET_TERM_MAXLEN+1];
361
	xpevent_t	telnet_ack_event;
362

363
	time_t	event_time;				// Time of next exclusive event
364
	char*	event_code;				// Internal code of next exclusive event
365 366
	bool	event_thread_running;
    bool	output_thread_running;
367
    bool	input_thread_running;
368

369 370
#ifdef JAVASCRIPT

371 372 373 374 375 376 377 378
	JSRuntime*		js_runtime;
	JSContext*		js_cx;
	JSObject*		js_glob;
	js_callback_t	js_callback;
	long			js_execfile(const char *fname, const char* startup_dir, JSObject* scope=NULL);
	bool			js_init(ulong* stack_frame);
	void			js_cleanup(const char* node);
	void			js_create_user_objects(void);
379 380 381

#endif

382 383 384 385 386 387
	char 	menu_dir[128];	/* Over-ride default menu dir */
	char 	menu_file[128]; /* Over-ride menu file */

	user_t	useron; 		/* User currently online */
	node_t	thisnode;		/* Node information */
	smb_t	smb;			/* Currently open message base */
388
	char	rlogin_name[LEN_ALIAS+1];
389
	char	rlogin_pass[LEN_PASS+1];
390
	char	rlogin_term[TELNET_TERM_MAXLEN+1];	/* RLogin passed terminal type/speed (e.g. "xterm/57600") */
391 392 393 394 395 396 397 398

	uint	temp_dirnum;

	FILE	*nodefile_fp,
			*node_ext_fp,
			*logfile_fp;

	int 	nodefile;		/* File handle for node.dab */
399
	pthread_mutex_t	nodefile_mutex;
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
	int		node_ext;		/* File handle for node.exb */
	int 	inputfile;		/* File handle to use for input */

							/* Batch download queue */
	char 	**batdn_name;	/* Filenames */
	ushort	*batdn_alt; 	/* Alternate path */
	uint 	*batdn_dir, 	/* Directory for each file */
			 batdn_total;	/* Total files */
	long 	*batdn_offset;	/* Offset for data */
	ulong	*batdn_size;	/* Size of file in bytes */
	ulong	*batdn_cdt; 	/* Credit value of file */

							/* Batch upload queue */
	char 	**batup_desc,	/* Description for each file */
			**batup_name;	/* Filenames */
	long	*batup_misc;	/* Miscellaneous bits */
	ushort	*batup_alt; 	/* Alternate path */
	uint 	*batup_dir, 	/* Directory for each file */
			batup_total;	/* Total files */

	/*********************************/
	/* Color Configuration Variables */
	/*********************************/
423 424
	char 	*text[TOTAL_TEXT];			/* Text from ctrl\text.dat */
	char 	*text_sav[TOTAL_TEXT];		/* Text from ctrl\text.dat */
425

426
	char 	dszlog[127];	/* DSZLOG enviornment variable */
427
    int     keybuftop,keybufbot;    /* Keyboard input buffer pointers (for ungetkey) */
428
	char    keybuf[KEY_BUFSIZE];    /* Keyboard input buffer */
429 430

	ushort	node_connection;
431
	char	connection[LEN_MODEM+1];	/* Connection Description */
432 433 434 435 436 437
	ulong	cur_rate;		/* Current Connection (DCE) Rate */
	ulong	cur_cps;		/* Current Average Transfer CPS */
	ulong	dte_rate;		/* Current COM Port (DTE) Rate */
	time_t 	timeout;		/* User inactivity timeout reference */
	ulong 	timeleft_warn;	/* low timeleft warning flag */
	uchar 	curatr; 		/* Current Text Attributes Always */
438 439
	uchar	attr_stack[64];	/* Saved attributes (stack) */
	int 	attr_sp;		/* Attribute stack pointer */
440 441
	long 	lncntr; 		/* Line Counter - for PAUSE */
	long 	tos;			/* Top of Screen */
442 443
	long 	rows;			/* Current number of Rows for User */
	long	cols;			/* Current number of Columns for User */
444
	long	column;			/* Current column counter (for line counter) */
445 446 447
	long 	autoterm;		/* Autodetected terminal type */
	char 	slbuf[SAVE_LINES][LINE_BUFSIZE+1]; /* Saved for redisplay */
	char 	slatr[SAVE_LINES];	/* Starting attribute of each line */
448 449
	char 	slcuratr[SAVE_LINES];	/* Ending attribute of each line */
	int 	slcnt;			/* Number of lines currently saved */
450 451 452 453 454
	char 	lbuf[LINE_BUFSIZE+1];/* Temp storage for each line output */
	int		lbuflen;		/* Number of characters in line buffer */
	char 	latr;			/* Starting attribute of line buffer */
	ulong	console;		/* Defines current Console settings */
	char 	wordwrap[81];	/* Word wrap buffer */
455
	time_t	now,			/* Used to store current time in Unix format */
456
			answertime, 	/* Time call was answered */
457 458
			logontime,		/* Time user logged on */
			starttime,		/* Time stamp to use for time left calcs */
459
			ns_time,		/* File new-scan time */
460 461 462 463
			last_ns_time;	/* Most recent new-file-scan this call */
	uchar 	action;			/* Current action of user */
	long 	online; 		/* Remote/Local or not online */
	long 	sys_status; 	/* System Status */
464
	subscan_t	*subscan;	/* User sub configuration/scan info */
465 466 467 468 469 470 471 472

	ulong	logon_ulb,		/* Upload Bytes This Call */
			logon_dlb,		/* Download Bytes This Call */
			logon_uls,		/* Uploads This Call */
			logon_dls,		/* Downloads This Call */
			logon_posts,	/* Posts This Call */
			logon_emails,	/* Emails This Call */
			logon_fbacks;	/* Feedbacks This Call */
473
	uchar	logon_ml;		/* ML of the user upon logon */
474 475 476 477 478 479 480

	uint 	main_cmds;		/* Number of Main Commands this call */
	uint 	xfer_cmds;		/* Number of Xfer Commands this call */
	ulong	posts_read; 	/* Number of Posts read this call */
	char 	temp_uler[31];  /* User who uploaded the files to temp dir */
	char 	temp_file[41];	/* Origin of extracted temp files */
	long 	temp_cdt;		/* Credit value of file that was extracted */
481
	bool 	autohang;		/* Used for auto-hangup after transfer */
482 483 484
	size_t 	logcol; 		/* Current column of log file */
	uint 	criterrs; 		/* Critical error counter */

485 486 487 488 489 490
	uint 	curgrp; 		/* Current group */
	uint	*cursub;		/* Current sub-board for each group */
	uint	curlib; 		/* Current library */
	uint	*curdir;		/* Current directory for each library */
	uint 	*usrgrp;		/* Real group numbers */
	uint	usrgrps;		/* Number groups this user has access to */
491
	uint	usrgrp_total;	/* Total number of groups */
492 493
	uint 	*usrlib;		/* Real library numbers */
	uint	usrlibs;		/* Number of libs this user can access */
494
	uint	usrlib_total;	/* Total number of libraries */
495 496 497 498
	uint 	**usrsub;		/* Real sub numbers */
	uint	*usrsubs;		/* Num of subs with access for each grp */
	uint 	**usrdir;		/* Real dir numbers */
	uint	*usrdirs;		/* Num of dirs with access for each lib */
499 500 501
	uint	cursubnum;		/* For ARS */
	uint	curdirnum;		/* For ARS */
	ulong 	timeleft;		/* Number of seconds user has left online */
502

503 504 505 506 507 508 509 510 511
	char 	*comspec;		/* Pointer to environment variable COMSPEC */
	ushort	altul;			/* Upload to alternate path flag */
	char 	cid[LEN_CID+1]; /* Caller ID (IP Address) of current caller */
	char 	*noaccess_str;	/* Why access was denied via ARS */
	long 	noaccess_val;	/* Value of parameter not met in ARS */
	int		errorlevel; 	/* Error level of external program */

	csi_t	main_csi;		/* Main Command Shell Image */

512 513
	smbmsg_t*	current_msg;	/* For message header @-codes */

514 515 516
			/* Global command shell variables */
	uint	global_str_vars;
	char **	global_str_var;
deuce's avatar
deuce committed
517
	int32_t *	global_str_var_name;
518
	uint	global_int_vars;
deuce's avatar
deuce committed
519
	int32_t *	global_int_var;
deuce's avatar
deuce committed
520
	int32_t *	global_int_var_name;
521 522
	char *	sysvar_p[MAX_SYSVARS];
	uint	sysvar_pi;
deuce's avatar
deuce committed
523
	int32_t	sysvar_l[MAX_SYSVARS];
524 525 526
	uint	sysvar_li;

    /* ansi_term.cpp */
527 528
	const char*	ansi(int atr);			/* Returns ansi escape sequence for atr */
	char*	ansi(int atr, int curatr, char* str);
529 530 531 532
    bool	ansi_gotoxy(int x, int y);
	bool	ansi_getxy(int* x, int* y);
	bool	ansi_save(void);
	bool	ansi_restore(void);
533 534 535 536 537 538
	void	ansi_getlines(void);

			/* Command Shell Methods */
	int		exec(csi_t *csi);
	int		exec_function(csi_t *csi);
	int		exec_misc(csi_t *csi, char *path);
rswindell's avatar
rswindell committed
539 540 541
	int		exec_net(csi_t *csi);
	int		exec_msg(csi_t *csi);
	int		exec_file(csi_t *csi);
542
	long	exec_bin(const char *mod, csi_t *csi, const char* startup_dir=NULL);
543 544
	void	clearvars(csi_t *bin);
	void	freevars(csi_t *bin);
deuce's avatar
deuce committed
545
	char**	getstrvar(csi_t *bin, int32_t name);
deuce's avatar
deuce committed
546
	int32_t*	getintvar(csi_t *bin, int32_t name);
547 548
	char*	copystrvar(csi_t *csi, char *p, char *str);
	void	skipto(csi_t *csi, uchar inst);
549
	bool	ftp_cmd(csi_t* csi, SOCKET ctrl_sock, const char* cmdsrc, char* rsp);
rswindell's avatar
rswindell committed
550
	bool	ftp_put(csi_t* csi, SOCKET ctrl_sock, char* src, char* dest);
551 552 553
	bool	ftp_get(csi_t* csi, SOCKET ctrl_sock, char* src, char* dest, bool dir=false);
	SOCKET	ftp_data_sock(csi_t* csi, SOCKET ctrl_sock, SOCKADDR_IN*);

554 555 556
	bool	select_shell(void);
	bool	select_editor(void);

557 558 559
	void	sys_info(void);
	void	user_info(void);
	void	xfer_policy(void);
560 561

	void	xfer_prot_menu(enum XFER_TYPE);
562 563 564 565
	void	node_stats(uint node_num);
	void	sys_stats(void);
	void	logonlist(void);
	bool	spy(uint node_num);
566 567 568 569 570 571 572 573 574 575 576 577 578 579

	void	reset_logon_vars(void);

	uint	finduser(char *str);

	int 	sub_op(uint subnum);

	int		dir_op(uint dirnum);
	int		getuserxfers(int fromuser, int destuser, char *fname);

	void	getmsgptrs(void);
	void	putmsgptrs(void);
	void	getusrsubs(void);
	void	getusrdirs(void);
580 581 582
	uint	getusrsub(uint subnum);
	uint	getusrgrp(uint subnum);

583
	uint	userdatdupe(uint usernumber, uint offset, uint datlen, char *dat
584
				,bool del=false, bool next=false);
585
	ulong	gettimeleft(bool handle_out_of_time=true);
586 587 588
	bool	gettimeleft_inside;

	/* str.cpp */
589
	char*	timestr(time_t intime);
590
    char	timestr_output[60];
591
	char*	age_of_posted_item(char* buf, size_t max, time_t);
592
	void	userlist(long mode);
593
	size_t	gettmplt(char *outstr, const char *tmplt, long mode);
594
	void	sif(char *fname, char *answers, long len);	/* Synchronet Interface File */
595 596 597 598
	void	sof(char *fname, char *answers, long len);
	void	create_sif_dat(char *siffile, char *datfile);
	void	read_sif_dat(char *siffile, char *datfile);
	void	printnodedat(uint number, node_t* node);
deuce's avatar
deuce committed
599
	bool	inputnstime32(time32_t *dt);
600
	bool	inputnstime(time_t *dt);
601
	bool	chkpass(char *pass, user_t* user, bool unique);
602
	char *	cmdstr(const char *instr, const char *fpath, const char *fspec, char *outstr);
603 604 605 606
	char	cmdstr_output[512];

	void	subinfo(uint subnum);
	void	dirinfo(uint dirnum);
607
	bool	trashcan(const char *insearch, const char *name);
608 609
	void	time_bank(void);
	void	change_user(void);
610 611 612

	/* writemsg.cpp */
	void	automsg(void);
613 614
	bool	writemsg(const char *str, const char *top, char *subj, long mode, uint subnum
				,const char *to, const char* from, char** editor=NULL);
615
	char*	quotes_fname(int xedit, char* buf, size_t len);
616
	char*	msg_tmp_fname(int xedit, char* fname, size_t len);
617
	char	putmsg(const char *str, long mode);
618
	bool	msgabort(void);
619
	bool	email(int usernumber, const char *top, const char *title, long mode);
620 621
	void	forwardmail(smbmsg_t* msg, int usernum);
	void	removeline(char *str, char *str2, char num, char skip);
622
	ulong	msgeditor(char *buf, const char *top, char *title);
623
	bool	editfile(char *path, bool msg=false);
rswindell's avatar
rswindell committed
624
	ushort	chmsgattr(smbmsg_t);
625 626
	void	quotemsg(smbmsg_t* msg, int tails);
	void	editmsg(smbmsg_t* msg, uint subnum);
627
	void	editor_inf(int xeditnum, const char *to, const char* from, const char *subj, long mode
628
				,uint subnum, const char* tagfile);
629 630
	void	copyfattach(uint to, uint from, char *title);
	bool	movemsg(smbmsg_t* msg, uint subnum);
631 632
	int		process_edited_text(char* buf, FILE* stream, long mode, unsigned* lines, unsigned maxlines);
	int		process_edited_file(const char* src, const char* dest, long mode, unsigned* lines, unsigned maxlines);
633

634 635 636
	/* postmsg.cpp */
	bool	postmsg(uint subnum, smbmsg_t* msg, long wm_mode);

637 638 639
	/* mail.cpp */
	int		delmail(uint usernumber,int which);
	void	telluser(smbmsg_t* msg);
640
	void	delallmail(uint usernumber, int which, bool permanent=true);
641 642

	/* getmsg.cpp */
643
	int		loadmsg(smbmsg_t *msg, ulong number);
rswindell's avatar
rswindell committed
644
	void	show_msgattr(smbmsg_t*);
645
	void	show_msghdr(smbmsg_t* msg);
646
	void	show_msg(smbmsg_t* msg, long mode, post_t* post = NULL);
647
	void	msgtotxt(smbmsg_t* msg, char *str, bool header, ulong mode);
648 649 650
	ulong	getlastmsg(uint subnum, uint32_t *ptr, time_t *t);
	time_t	getmsgtime(uint subnum, ulong ptr);
	ulong	getmsgnum(uint subnum, time_t t);
651 652 653

	/* readmail.cpp */
	void	readmail(uint usernumber, int sent);
654
	bool	readmail_inside;
655 656

	/* bulkmail.cpp */
657 658
	bool	bulkmail(uchar *ar);
	int		bulkmailhdr(smb_t*, smbmsg_t*, uint usernum);
659 660

	/* con_out.cpp */
661 662 663 664
	int		bputs(const char *str);					/* BBS puts function */
	int		rputs(const char *str, size_t len=0);	/* BBS raw puts function */
	int		bprintf(const char *fmt, ...);			/* BBS printf function */
	int		rprintf(const char *fmt, ...);			/* BBS raw printf function */
665
	void	backspace(void);				/* Output a destructive backspace via outchar */
666
	void	outchar(char ch);				/* Output a char - check echo and emu.  */
667
	void	center(char *str);
668 669 670 671 672 673 674
	void	clearline(void);
	void	cleartoeol(void);
	void	cursor_home(void);
	void	cursor_up(int count=1);
	void	cursor_down(int count=1);
	void	cursor_left(int count=1);
	void	cursor_right(int count=1);
675
	long	term_supports(long cmp_flags=0);
676
	int		backfill(const char* str, float pct);
677 678

	/* getstr.cpp */
679
	size_t	getstr_offset;
680
	size_t	getstr(char *str, size_t length, long mode);
681
	long	getnum(ulong max, ulong dflt=0);
682
	void	insert_indicator(void);
683 684

	/* getkey.cpp */
685
	char	getkey(long mode); 		/* Waits for a key hit local or remote  */
686
	long	getkeys(const char *str, ulong max);
687
	void	ungetkey(char ch);		/* Places 'ch' into the input buffer    */
688
	char	question[MAX_TEXTDAT_ITEM_LEN+1];
689 690
	bool	yesno(const char *str);
	bool	noyes(const char *str);
691
	void	pause(void);
692 693
	const char *	mnestr;
	void	mnemonics(const char *str);
694

rswindell's avatar
rswindell committed
695
	/* inkey.cpp */
696
	char	inkey(long mode, unsigned long timeout=0);
rswindell's avatar
rswindell committed
697 698
	char	handle_ctrlkey(char ch, long mode=0);

699 700 701
	/* prntfile.cpp */
	void	printfile(char *str, long mode);
	void	printtail(char *str, int lines, long mode);
702
	void	menu(const char *code);
703

704
	int		uselect(int add, uint n, const char *title, const char *item, const uchar *ar);
705 706 707 708 709 710 711
	uint	uselect_total, uselect_num[500];

	void	redrwstr(char *strin, int i, int l, long mode);
	void	attr(int atr);				/* Change local and remote text attributes */
	void	ctrl_a(char x);			/* Peforms the Ctrl-Ax attribute changes */

	/* atcodes.cpp */
712 713
	int		show_atcode(const char *code);
	const char*	atcode(char* sp, char* str, size_t maxlen);
714 715

	/* getnode.cpp */
716 717
	int		getsmsg(int usernumber);
	int		getnmsg(void);
718
	int		whos_online(bool listself);/* Lists active nodes, returns active nodes */
719
	void	nodelist(void);
720 721 722 723 724 725 726 727 728
	int		getnodeext(uint number, char * str);
	int		getnodedat(uint number, node_t * node, bool lock);
	void	nodesync(void);
	user_t	nodesync_user;
	bool	nodesync_inside;

	/* putnode.cpp */
	int		putnodedat(uint number, node_t * node);
	int		putnodeext(uint number, char * str);
729

730
	/* login.ccp */
731
	int		login(char *str, char *pw);
732 733 734 735 736 737
	void	badlogin(char* user, char* passwd);

	/* answer.cpp */
	bool	answer();

	/* logon.ccp */
738
	bool	logon(void);
739 740

	/* logout.cpp */
741 742 743
	void	logout(void);
	void	backout(void);

744 745 746
	/* newuser.cpp */
	BOOL	newuser(void);					/* Get new user							*/

747
	/* text_sec.cpp */
748
	int		text_sec(void);						/* Text sections */
749 750

	/* readmsgs.cpp */
751
	post_t* loadposts(uint32_t *posts, uint subnum, ulong ptr, long mode, ulong *unvalidated_num, uint32_t* visible=NULL);
752
	int		scanposts(uint subnum, long mode, const char* find);	/* Scan sub-board */
753
	bool	scanposts_inside;
754
	long	listsub(uint subnum, long mode, long start, const char* search);
755
	long	listmsgs(uint subnum, long mode, post_t* post, long start, long posts);
756
	long	searchposts(uint subnum, post_t* post, long start, long msgs, const char* find);
757
	long	showposts_toyou(uint subnum, post_t* post, ulong start, long posts, long mode=0);
758
	void	msghdr(smbmsg_t* msg);
rswindell's avatar
rswindell committed
759
	uchar	msg_listing_flag(uint subnum, smbmsg_t*, post_t*);
760 761 762

	/* chat.cpp */
	void	chatsection(void);
rswindell's avatar
rswindell committed
763
	void	multinodechat(int channel=1);
764 765
	void	nodepage(void);
	void	nodemsg(void);
766 767
	uint	nodemsg_inside;
	uint	hotkey_inside;
768 769
	uchar	lastnodemsg;	/* Number of node last message was sent to */
	char	lastnodemsguser[LEN_ALIAS+1];
770
	void	guruchat(char* line, char* guru, int gurunum, char* last_answer);
771 772
	bool	guruexp(char **ptrptr, char *line);
	void	localguru(char *guru, int gurunum);
rswindell's avatar
rswindell committed
773 774
	bool	sysop_page(void);
	bool	guru_page(void);
775 776 777 778 779 780 781 782
	void	privchat(bool local=false);
	bool	chan_access(uint cnum);
	int		getnodetopage(int all, int telegram);

	/* main.cpp */
	void	printstatslog(uint node);
	ulong	logonstats(void);
	void	logoffstats(void);
783
	int		nopen(char *str, int access);
784
	int		mv(char *src, char *dest, char copy); /* fast file move/copy function */
785
	bool	chksyspass(void);
rswindell's avatar
rswindell committed
786 787
	bool	chk_ar(const uchar * str, user_t* user, client_t* client); /* checks access requirements */
	bool	ar_exp(const uchar ** ptrptr, user_t*, client_t*);
788
	void	daily_maint(void);
789 790 791 792

	/* upload.cpp */
	bool	uploadfile(file_t* f);
	char	sbbsfilename[128],sbbsfiledesc[128]; /* env vars */
793
	bool	upload(uint dirnum);
794 795 796 797 798 799
    char	upload_lastdesc[LEN_FDESC+1];
	bool	bulkupload(uint dirnum);

	/* download.cpp */
	void	downloadfile(file_t* f);
	void	notdownloaded(ulong size, time_t start, time_t end);
800
	int		protocol(prot_t* prot, enum XFER_TYPE, char *fpath, char *fspec, bool cd);
801
	const char*	protcmdline(prot_t* prot, enum XFER_TYPE type);
802 803
	void	seqwait(uint devnum);
	void	autohangup(void);
804 805
	bool	checkdszlog(file_t*);
	bool	checkprotresult(prot_t*, int error, file_t*);
806 807
	bool	sendfile(char* fname, char prot=0);
	bool	recvfile(char* fname, char prot=0);
808 809 810 811 812 813

	/* file.cpp */
	void	fileinfo(file_t* f);
	void	openfile(file_t* f);
	void	closefile(file_t* f);
	bool	removefcdt(file_t* f);
814
	bool	removefile(file_t* f);
815 816 817 818 819 820
	bool	movefile(file_t* f, int newdir);
	char *	getfilespec(char *str);
	bool	checkfname(char *fname);
	bool	addtobatdl(file_t* f);

	/* listfile.cpp */
821 822 823
	bool	listfile(const char *fname, const char *buf, uint dirnum
				,const char *search, const char letter, ulong datoffset);
	int		listfiles(uint dirnum, const char *filespec, int tofile, long mode);
824
	int		listfileinfo(uint dirnum, char *filespec, long mode);
deuce's avatar
deuce committed
825
	void	listfiletofile(char *fname, char *buf, uint dirnum, int file);
826 827 828 829
	int		batchflagprompt(uint dirnum, file_t bf[], uint total, long totalfiles);

	/* bat_xfer.cpp */
	void	batchmenu(void);
830
	void	batch_create_list(void);
831 832
	void	batch_add_list(char *list);
	bool	create_batchup_lst(void);
833
	bool	create_batchdn_lst(bool native);
834 835 836
	bool	create_bimodem_pth(void);
	void	batch_upload(void);
	void	batch_download(int xfrprot);
837
	BOOL	start_batch_download(void);
838 839 840 841 842

	/* tmp_xfer.cpp */
	void	temp_xfer(void);
	void	extract(uint dirnum);
	char *	temp_cmd(void);					/* Returns temp file command line */
843
	ulong	create_filelist(const char *name, long mode);
844 845 846 847 848 849 850 851 852 853

	/* viewfile.cpp */
	int		viewfile(file_t* f, int ext);
	void	viewfiles(uint dirnum, char *fspec);
	void	viewfilecontents(file_t* f);

	/* sortdir.cpp */
	void	resort(uint dirnum);

	/* xtrn.cpp */
854
	int		external(const char* cmdline, long mode, const char* startup_dir=NULL);
855 856 857

	/* xtrn_sec.cpp */
	int		xtrn_sec(void);					/* The external program section  */
858
	void	xtrndat(const char* name, const char* dropdir, uchar type, ulong tleft
859
				,ulong misc);
860 861
	bool	exec_xtrn(uint xtrnnum);			/* Executes online external program */
	bool	user_event(user_event_t);			/* Executes user event(s) */
862 863 864
	char	xtrn_access(uint xnum);			/* Does useron have access to xtrn? */
	void	moduserdat(uint xtrnnum);

rswindell's avatar
rswindell committed
865
	/* logfile.cpp */
866
	void	logentry(const char *code,const char *entry);
867
	void	log(char *str);				/* Writes 'str' to node log */
868
	void	logch(char ch, bool comma);	/* Writes 'ch' to node log */
869 870
	void	logline(const char *code,const char *str); /* Writes 'str' on it's own line in log (LOG_INFO level) */
	void	logline(int level, const char *code,const char *str);
871
	void	logofflist(void);              /* List of users logon activity */
872
	bool	syslog(const char* code, const char *entry);
873
	bool	errormsg_inside;
874
	void	errormsg(int line, const char *file, const char* action, const char *object
875
				,ulong access, const char *extinfo=NULL);
876
	BOOL	hacklog(char* prot, char* text);
877

878 879
	/* qwk.cpp */
	bool	qwklogon;
880
	ulong	qwkmail_last;
881
	void	qwk_sec(void);
882 883 884 885 886 887
	uint	total_qwknodes;
	struct qwknode {
		char	id[LEN_QWKID+1];
		char	path[MAX_PATH+1];
		time_t	time;
	}* qwknode;
888 889 890 891
	void	update_qwkroute(char *via);
	void	qwk_success(ulong msgcnt, char bi, char prepack);
	void	qwksetptr(uint subnum, char *buf, int reset);
	void	qwkcfgline(char *buf,uint subnum);
892
	int		set_qwk_flag(ulong flag);
893
	uint	resolve_qwkconf(uint n, int hubnum=-1);
894 895 896
	bool	qwk_vote(str_list_t ini, const char* section, smb_net_type_t, const char* qnet_id, int hubnum);
	bool	qwk_voting(str_list_t* ini, long offset, smb_net_type_t, const char* qnet_id, int hubnum = -1);
	void	qwk_handle_remaining_votes(str_list_t* ini, smb_net_type_t, const char* qnet_id, int hubnum = -1);
897 898 899 900 901

	/* pack_qwk.cpp */
	bool	pack_qwk(char *packet, ulong *msgcnt, bool prepack);

	/* un_qwk.cpp */
902
	bool	unpack_qwk(char *packet,uint hubnum);
903 904 905 906 907 908 909 910

	/* pack_rep.cpp */
	bool	pack_rep(uint hubnum);

	/* un_rep.cpp */
	bool	unpack_rep(char* repfile=NULL);

	/* msgtoqwk.cpp */
911
	ulong	msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, uint subnum, int conf, FILE* hdrs_dat, FILE* voting_dat = NULL);
912 913

	/* qwktomsg.cpp */
914
	void	qwk_new_msg(ulong confnum, smbmsg_t* msg, char* hdrblk, long offset, str_list_t headers, bool parse_sender_hfields);
rswindell's avatar
rswindell committed
915 916
	bool	qwk_import_msg(FILE *qwk_fp, char *hdrblk, ulong blocks, char fromhub, uint subnum
				,uint touser, smbmsg_t* msg);
917