xtrn_sec.cpp 53.6 KB
Newer Older
1
2
3
4
5
6
/* Synchronet external program/door section and drop file routines */

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
7
 * Copyright Rob Swindell - http://www.synchro.net/copyright.html			*
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 *																			*
 * 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										*
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * 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. 						*/
/****************************************************************************/
28
int sbbs_t::xtrn_sec(const char* section)
29
{
30
	char	str[MAX_PATH+1];
31

32
33
34
	if(cfg.xtrnsec_mod[0] == '\0') {
		errormsg(WHERE, ERR_CHK, "xtrnsec_mod", 0);
		return 1;
35
	}
36
37
	SAFEPRINTF2(str, "%s %s", cfg.xtrnsec_mod, section);
	return exec_bin(str, &main_csi);
38
39
}

40
const char *hungupstr="\1n\1h%s\1n hung up on \1h%s\1n %s\r\n";
41
42
43
44

/****************************************************************************/
/* Convert C string to pascal string										*/
/****************************************************************************/
45
void str2pas(const char *instr, char *outstr)
46
47
48
49
50
51
52
53
54
55
56
{
	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)	*/
/****************************************************************************/
57
int unixtojulian(time_t unix_time)
58
59
60
{
	int days[12]={0,31,59,90,120,151,181,212,243,273,304,334};
	long j;
61
	struct tm tm;
62

63
	if(localtime_r(&unix_time,&tm)==NULL)
64
		return(0);
65
66
	j=36525L*(1900+tm.tm_year);
	if(!(j%100) && (tm.tm_mon+1)<3)
67
68
		j--;
	j=(j-(1900*36525))/100;
69
	j+=tm.tm_mday+days[tm.tm_mon];
70
71
72
73
74
75
	return(j);
}

/****************************************************************************/
/* Convert julian date into unix format 									*/
/****************************************************************************/
76
77
78
#ifdef __BORLANDC__
#pragma argsused
#endif
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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++;
97
98
		leap=1; 
	}
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
	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
}

115
116
117
118
119
#ifdef __unix__
static void lfexpand(char *str, ulong misc)
{
	char *p;
	char newstr[1024];
rswindell's avatar
rswindell committed
120
	size_t len=0;
121
122
123
124

	if(misc&XTRN_NATIVE)
		return;

rswindell's avatar
rswindell committed
125
	for(p=str;*p && len < sizeof(newstr)-2;p++) {
126
127
128
129
130
131
132
133
134
135
136
137
		if(*p=='\n')
			newstr[len++]='\r';
		newstr[len++]=*p;
	}

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

138
139
140
/****************************************************************************/
/* Creates various types of xtrn (Doors, Chains, etc.) data (drop) files.	*/
/****************************************************************************/
141
void sbbs_t::xtrndat(const char *name, const char *dropdir, uchar type, ulong tleft
142
143
					,ulong misc)
{
144
145
	char	str[1024],tmp2[128],c,*p;
	char 	tmp[512];
deuce's avatar
64-bit    
deuce committed
146
147
148
149
150
	/* TODO: 16-bit i */
	int16_t	i;
	int		file;
	uint16_t	w;
	int32_t	l;
151
152
	struct tm tm;
	struct tm tl;
153
	stats_t stats;
154
	long term = term_supports();
155

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
	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)) {
171
#ifdef _WIN32
172
173
		/* Put Micros~1 shortened paths in drop files when running 16-bit DOS programs */
		GetShortPathName(cfg.node_dir,node_dir,sizeof(node_dir));
174
		GetShortPathName(cfg.ctrl_dir,ctrl_dir,sizeof(ctrl_dir));
175
176
177
178
		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));
179
180
#elif defined(__linux__) && defined(USE_DOSEMU)
		/* These drive mappings must match the Linux/DOSEMU patch in xtrn.cpp: */
181
182
183
184
185
186
		SAFECOPY(node_dir, DOSEMU_NODE_DIR);
		SAFECOPY(ctrl_dir, DOSEMU_CTRL_DIR);
		SAFECOPY(data_dir, DOSEMU_DATA_DIR);
		SAFECOPY(exec_dir, DOSEMU_EXEC_DIR);
		SAFECOPY(text_dir, DOSEMU_TEXT_DIR);
		SAFECOPY(temp_dir, DOSEMU_TEMP_DIR);
