uedit.c 57.4 KB
Newer Older
1
2
/* Synchronet for *nix user editor */

Rob Swindell's avatar
Rob Swindell committed
3
/* $Id: uedit.c,v 1.65 2020/08/17 00:48:48 rswindell Exp $ */
rswindell's avatar
rswindell committed
4
// vi: tabstop=4
5
6
7
8
9

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

#include <sys/types.h>
#include <time.h>
#ifdef __QNX__
#include <string.h>
#endif
#include <stdio.h>
43
#ifdef __unix__
44
#include <unistd.h>
45
#include <sys/time.h>
deuce's avatar
deuce committed
46
#include <signal.h>
47
#endif
deuce's avatar
deuce committed
48

49
#include "ciolib.h"
50
51
#include "curs_cio.h"
#undef OK
52
53
#include "sbbs.h"

54
55
56
57
58
59
60
61
62
63
64
65
66
#include "genwrap.h"
#include "uifc.h"
#include "sbbsdefs.h"
#include "genwrap.h"	/* stricmp */
#include "dirwrap.h"	/* lock/unlock/sopen */
#include "filewrap.h"	/* lock/unlock/sopen */
#include "sbbs_ini.h"	/* INI parsing */
#include "scfglib.h"	/* SCFG files */
#include "ars_defs.h"	/* needed for SCFG files */
#include "userdat.h"	/* getnodedat() */

#define CTRL(x) (x&037)

deuce's avatar
deuce committed
67
68
69
70
71
struct user_list {
	char	info[MAX_OPLN];
	int		usernum;
};

72
73
74
75
/********************/
/* Global Variables */
/********************/
uifcapi_t uifc; /* User Interface (UIFC) Library API */
deuce's avatar
deuce committed
76
77
char YesStr[]="Yes";
char NoStr[]="No";
78

79
80
#define GETUSERDAT(cfg, user)	if (getuserdat(cfg, user) != 0) { uifc.msg("Error reading user database!"); return -1; }

81
82
83
84
85
/*
 * Find the first occurrence of find in s, ignore case.
 * From FreeBSD src/lib/libc/string/strcasestr.c
 */
char *
86
strcasestr(const char *s, const char *find)
87
88
89
90
91
92
93
94
95
96
97
98
{
	char c, sc;
	size_t len;

	if ((c = *find++) != 0) {
		c = tolower((unsigned char)c);
		len = strlen(find);
		do {
			do {
				if ((sc = *s++) == 0)
					return (NULL);
			} while ((char)tolower((unsigned char)sc) != c);
99
		} while (strnicmp(s, find, len) != 0);
100
101
102
103
104
		s--;
	}
	return ((char *)s);
}

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
int lprintf(char *fmt, ...)
{
	va_list argptr;
	char sbuf[1024];
	int	len;

	va_start(argptr,fmt);
	len=vsnprintf(sbuf,sizeof(sbuf),fmt,argptr);
	sbuf[sizeof(sbuf)-1]=0;
	va_end(argptr);
	uifc.msg(sbuf);
	return(len);
}

void bail(int code)
{
    if(code) {
        puts("\nHit a key...");
deuce's avatar
deuce committed
123
        getch();
124
125
126
127
128
129
130
131
132
133
134
135
	}
    uifc.bail();

    exit(code);
}

void allocfail(uint size)
{
    printf("\7Error allocating %u bytes of memory.\n",size);
    bail(1);
}

deuce's avatar
deuce committed
136
137
138
139
140
141
142
143
144
int confirm(char *prompt)
{
	int i=0;
	char *opt[3]={
		 YesStr
		,NoStr
		,""
	};

deuce's avatar
deuce committed
145
	i=uifc.list(WIN_MID|WIN_ACT|WIN_SAV,0,0,0,&i,0,prompt,opt);
deuce's avatar
deuce committed
146
147
	if(i==0)
		return(1);
148
149
150
	if(i==-1)
		return(-1);
	return(0);
deuce's avatar
deuce committed
151
152
}

deuce's avatar
deuce committed
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/****************************************************************************/
/* Takes a string in the format HH:MM:SS and returns in seconds             */
/****************************************************************************/
time_t DLLCALL strtosec(char *str)
{
	char *p1;
	char *p2;
	long int hour=0;
	long int min=0;
	long int sec2=0;
	time_t	sec=0;

	hour=strtol(str,&p1,10);
	if(hour<0 || hour > 24)
		return(-1);
	if(*p1==':') {
		p1++;
		min=strtol(p1,&p2,10);
		if(min<0 || min > 59)
			return(-1);
		if(*p2==':') {
			p2++;
			sec2=strtol(p2,&p1,10);
			if(sec2 < 0 || sec2 > 59)
				return(-1);
		}
	}

	sec=hour*60*60;
	sec+=min*60;
	sec+=sec2;
	return(sec);
}

deuce's avatar
deuce committed
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
char *geteditor(char *edit)
{
	if(getenv("EDITOR")==NULL && (getenv("VISUAL")==NULL || getenv("DISPLAY")==NULL))
#ifdef __unix__
		strcpy(edit,"vi");
#else
		strcpy(edit,"notepad");
#endif
	else {
		if(getenv("DISPLAY")!=NULL && getenv("VISUAL")!=NULL)
			strcpy(edit,getenv("VISUAL"));
		else
			strcpy(edit,getenv("EDITOR"));
	}
	return(edit);
}

int do_cmd(char *cmd)
{
	int i;

208
209
210
#ifdef HAS_CURSES
	if(cio_api.mode == CIOLIB_MODE_CURSES || cio_api.mode == CIOLIB_MODE_CURSES_IBM)
		endwin();
deuce's avatar
deuce committed
211
212
#endif
	i=system(cmd);
213
214
215
#ifdef HAS_CURSES
	if(cio_api.mode == CIOLIB_MODE_CURSES || cio_api.mode == CIOLIB_MODE_CURSES_IBM)
		refresh();
deuce's avatar
deuce committed
216
217
218
219
#endif
	return(i);
}

deuce's avatar
deuce committed
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/* Edit terminal settings
 *       Auto-Detect
 *       Extended ASCII
 *       ANSI
 *       Color
 *       RIP
 *       WIP
 *       Pause
 *       Hot Keys
 *       Spinning Cursor
 *       Number of Rows
 */
