xtrn_sec.cpp 52.6 KB
Newer Older
1
2
3
4
/* xtrn_sec.cpp */

/* Synchronet external program/door section and drop file routines */

5
/* $Id: xtrn_sec.cpp,v 1.91 2020/08/01 18:34:24 rswindell Exp $ */
6
7
8
9
10

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
11
 * Copyright Rob Swindell - http://www.synchro.net/copyright.html			*
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
43
 *																			*
 * 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.	*
 ****************************************************************************/

#include "sbbs.h"

/****************************************************************************/
/* This is the external programs (doors) section of the bbs                 */
/* Return 1 if no externals available, 0 otherwise. 						*/
/****************************************************************************/
44
int sbbs_t::xtrn_sec(const char* section)
45
{
46
	char	str[MAX_PATH+1];
47

48
49
50
	if(cfg.xtrnsec_mod[0] == '\0') {
		errormsg(WHERE, ERR_CHK, "xtrnsec_mod", 0);
		return 1;
51
	}
52
53
	SAFEPRINTF2(str, "%s %s", cfg.xtrnsec_mod, section);
	return exec_bin(str, &main_csi);
54
55
}

56
const char *hungupstr="\1n\1h%s\1n hung up on \1h%s\1n %s\r\n";
57
58
59
60

/****************************************************************************/
/* Convert C string to pascal string										*/
/****************************************************************************/
61
void str2pas(const char *instr, char *outstr)
62
63
64
65
66
67
68
69
70
71
72
{
	int i;

	outstr[0]=(char)strlen(instr);
	for(i=0;i<outstr[0];i++)
		outstr[i+1]=instr[i];
}

/****************************************************************************/
/* Convert from unix time (seconds since 1/70) to julian (days since 1900)	*/
/****************************************************************************/
73
int unixtojulian(time_t unix_time)
74
75
76
{
	int days[12]={0,31,59,90,120,151,181,212,243,273,304,334};
	long j;
77
	struct tm tm;
78

79
	if(localtime_r(&unix_time,&tm)==NULL)
80
		return(0);
81
82
	j=36525L*(1900+tm.tm_year);
	if(!(j%100) && (tm.tm_mon+1)<3)
83
84
		j--;
	j=(j-(1900*36525))/100;
85
	j+=tm.tm_mday+days[tm.tm_mon];
86
87
88
89
90
91
	return(j);
}

/****************************************************************************/
/* Convert julian date into unix format 									*/
/****************************************************************************/
92
93
94
#ifdef __BORLANDC__
#pragma argsused
#endif
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
time_t juliantounix(ulong j)
{
#if 0 /* julian time */
    int days[2][12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
                       0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
    long temp;
	int leap,counter;
	struct tm tm;

	if(!j) return(0L);

	tm.tm_year=((100L*j)/36525L)-1900;
	temp=(long)date.da_year*36525L;
	date.da_year+=1900;
	j-=temp/100L;

	if (!(temp%100)) {
		j++;
113
114
		leap=1; 
	}
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
	else leap=0;

	for(date.da_mon=counter=0;counter<12;counter++)
		if(days[leap][counter]<j)
			date.da_mon=counter;

	date.da_day=j-days[leap][date.da_mon];
	date.da_mon++;	/* go from 0 to 1 based */

	curtime.ti_hour=curtime.ti_min=curtime.ti_sec=0;
	return(dostounix(&date,&curtime));
#else
	return((time_t)-1);
#endif
}

131
132
133
134
135
#ifdef __unix__
static void lfexpand(char *str, ulong misc)
{
	char *p;
	char newstr[1024];
rswindell's avatar
rswindell committed
136
	size_t len=0;
137
138
139
140

	if(misc&XTRN_NATIVE)
		return;

rswindell's avatar
rswindell committed
141
	for(p=str;*p && len < sizeof(newstr)-2;p++) {
142
143
144
145
146
147
148
149
150
151
152
153
		if(*p=='\n')
			newstr[len++]='\r';
		newstr[len++]=*p;
	}

	newstr[len]=0;
	strcpy(str,newstr);
}
#else
	#define lfexpand(str, misc)
#endif

154
155
156
/****************************************************************************/
/* Creates various types of xtrn (Doors, Chains, etc.) data (drop) files.	*/
/****************************************************************************/
157
void sbbs_t::xtrndat(const char *name, const char *dropdir, uchar type, ulong tleft
158
159
					,ulong misc)
{
160
161
	char	str[1024],tmp2[128],c,*p;
	char 	tmp[512];
deuce's avatar
64-bit    
deuce committed
162
163
164
165
166
	/* TODO: 16-bit i */
	int16_t	i;
	int		file;
	uint16_t	w;
	int32_t	l;
167
168
	struct tm tm;
	struct tm tl;
169
170
	stats_t stats;

171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
	char	node_dir[MAX_PATH+1];
	char	ctrl_dir[MAX_PATH+1];
	char	data_dir[MAX_PATH+1];
	char	exec_dir[MAX_PATH+1];
	char	text_dir[MAX_PATH+1];
	char	temp_dir[MAX_PATH+1];

	SAFECOPY(node_dir,cfg.node_dir);
	SAFECOPY(ctrl_dir,cfg.ctrl_dir);
	SAFECOPY(data_dir,cfg.data_dir);
	SAFECOPY(exec_dir,cfg.exec_dir);
	SAFECOPY(text_dir,cfg.text_dir);
	SAFECOPY(temp_dir,cfg.temp_dir);

	if(!(misc&XTRN_NATIVE)) {
186
#ifdef _WIN32
187
188
		/* Put Micros~1 shortened paths in drop files when running 16-bit DOS programs */
		GetShortPathName(cfg.node_dir,node_dir,sizeof(node_dir));
189
		GetShortPathName(cfg.ctrl_dir,ctrl_dir,sizeof(ctrl_dir));
190
191
192
193
		GetShortPathName(cfg.data_dir,data_dir,sizeof(data_dir));
		GetShortPathName(cfg.exec_dir,exec_dir,sizeof(exec_dir));
		GetShortPathName(cfg.text_dir,text_dir,sizeof(text_dir));
		GetShortPathName(cfg.temp_dir,temp_dir,sizeof(temp_dir));
194
195
196
197
198
199
200
#elif defined(__linux__) && defined(USE_DOSEMU)
		/* These drive mappings must match the Linux/DOSEMU patch in xtrn.cpp: */
		SAFECOPY(node_dir, "D:");
		SAFECOPY(ctrl_dir, "F:");
		SAFECOPY(data_dir, "G:");
		SAFECOPY(exec_dir, "H:");
#endif
201
202
203
	}


204
	if(type==XTRN_SBBS) {	/* SBBS XTRN.DAT file */
205
206
207
208
		strcpy(tmp,"XTRN.DAT");
		if(misc&XTRN_LWRCASE)
			strlwr(tmp);
		sprintf(str,"%s%s",dropdir,tmp);
rswindell's avatar
rswindell committed
209
		removecase(str);
210
211
		if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT))==-1) {
			errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT);