187
#endif
188
189
190
	}


191
	if(type==XTRN_SBBS) {	/* SBBS XTRN.DAT file */
Rob Swindell's avatar
Rob Swindell committed
192
		SAFECOPY(tmp,"XTRN.DAT");
193
194
		if(misc&XTRN_LWRCASE)
			strlwr(tmp);
Rob Swindell's avatar
Rob Swindell committed
195
		SAFEPRINTF2(str,"%s%s",dropdir,tmp);
rswindell's avatar
rswindell committed
196
		removecase(str);
197
198
		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);
199
200
			return; 
		}
201

202
		safe_snprintf(str, sizeof(str), "%s\n%s\n%s\n%s\n"
203
204
205
206
			,name								/* User name */
			,cfg.sys_name						/* System name */
			,cfg.sys_op 						/* Sysop name */
			,cfg.sys_guru); 					/* Guru name */
207
		lfexpand(str,misc);
208
209
		write(file,str,strlen(str));

210
		safe_snprintf(str, sizeof(str), "%s\n%s\n%u\n%u\n%lu\n%s\n%lu\n%lu\n"
211
212
			,ctrl_dir							/* Ctrl dir */
			,data_dir							/* Data dir */
213
214
215
			,cfg.sys_nodes						/* Total system nodes */
			,cfg.node_num						/* Current node */
			,tleft								/* User Timeleft in seconds */
216
217
			,(term & ANSI)						/* User ANSI ? (Yes/Mono/No) */
				? (term & COLOR)
218
219
220
				? "Yes":"Mono":"No"
			,rows								/* User Screen lines */
			,useron.cdt+useron.freecdt);		/* User Credits */
221
		lfexpand(str,misc);
222
223
		write(file,str,strlen(str));

224
		safe_snprintf(str, sizeof(str), "%u\n%u\n%s\n%c\n%u\n%s\n"
225
226
			,useron.level						/* User main level */
			,useron.level						/* User transfer level */
227
			,getbirthmmddyy(&cfg, useron.birth, tmp, sizeof(tmp)) /* User birthday (MM/DD/YY) */
228
			,useron.sex ? useron.sex : '?'		/* User sex (M/F) */
229
230
			,useron.number						/* User number */
			,useron.phone); 					/* User phone number */
231
		lfexpand(str,misc);
232
233
		write(file,str,strlen(str));

234
		safe_snprintf(str, sizeof(str), "%u\n%u\n%x\n%lu\n%s\n%s\n"
235
			"%s\n%s\n%s\n%s\n%s\n%s\n%lu\n"
236
			,misc&(XTRN_STDIO|XTRN_CONIO) ? 0:cfg.com_port		/* Com port or 0 if !FOSSIL */
237
238
239
240
241
242
243
244
245
246
247
			,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 */
248
			,0L
249
			);
250
		lfexpand(str,misc);
251
252
		write(file,str,strlen(str));

Rob Swindell's avatar
Rob Swindell committed
253
		SAFEPRINTF(str,"%u\n",cfg.total_xtrns);
254
		lfexpand(str,misc);
255
256
257
		write(file,str,strlen(str));			/* Total external programs */

		for(i=0;i<cfg.total_xtrns;i++) {		/* Each program's name */
Rob Swindell's avatar
Rob Swindell committed
258
259
260
			if(SYSOP || chk_ar(cfg.xtrn[i]->ar,&useron,&client)) {
				SAFECOPY(str,cfg.xtrn[i]->name);
			} else
261
				str[0]=0;						/* Blank if no access */
rswindell's avatar
rswindell committed
262
			SAFECAT(str,"\n");
263
			lfexpand(str,misc);
264
265
			write(file,str,strlen(str)); 
		}
266

Rob Swindell's avatar
Rob Swindell committed
267
		SAFEPRINTF2(str,"%s\n%s\n"
268
269
270
			,ltoaf(useron.flags1,tmp)			/* Main flags */
			,ltoaf(useron.flags2,tmp2)			/* Transfer flags */
			);
271
		lfexpand(str,misc);
272
273
		write(file,str,strlen(str));