int edit_terminal(scfg_t *cfg, user_t *user)
{
deuce's avatar
deuce committed
234
235
236
237
	int 	i,j;
	char 	**opt;
	char	str[256];

238
239
240
	if((opt=(char **)alloca(sizeof(char *)*(10+1)))==NULL)
		allocfail(sizeof(char *)*(10+1));
	for(i=0;i<(10+1);i++)
241
		if((opt[i]=(char *)alloca(MAX_OPLN))==NULL)
deuce's avatar
deuce committed
242
243
244
245
			allocfail(MAX_OPLN);

	j=0;
	while(1) {
246
		GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
247
		i=0;
248
249
250
251
252
253
254
255
256
		sprintf(opt[i++],"Auto-detect      %s",user->misc & AUTOTERM?"Yes":"No");
		sprintf(opt[i++],"Extended ASCII   %s",user->misc & NO_EXASCII?"No":"Yes");
		sprintf(opt[i++],"ANSI             %s",user->misc & ANSI?"Yes":"No");
		sprintf(opt[i++],"Color            %s",user->misc & COLOR?"Yes":"No");
		sprintf(opt[i++],"RIP              %s",user->misc & RIP?"Yes":"No");
		sprintf(opt[i++],"WIP              %s",user->misc & WIP?"Yes":"No");
		sprintf(opt[i++],"Pause            %s",user->misc & UPAUSE?"Yes":"No");
		sprintf(opt[i++],"Hot Keys         %s",user->misc & COLDKEYS?"No":"Yes");
		sprintf(opt[i++],"Spinning Cursor  %s",user->misc & SPIN?"Yes":"No");
deuce's avatar
deuce committed
257
		sprintf(str,"%u",user->rows);
258
		sprintf(opt[i++],"Number of Rows   %s",user->rows?str:"Auto");
deuce's avatar
deuce committed
259
260
261
262
263
264
265
266
		opt[i][0]=0;
		switch(uifc.list(WIN_MID|WIN_ACT|WIN_SAV,0,0,0,&j,0,"Terminal Settings",opt)) {
			case -1:
				return(0);
				break;
			case 0:
				/* Auto-detect */
				user->misc ^= AUTOTERM;
deuce's avatar
deuce committed
267
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
268
269
270
271
				break;
			case 1:
				/* EX-ASCII */
				user->misc ^= NO_EXASCII;
deuce's avatar
deuce committed
272
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
273
274
275
276
				break;
			case 2:
				/* ANSI */
				user->misc ^= ANSI;
deuce's avatar
deuce committed
277
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
278
279
280
281
				break;
			case 3:
				/* Colour */
				user->misc ^= COLOR;
deuce's avatar
deuce committed
282
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
283
284
285
286
				break;
			case 4:
				/* RIP */
				user->misc ^= RIP;
deuce's avatar
deuce committed
287
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
288
289
290
291
				break;
			case 5:
				/* WIP */
				user->misc ^= WIP;
deuce's avatar
deuce committed
292
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
293
294
295
296
				break;
			case 6:
				/* Pause */
				user->misc ^= UPAUSE;
deuce's avatar
deuce committed
297
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
298
299
300
301
				break;
			case 7:
				/* Hot Keys */
				user->misc ^= COLDKEYS;
deuce's avatar
deuce committed
302
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
303
304
305
306
				break;
			case 8:
				/* Spinning Cursor */
				user->misc ^= SPIN;
deuce's avatar
deuce committed
307
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
308
309
310
311
				break;
			case 9:
				/* Rows */
				sprintf(str,"%u",user->rows);
deuce's avatar
deuce committed
312
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Rows",str,2,K_EDIT|K_NUMBER);
deuce's avatar
deuce committed
313
314
				if(uifc.changes) {
					user->rows=strtoul(str,NULL,10);
deuce's avatar
deuce committed
315
					putuserrec(cfg,user->number,U_ROWS,2,ultoa(user->rows,str,10));
deuce's avatar
deuce committed
316
317
318
				}
				break;
		}
deuce's avatar
deuce committed
319
	}
deuce's avatar
deuce committed
320
321
322
323
324
325
326
327
328
329
330
331
	return(0);
}

/* Edit Logon settings
 *       Ask for New Message Scan
 *       Ask for Your Message Scan
 *       Remember Current Sub-board
 *       Quiet Mode (Q exempt)
 *       Auto-Login via IP (V exempt)
 */
int edit_logon(scfg_t *cfg, user_t *user)
{
deuce's avatar
deuce committed
332
333
	int 	i,j;
	char 	**opt;
deuce's avatar
deuce committed
334
	char	str[256];
deuce's avatar
deuce committed
335

336
337
338
	if((opt=(char **)alloca(sizeof(char *)*(5+1)))==NULL)
		allocfail(sizeof(char *)*(5+1));
	for(i=0;i<(5+1);i++)
339
		if((opt[i]=(char *)alloca(MAX_OPLN))==NULL)
deuce's avatar
deuce committed
340
341
342
343
344
			allocfail(MAX_OPLN);

	j=0;
	while(1) {
		i=0;
345
		GETUSERDAT(cfg,user);
346
347
348
349
		sprintf(opt[i++],"Ask for New Message Scan     %s",user->misc & ASK_NSCAN?"Yes":"No");
		sprintf(opt[i++],"Ask for Your Message Scan    %s",user->misc & ASK_SSCAN?"Yes":"No");
		sprintf(opt[i++],"Remember Current Sub         %s",user->misc & CURSUB?"Yes":"No");
		sprintf(opt[i++],"Quiet Mode  (Q exempt)       %s",user->misc & QUIET?"Yes":"No");
deuce's avatar
deuce committed
350
351
352
353
354
355
356
357
358
		sprintf(opt[i++],"Auto-Login via IP (V exempt) %s",user->misc & AUTOLOGON?"Yes":"No");
		opt[i][0]=0;
		switch(uifc.list(WIN_MID|WIN_ACT|WIN_SAV,0,0,0,&j,0,"Logon Settings",opt)) {
			case -1:
				return(0);
				break;
			case 0:
				/* Ask New MSG Scan */
				user->misc ^= ASK_NSCAN;
deuce's avatar
deuce committed
359
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
360
361
362
363
				break;
			case 1:
				/* Ask YOUR MSG scan */
				user->misc ^= ASK_SSCAN;
deuce's avatar
deuce committed
364
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
365
366
367
368
				break;
			case 2:
				/* Remember Curr Sub */
				user->misc ^= CURSUB;
deuce's avatar
deuce committed
369
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
370
371
372
373
				break;
			case 3:
				/* Quiet Mode */
				user->misc ^= QUIET;
deuce's avatar
deuce committed
374
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
375
376
377
378
				break;
			case 4:
				/* Auto-Login by IP */
				user->misc ^= AUTOLOGON;
deuce's avatar
deuce committed
379
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
380
381
382
				break;
		}
	}
deuce's avatar
deuce committed
383
384
385
386
387
388
389
390
391
392
393
394
	return(0);
}