212
213
			return; 
		}
214

215
		safe_snprintf(str, sizeof(str), "%s\n%s\n%s\n%s\n"
216
217
218
219
			,name								/* User name */
			,cfg.sys_name						/* System name */
			,cfg.sys_op 						/* Sysop name */
			,cfg.sys_guru); 					/* Guru name */
220
		lfexpand(str,misc);
221
222
		write(file,str,strlen(str));

223
		safe_snprintf(str, sizeof(str), "%s\n%s\n%u\n%u\n%lu\n%s\n%lu\n%lu\n"
224
225
			,ctrl_dir							/* Ctrl dir */
			,data_dir							/* Data dir */
226
227
228
			,cfg.sys_nodes						/* Total system nodes */
			,cfg.node_num						/* Current node */
			,tleft								/* User Timeleft in seconds */
229
230
			,term_supports(ANSI)				/* User ANSI ? (Yes/Mono/No) */
				? term_supports(COLOR)
231
232
233
				? "Yes":"Mono":"No"
			,rows								/* User Screen lines */
			,useron.cdt+useron.freecdt);		/* User Credits */
234
		lfexpand(str,misc);
235
236
		write(file,str,strlen(str));

237
		safe_snprintf(str, sizeof(str), "%u\n%u\n%s\n%c\n%u\n%s\n"
238
239
240
			,useron.level						/* User main level */
			,useron.level						/* User transfer level */
			,useron.birth						/* User birthday */
241
			,useron.sex ? useron.sex : '?'		/* User sex (M/F) */
242
243
			,useron.number						/* User number */
			,useron.phone); 					/* User phone number */
244
		lfexpand(str,misc);
245
246
		write(file,str,strlen(str));

247
		safe_snprintf(str, sizeof(str), "%u\n%u\n%x\n%lu\n%s\n%s\n"
248
			"%s\n%s\n%s\n%s\n%s\n%s\n%lu\n"
249
			,misc&(XTRN_STDIO|XTRN_CONIO) ? 0:cfg.com_port		/* Com port or 0 if !FOSSIL */
250
251
252
253
254
255
256
257
258
259
260
			,cfg.com_irq						/* Com IRQ */
			,cfg.com_base						/* Com base in hex */
			,dte_rate							/* Com rate */
			,"Yes"								/* Hardware flow ctrl Y/N */
			,"Yes"								/* Locked DTE rate Y/N */
			,cfg.mdm_init						/* Modem initialization string */
			,cfg.mdm_spec						/* Modem special init string */
			,cfg.mdm_term						/* Modem terminal mode init str */
			,cfg.mdm_dial						/* Modem dial string */
			,cfg.mdm_offh						/* Modem off-hook string */
			,cfg.mdm_answ						/* Modem answer string */
261
			,0L
262
			);
263
		lfexpand(str,misc);
264
265
		write(file,str,strlen(str));

266
		sprintf(str,"%u\n",cfg.total_xtrns);
267
		lfexpand(str,misc);
268
269
270
		write(file,str,strlen(str));			/* Total external programs */

		for(i=0;i<cfg.total_xtrns;i++) {		/* Each program's name */
rswindell's avatar
rswindell committed
271
			if(SYSOP || chk_ar(cfg.xtrn[i]->ar,&useron,&client))
272
273
274
				strcpy(str,cfg.xtrn[i]->name);
			else
				str[0]=0;						/* Blank if no access */
rswindell's avatar
rswindell committed
275
			SAFECAT(str,"\n");
276
			lfexpand(str,misc);
277
278
			write(file,str,strlen(str)); 
		}
279

280
		sprintf(str,"%s\n%s\n"
281
282
283
			,ltoaf(useron.flags1,tmp)			/* Main flags */
			,ltoaf(useron.flags2,tmp2)			/* Transfer flags */
			);
284
		lfexpand(str,misc);
285
286
		write(file,str,strlen(str));

287
		sprintf(str,"%s\n%s\n%lx\n%s\n%s\n%s\n"
288
289
			,ltoaf(useron.exempt,tmp)			/* Exemptions */
			,ltoaf(useron.rest,tmp2)			/* Restrictions */
290
			,(long)useron.expire				/* Expiration date in unix form */
291
292
293
294
			,useron.address 					/* Address */
			,useron.location					/* City/State */
			,useron.zipcode 					/* Zip/Postal code */
			);
295
		lfexpand(str,misc);
296
297
		write(file,str,strlen(str));

298
		safe_snprintf(str, sizeof(str), "%s\n%s\n%d\n%s\n%lu\n%s\n%s\n%s\n%s\n"
299
			"%" PRIx32 "\n%d\n"
300
301
			,ltoaf(useron.flags3,tmp)			/* Flag set #3 */
			,ltoaf(useron.flags4,tmp2)			/* Flag set #4 */
302
			,0									/* Time-slice type */
303
304
			,useron.name						/* Real name/company */
			,cur_rate							/* DCE rate */
305
306
307
			,exec_dir
			,text_dir
			,temp_dir
308
309
			,cfg.sys_id
			,cfg.node_misc
310
			,misc&(XTRN_STDIO|XTRN_CONIO) ? INVALID_SOCKET : client_socket_dup
311
			);
312
		lfexpand(str,misc);