Rob Swindell's avatar
Rob Swindell committed
274
		safe_snprintf(str, sizeof(str), "%s\n%s\n%lx\n%s\n%s\n%s\n"
275
276
			,ltoaf(useron.exempt,tmp)			/* Exemptions */
			,ltoaf(useron.rest,tmp2)			/* Restrictions */
277
			,(long)useron.expire				/* Expiration date in unix form */
278
279
280
281
			,useron.address 					/* Address */
			,useron.location					/* City/State */
			,useron.zipcode 					/* Zip/Postal code */
			);
282
		lfexpand(str,misc);
283
284
		write(file,str,strlen(str));

285
		safe_snprintf(str, sizeof(str), "%s\n%s\n%d\n%s\n%lu\n%s\n%s\n%s\n%s\n"
286
			"%" PRIx32 "\n%d\n"
287
288
			,ltoaf(useron.flags3,tmp)			/* Flag set #3 */
			,ltoaf(useron.flags4,tmp2)			/* Flag set #4 */
289
			,0									/* Time-slice type */
290
291
			,useron.name						/* Real name/company */
			,cur_rate							/* DCE rate */
292
293
294
			,exec_dir
			,text_dir
			,temp_dir
295
296
			,cfg.sys_id
			,cfg.node_misc
297
			,misc&(XTRN_STDIO|XTRN_CONIO) ? INVALID_SOCKET : client_socket_dup
298
			);
299
		lfexpand(str,misc);
300
301
		write(file,str,strlen(str));

302
303
		close(file); 
	}
304
305

	else if(type==XTRN_WWIV) {	/*	WWIV CHAIN.TXT File */
Rob Swindell's avatar
Rob Swindell committed
306
		SAFECOPY(tmp,"CHAIN.TXT");
307
308
		if(misc&XTRN_LWRCASE)
			strlwr(tmp);
Rob Swindell's avatar
Rob Swindell committed
309
		SAFEPRINTF2(str,"%s%s",dropdir,tmp);
rswindell's avatar
rswindell committed
310
		removecase(str);
311
312
		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);
313
314
			return; 
		}
315

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

319
		safe_snprintf(str, sizeof(str), "%u\n%s\n%s\n%s\n%u\n%c\n"
320
321
322
323
324
			,useron.number						/* User number */
			,name								/* User name */
			,useron.name						/* User real name */
			,nulstr 							/* User call sign */
			,getage(&cfg,useron.birth)			/* User age */
325
			,useron.sex ? useron.sex : '?');	/* User sex (M/F) */
326
		strupr(str);
327
		lfexpand(str,misc);
328
329
		write(file,str,strlen(str));

330
		safe_snprintf(str, sizeof(str), "%lu\n%s\n%lu\n%ld\n%u\n%u\n%u\n%ld\n%u\n"
331
332
			,useron.cdt+useron.freecdt			/* Gold */
			,unixtodstr(&cfg,useron.laston,tmp)	/* User last on date */
333
			,cols 								/* User screen width */
334
335
336
337
			,rows								/* User screen length */
			,useron.level						/* User SL */
			,0									/* Cosysop? */
			,SYSOP								/* Sysop? (1/0) */
338
			,INT_TO_BOOL(term & ANSI)			/* ANSI ? (1/0) */
339
			,online==ON_REMOTE);				/* Remote (1/0) */
340
		lfexpand(str,misc);
341
342
		write(file,str,strlen(str));

343
		safe_snprintf(str, sizeof(str), "%lu\n%s\n%s\n%s\n%lu\n%d\n%s\n%s\n"
344
			"%u\n%u\n%lu\n%u\n%lu\n%u\n%s\n"
345
			,tleft								/* Time left in seconds */
346
347
			,node_dir							/* Gfiles dir (log dir) */
			,data_dir							/* Data dir */
348
			,"node.log"                         /* Name of log file */
349
350
351
352
353
354
355
356
357
358
359
			,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 */
360
		lfexpand(str,misc);
361
362
		write(file,str,strlen(str));

363
364
		close(file); 
	}
365
366

	else if(type==XTRN_GAP) {	/* Gap DOOR.SYS File */
Rob Swindell's avatar
Rob Swindell committed
367
		SAFECOPY(tmp,"DOOR.SYS");
368
369
		if(misc&XTRN_LWRCASE)
			strlwr(tmp);
Rob Swindell's avatar
Rob Swindell committed
370
		SAFEPRINTF2(str,"%s%s",dropdir,tmp);
rswindell's avatar
rswindell committed
371
		removecase(str);
372
373
		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);