/* Edit Chat Settings
 *       Multinode Chat Echo
 *       Multinode Chat Actions
 *       Available for Internode chat
 *       Multinode Activity Alerts
 *       Split-screen Private Chat
 */
int edit_chat(scfg_t *cfg, user_t *user)
{
deuce's avatar
deuce committed
395
396
	int 	i,j;
	char 	**opt;
deuce's avatar
deuce committed
397
	char	str[256];
deuce's avatar
deuce committed
398

399
400
401
	if((opt=(char **)alloca(sizeof(char *)*(5+1)))==NULL)
		allocfail(sizeof(char *)*(5+1));
	for(i=0;i<(5+1);i++)
402
		if((opt[i]=(char *)alloca(MAX_OPLN))==NULL)
deuce's avatar
deuce committed
403
404
405
406
407
			allocfail(MAX_OPLN);

	j=0;
	while(1) {
		i=0;
408
		GETUSERDAT(cfg,user);
409
410
411
		sprintf(opt[i++],"Chat Echo                  %s",user->chat & CHAT_ECHO?"Yes":"No");
		sprintf(opt[i++],"Chat Actions               %s",user->chat & CHAT_ACTION?"Yes":"No");
		sprintf(opt[i++],"Available for Chat         %s",user->chat & CHAT_NOPAGE?"No":"Yes");
deuce's avatar
deuce committed
412
		sprintf(opt[i++],"Activity Alerts            %s",user->chat & CHAT_NOACT?"No":"Yes");
413
		sprintf(opt[i++],"Split-Screen Private Chat  %s",user->chat & CHAT_SPLITP?"Yes":"No");
deuce's avatar
deuce committed
414
415
416
417
418
419
420
421
		opt[i][0]=0;
		switch(uifc.list(WIN_MID|WIN_ACT|WIN_SAV,0,0,0,&j,0,"Chat Settings",opt)) {
			case -1:
				return(0);
				break;
			case 0:
				/* Chat Echo */
				user->chat ^= CHAT_ECHO;
deuce's avatar
deuce committed
422
				putuserrec(cfg,user->number,U_CHAT,8,ultoa(user->chat,str,16));
deuce's avatar
deuce committed
423
424
425
426
				break;
			case 1:
				/* Chat Actions */
				user->chat ^= CHAT_ACTION;
deuce's avatar
deuce committed
427
				putuserrec(cfg,user->number,U_CHAT,8,ultoa(user->chat,str,16));
deuce's avatar
deuce committed
428
429
430
431
				break;
			case 2:
				/* Availabe for Chat */
				user->chat ^= CHAT_NOPAGE;
deuce's avatar
deuce committed
432
				putuserrec(cfg,user->number,U_CHAT,8,ultoa(user->chat,str,16));
deuce's avatar
deuce committed
433
434
435
436
				break;
			case 3:
				/* Activity Alerts */
				user->chat ^= CHAT_NOACT;
deuce's avatar
deuce committed
437
				putuserrec(cfg,user->number,U_CHAT,8,ultoa(user->chat,str,16));
deuce's avatar
deuce committed
438
439
440
441
				break;
			case 4:
				/* Split-Screen Priv Chat */
				user->chat ^= CHAT_SPLITP;
deuce's avatar
deuce committed
442
				putuserrec(cfg,user->number,U_CHAT,8,ultoa(user->chat,str,16));
deuce's avatar
deuce committed
443
444
445
446
447
448
449
				break;
		}
	}
	return(0);
}

/* Pick Command Shell */
deuce's avatar
deuce committed
450

deuce's avatar
deuce committed
451
452
453
454
455
int edit_shell(scfg_t *cfg, user_t *user)
{
	int 	i,j;
	char 	**opt;

456
457
	if((opt=(char **)alloca(sizeof(char *)*(cfg->total_shells+1)))==NULL)
		allocfail(sizeof(char *)*(cfg->total_shells+1));
deuce's avatar
deuce committed
458
459
460
461
462

	for(i=0;i<cfg->total_shells;i++) {
		opt[i]=cfg->shell[i]->name;
	}
	opt[i]="";
deuce's avatar
deuce committed
463
464
	j=user->shell;
	switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0,"Command Shell",opt)) {
deuce's avatar
deuce committed
465
466
467
		case -1:
			break;
		default:
deuce's avatar
deuce committed
468
469
470
			if(user->shell != j) {
				user->shell=j;
				putuserrec(cfg,user->number,U_SHELL,8,cfg->shell[j]->code);
deuce's avatar
deuce committed
471
			}
deuce's avatar
deuce committed
472
473
			break;
	}
474

deuce's avatar
deuce committed
475
476
477
478
479
480
481
482
483
	return(0);
}

/* Edit Command Shell
 *       Name
 *       Expert Mode
 */
int edit_cmd(scfg_t *cfg, user_t *user)
{
deuce's avatar
deuce committed
484
485
	int 	i,j;
	char 	**opt;
deuce's avatar
deuce committed
486
	char	str[256];
deuce's avatar
deuce committed
487

488
489
490
	if((opt=(char **)alloca(sizeof(char *)*(2+1)))==NULL)
		allocfail(sizeof(char *)*(2+1));
	for(i=0;i<(2+1);i++)
491
		if((opt[i]=(char *)alloca(MAX_OPLN))==NULL)
deuce's avatar
deuce committed
492
493
494
495
496
			allocfail(MAX_OPLN);

	j=0;
	while(1) {
		i=0;
497
		GETUSERDAT(cfg,user);
498
499
		sprintf(opt[i++],"Command Shell  %s",cfg->shell[user->shell]->name);
		sprintf(opt[i++],"Expert Mode    %s",user->misc & EXPERT?"Yes":"No");
deuce's avatar
deuce committed
500
501
502
503
504
505
506
507
508
509
		opt[i][0]=0;
		switch(uifc.list(WIN_MID|WIN_ACT|WIN_SAV,0,0,0,&j,0,"Command Shell",opt)) {
			case -1:
				return(0);
				break;
			case 0:
				/* Command Shell */
				edit_shell(cfg,user);
				break;
			case 1:
deuce's avatar
deuce committed
510
				/* Expert Mode */
deuce's avatar
deuce committed
511
				user->misc ^= EXPERT;
deuce's avatar
deuce committed
512
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
513
514
515
516
				break;
		}
	}

deuce's avatar
deuce committed
517
518
519
	return(0);
}