313
314
		write(file,str,strlen(str));

315
316
		close(file); 
	}
317
318

	else if(type==XTRN_WWIV) {	/*	WWIV CHAIN.TXT File */
319
320
321
322
		strcpy(tmp,"CHAIN.TXT");
		if(misc&XTRN_LWRCASE)
			strlwr(tmp);
		sprintf(str,"%s%s",dropdir,tmp);
rswindell's avatar
rswindell committed
323
		removecase(str);
324
325
		if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT))==-1) {
			errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT);
326
327
			return; 
		}
328

329
330
331
		if(tleft>0x7fff)	/* Reduce time-left for broken 16-bit doors		*/
			tleft=0x7fff;	/* That interpret this value as a signed short	*/

332
		safe_snprintf(str, sizeof(str), "%u\n%s\n%s\n%s\n%u\n%c\n"
333
334
335
336
337
			,useron.number						/* User number */
			,name								/* User name */
			,useron.name						/* User real name */
			,nulstr 							/* User call sign */
			,getage(&cfg,useron.birth)			/* User age */
338
			,useron.sex ? useron.sex : '?');	/* User sex (M/F) */
339
		strupr(str);
340
		lfexpand(str,misc);
341
342
		write(file,str,strlen(str));

343
		safe_snprintf(str, sizeof(str), "%lu\n%s\n%lu\n%ld\n%u\n%u\n%u\n%ld\n%u\n"
344
345
			,useron.cdt+useron.freecdt			/* Gold */
			,unixtodstr(&cfg,useron.laston,tmp)	/* User last on date */
346
			,cols 								/* User screen width */
347
348
349
350
			,rows								/* User screen length */
			,useron.level						/* User SL */
			,0									/* Cosysop? */
			,SYSOP								/* Sysop? (1/0) */
351
			,term_supports(ANSI)				/* ANSI ? (1/0) */
352
			,online==ON_REMOTE);				/* Remote (1/0) */
353
		lfexpand(str,misc);
354
355
		write(file,str,strlen(str));

356
		safe_snprintf(str, sizeof(str), "%lu\n%s\n%s\n%s\n%lu\n%d\n%s\n%s\n"
357
			"%u\n%u\n%lu\n%u\n%lu\n%u\n%s\n"
358
			,tleft								/* Time left in seconds */
359
360
			,node_dir							/* Gfiles dir (log dir) */
			,data_dir							/* Data dir */
361
			,"node.log"                         /* Name of log file */
362
363
364
365
366
367
368
369
370
371
372
			,dte_rate							/* DTE rate */
			,cfg.com_port						/* COM port number */
			,cfg.sys_name						/* System name */
			,cfg.sys_op 						/* Sysop name */
			,0									/* Logon time (sec past 12am) */
			,0									/* Current time (sec past 12am) */
			,useron.ulb/1024UL					/* User uploaded kbytes */
			,useron.uls 						/* User uploaded files */
			,useron.dlb/1024UL					/* User downloaded kbytes */
			,useron.dls 						/* User downloaded files */
			,"8N1");                            /* Data, parity, stop bits */
373
		lfexpand(str,misc);
374
375
		write(file,str,strlen(str));

376
377
		close(file); 
	}
378
379

	else if(type==XTRN_GAP) {	/* Gap DOOR.SYS File */
380
381
382
383
		strcpy(tmp,"DOOR.SYS");
		if(misc&XTRN_LWRCASE)
			strlwr(tmp);
		sprintf(str,"%s%s",dropdir,tmp);
rswindell's avatar
rswindell committed
384
		removecase(str);
385
386
		if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT))==-1) {
			errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT);
387
388
			return; 
		}
389

390
391
392
		if(tleft>0x7fff)	/* Reduce time-left for broken 16-bit doors		*/
			tleft=0x7fff;	/* That interpret this value as a signed short	*/

393
394
#if 0
		if(misc&XTRN_NATIVE) {
395
			if(misc&(XTRN_STDIO|XTRN_CONIO)) {
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
				strcpy(str,"COM0:STDIO\n");
			}
			else {
				sprintf(str,"COM0:SOCKET%d\n",
					client_socket_dup
				);
			}
		}
		else {
			sprintf(str,"COM%d:\n"
				,online==ON_REMOTE ? cfg.com_port:0);	/* 01: COM port - 0 if Local */
		}
#else
		sprintf(str,"COM%d:\n"
			,online==ON_REMOTE ? cfg.com_port:0);	/* 01: COM port - 0 if Local */
#endif
		lfexpand(str,misc);
		write(file,str,strlen(str));
414
415
416
417
418
419
420
421
		/* Note about door.sys, line 2 (April-24-2005):
		   It *should* be the DCE rate (any number, including the popular modem
		   DCE rates of 14400, 28800, and 33600).  However, according to Deuce,
		   doors created with the DMlib door kit choke with "Error -25: Illegal
		   baud rate" if this isn't a valid FOSSIL baud (DTE) rate, so we're
		   changing this value to the DTE rate until/unless some other doors
		   have an issue with that. <sigh>
		*/
422
		sprintf(str,"%lu\n%u\n%u\n%lu\n%c\n%c\n%c\n%c\n"
423
			,dte_rate /* was cur_rate */		/* 02: DCE rate, see note above */
424
425
426
			,8									/* 03: Data bits */
			,cfg.node_num						/* 04: Node number */
			,dte_rate							/* 05: DTE rate */
427
			,'Y'								/* 06: Screen display */
428
429
430
			,'Y'                                /* 07: Printer toggle */
			,'Y'                                /* 08: Page bell */
			,'Y');                              /* 09: Caller alarm */
431
		lfexpand(str,misc);
432
433
		write(file,str,strlen(str));

434
		sprintf(str,"%s\n%s\n%s\n%s\n%s\n"
435
436
437
438
439
			,name								/* 10: User name */
			,useron.location					/* 11: User location */
			,useron.phone						/* 12: User home phone */
			,useron.phone						/* 13: User work/data phone */
			,useron.pass);						/* 14: User password */
440
		lfexpand(str,misc);
441
442
		write(file,str,strlen(str));