374
375
			return; 
		}
376

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

Rob Swindell's avatar
Rob Swindell committed
380
		SAFEPRINTF(str,"COM%d:\n"
381
			,online==ON_REMOTE ? cfg.com_port:0);	/* 01: COM port - 0 if Local */
Rob Swindell's avatar
Rob Swindell committed
382

383
384
		lfexpand(str,misc);
		write(file,str,strlen(str));
385
386
387
388
389
390
391
392
		/* 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>
		*/
Rob Swindell's avatar
Rob Swindell committed
393
		safe_snprintf(str, sizeof(str), "%lu\n%u\n%u\n%lu\n%c\n%c\n%c\n%c\n"
394
			,dte_rate /* was cur_rate */		/* 02: DCE rate, see note above */
395
396
397
			,8									/* 03: Data bits */
			,cfg.node_num						/* 04: Node number */
			,dte_rate							/* 05: DTE rate */
398
			,'Y'								/* 06: Screen display */
399
400
401
			,'Y'                                /* 07: Printer toggle */
			,'Y'                                /* 08: Page bell */
			,'Y');                              /* 09: Caller alarm */
402
		lfexpand(str,misc);
403
404
		write(file,str,strlen(str));

Rob Swindell's avatar
Rob Swindell committed
405
		safe_snprintf(str, sizeof(str), "%s\n%s\n%s\n%s\n%s\n"
406
407
408
409
410
			,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 */
411
		lfexpand(str,misc);
412
413
		write(file,str,strlen(str));

Rob Swindell's avatar
Rob Swindell committed
414
		safe_snprintf(str, sizeof(str), "%u\n%u\n%s\n%lu\n%lu\n%s\n"
415
416
417
418
419
			,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 */
420
421
			,(term & NO_EXASCII)				/* 20: GR if COLOR ANSI */
				? "7E" : (term & (ANSI|COLOR)) == (ANSI|COLOR) ? "GR" : "NG");
422
		lfexpand(str,misc);
423
424
		write(file,str,strlen(str));

Rob Swindell's avatar
Rob Swindell committed
425
		safe_snprintf(str, sizeof(str), "%lu\n%c\n%s\n%u\n%s\n%u\n%c\n%u\n%u\n"
426
			,rows								/* 21: User screen length */
427
			,(useron.misc&EXPERT) ? 'Y':'N'     /* 22: Expert? (Y/N) */
428
429
430
431
			,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 */
432
			,useron.prot                        /* 27: Default protocol */
433
434
			,useron.uls 						/* 28: User total uploads */
			,useron.dls);						/* 29: User total downloads */
435
		lfexpand(str,misc);
436
437
		write(file,str,strlen(str));

438
		safe_snprintf(str, sizeof(str), "%u\n%lu\n%s\n%s\n%s\n%s"
439
			"\n%s\n%02d:%02d\n%c\n"
440
441
			,0									/* 30: Kbytes downloaded today */
			,(useron.cdt+useron.freecdt)/1024UL /* 31: Max Kbytes to download today */
442
			,getbirthmmddyy(&cfg, useron.birth, tmp, sizeof(tmp))	/* 32: User birthday (MM/DD/YY) */
443
444
			,node_dir							/* 33: Path to MAIN directory */
			,data_dir							/* 34: Path to GEN directory */
445
446
447
448
449
			,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 */
450
		lfexpand(str,misc);
451
452
		write(file,str,strlen(str));

453
		localtime_r(&ns_time,&tm);
Rob Swindell's avatar
Rob Swindell committed
454
		safe_snprintf(str, sizeof(str), "%c\n%c\n%u\n%lu\n%02d/%02d/%02d\n"
455
			,(term & (NO_EXASCII|ANSI|COLOR)) == ANSI
456
457
				? 'Y':'N'                       /* 39: ANSI supported but NG mode */
			,'Y'                                /* 40: Use record locking */
458
			,cfg.color[clr_external]			/* 41: BBS default color */
459
			,useron.min 						/* 42: Time credits in minutes */
460
461
462
			,tm.tm_mon+1						/* 43: File new-scan date */
			,tm.tm_mday
			,TM_YEAR(tm.tm_year));
463
		lfexpand(str,misc);
464
465
		write(file,str,strlen(str));

deuce's avatar
deuce committed
466
		localtime_r(&logontime,&tm);
467
		localtime32(&useron.laston,&tl);
Rob Swindell's avatar
Rob Swindell committed
468
		safe_snprintf(str, sizeof(str), "%02d:%02d\n%02d:%02d\n%u\n%u\n%lu\n"
469
			"%lu\n%s\n%u\n%u\n"
470
			,tm.tm_hour							/* 44: Time of this call */
471
			,tm.tm_min
472
			,tl.tm_hour							/* 45: Time of last call */
473
			,tl.tm_min
474
475
476
477
478
479
480
			,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 */
481
		lfexpand(str,misc);
482
483
		write(file,str,strlen(str));

484
485
		close(file); 
	}
486
487

	else if(type==XTRN_RBBS || type==XTRN_RBBS1) {
Rob Swindell's avatar
Rob Swindell committed
488
489
490
491
492
		if(type==XTRN_RBBS) {
			SAFEPRINTF(tmp,"DORINFO%X.DEF",cfg.node_num);   /* support 1-F */
		} else {
			SAFECOPY(tmp,"DORINFO1.DEF");
		}
493
494
		if(misc&XTRN_LWRCASE)
			strlwr(tmp);
Rob Swindell's avatar
Rob Swindell committed
495
		SAFEPRINTF2(str,"%s%s",dropdir,tmp);
rswindell's avatar
rswindell committed
496
		removecase(str);
497
498
		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);
499
500
			return; 
		}
501

Rob Swindell's avatar
Rob Swindell committed
502
		SAFECOPY(tmp,cfg.sys_op);
503
		p=strchr(tmp,' ');
504
505
506
507
508
		if(p)
			*(p++)=0;
		else
			p=nulstr;

Rob Swindell's avatar
Rob Swindell committed
509
		safe_snprintf(str, sizeof(str), "%s\n%s\n%s\nCOM%d\n%lu BAUD,N,8,1\n%u\n"
510
511
512
513
514
515
516
			,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);
517
		lfexpand(str,misc);
518
519
		write(file,str,strlen(str));

Rob Swindell's avatar
Rob Swindell committed
520
		SAFECOPY(tmp,name);
521
		p=strchr(tmp,' ');
522
523
524
525
		if(p)
			*(p++)=0;
		else
			p=nulstr;
Rob Swindell's avatar
Rob Swindell committed
526
		safe_snprintf(str, sizeof(str), "%s\n%s\n%s\n%ld\n%u\n%lu\n"
527
528
529
			,tmp								/* User's firstname */
			,p									/* User's lastname */
			,useron.location					/* User's city */
530
			,INT_TO_BOOL(term & ANSI)			/* 1=ANSI 0=ASCII */
531
532
533
			,useron.level						/* Security level */
			,tleft/60); 						/* Time left in minutes */
		strupr(str);
534
		lfexpand(str,misc);
535
536
537
538
		write(file,str,strlen(str));

		close(file);

Rob Swindell's avatar
Rob Swindell committed
539
		SAFECOPY(tmp,"EXITINFO.BBS");
540
541
		if(misc&XTRN_LWRCASE)
			strlwr(tmp);
Rob Swindell's avatar
Rob Swindell committed
542
		SAFEPRINTF2(str,"%s%s",dropdir,tmp);
rswindell's avatar
rswindell committed
543
		removecase(str);
544
545
		if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
			errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC);