deuce's avatar
deuce committed
520
521
522
523
524
525
/* Pick External Editor */
int edit_xedit(scfg_t *cfg, user_t *user)
{
	int 	i,j;
	char 	**opt;

526
527
	if((opt=(char **)alloca(sizeof(char *)*(cfg->total_xedits+1)))==NULL)
		allocfail(sizeof(char *)*(cfg->total_xedits+1));
deuce's avatar
deuce committed
528

529
	GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
530
531
532
533
534
535
	opt[0]="None";
	for(i=1;i<=cfg->total_xedits;i++) {
		opt[i]=cfg->xedit[i-1]->name;
	}
	opt[i]="";
	j=user->xedit;
deuce's avatar
deuce committed
536
	switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0,"External Editor",opt)) {
deuce's avatar
deuce committed
537
538
539
		case -1:
			break;
		default:
deuce's avatar
deuce committed
540
541
			if(user->xedit != j) {
				user->xedit=j;
deuce's avatar
deuce committed
542
543
544
545
				if(j > 0)
				    putuserrec(cfg,user->number,U_XEDIT,8,cfg->xedit[j-1]->code);
				else
				    putuserrec(cfg,user->number,U_XEDIT,8,nulstr);
deuce's avatar
deuce committed
546
			}
deuce's avatar
deuce committed
547
548
549
550
551
552
553
554
555
556
557
			break;
	}
	return(0);
}

/* Edit Message Options
 *       Forward Email to NetMail
 *       Clear Screen Between Messages
 *       External Editor
 */
int edit_msgopts(scfg_t *cfg, user_t *user)
deuce's avatar
deuce committed
558
{
deuce's avatar
deuce committed
559
560
	int 	i,j;
	char 	**opt;
deuce's avatar
deuce committed
561
	char	str[256];
deuce's avatar
deuce committed
562

563
564
565
	if((opt=(char **)alloca(sizeof(char *)*(3+1)))==NULL)
		allocfail(sizeof(char *)*(3+1));
	for(i=0;i<(3+1);i++)
566
		if((opt[i]=(char *)alloca(MAX_OPLN))==NULL)
deuce's avatar
deuce committed
567
568
569
570
			allocfail(MAX_OPLN);

	j=0;
	while(1) {
571
		GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
572
		i=0;
573
574
575
		sprintf(opt[i++],"Forward Email to NetMail       %s",user->misc & NETMAIL?"Yes":"No");
		sprintf(opt[i++],"Clear Screen Between Messages  %s",user->misc & CLRSCRN?"Yes":"No");
		sprintf(opt[i++],"External Editor                %s",user->xedit?cfg->xedit[user->xedit-1]->name:"None");
deuce's avatar
deuce committed
576
577
578
579
580
581
582
583
		opt[i][0]=0;
		switch(uifc.list(WIN_MID|WIN_ACT|WIN_SAV,0,0,0,&j,0,"Message Options",opt)) {
			case -1:
				return(0);
				break;
			case 0:
				/* FWD Email */
				user->misc ^= NETMAIL;
deuce's avatar
deuce committed
584
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
585
586
587
588
				break;
			case 1:
				/* Clear Between MSGS */
				user->misc ^=CLRSCRN;
deuce's avatar
deuce committed
589
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
				break;
			case 2:
				/* External Editor */
				edit_xedit(cfg,user);
				break;
		}
	}
	return(0);
}

/* Pick Tmp/QWK File Type */
int edit_tmpqwktype(scfg_t *cfg, user_t *user)
{
	int 	i;
	int		j=0;
	char 	**opt;

607
608
	if((opt=(char **)alloca(sizeof(char *)*(cfg->total_fcomps+1)))==NULL)
		allocfail(sizeof(char *)*(cfg->total_fcomps+1));
deuce's avatar
deuce committed
609

610
	GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
611
612
613
614
615
616
617
618
619
620
	for(i=0;i<cfg->total_fcomps;i++) {
		opt[i]=cfg->fcomp[i]->ext;
		if(!strcmp(cfg->fcomp[i]->ext,user->tmpext))
			j=i;
	}
	opt[i]="";
	switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0,"Temp/QWK File Type",opt)) {
		case -1:
			break;
		default:
deuce's avatar
deuce committed
621
622
623
624
			if(strcmp(cfg->fcomp[j]->ext,user->tmpext)) {
				strcpy(user->tmpext,cfg->fcomp[j]->ext);
				putuserrec(cfg,user->number,U_TMPEXT,3,user->tmpext);
			}
deuce's avatar
deuce committed
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
			break;
	}
	return(0);
}

/* Edit QWK Packet Options
 *       Include New Files List
 *       Include Unread Email
 *       Delete Email After Download
 *       Include Messages From Self
 *       Expand CTRL-A Codes to ANSI
 *       Strip CTRL-A Codes
 *       Include File Attachments
 *       Include Index Files
 *       Include Time Zone (@TZ)
 *       Include Seen-Bys (@VIA)
 *       Extraneous Control Files
 */