443
		sprintf(str,"%u\n%u\n%s\n%lu\n%lu\n%s\n"
444
445
446
447
448
449
450
			,useron.level						/* 15: User security level */
			,useron.logons						/* 16: User total logons */
			,unixtodstr(&cfg,useron.laston,tmp)	/* 17: User last on date */
			,tleft								/* 18: User time left in sec */
			,tleft/60							/* 19: User time left in min */
			,useron.misc&NO_EXASCII 			/* 20: GR if COLOR ANSI */
				? "7E" : (useron.misc&(ANSI|COLOR))==(ANSI|COLOR) ? "GR" : "NG");
451
		lfexpand(str,misc);
452
453
		write(file,str,strlen(str));

454
		sprintf(str,"%lu\n%c\n%s\n%u\n%s\n%u\n%c\n%u\n%u\n"
455
			,rows								/* 21: User screen length */
456
			,(useron.misc&EXPERT) ? 'Y':'N'     /* 22: Expert? (Y/N) */
457
458
459
460
			,ltoaf(useron.flags1,tmp2)			/* 23: Registered conferences */
			,0									/* 24: Conference came from */
			,unixtodstr(&cfg,useron.expire,tmp)	/* 25: User expiration date */
			,useron.number						/* 26: User number */
461
			,useron.prot                        /* 27: Default protocol */
462
463
			,useron.uls 						/* 28: User total uploads */
			,useron.dls);						/* 29: User total downloads */
464
		lfexpand(str,misc);
465
466
		write(file,str,strlen(str));

467
		safe_snprintf(str, sizeof(str), "%u\n%lu\n%s\n%s\n%s\n%s"
468
			"\n%s\n%02d:%02d\n%c\n"
469
470
471
			,0									/* 30: Kbytes downloaded today */
			,(useron.cdt+useron.freecdt)/1024UL /* 31: Max Kbytes to download today */
			,useron.birth						/* 32: User birthday */
472
473
			,node_dir							/* 33: Path to MAIN directory */
			,data_dir							/* 34: Path to GEN directory */
474
475
476
477
478
			,cfg.sys_op 						/* 35: Sysop name */
			,nulstr 							/* 36: Alias name */
			,0 // sys_eventtime/60				/* 37: Event time HH:MM */
			,0 // sys_eventtime%60
			,'Y');                              /* 38: Error correcting connection */
479
		lfexpand(str,misc);
480
481
		write(file,str,strlen(str));

482
		localtime_r(&ns_time,&tm);
483
		sprintf(str,"%c\n%c\n%u\n%lu\n%02d/%02d/%02d\n"
484
485
486
			,(useron.misc&(NO_EXASCII|ANSI|COLOR))==ANSI
				? 'Y':'N'                       /* 39: ANSI supported but NG mode */
			,'Y'                                /* 40: Use record locking */
487
			,cfg.color[clr_external]			/* 41: BBS default color */
488
			,useron.min 						/* 42: Time credits in minutes */
489
490
491
			,tm.tm_mon+1						/* 43: File new-scan date */
			,tm.tm_mday
			,TM_YEAR(tm.tm_year));
492
		lfexpand(str,misc);
493
494
		write(file,str,strlen(str));

deuce's avatar
deuce committed
495
		localtime_r(&logontime,&tm);
496
		localtime32(&useron.laston,&tl);
497
498
		sprintf(str,"%02d:%02d\n%02d:%02d\n%u\n%u\n%lu\n"
			"%lu\n%s\n%u\n%u\n"
499
			,tm.tm_hour							/* 44: Time of this call */
500
			,tm.tm_min
501
			,tl.tm_hour							/* 45: Time of last call */
502
			,tl.tm_min
503
504
505
506
507
508
509
			,999								/* 46: Max daily files available */
			,0									/* 47: Files downloaded so far today */
			,useron.ulb/1024UL					/* 48: Total Kbytes uploaded */
			,useron.dlb/1024UL					/* 49: Total Kbytes downloaded */
			,useron.comment 					/* 50: User comment */
			,0									/* 51: Total doors opened */
			,useron.posts); 					/* 52: User message left */
510
		lfexpand(str,misc);
511
512
		write(file,str,strlen(str));

513
514
		close(file); 
	}
515
516
517

	else if(type==XTRN_RBBS || type==XTRN_RBBS1) {
		if(type==XTRN_RBBS)
518
			sprintf(tmp,"DORINFO%X.DEF",cfg.node_num);   /* support 1-F */
519
		else
520
521
522
523
			sprintf(tmp,"DORINFO1.DEF");
		if(misc&XTRN_LWRCASE)
			strlwr(tmp);
		sprintf(str,"%s%s",dropdir,tmp);
rswindell's avatar
rswindell committed
524
		removecase(str);
525
526
		if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT))==-1) {
			errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT);
527
528
			return; 
		}
529
530

		strcpy(tmp,cfg.sys_op);
531
		p=strchr(tmp,' ');
532
533
534
535
536
		if(p)
			*(p++)=0;
		else
			p=nulstr;

537
		sprintf(str,"%s\n%s\n%s\nCOM%d\n%lu BAUD,N,8,1\n%u\n"
538
539
540
541
542
543
544
			,cfg.sys_name						/* Name of BBS */
			,tmp								/* Sysop's firstname */
			,p									/* Sysop's lastname */
			,online==ON_REMOTE ? cfg.com_port:0 /* COM port number, 0 if local */
			,dte_rate							/* DTE rate */
			,0);								/* Network type */
		strupr(str);
545
		lfexpand(str,misc);
546
547
548
		write(file,str,strlen(str));

		strcpy(tmp,name);
549
		p=strchr(tmp,' ');
550
551
552
553
		if(p)
			*(p++)=0;
		else
			p=nulstr;
deuce's avatar
deuce committed
554
		sprintf(str,"%s\n%s\n%s\n%ld\n%u\n%lu\n"
555
556
557
			,tmp								/* User's firstname */
			,p									/* User's lastname */
			,useron.location					/* User's city */
558
			,term_supports(ANSI)				/* 1=ANSI 0=ASCII */
559
560
561
			,useron.level						/* Security level */
			,tleft/60); 						/* Time left in minutes */
		strupr(str);