546
547
			return; 
		}
548
		w=(WORD)dte_rate;
deuce's avatar
64-bit    
deuce committed
549
		write(file,&w,sizeof(w));			/* BaudRate */
550
551
		/* SysInfo */
		getstats(&cfg,0,&stats);
deuce's avatar
64-bit    
deuce committed
552
		write(file,&stats.logons,sizeof(stats.logons)); /* CallCount */
553
554
555
556
557
		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
558
559
		write(file,nulstr,24*sizeof(int16_t));	/* BusyPerHour */
		write(file,nulstr,7*sizeof(int16_t));		/* BusyPerDay */
560
561
562
563
564
565
566
567
568
569
		/* 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 */
570
		localtime32(&useron.laston,&tm);
Rob Swindell's avatar
Rob Swindell committed
571
		SAFEPRINTF2(tmp,"%02d:%02d",tm.tm_hour,tm.tm_min);
572
573
574
575
576
577
578
579
580
		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);
581
		if(term & ANSI)			c|=(1<<3);
582
583
584
585
		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
586
587
588
589
		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 */
590
		w=useron.level;
deuce's avatar
64-bit    
deuce committed
591
		write(file,&w,sizeof(w)); 			/* SecLvl */
592
		w=0;
deuce's avatar
64-bit    
deuce committed
593
594
595
		write(file,&w,sizeof(w)); 			/* Times */
		write(file,&useron.uls,sizeof(useron.uls));	/* Ups */
		write(file,&useron.dls,sizeof(useron.dls));	/* Downs */