int edit_qwk(scfg_t *cfg, user_t *user)
{
	int 	i,j;
	char 	**opt;
deuce's avatar
deuce committed
647
	char	str[256];
deuce's avatar
deuce committed
648

649
650
651
	if((opt=(char **)alloca(sizeof(char *)*(15+1)))==NULL)
		allocfail(sizeof(char *)*(15+1));
	for(i=0;i<(15+1);i++)
652
		if((opt[i]=(char *)alloca(MAX_OPLN))==NULL)
deuce's avatar
deuce committed
653
654
655
656
657
			allocfail(MAX_OPLN);

	j=0;
	while(1) {
		i=0;
658
		GETUSERDAT(cfg,user);
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
		sprintf(opt[i++],"Include New Files List        %s",user->qwk & QWK_FILES?"Yes":"No");
		sprintf(opt[i++],"Include Unread Email          %s",user->qwk & QWK_EMAIL?"Yes":"No");
		sprintf(opt[i++],"Include ALL Email             %s",user->qwk & QWK_ALLMAIL?"Yes":"No");
		sprintf(opt[i++],"Delete Email After Download   %s",user->qwk & QWK_DELMAIL?"Yes":"No");
		sprintf(opt[i++],"Include Messages from Self    %s",user->qwk & QWK_BYSELF?"Yes":"No");
		sprintf(opt[i++],"Expand CTRL-A to ANSI         %s",user->qwk & QWK_EXPCTLA?"Yes":"No");
		sprintf(opt[i++],"Strip CTRL-A Codes            %s",user->qwk & QWK_RETCTLA?"No":"Yes");
		sprintf(opt[i++],"Include File Attachments      %s",user->qwk & QWK_ATTACH?"Yes":"No");
		sprintf(opt[i++],"Include Index Files           %s",user->qwk & QWK_NOINDEX?"No":"Yes");
		sprintf(opt[i++],"Include Time Zone (@TZ)       %s",user->qwk & QWK_TZ?"Yes":"No");
		sprintf(opt[i++],"Include Seen-Bys (@VIA)       %s",user->qwk & QWK_VIA?"Yes":"No");
		sprintf(opt[i++],"Extraneous Control Files      %s",user->qwk & QWK_NOCTRL?"No":"Yes");
		sprintf(opt[i++],"Extended (QWKE) Format        %s",user->qwk & QWK_EXT?"Yes":"No");
		sprintf(opt[i++],"Include Message IDs (@MSGID)  %s",user->qwk & QWK_MSGID?"Yes":"No");
		sprintf(opt[i++],"Temp/QWK File Type            %s",user->tmpext);
deuce's avatar
deuce committed
674
675
676
677
678
679
680
681
		opt[i][0]=0;
		switch(uifc.list(WIN_MID|WIN_ACT|WIN_SAV,0,0,0,&j,0,"Command Shell",opt)) {
			case -1:
				return(0);
				break;
			case 0:
				/* New Files List */
				user->qwk ^= QWK_FILES;
deuce's avatar
deuce committed
682
				putuserrec(cfg,user->number,U_QWK,8,ultoa(user->qwk,str,16));
deuce's avatar
deuce committed
683
684
685
686
				break;
			case 1:
				/* Unread Email */
				user->qwk ^= QWK_EMAIL;
deuce's avatar
deuce committed
687
				putuserrec(cfg,user->number,U_QWK,8,ultoa(user->qwk,str,16));
deuce's avatar
deuce committed
688
689
690
691
				break;
			case 2:
				/* ALL Email */
				user->qwk ^= QWK_ALLMAIL;
deuce's avatar
deuce committed
692
				putuserrec(cfg,user->number,U_QWK,8,ultoa(user->qwk,str,16));
deuce's avatar
deuce committed
693
694
695
696
				break;
			case 3:
				/* Del Email after Download */
				user->qwk ^= QWK_DELMAIL;
deuce's avatar
deuce committed
697
				putuserrec(cfg,user->number,U_QWK,8,ultoa(user->qwk,str,16));
deuce's avatar
deuce committed
698
699
700
701
				break;
			case 4:
				/* Include From Self */
				user->qwk ^= QWK_BYSELF;
deuce's avatar
deuce committed
702
				putuserrec(cfg,user->number,U_QWK,8,ultoa(user->qwk,str,16));
deuce's avatar
deuce committed
703
704
705
706
				break;
			case 5:
				/* Expand CTRL-A */
				user->qwk ^= QWK_EXPCTLA;
deuce's avatar
deuce committed
707
				putuserrec(cfg,user->number,U_QWK,8,ultoa(user->qwk,str,16));
deuce's avatar
deuce committed
708
709
710
711
				break;
			case 6:
				/* Strip CTRL-A */
				user->qwk ^= QWK_RETCTLA;
deuce's avatar
deuce committed
712
				putuserrec(cfg,user->number,U_QWK,8,ultoa(user->qwk,str,16));
deuce's avatar
deuce committed
713
714
715
716
				break;
			case 7:
				/* Include Attach */
				user->qwk ^= QWK_ATTACH;
deuce's avatar
deuce committed
717
				putuserrec(cfg,user->number,U_QWK,8,ultoa(user->qwk,str,16));
deuce's avatar
deuce committed
718
719
720
721
				break;
			case 8:
				/* Include Indexes */
				user->qwk ^= QWK_NOINDEX;
deuce's avatar
deuce committed
722
				putuserrec(cfg,user->number,U_QWK,8,ultoa(user->qwk,str,16));
deuce's avatar
deuce committed
723
724
725
726
				break;
			case 9:
				/* Include TZ */
				user->qwk ^= QWK_TZ;
deuce's avatar
deuce committed
727
				putuserrec(cfg,user->number,U_QWK,8,ultoa(user->qwk,str,16));
deuce's avatar
deuce committed
728
729
730
731
				break;
			case 10:
				/* Include VIA */
				user->qwk ^= QWK_VIA;
deuce's avatar
deuce committed
732
				putuserrec(cfg,user->number,U_QWK,8,ultoa(user->qwk,str,16));
deuce's avatar
deuce committed
733
734
735
736
				break;
			case 11:
				/* Extra CTRL Files */
				user->qwk ^= QWK_NOCTRL;
deuce's avatar
deuce committed
737
				putuserrec(cfg,user->number,U_QWK,8,ultoa(user->qwk,str,16));
deuce's avatar
deuce committed
738
739
740
741
				break;
			case 12:
				/* Extended QWKE */
				user->qwk ^= QWK_EXT;
deuce's avatar
deuce committed
742
				putuserrec(cfg,user->number,U_QWK,8,ultoa(user->qwk,str,16));
deuce's avatar
deuce committed
743
744
745
746
				break;
			case 13:
				/* Include MSGID */
				user->qwk ^= QWK_MSGID;
deuce's avatar
deuce committed
747
				putuserrec(cfg,user->number,U_QWK,8,ultoa(user->qwk,str,16));
deuce's avatar
deuce committed
748
749
750
751
752
753
754
755
756
757
758
				break;
			case 14:
				/* Temp/QWK Type */
				edit_tmpqwktype(cfg,user);
				break;
		}
	}
	return(0);
}

/* Pick Protocol */
deuce's avatar
deuce committed
759

deuce's avatar
deuce committed
760
761
762
763
764
765
int edit_proto(scfg_t *cfg, user_t *user)
{
	int 	i;
	int		j=0;
	char 	**opt;

766
767
	if((opt=(char **)alloca(sizeof(char *)*(cfg->total_prots+1)))==NULL)
		allocfail(sizeof(char *)*(cfg->total_prots+1));
deuce's avatar
deuce committed
768

769
	GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
770
771
772
773
774
775
776
777
778
779
780
781
	opt[0]="None";
	for(i=1;i<=cfg->total_prots;i++) {
		opt[i]=cfg->prot[i-1]->name;
		if(cfg->prot[i-1]->mnemonic == user->prot)
			j=i;
	}
	opt[i]="";
	switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0,"Default Protcol",opt)) {
		case -1:
			break;
		case 0:
			if(user->prot != ' ')
deuce's avatar
deuce committed
782
				putuserrec(cfg,user->number,U_PROT,1," ");
deuce's avatar
deuce committed
783
784
785
			user->prot=' ';
			break;
		default:
deuce's avatar
deuce committed
786
787
			if(user->prot != cfg->prot[j-1]->mnemonic) {
				user->prot=cfg->prot[j-1]->mnemonic;
788
				putuserrec(cfg,user->number,U_PROT,1,(char*)&user->prot);
deuce's avatar
deuce committed
789
			}
deuce's avatar
deuce committed
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
			break;
	}
	return(0);
}