562
		lfexpand(str,misc);
563
564
565
566
		write(file,str,strlen(str));

		close(file);

567
568
569
570
		strcpy(tmp,"EXITINFO.BBS");
		if(misc&XTRN_LWRCASE)
			strlwr(tmp);
		sprintf(str,"%s%s",dropdir,tmp);
rswindell's avatar
rswindell committed
571
		removecase(str);
572
573
		if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
			errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC);
574
575
			return; 
		}
576
		w=(WORD)dte_rate;
deuce's avatar
64-bit    
deuce committed
577
		write(file,&w,sizeof(w));			/* BaudRate */
578
579
		/* SysInfo */
		getstats(&cfg,0,&stats);
deuce's avatar
64-bit    
deuce committed
580
		write(file,&stats.logons,sizeof(stats.logons)); /* CallCount */
581
582
583
584
585
		write(file,nulstr,36);					/* LastCallerName */
		write(file,nulstr,36);					/* LastCallerAlias */
		write(file,nulstr,92);					/* ExtraSpace */
		/* TimeLogInfo */
		write(file,nulstr,9);					/* StartDate */
deuce's avatar
64-bit    
deuce committed
586
587
		write(file,nulstr,24*sizeof(int16_t));	/* BusyPerHour */
		write(file,nulstr,7*sizeof(int16_t));		/* BusyPerDay */
588
589
590
591
592
593
594
595
596
597
		/* UserInfo */
		str2pas(name,str);				/* Name */
		write(file,str,36);
		str2pas(useron.location,str);
		write(file,str,26); 					/* City */
		str2pas(useron.pass,str);
		write(file,str,16); 					/* Pwd */
		str2pas(useron.phone,str);
		write(file,str,13); 					/* DataPhone */
		write(file,str,13); 					/* HomePhone */
598
		localtime32(&useron.laston,&tm);
599
		sprintf(tmp,"%02d:%02d",tm.tm_hour,tm.tm_min);
600
601
602
603
604
605
606
607
608
		str2pas(tmp,str);
		write(file,str,6);						/* LastTime */
		unixtodstr(&cfg,useron.laston,tmp);
		str2pas(tmp,str);
		write(file,str,9);						/* LastDate */
		c=0;
		if(useron.misc&DELETED) c|=(1<<0);
		if(useron.misc&CLRSCRN) c|=(1<<1);
		if(useron.misc&UPAUSE)	 c|=(1<<2);
609
		if(term_supports(ANSI))	c|=(1<<3);
610
611
612
613
		if(useron.sex=='F')     c|=(1<<7);
		write(file,&c,1);						/* Attrib */
		write(file,&useron.flags1,4);			/* Flags */
		w=0;
deuce's avatar
64-bit    
deuce committed
614
615
616
617
		write(file,&w,sizeof(w)); 			/* Credit */
		write(file,&w,sizeof(w)); 			/* Pending */
		write(file,&useron.posts,sizeof(useron.posts));/* TimesPosted */
		write(file,&w,sizeof(w)); 			/* HighMsgRead */
618
		w=useron.level;
deuce's avatar
64-bit    
deuce committed
619
		write(file,&w,sizeof(w)); 			/* SecLvl */
620
		w=0;
deuce's avatar
64-bit    
deuce committed
621
622
623
		write(file,&w,sizeof(w)); 			/* Times */
		write(file,&useron.uls,sizeof(useron.uls));	/* Ups */
		write(file,&useron.dls,sizeof(useron.dls));	/* Downs */
624
		w=(ushort)(useron.ulb/1024UL);
deuce's avatar
64-bit    
deuce committed
625
		write(file,&w,sizeof(w)); 			/* UpK */
626
		w=(ushort)(useron.dlb/1024UL);
deuce's avatar
64-bit    
deuce committed
627
		write(file,&w,sizeof(w)); 			/* DownK */
628
		w=(ushort)(logon_dlb/1024UL);
deuce's avatar
64-bit    
deuce committed
629
		write(file,&w,sizeof(w)); 			/* TodayK */
630
		w=0;
deuce's avatar
64-bit    
deuce committed
631
632
633
634
		write(file,&w,sizeof(w)); 			/* Elapsed */
		write(file,&w,sizeof(w)); 			/* Len */
		write(file,&w,sizeof(w)); 			/* CombinedPtr */
		write(file,&w,sizeof(w)); 			/* AliasPtr */
635
		l=0;
deuce's avatar
64-bit    
deuce committed
636
		write(file,&l,sizeof(l));			/* Birthday (as a long?) */
637
638
639
		/* EventInfo */
		c=0;
		write(file,&c,sizeof(char));			/* Status */
deuce's avatar
64-bit    
deuce committed
640
		write(file,&l /* sys_eventtime */,sizeof(l));	/* RunTime */
641
642
643
644
645
646
647
648
649
650
		write(file,&c,sizeof(char));			/* ErrorLevel */
		c='\xff';
		write(file,&c,sizeof(char));			/* Days */
		// c=sys_eventnode==node_num || sys_misc&SM_TIMED_EX ? 1 : 0;
		c=0;
		write(file,&c,sizeof(char));			/* Forced */
		if(!cfg.total_events)
			l=0;
		else
			l=cfg.event[0]->last;
deuce's avatar
64-bit    
deuce committed
651
		write(file,&l,sizeof(l));			/* LastTimeRun */
652
653
654
655
656
657
658
		memset(str,0,40);
		write(file,str,7);						/* Spare */

		c=0;
		write(file,&c,1);						/* NetMailEntered */
		write(file,&c,1);						/* EchoMailEntered */

deuce's avatar
deuce committed
659
		localtime_r(&logontime,&tm);
660
		sprintf(tmp,"%02d:%02d",tm.tm_hour,tm.tm_min);
661
662
		str2pas(tmp,str);
		write(file,str,6);						/* LoginTime */
663
		unixtodstr(&cfg,(time32_t)logontime,tmp);
664
665
		str2pas(tmp,str);
		write(file,str,9);						/* LoginDate */