596
		w=(ushort)(useron.ulb/1024UL);
deuce's avatar
64-bit    
deuce committed
597
		write(file,&w,sizeof(w)); 			/* UpK */
598
		w=(ushort)(useron.dlb/1024UL);
deuce's avatar
64-bit    
deuce committed
599
		write(file,&w,sizeof(w)); 			/* DownK */
600
		w=(ushort)(logon_dlb/1024UL);
deuce's avatar
64-bit    
deuce committed
601
		write(file,&w,sizeof(w)); 			/* TodayK */
602
		w=0;
deuce's avatar
64-bit    
deuce committed
603
604
605
606
		write(file,&w,sizeof(w)); 			/* Elapsed */
		write(file,&w,sizeof(w)); 			/* Len */
		write(file,&w,sizeof(w)); 			/* CombinedPtr */
		write(file,&w,sizeof(w)); 			/* AliasPtr */
607
		l = strtol(useron.birth, NULL, 10);
deuce's avatar
64-bit    
deuce committed
608
		write(file,&l,sizeof(l));			/* Birthday (as a long?) */
609
610
611
		/* EventInfo */
		c=0;
		write(file,&c,sizeof(char));			/* Status */
deuce's avatar
64-bit    
deuce committed
612
		write(file,&l /* sys_eventtime */,sizeof(l));	/* RunTime */
613
614
615
616
617
618
619
620
621
622
		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
623
		write(file,&l,sizeof(l));			/* LastTimeRun */
624
625
626
627
628
629
630
		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
631
		localtime_r(&logontime,&tm);
Rob Swindell's avatar
Rob Swindell committed
632
		SAFEPRINTF2(tmp,"%02d:%02d",tm.tm_hour,tm.tm_min);
633
634
		str2pas(tmp,str);
		write(file,str,6);						/* LoginTime */
635
		unixtodstr(&cfg,(time32_t)logontime,tmp);
636
637
		str2pas(tmp,str);
		write(file,str,9);						/* LoginDate */
deuce's avatar
64-bit    
deuce committed
638
639
640
641
		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
642
		i=0;
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
		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 */
659
		c=(term & NO_EXASCII) ? 0:1;
660
661
662
		write(file,&c,1);						/* GraphicsMode */
		c=useron.xedit ? 1:0;
		write(file,&c,1);						/* ExternEdit */
663
		i=(int16_t)rows;
664
665
666
667
668
669
		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 */
670
		c=(char)INT_TO_BOOL(term & ANSI);
671
672
		write(file,&c,1);						/* ANSI_Capable */
		close(file);
673
	}
674
675

	else if(type==XTRN_WILDCAT) { /* WildCat CALLINFO.BBS File */
Rob Swindell's avatar
Rob Swindell committed
676
		SAFECOPY(tmp,"CALLINFO.BBS");
677
678
		if(misc&XTRN_LWRCASE)
			strlwr(tmp);
Rob Swindell's avatar
Rob Swindell committed
679
		SAFEPRINTF2(str,"%s%s",dropdir,tmp);
rswindell's avatar
rswindell committed
680
		removecase(str);
681
682
		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);
683
684
			return; 
		}
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708

		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;
709
710
					break; 
		}
Rob Swindell's avatar
Rob Swindell committed
711
		safe_snprintf(str, sizeof(str), "%s\n%u\n%s\n%u\n%lu\n%s\n%s\n%u\n"
712
713
714
715
716
			,name								/* User name */
			,i									/* DTE rate */
			,useron.location					/* User location */
			,useron.level						/* Security level */
			,tleft/60							/* Time left in min */
717
			,(term & ANSI) ? "COLOR":"MONO"		/* ANSI ??? */
718
719
			,useron.pass						/* Password */
			,useron.number);					/* User number */