/* Edit File Options
 *       Auto-New Scan
 *       Extended Descriptions
 *       Batch Flagging
 *       Auto-Hangup After Transfer
 *       Default download Protocol
 *       Temp/QWK File Type
 */
int edit_fileopts(scfg_t *cfg, user_t *user)
{
	int 	i,j;
	int		k;
	char 	**opt;
	char 	str[256];

810
811
812
	if((opt=(char **)alloca(sizeof(char *)*(6+1)))==NULL)
		allocfail(sizeof(char *)*(6+1));
	for(i=0;i<(6+1);i++)
813
		if((opt[i]=(char *)alloca(MAX_OPLN))==NULL)
deuce's avatar
deuce committed
814
815
816
817
			allocfail(MAX_OPLN);

	j=0;
	while(1) {
818
		GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
819
		i=0;
820
821
822
823
		sprintf(opt[i++],"Auto-New Scan              %s",user->misc & ANFSCAN?"Yes":"No");
		sprintf(opt[i++],"Extended Descriptions      %s",user->misc & EXTDESC?"Yes":"No");
		sprintf(opt[i++],"Batch Flagging             %s",user->misc & BATCHFLAG?"Yes":"No");
		sprintf(opt[i++],"Auto Transfer Hangup       %s",user->misc & AUTOHANG?"Yes":"No");
deuce's avatar
deuce committed
824
825
826
827
		strcpy(str,"None");
		for(k=0;k<cfg->total_prots;k++)
			if(cfg->prot[k]->mnemonic==user->prot)
				strcpy(str,cfg->prot[k]->name);
828
829
		sprintf(opt[i++],"Default Download Protocol  %s",str);
		sprintf(opt[i++],"Temp/QWK File Type         %s",user->tmpext);
deuce's avatar
deuce committed
830
831
832
833
834
835
836
837
		opt[i][0]=0;
		switch(uifc.list(WIN_MID|WIN_ACT|WIN_SAV,0,0,0,&j,0,"File Options",opt)) {
			case -1:
				return(0);
				break;
			case 0:
				/* Auto-New Scan */
				user->misc ^= ANFSCAN;
deuce's avatar
deuce committed
838
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
839
840
841
842
				break;
			case 1:
				/* Extended Descs */
				user->misc ^= EXTDESC;
deuce's avatar
deuce committed
843
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
844
845
846
847
				break;
			case 2:
				/* Batch Flagging */
				user->misc ^= BATCHFLAG;
deuce's avatar
deuce committed
848
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
849
850
				break;
			case 3:
deuce's avatar
deuce committed
851
				/* Auto-Hangup */
deuce's avatar
deuce committed
852
				user->misc ^= AUTOHANG;
deuce's avatar
deuce committed
853
				putuserrec(cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
deuce's avatar
deuce committed
854
855
856
857
858
859
860
861
862
863
864
865
866
867
				break;
			case 4:
				/* Default Download Protocol */
				edit_proto(cfg,user);
				break;
			case 5:
				/* Temp/QWK File Type */
				edit_tmpqwktype(cfg,user);
				break;
		}
	}
	return(0);
}

deuce's avatar
deuce committed
868
869
/* Edit "Extended Comment" */

deuce's avatar
deuce committed
870
871
int edit_comment(scfg_t *cfg, user_t *user)
{
deuce's avatar
deuce committed
872
873
874
	char str[1024];
	char editor[1024];

deuce's avatar
deuce committed
875
	sprintf(str,"%s %suser/%04u.msg",geteditor(editor),cfg->data_dir,user->number);
deuce's avatar
deuce committed
876
	do_cmd(str);
deuce's avatar
deuce committed
877
878
879
880
881
882
883
884
885
886
	return(0);
}

/* MSG and File settings
 *      - Message Options
 *      - QWK Message Packet
 *      - File Options
 */
int edit_msgfile(scfg_t *cfg, user_t *user)
{
deuce's avatar
deuce committed
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
	char *opt[4]={
		 "Message Options"
		,"QWK Message Packet"
		,"File Options"
		,""};
	int i=0;
	while(1) {
		switch(uifc.list(WIN_BOT|WIN_RHT|WIN_ACT,0,0,0,&i,0,"Settings",opt)) {
			case -1:
				return(0);
				break;
			case 0:
				/* Message Options */
				edit_msgopts(cfg,user);
				break;
			case 1:
				/* QWK Message Packet */
				edit_qwk(cfg,user);
				break;
			case 2:
				/* File Options */
				edit_fileopts(cfg,user);
				break;
		}
	}
deuce's avatar
deuce committed
912
913
914
915
916
917
918
919
920
921
922
	return(0);
}

/* Settings
 *     - Terminal Settings
 *     - Logon Toggles
 *     - Chat Toggles
 *     - Command Shell
 */
int edit_settings(scfg_t *cfg, user_t *user)
{
deuce's avatar
deuce committed
923
924
925
926
927
928
929
930
931
	char *opt[5]={
		 "Terminal Settings"
		,"Logon Toggles"
		,"Chat Toggles"
		,"Command Shell"
		,""};
	int i=0;

	while(1) {
deuce's avatar
deuce committed
932
		switch(uifc.list(WIN_BOT|WIN_RHT|WIN_ACT,0,0,0,&i,0,"Settings",opt)) {
deuce's avatar
deuce committed
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
			case -1:
				return(0);
				break;
			case 0:
				/* Terminal Settings */
				edit_terminal(cfg,user);
				break;
			case 1:
				/* Logon Toggles */
				edit_logon(cfg,user);
				break;
			case 2:
				/* Chat Toggles */
				edit_chat(cfg,user);
				break;
			case 3:
				/* Command Shell */
				edit_cmd(cfg,user);
				break;
		}
	}
deuce's avatar
deuce committed
954
955
956
957
958
959
960
961
962
963
964
965
966
967
	return(0);
}

/* Statistics
 *     First On
 *     Last On
 *     Total Logons
 *     Todays Logons
 *     Total Posts
 *     Todays Posts
 *     Total Uploads
 *     Todays Uploads
 *     Total Time On
 *     Todays Time On
deuce's avatar
deuce committed
968
 *     Last Call Time On
deuce's avatar
deuce committed
969
970
971
972
973
974
975
976
977
978
 *     Extra
 *     Total Downloads
 *     Bytes
 *     Leech
 *     Total Email
 *     Todays Email
 *     Email to Sysop
 */
int edit_stats(scfg_t *cfg, user_t *user)
{
deuce's avatar
deuce committed
979
980
981
982
983
	int 	i,j;
	char 	**opt;
	char	str[256];
	time_t	temptime,temptime2;

984
985
986
	if((opt=(char **)alloca(sizeof(char *)*(20+1)))==NULL)
		allocfail(sizeof(char *)*(20+1));
	for(i=0;i<(20+1);i++)
987
		if((opt[i]=(char *)alloca(MAX_OPLN))==NULL)
deuce's avatar
deuce committed
988
989
990
991
			allocfail(MAX_OPLN);

	j=0;
	while(1) {
992
		GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
993
		i=0;
994
995
996
		sprintf(opt[i++],"First On           %s",user->firston?timestr(cfg, user->firston, str):"Never");
		sprintf(opt[i++],"Last On            %s",user->laston?timestr(cfg, user->laston, str):"Never");
		sprintf(opt[i++],"Logon Time         %s",user->laston?timestr(cfg, user->logontime, str):"Not On");
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
		sprintf(opt[i++],"Total Logons       %hu",user->logons);
		sprintf(opt[i++],"Todays Logons      %hu",user->ltoday);
		sprintf(opt[i++],"Total Posts        %hu",user->posts);
		sprintf(opt[i++],"Todays Posts       %hu",user->ptoday);
		sprintf(opt[i++],"Total Email        %hu",user->emails);
		sprintf(opt[i++],"Todays Email       %hu",user->etoday);
		sprintf(opt[i++],"Email To Sysop     %hu",user->fbacks);
		sprintf(opt[i++],"Total Time On      %hu",user->timeon);
		sprintf(opt[i++],"Time On Today      %hu",user->ttoday);
		sprintf(opt[i++],"Time On Last Call  %hu",user->tlast);
		sprintf(opt[i++],"Extra Time Today   %hu",user->textra);
		sprintf(opt[i++],"Total Downloads    %hu",user->dls);
		sprintf(opt[i++],"Downloaded Bytes   %lu",user->dlb);
		sprintf(opt[i++],"Total Uploads      %hu",user->uls);
		sprintf(opt[i++],"Uploaded Bytes     %lu",user->ulb);
		sprintf(opt[i++],"Leech Downloads    %u",user->leech);
1013
		sprintf(opt[i++],"Password Modified  %s",user->pwmod?timestr(cfg, user->pwmod, str):"Never");
deuce's avatar
deuce committed
1014
		opt[i][0]=0;
deuce's avatar
deuce committed
1015
		switch(uifc.list(WIN_MID|WIN_ACT,0,0,0,&j,0,"Statistics",opt)) {
deuce's avatar
deuce committed
1016
1017
1018
1019
1020
			case -1:
				return(0);
				break;
			case 0:
				/* First On */
1021
				GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
1022
1023
				temptime=user->firston;
				unixtodstr(cfg,temptime,str);
deuce's avatar
deuce committed
1024
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"First On Date",str,8,K_EDIT);
deuce's avatar
deuce committed
1025
1026
1027
				user->firston=dstrtounix(cfg, str);
				temptime2=temptime-user->firston;
				sectostr(temptime2,str);
deuce's avatar
deuce committed
1028
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"First On Time",str,8,K_EDIT);
deuce's avatar
deuce committed
1029
1030
1031
1032
				temptime2=strtosec(str);
				if(temptime2!=-1)
					user->firston += temptime2;
				if(temptime!=user->firston)
deuce's avatar
deuce committed
1033
					putuserrec(cfg,user->number,U_FIRSTON,8,ultoa(user->firston,str,16));
deuce's avatar
deuce committed
1034
1035
1036
				break;
			case 1:
				/* Last On */
1037
				GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
1038
1039
				temptime=user->laston;
				unixtodstr(cfg,temptime,str);
deuce's avatar
deuce committed
1040
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Last On Date",str,8,K_EDIT);
deuce's avatar
deuce committed
1041
1042
1043
				user->laston=dstrtounix(cfg, str);
				temptime2=temptime-user->laston;
				sectostr(temptime2,str);
deuce's avatar
deuce committed
1044
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Last On Time",str,8,K_EDIT);
deuce's avatar
deuce committed
1045
1046
1047
1048
				temptime2=strtosec(str);
				if(temptime2!=-1)
					user->laston += temptime2;
				if(temptime!=user->laston)
deuce's avatar
deuce committed
1049
					putuserrec(cfg,user->number,U_LASTON,8,ultoa(user->laston,str,16));
deuce's avatar
deuce committed
1050
1051
1052
				break;
			case 2:
				/* Logon Time */
1053
				GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
1054
1055
				temptime=user->logontime;
				unixtodstr(cfg,temptime,str);
deuce's avatar
deuce committed
1056
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Logon Date",str,8,K_EDIT);
deuce's avatar
deuce committed
1057
1058
1059
				user->logontime=dstrtounix(cfg, str);
				temptime2=temptime-user->logontime;
				sectostr(temptime2,str);
deuce's avatar
deuce committed
1060
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Logon Time",str,8,K_EDIT);
deuce's avatar
deuce committed
1061
1062
1063
1064
				temptime2=strtosec(str);
				if(temptime2!=-1)
					user->logontime += temptime2;
				if(temptime!=user->logontime)
deuce's avatar
deuce committed
1065
					putuserrec(cfg,user->number,U_LOGONTIME,8,ultoa(user->logontime,str,16));
deuce's avatar
deuce committed
1066
1067
1068
				break;
			case 3:
				/* Total Logons */
1069
				GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
1070
				sprintf(str,"%hu",user->logons);
deuce's avatar
deuce committed
1071
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Total Logons",str,5,K_EDIT|K_NUMBER);
deuce's avatar
deuce committed
1072
1073
				if(uifc.changes) {
					user->logons=strtoul(str,NULL,10);
deuce's avatar
deuce committed
1074
					putuserrec(cfg,user->number,U_LOGONS,5,ultoa(user->logons,str,10));
deuce's avatar
deuce committed
1075
1076
1077
1078
				}
				break;
			case 4:
				/* Todays Logons */
1079
				GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
1080
				sprintf(str,"%hu",user->ltoday);
deuce's avatar
deuce committed
1081
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Todays Logons",str,5,K_EDIT|K_NUMBER);
deuce's avatar
deuce committed
1082
1083
				if(uifc.changes) {
					user->ltoday=strtoul(str,NULL,10);
deuce's avatar
deuce committed
1084
					putuserrec(cfg,user->number,U_LTODAY,5,ultoa(user->ltoday,str,10));
deuce's avatar
deuce committed
1085
1086
1087
1088
				}
				break;
			case 5:
				/* Total Posts */
1089
				GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
1090
				sprintf(str,"%hu",user->posts);
deuce's avatar
deuce committed
1091
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Total Posts",str,5,K_EDIT|K_NUMBER);
deuce's avatar
deuce committed
1092
1093
				if(uifc.changes) {
					user->posts=strtoul(str,NULL,10);
deuce's avatar
deuce committed
1094
					putuserrec(cfg,user->number,U_POSTS,5,ultoa(user->posts,str,10));
deuce's avatar
deuce committed
1095
1096
1097
1098
				}
				break;
			case 6:
				/* Todays Posts */
1099
				GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
1100
				sprintf(str,"%hu",user->ptoday);
deuce's avatar
deuce committed
1101
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Todays Posts",str,5,K_EDIT|K_NUMBER);
deuce's avatar
deuce committed
1102
1103
				if(uifc.changes) {
					user->ptoday=strtoul(str,NULL,10);
deuce's avatar
deuce committed
1104
					putuserrec(cfg,user->number,U_PTODAY,5,ultoa(user->ptoday,str,10));
deuce's avatar
deuce committed
1105
1106
1107
1108
				}
				break;
			case 7:
				/* Total Emails */
1109
				GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
1110
				sprintf(str,"%hu",user->emails);
deuce's avatar
deuce committed
1111
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Total Emails",str,5,K_EDIT|K_NUMBER);
deuce's avatar
deuce committed
1112
1113
				if(uifc.changes) {
					user->emails=strtoul(str,NULL,10);
deuce's avatar
deuce committed
1114
					putuserrec(cfg,user->number,U_EMAILS,5,ultoa(user->emails,str,10));
deuce's avatar
deuce committed
1115
1116
1117
1118
				}
				break;
			case 8:
				/* Todays Emails */
1119
				GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
1120
				sprintf(str,"%hu",user->etoday);
deuce's avatar
deuce committed
1121
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Todays Emails",str,5,K_EDIT|K_NUMBER);
deuce's avatar
deuce committed
1122
1123
				if(uifc.changes) {
					user->etoday=strtoul(str,NULL,10);
deuce's avatar
deuce committed
1124
					putuserrec(cfg,user->number,U_ETODAY,5,ultoa(user->etoday,str,10));
deuce's avatar
deuce committed
1125
1126
1127
1128
				}
				break;
			case 9:
				/* Emails to Sysop */
1129
				GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
1130
				sprintf(str,"%hu",user->fbacks);
deuce's avatar
deuce committed
1131
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Emails to Sysop",str,5,K_EDIT|K_NUMBER);
deuce's avatar
deuce committed
1132
1133
				if(uifc.changes) {
					user->fbacks=strtoul(str,NULL,10);
deuce's avatar
deuce committed
1134
					putuserrec(cfg,user->number,U_FBACKS,5,ultoa(user->fbacks,str,10));
deuce's avatar
deuce committed
1135
1136
1137
1138
				}
				break;
			case 10:
				/* Total Time On */
1139
				GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
1140
				sprintf(str,"%hu",user->timeon);
deuce's avatar
deuce committed
1141
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Total Time On",str,5,K_EDIT|K_NUMBER);
deuce's avatar
deuce committed
1142
1143
				if(uifc.changes) {
					user->timeon=strtoul(str,NULL,10);
deuce's avatar
deuce committed
1144
					putuserrec(cfg,user->number,U_TIMEON,5,ultoa(user->timeon,str,10));
deuce's avatar
deuce committed
1145
1146
1147
1148
				}
				break;
			case 11:
				/* Time On Today */
1149
				GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
1150
				sprintf(str,"%hu",user->ttoday);
deuce's avatar
deuce committed
1151
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Time On Today",str,5,K_EDIT|K_NUMBER);
deuce's avatar
deuce committed
1152
1153
				if(uifc.changes) {
					user->ttoday=strtoul(str,NULL,10);
deuce's avatar
deuce committed
1154
					putuserrec(cfg,user->number,U_TTODAY,5,ultoa(user->ttoday,str,10));
deuce's avatar
deuce committed
1155
1156
1157
1158
				}
				break;
			case 12:
				/* Time On Last Call */
1159
				GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
1160
				sprintf(str,"%hu",user->tlast);
deuce's avatar
deuce committed
1161
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Time On Last Call",str,5,K_EDIT|K_NUMBER);
deuce's avatar
deuce committed
1162
1163
				if(uifc.changes) {
					user->tlast=strtoul(str,NULL,10);
deuce's avatar
deuce committed
1164
					putuserrec(cfg,user->number,U_TLAST,5,ultoa(user->tlast,str,10));
deuce's avatar
deuce committed
1165
1166
1167
1168
				}
				break;
			case 13:
				/* Extra Time Today */
1169
				GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
1170
				sprintf(str,"%hu",user->textra);
deuce's avatar
deuce committed
1171
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Extra Time Today",str,5,K_EDIT|K_NUMBER);
deuce's avatar
deuce committed
1172
1173
				if(uifc.changes) {
					user->textra=strtoul(str,NULL,10);
deuce's avatar
deuce committed
1174
					putuserrec(cfg,user->number,U_TEXTRA,5,ultoa(user->textra,str,10));
deuce's avatar
deuce committed
1175
1176
1177
1178
				}
				break;
			case 14:
				/* Total Downloads */
1179
				GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
1180
				sprintf(str,"%hu",user->dls);
deuce's avatar
deuce committed
1181
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Total Downloads",str,5,K_EDIT|K_NUMBER);
deuce's avatar
deuce committed
1182
1183
				if(uifc.changes) {
					user->dls=strtoul(str,NULL,10);
deuce's avatar
deuce committed
1184
					putuserrec(cfg,user->number,U_DLS,5,ultoa(user->dls,str,10));
deuce's avatar
deuce committed
1185
1186
1187
1188
				}
				break;
			case 15:
				/* Downloaded Bytes */
1189
				GETUSERDAT(cfg,user);
deuce's avatar
deuce committed
1190
				sprintf(str,"%lu",user->dlb);
deuce's avatar
deuce committed
1191
				uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Downloaded Bytes",str,10,K_EDIT|K_NUMBER);
deuce's avatar
deuce committed
1192
1193
				if(uifc.changes) {
					user->dlb=strtoul(str,NULL,10);
deuce's avatar
deuce committed
1194
					putuserrec(cfg,user->number,U_DLB,10,ultoa(user->dlb,str,10));
deuce's avatar
deuce committed
1195
1196
1197
1198
				}
				break;
			case 16:
				/* Total Uploads */
1199
				GETUSERDAT(cfg,user);
deuce's avatar