deuce's avatar
64-bit    
deuce committed
666
667
668
669
		write(file,&cfg.level_timepercall[useron.level],sizeof(int16_t));  /* TmLimit */
		write(file,&logontime,sizeof(logontime));	/* LoginSec */
		write(file,&useron.cdt,sizeof(useron.cdt));	/* Credit */
		write(file,&useron.number,sizeof(useron.number)); /* UserRecNum */
rswindell's avatar
rswindell committed
670
		i=0;
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
		write(file,&i,2);						/* ReadThru */
		write(file,&i,2);						/* PageTimes */
		write(file,&i,2);						/* DownLimit */
		c=sys_status&SS_SYSPAGE ? 1:0;
		write(file,&c,1);						/* WantChat */
		c=0;
		write(file,&c,1);						/* GosubLevel */

		memset(str,0,255);
		for(i=1;i<20;i++)
			write(file,str,9);					/* GosubData */
		write(file,str,9);						/* Menu */
		c=useron.misc&CLRSCRN ? 1:0;
		write(file,&c,1);						/* ScreenClear */
		c=useron.misc&UPAUSE ? 1:0;
		write(file,&c,1);						/* MorePrompts */
		c=useron.misc&NO_EXASCII ? 0:1;
		write(file,&c,1);						/* GraphicsMode */
		c=useron.xedit ? 1:0;
		write(file,&c,1);						/* ExternEdit */
691
		i=(int16_t)rows;
692
693
694
695
696
697
		write(file,&i,2);						/* ScreenLength */
		c=1;
		write(file,&c,1);						/* MNP_Connect */
		write(file,str,49); 					/* ChatReason */
		c=0;
		write(file,&c,1);						/* ExternLogoff */
698
		c=(char)term_supports(ANSI);
699
700
		write(file,&c,1);						/* ANSI_Capable */
		close(file);
701
	}
702
703

	else if(type==XTRN_WILDCAT) { /* WildCat CALLINFO.BBS File */
704
705
706
707
		strcpy(tmp,"CALLINFO.BBS");
		if(misc&XTRN_LWRCASE)
			strlwr(tmp);
		sprintf(str,"%s%s",dropdir,tmp);
rswindell's avatar
rswindell committed
708
		removecase(str);
709
710
		if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT))==-1) {
			errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT);
711
712
			return; 
		}
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736

		if(online==ON_LOCAL) i=5;
		else
			switch(dte_rate) {
				case 300:
					i=1;
					break;
				case 1200:
					i=2;
					break;
				case 2400:
					i=0;
					break;
				case 9600:
					i=3;
					break;
				case 19200:
					i=4;
					break;
				case 38400:
					i=6;
					break;
				default:
					i=7;
737
738
					break; 
		}
739
		sprintf(str,"%s\n%u\n%s\n%u\n%lu\n%s\n%s\n%u\n"
740
741
742
743
744
			,name								/* User name */
			,i									/* DTE rate */
			,useron.location					/* User location */
			,useron.level						/* Security level */
			,tleft/60							/* Time left in min */
745
			,term_supports(ANSI) ? "COLOR":"MONO"  /* ANSI ??? */
746
747
			,useron.pass						/* Password */
			,useron.number);					/* User number */
748
		lfexpand(str,misc);
749
750
		write(file,str,strlen(str));

751
		localtime_r(&now,&tm);
752
		sprintf(str,"%lu\n%02d:%02d\n%02d:%02d %02d/%02d/%02d\n%s\n"
753
			,tleft								/* Time left in seconds */
754
755
756
757
			,tm.tm_hour,tm.tm_min 			/* Current time HH:MM */
			,tm.tm_hour,tm.tm_min 			/* Current time and date HH:MM */
			,tm.tm_mon+1,tm.tm_mday			/* MM/DD/YY */
			,TM_YEAR(tm.tm_year)
758
			,nulstr);							/* Conferences with access */
759
		lfexpand(str,misc);
760
761
		write(file,str,strlen(str));

762
		localtime32(&useron.laston,&tm);
763
		sprintf(str,"%u\n%u\n%u\n%u\n%s\n%s %02u:%02u\n"
764
765
766
767
768
769
			,0									/* Daily download total */
			,0									/* Max download files */
			,0									/* Daily download k total */
			,0									/* Max download k total */
			,useron.phone						/* User phone number */
			,unixtodstr(&cfg,useron.laston,tmp)	/* Last on date and time */
770
771
			,tm.tm_hour						/* MM/DD/YY  HH:MM */
			,tm.tm_min);
772
		lfexpand(str,misc);
773
774
		write(file,str,strlen(str));

775
		localtime_r(&ns_time,&tm);
776
777
		sprintf(str,"%s\n%s\n%02d/%02d/%02d\n%u\n%lu\n%u"
			"\n%u\n%u\n"
778
779
780
			,useron.misc&EXPERT 				/* Expert or Novice mode */
				? "EXPERT":"NOVICE"
			,"All"                              /* Transfer Protocol */
781
782
			,tm.tm_mon+1,tm.tm_mday			/* File new-scan date */
			,TM_YEAR(tm.tm_year)				/* in MM/DD/YY */
783
784
785
786
787
			,useron.logons						/* Total logons */
			,rows								/* Screen length */
			,0									/* Highest message read */
			,useron.uls 						/* Total files uploaded */
			,useron.dls);						/* Total files downloaded */
788
		lfexpand(str,misc);
789
790
		write(file,str,strlen(str));

791
		sprintf(str,"%u\n%s\nCOM%u\n%s\n%lu\n%s\n%s\n"
792
793
794
795
796
797
798
			,8									/* Data bits */
			,online==ON_LOCAL?"LOCAL":"REMOTE"  /* Online local or remote */
			,cfg.com_port						/* COMx port */
			,useron.birth						/* User birthday */
			,dte_rate							/* DTE rate */
			,"FALSE"                            /* Already connected? */
			,"Normal Connection");              /* Normal or ARQ connect */
799
		lfexpand(str,misc);
800
801
		write(file,str,strlen(str));

802
		localtime_r(&now,&tm);