720
		lfexpand(str,misc);
721
722
		write(file,str,strlen(str));

723
		localtime_r(&now,&tm);
Rob Swindell's avatar
Rob Swindell committed
724
		safe_snprintf(str, sizeof(str), "%lu\n%02d:%02d\n%02d:%02d %02d/%02d/%02d\n%s\n"
725
			,tleft								/* Time left in seconds */
726
727
728
729
			,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)
730
			,nulstr);							/* Conferences with access */
731
		lfexpand(str,misc);
732
733
		write(file,str,strlen(str));

734
		localtime32(&useron.laston,&tm);
Rob Swindell's avatar
Rob Swindell committed
735
		safe_snprintf(str, sizeof(str), "%u\n%u\n%u\n%u\n%s\n%s %02u:%02u\n"
736
737
738
739
740
741
			,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 */
742
743
			,tm.tm_hour						/* MM/DD/YY  HH:MM */
			,tm.tm_min);
744
		lfexpand(str,misc);
745
746
		write(file,str,strlen(str));

747
		localtime_r(&ns_time,&tm);
Rob Swindell's avatar
Rob Swindell committed
748
		safe_snprintf(str, sizeof(str), "%s\n%s\n%02d/%02d/%02d\n%u\n%lu\n%u"
749
			"\n%u\n%u\n"
750
751
752
			,useron.misc&EXPERT 				/* Expert or Novice mode */
				? "EXPERT":"NOVICE"
			,"All"                              /* Transfer Protocol */
753
754
			,tm.tm_mon+1,tm.tm_mday			/* File new-scan date */
			,TM_YEAR(tm.tm_year)				/* in MM/DD/YY */
755
756
757
758
759
			,useron.logons						/* Total logons */
			,rows								/* Screen length */
			,0									/* Highest message read */
			,useron.uls 						/* Total files uploaded */
			,useron.dls);						/* Total files downloaded */
760
		lfexpand(str,misc);
761
762
		write(file,str,strlen(str));

Rob Swindell's avatar
Rob Swindell committed
763
		safe_snprintf(str, sizeof(str), "%u\n%s\nCOM%u\n%s\n%lu\n%s\n%s\n"
764
765
766
			,8									/* Data bits */
			,online==ON_LOCAL?"LOCAL":"REMOTE"  /* Online local or remote */
			,cfg.com_port						/* COMx port */
767
			,getbirthmmddyy(&cfg, useron.birth, tmp, sizeof(tmp))	/* User birthday (MM/DD/YY) */
768
769
770
			,dte_rate							/* DTE rate */
			,"FALSE"                            /* Already connected? */
			,"Normal Connection");              /* Normal or ARQ connect */
771
		lfexpand(str,misc);
772
773
		write(file,str,strlen(str));

774
		localtime_r(&now,&tm);
Rob Swindell's avatar
Rob Swindell committed
775
		safe_snprintf(str, sizeof(str), "%02d/%02d/%02d %02d:%02d\n%u\n%u\n"
776
777
778
			,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 */
779
780
			,cfg.node_num						/* Node number */
			,0);								/* Door number */
781
		lfexpand(str,misc);
782
783
		write(file,str,strlen(str));

784
785
		close(file); 
	}
786
787

	else if(type==XTRN_PCBOARD) { /* PCBoard Files */
Rob Swindell's avatar
Rob Swindell committed
788
		SAFECOPY(tmp,"PCBOARD.SYS");
789
790
		if(misc&XTRN_LWRCASE)
			strlwr(tmp);
Rob Swindell's avatar
Rob Swindell committed
791
		SAFEPRINTF2(str,"%s%s",dropdir,tmp);
rswindell's avatar
rswindell committed
792
		removecase(str);
793
794
		if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
			errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC);
795
796
			return; 
		}
797