803
		sprintf(str,"%02d/%02d/%02d %02d:%02d\n%u\n%u\n"
804
805
806
			,tm.tm_mon+1,tm.tm_mday			/* Current date MM/DD/YY */
			,TM_YEAR(tm.tm_year)
			,tm.tm_hour,tm.tm_min 			/* Current time HH:MM */
807
808
			,cfg.node_num						/* Node number */
			,0);								/* Door number */
809
		lfexpand(str,misc);
810
811
		write(file,str,strlen(str));

812
813
		close(file); 
	}
814
815

	else if(type==XTRN_PCBOARD) { /* PCBoard Files */
816
817
818
819
		strcpy(tmp,"PCBOARD.SYS");
		if(misc&XTRN_LWRCASE)
			strlwr(tmp);
		sprintf(str,"%s%s",dropdir,tmp);
rswindell's avatar
rswindell committed
820
		removecase(str);
821
822
		if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
			errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC);
823
824
			return; 
		}
825
826
827
828
829

		sprintf(str,"%2d%2d%2d%2d%c%2d%c%c%5u%-5.5s"
			,-1 								/* Display on/off */
			,0									/* Printer on/off */
			,sys_status&SS_SYSPAGE ? -1:0		/* Page Bell on/off */
830
			,startup->answer_sound[0] ? -1:0	/* Caller Alarm on/off */
831
			,' ' 								/* Sysop next flag */
832
833
834
835
836
837
838
839
840
841
842
843
			,0									/* Error corrected */
			,useron.misc&NO_EXASCII ? '7'       /* Graphics mode */
				: (useron.misc&(COLOR|ANSI))==(COLOR|ANSI) ? 'Y':'N'
			,'A'                                /* Node chat status */
			,(uint)dte_rate 					/* DTE Port Speed */
			,connection 						/* Connection description */
			);
		write(file,str,23);

		write(file,&useron.number,2);			/* User record number */

		strcpy(tmp,name);
844
		p=strchr(tmp,' ');
845
846
847
848
849
850
		if(p) *p=0;
		sprintf(str,"%-15.15s%-12s"
			,tmp								/* User's first name */
			,useron.pass);						/* User's password */
		write(file,str,27);

deuce's avatar
deuce committed
851
		if(localtime_r(&logontime,&tm)==NULL)
852
853
			i=0;
		else
854
			i=(tm.tm_hour*60)+tm.tm_min;
855
856
857
		write(file,&i,2);						/* Logon time in min since mid */

		now=time(NULL);
858
		i=-(int16_t)(((now-starttime)/60)+(time_t)useron.ttoday);/* Negative minutes used */
859
860
		write(file,&i,2);

861
		sprintf(str,"%02d:%02d",tm.tm_hour,tm.tm_min);
862
863
864
865
866
		write(file,str,5);

		i=cfg.level_timepercall[useron.level];	/* Time allowed on */
		write(file,&i,2);

867
		c=0;
868
869
		i=0;									/* Allowed K-bytes for D/L */
		write(file,&i,2);
870
		write(file,&c,1);						/* Conference user was in */
871
872
873
874
875
876
877
878
879
880
881
882
883
884
		write(file,&i,2);						/* Conferences joined */
		write(file,&i,2);						/* "" */
		write(file,&i,2);						/* "" */
		write(file,&i,2);						/* Conferences scanned */
		write(file,&i,2);						/* "" */
		write(file,&i,2);						/* Conference add time */
		write(file,&i,2);						/* Upload/Sysop Chat time min */

		strcpy(str,"    ");
		write(file,str,4);						/* Language extension */

		sprintf(str,"%-25.25s",name);           /* User's full name */
		write(file,str,25);

885
		i=(int16_t)(tleft/60);
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
		write(file,&i,2);						/* Minutes remaining */

		write(file,&cfg.node_num,1);			/* Node number */

		sprintf(str,"%02d:%02d%2d%2d"           /* Scheduled Event time */
			,0 // sys_eventtime/60
			,0 // sys_eventtime%60
			,0 // sys_timed[0] ? -1:0				 /* Event active ? */
			,0									/* Slide event ? */
			);
		write(file,str,9);

		l=0L;
		write(file,&l,4);						/* Memorized message number */

deuce's avatar
deuce committed
901
		sprintf(str,"%d%c%c%ld%s%c%c%d%d%d%c%c"
902
			,cfg.com_port						/* COM Port number */
903
904
			,' ' 								/* Reserved */
			,' ' 								/* "" */
905
			,term_supports(ANSI)				/* 1=ANSI 0=NO ANSI */
906
907
908
909
910
911
912
913
914
915
916
			,"01-01-80"                         /* last event date */
			,0,0								/* last event minute */
			,0									/* caller exited to dos */
			,sys_status&SS_EVENT ? 1:0			/* event up coming */
			,0									/* stop uploads */
			,0,0								/* conference user was in */
			);
		write(file,str,19);

		close(file);			/* End of PCBOARD.SYS creation */

917
918
919
920
		strcpy(tmp,"USERS.SYS");
		if(misc&XTRN_LWRCASE)
			strlwr(tmp);
		sprintf(str,"%s%s",dropdir,tmp);
rswindell's avatar
rswindell committed
921
		removecase(str);
922
923
		if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
			errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC);
924
925
			return; 
		}
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956

		/* Write goof-ball header */

		i=145;
		write(file,&i,2);		/* PCBoard version number (i.e. 145) */
		l=useron.number;
		write(file,&l,4);		/* Record number for USER's file */
		i=218;
		write(file,&i,2);		/* Size of "fixed" user record */
		i=1;
		write(file,&i,2);		/* Number of conference areas */
		i=7;
		write(file,&i,2);		/* Number of bit map fields for conferences */
		i=5;
		write(file,&i,2);		/* Size of each bit map field */
		memset(str,0,15);
		write(file,str,15); 	/* Name of Third Party Application (if any) */
		i=0;
		write(file,&i,2);		/* Version number for application (if any) */
		write(file,&i,2);		/* Size of a "fixed length" record (if any) */
		write(file,&i,2);		/* Size of conference record (if any) */
		l=0;
		write(file,&l,4);		/* Offset of AppRec into USERS.INF (if any) */
		i=0;
		write(file,&i,1);		/* 1, if USERS.SYS file has been updated */

		/* Write fixed record portion */

		write(file,name,26);			/* Name */
		sprintf(str,"%.24s",useron.location);
		write(file,str,25); 			/* Location */
rswindell's avatar
rswindell committed
957
958
959
960
961
962
963
964
		write(file,useron.pass, 9); 	/* Password */
		l=0;
		write(file, &l, 4);	/* more password bytes */
		c=0;
		write(file,useron.phone, 13);	/* Business or Data Phone */
		write(file, &c, 1);	/* more phone number bytes */
		write(file,useron.phone, 13);	/* Home or Voice Phone */
		write(file, &c, 1);	/* more phone number bytes */
965
966
		i=unixtojulian(useron.laston);
		write(file,&i,2);				/* Date last on */
967
		localtime32(&useron.laston,&tm);
968
		sprintf(str,"%02d:%02d",tm.tm_hour,tm.tm_min);
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
		write(file,str,6);				/* Last time on */
		if(useron.misc&EXPERT)
			i=1;
		else
			i=0;
		write(file,&i,1);				/* Expert mode */
		i='Z';
		write(file,&i,1);				/* Protocol (A-Z) */
		if(useron.misc&CLRSCRN)
			i=2;
		else
			i=0;
		write(file,&i,1);				/* bit packed flags */
		i=0;
		write(file,&i,2);				/* DOS date for last DIR Scan */
		i=useron.level;
		write(file,&i,2);				/* Security level */
		write(file,&useron.logons,2);	/* Number of times caller has connected */
		c=(char)rows;
		write(file,&c,1);				/* Page length */
		write(file,&useron.uls,2);		/* Number of uploads */
		write(file,&useron.dls,2);		/* Number of downloads */
		l=0;
		write(file,&l,4);				/* Number of download bytes today */
		write(file,&useron.note,31);	/* Comment #1 */
		write(file,&useron.comp,31);	/* Comment #2 */
995
		i=(int16_t)(now-starttime)/60;
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
		write(file,&i,2);				/* Minutes online (this logon?) */
		i=unixtojulian(useron.expire);
		write(file,&i,2);				/* Expiration date */
		i=cfg.expired_level;
		write(file,&i,2);				/* Expired security level */
		i=1;
		write(file,&i,2);				/* Current conference */
		write(file,&useron.dlb,4);		/* Bytes downloaded */
		write(file,&useron.ulb,4);		/* Bytes uploaded */
		if(useron.misc&DELETED)
			i=1;
		else
			i=0;
		write(file,&i,1);				/* Deleted? */
		l=useron.number;
		write(file,&l,4);				/* Record number in USERS.INF file */
		l=0;
		memset(str,0,9);
		write(file,str,9);				/* Reserved */
		write(file,&l,4);				/* Number of messages read */
		l=useron.posts+useron.emails+useron.fbacks;
		write(file,&l,4);				/* Number of messages left */
		close(file);

		/* End of USERS.SYS creation */
1021
	}
1022
1023

	else if(type==XTRN_SPITFIRE) {	 /* SpitFire SFDOORS.DAT File */
1024
1025
1026
1027
		strcpy(tmp,"SFDOORS.DAT");
		if(misc&XTRN_LWRCASE)
			strlwr(tmp);
		sprintf(str,"%s%s",dropdir,tmp);
rswindell's avatar
rswindell committed
1028
		removecase(str);
1029
1030
		if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT))==-1) {
			errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT);
1031
1032
			return; 
		}
1033
1034

		now=time(NULL);
1035
		if(localtime_r(&now,&tm)==NULL)
1036
1037
			l=0;
		else
1038
1039
			l=((((long)tm.tm_hour*60L)+(long)tm.tm_min)*60L)
				+(long)tm.tm_sec;
1040
1041

		strcpy(tmp,name);
1042
		if((p=strchr(tmp,' '))!=NULL)
1043
1044
			*p=0;

1045
		sprintf(str,"%u\n%s\n%s\n%s\n%lu\n%u\n%lu\n%" PRId32 "\n"
1046
1047
1048
1049
1050
1051
1052
1053
1054
			,useron.number						/* User number */
			,name								/* User name */
			,useron.pass						/* Password */
			,tmp								/* User's first name */
			,dte_rate							/* DTE Rate */
			,cfg.com_port						/* COM Port */
			,tleft/60							/* Time left in minutes */
			,l									/* Seconds since midnight (now) */
			);
1055
		lfexpand(str,misc);
1056
1057
		write(file,str,strlen(str));

deuce's avatar
deuce committed
1058
		if(localtime_r(&logontime,&tm)==NULL)
1059
1060
			l=0;
		else
1061
1062
			l=((((long)tm.tm_hour*60L)+(long)tm.tm_min)*60L)
				+(long)tm.tm_sec;
1063

1064
		sprintf(str,"%s\n%s\n%u\n%u\n%u\n%u\n%" PRId32 "\n%lu\n%s\n"
1065
1066
			"%s\n%s\n%lu\n%s\n%u\n%u\n%u\n%u\n%u\n%lu\n%u\n"
			"%lu\n%lu\n%s\n%s\n"
1067
			,dropdir
1068
			,term_supports(ANSI) ? "TRUE":"FALSE"  /* ANSI ? True or False */
1069
1070
1071
1072
1073
			,useron.level						/* Security level */
			,useron.uls 						/* Total uploads */
			,useron.dls 						/* Total downloads */
			,cfg.level_timepercall[useron.level]/* Minutes allowed this call */
			,l									/* Secs since midnight (logon) */
1074
			,(long)(starttime-logontime)		/* Extra time in seconds */
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
			,"FALSE"                            /* Sysop next? */
			,"FALSE"                            /* From Front-end? */
			,"FALSE"                            /* Software Flow Control? */
			,dte_rate							/* DTE Rate */
			,"FALSE"                            /* Error correcting connection? */
			,0									/* Current conference */
			,0									/* Current file dir */
			,cfg.node_num						/* Node number */
			,15 								/* Downloads allowed per day */
			,0									/* Downloads already this day */
1085
			,100000L 							/* Download bytes allowed/day */