Rob Swindell's avatar
Rob Swindell committed
798
		safe_snprintf(str, sizeof(str), "%2d%2d%2d%2d%c%2d%c%c%5u%-5.5s"
799
800
801
			,-1 								/* Display on/off */
			,0									/* Printer on/off */
			,sys_status&SS_SYSPAGE ? -1:0		/* Page Bell on/off */
802
			,startup->answer_sound[0] ? -1:0	/* Caller Alarm on/off */
803
			,' ' 								/* Sysop next flag */
804
			,0									/* Error corrected */
805
806
			,(term & NO_EXASCII) ? '7'			/* Graphics mode */
				: (term & (COLOR|ANSI)) == (COLOR|ANSI) ? 'Y':'N'
807
808
809
810
811
812
813
814
			,'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 */

Rob Swindell's avatar
Rob Swindell committed
815
		SAFECOPY(tmp,name);
816
		p=strchr(tmp,' ');
817
		if(p) *p=0;
Rob Swindell's avatar
Rob Swindell committed
818
		SAFEPRINTF2(str,"%-15.15s%-12s"
819
820
821
822
			,tmp								/* User's first name */
			,useron.pass);						/* User's password */
		write(file,str,27);

deuce's avatar
deuce committed
823
		if(localtime_r(&logontime,&tm)==NULL)
824
825
			i=0;
		else
826
			i=(tm.tm_hour*60)+tm.tm_min;
827
828
829
		write(file,&i,2);						/* Logon time in min since mid */

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

Rob Swindell's avatar
Rob Swindell committed
833
		SAFEPRINTF2(str,"%02d:%02d",tm.tm_hour,tm.tm_min);
834
835
836
837
838
		write(file,str,5);

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

839
		c=0;
840
841
		i=0;									/* Allowed K-bytes for D/L */
		write(file,&i,2);
842
		write(file,&c,1);						/* Conference user was in */
843
844
845
846
847
848
849
850
		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 */

Rob Swindell's avatar
Rob Swindell committed
851
		SAFECOPY(str,"    ");
852
853
		write(file,str,4);						/* Language extension */

Rob Swindell's avatar
Rob Swindell committed
854
		SAFEPRINTF(str,"%-25.25s",name);           /* User's full name */
855
856
		write(file,str,25);

857
		i=(int16_t)(tleft/60);
858
859
860
861
		write(file,&i,2);						/* Minutes remaining */

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

Rob Swindell's avatar
Rob Swindell committed
862
		safe_snprintf(str, sizeof(str), "%02d:%02d%2d%2d"           /* Scheduled Event time */
863
864
865
866
867
868
869
870
871
872
			,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 */

Rob Swindell's avatar
Rob Swindell committed
873
		safe_snprintf(str, sizeof(str), "%d%c%c%ld%s%c%c%d%d%d%c%c"
874
			,cfg.com_port						/* COM Port number */
875
876
			,' ' 								/* Reserved */
			,' ' 								/* "" */
877
			,INT_TO_BOOL(term & ANSI)			/* 1=ANSI 0=NO ANSI */
878
879
880
881
882
883
884
885
886
887
888
			,"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 */

Rob Swindell's avatar
Rob Swindell committed
889
		SAFECOPY(tmp,"USERS.SYS");
890
891
		if(misc&XTRN_LWRCASE)
			strlwr(tmp);
Rob Swindell's avatar
Rob Swindell committed
892
		safe_snprintf(str, sizeof(str), "%s%s",dropdir,tmp);
rswindell's avatar
rswindell committed
893
		removecase(str);
894
895
		if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
			errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC);
896
897
			return; 
		}
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926

		/* 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 */
Rob Swindell's avatar
Rob Swindell committed
927
		SAFEPRINTF(str,"%.24s",useron.location);
928
		write(file,str,25); 			/* Location */
rswindell's avatar
rswindell committed
929
930
931
932
933
934
935
936
		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 */
937
938
		i=unixtojulian(useron.laston);
		write(file,&i,2);				/* Date last on */
939
		localtime32(&useron.laston,&tm);
Rob Swindell's avatar
Rob Swindell committed
940
		SAFEPRINTF2(str,"%02d:%02d",tm.tm_hour,tm.tm_min);
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
		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 */
967
		i=(int16_t)(now-starttime)/60;
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
		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 */
993
	}
994
995

	else if(type==XTRN_SPITFIRE) {	 /* SpitFire SFDOORS.DAT File */
Rob Swindell's avatar
Rob Swindell committed
996
		SAFECOPY(tmp,"SFDOORS.DAT");
997
998
		if(misc&XTRN_LWRCASE)
			strlwr(tmp);
Rob Swindell's avatar
Rob Swindell committed
999
		SAFEPRINTF2(str,"%s%s",dropdir,tmp);