chk_ar.cpp 18.5 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
/* chk_ar.cpp */

/* Synchronet ARS checking routine */

/* $Id$ */

/****************************************************************************
 * @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
 *																			*
 * 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"

rswindell's avatar
rswindell committed
40
bool sbbs_t::ar_exp(const uchar **ptrptr, user_t* user, client_t* client)
41
{
42
	bool	result,_not,_or,equal;
43
44
	uint	i,n,artype,age;
	ulong	l;
45
	struct tm tm;
rswindell's avatar
rswindell committed
46
	const char*	p;
47
48
49
50
51
52
53
54

	result = true;

	for(;(**ptrptr);(*ptrptr)++) {

		if((**ptrptr)==AR_ENDNEST)
			break;

55
		_not=_or=equal = false;
56
57

		if((**ptrptr)==AR_OR) {
58
			_or=true;
59
60
			(*ptrptr)++; 
		}
61
62
		
		if((**ptrptr)==AR_NOT) {
63
			_not=true;
64
65
			(*ptrptr)++; 
		}
66
67
68

		if((**ptrptr)==AR_EQUAL) {
			equal=true;
69
70
			(*ptrptr)++; 
		}
71

72
		if((result && _or) || (!result && !_or))
73
74
75
76
			break;

		if((**ptrptr)==AR_BEGNEST) {
			(*ptrptr)++;
rswindell's avatar
rswindell committed
77
			if(ar_exp(ptrptr,user,client))
78
				result=!_not;
79
			else
80
				result=_not;
81
82
83
84
			while((**ptrptr)!=AR_ENDNEST && (**ptrptr)) /* in case of early exit */
				(*ptrptr)++;
			if(!(**ptrptr))
				break;
85
86
			continue; 
		}
87
88
89
90

		artype=(**ptrptr);
		switch(artype) {
			case AR_ANSI:				/* No arguments */
rswindell's avatar
rswindell committed
91
			case AR_PETSCII:
92
93
94
95
96
			case AR_RIP:
			case AR_WIP:
			case AR_LOCAL:
			case AR_EXPERT:
			case AR_SYSOP:
97
98
			case AR_GUEST:
			case AR_QNODE:
99
100
101
			case AR_QUIET:
			case AR_OS2:
			case AR_DOS:
102
103
104
			case AR_WIN32:
			case AR_UNIX:
			case AR_LINUX:
105
106
107
			case AR_ACTIVE:
			case AR_INACTIVE:
			case AR_DELETED:
108
109
110
				break;
			default:
				(*ptrptr)++;
111
112
				break; 
		}
113
114
115
116
117
118

		n=(**ptrptr);
		i=(*(short *)*ptrptr);
		switch(artype) {
			case AR_LEVEL:
				if((equal && user->level!=n) || (!equal && user->level<n))
119
					result=_not;
120
				else
121
					result=!_not;
122
123
				if(!result) {
					noaccess_str=text[NoAccessLevel];
124
125
					noaccess_val=n; 
				}
126
127
128
129
				break;
			case AR_AGE:
				age=getage(&cfg,user->birth);
				if((equal && age!=n) || (!equal && age<n))
130
					result=_not;
131
				else
132
					result=!_not;
133
134
				if(!result) {
					noaccess_str=text[NoAccessAge];
135
136
					noaccess_val=n; 
				}
137
138
139
				break;
			case AR_BPS:
				if((equal && cur_rate!=i) || (!equal && cur_rate<i))
140
					result=_not;
141
				else
142
					result=!_not;
143
144
145
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessBPS];
146
147
					noaccess_val=i; 
				}
148
149
				break;
			case AR_ANSI:
150
				if(!term_supports(ANSI))
151
152
					result=_not;
				else result=!_not;
rswindell's avatar
rswindell committed
153
154
155
156
157
158
				if(!result) {
					noaccess_str=text[NoAccessTerminal];
					noaccess_val=ANSI; 
				}
				break;
			case AR_PETSCII:
159
				if(!term_supports(PETSCII))
rswindell's avatar
rswindell committed
160
161
162
163
164
165
					result=_not;
				else result=!_not;
				if(!result) {
					noaccess_str=text[NoAccessTerminal];
					noaccess_val=PETSCII; 
				}
166
167
				break;
			case AR_RIP:
168
				if(!term_supports(RIP))
169
170
					result=_not;
				else result=!_not;
rswindell's avatar
rswindell committed
171
172
173
174
				if(!result) {
					noaccess_str=text[NoAccessTerminal];
					noaccess_val=RIP; 
				}
175
176
				break;
			case AR_WIP:
177
				if(!term_supports(WIP))
178
179
					result=_not;
				else result=!_not;
rswindell's avatar
rswindell committed
180
181
182
183
				if(!result) {
					noaccess_str=text[NoAccessTerminal];
					noaccess_val=WIP; 
				}
184
185
186
				break;
			case AR_OS2:
				#ifndef __OS2__
187
					result=_not;
188
				#else
189
					result=!_not;
190
191
				#endif
				break;
192
			case AR_DOS:	/* DOS program support */
deuce's avatar
deuce committed
193
				result=_not;
194
195
196
197
198
				if(startup->options&BBS_OPT_NO_DOS)
					break;
				#if defined(_WIN32) || (defined(__linux__) && defined(USE_DOSEMU)) || defined(__FreeBSD__)
					result=!_not;
				#endif
199
200
201
				break;
			case AR_WIN32:
				#ifndef _WIN32
202
					result=_not;
203
				#else
204
					result=!_not;
205
206
207
208
				#endif
				break;
			case AR_UNIX:
				#ifndef __unix__
209
					result=_not;
210
				#else
211
					result=!_not;
212
213
214
215
				#endif
				break;
			case AR_LINUX:
				#ifndef __linux__
216
					result=_not;
217
				#else
218
					result=!_not;
219
220
				#endif
				break;
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
			case AR_ACTIVE:
				if(user->misc&(DELETED|INACTIVE))
					result=_not;
				else result=!_not;
				break;
			case AR_INACTIVE:
				if(!(user->misc&INACTIVE))
					result=_not;
				else result=!_not;
				break;
			case AR_DELETED:
				if(!(user->misc&DELETED))
					result=_not;
				else result=!_not;
				break;
236
237
			case AR_EXPERT:
				if(!(user->misc&EXPERT))
238
239
					result=_not;
				else result=!_not;
240
241
242
				break;
			case AR_SYSOP:
				if(!SYSOP)
243
244
					result=_not;
				else result=!_not;
245
				break;
246
247
248
249
250
251
252
253
254
255
			case AR_GUEST:
				if(!(user->rest&FLAG('G')))
					result=_not;
				else result=!_not;
				break;
			case AR_QNODE:
				if(!(user->rest&FLAG('Q')))
					result=_not;
				else result=!_not;
				break;
256
257
			case AR_QUIET:
				if(thisnode.status!=NODE_QUIET)
258
259
					result=_not;
				else result=!_not;
260
261
262
				break;
			case AR_LOCAL:
				if(online!=ON_LOCAL)
263
264
					result=_not;
				else result=!_not;
265
266
267
				break;
			case AR_DAY:
				now=time(NULL);
268
269
270
				localtime_r(&now,&tm);
				if((equal && tm.tm_wday!=(int)n) 
					|| (!equal && tm.tm_wday<(int)n))
271
					result=_not;
272
				else
273
					result=!_not;
274
275
				if(!result) {
					noaccess_str=text[NoAccessDay];
276
277
					noaccess_val=n; 
				}
278
279
280
281
282
				break;
			case AR_CREDIT:
				l=(ulong)i*1024UL;
				if((equal && user->cdt+user->freecdt!=l)
					|| (!equal && user->cdt+user->freecdt<l))
283
					result=_not;
284
				else
285
					result=!_not;
286
287
288
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessCredit];
289
290
					noaccess_val=l; 
				}
291
292
293
				break;
			case AR_NODE:
				if((equal && cfg.node_num!=n) || (!equal && cfg.node_num<n))
294
					result=_not;
295
				else
296
					result=!_not;
297
298
				if(!result) {
					noaccess_str=text[NoAccessNode];
299
300
					noaccess_val=n; 
				}
301
302
303
				break;
			case AR_USER:
				if((equal && user->number!=i) || (!equal && user->number<i))
304
					result=_not;
305
				else
306
					result=!_not;
307
308
309
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessUser];
310
311
					noaccess_val=i; 
				}
312
313
314
315
316
317
318
				break;
			case AR_GROUP:
				if((equal
					&& (cursubnum>=cfg.total_subs
						|| cfg.sub[cursubnum]->grp!=i))
					|| (!equal && cursubnum<cfg.total_subs
						&& cfg.sub[cursubnum]->grp<i))
319
					result=_not;
320
				else
321
					result=!_not;
322
323
324
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessGroup];
325
326
					noaccess_val=i+1; 
				}
327
328
329
				break;
			case AR_SUB:
				if((equal && cursubnum!=i) || (!equal && cursubnum<i))
330
					result=_not;
331
				else
332
					result=!_not;
333
334
335
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessSub];
336
337
					noaccess_val=i+1; 
				}
338
339
340
				break;
			case AR_SUBCODE:
				if(cursubnum>=cfg.total_subs
rswindell's avatar
rswindell committed
341
					|| !findstr_in_string(cfg.sub[cursubnum]->code,(char*)*ptrptr))
342
					result=_not;
343
				else
344
					result=!_not;
345
346
347
348
349
350
351
352
353
354
355
				while(*(*ptrptr))
					(*ptrptr)++;
				if(!result)
					noaccess_str=text[NoAccessSub];
				break;
			case AR_LIB:
				if((equal
					&& (curdirnum>=cfg.total_dirs
						|| cfg.dir[curdirnum]->lib!=i))
					|| (!equal && curdirnum<cfg.total_dirs
						&& cfg.dir[curdirnum]->lib<i))
356
					result=_not;
357
				else
358
					result=!_not;
359
360
361
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessLib];
362
363
					noaccess_val=i+1; 
				}
364
365
366
				break;
			case AR_DIR:
				if((equal && curdirnum!=i) || (!equal && curdirnum<i))
367
					result=_not;
368
				else
369
					result=!_not;
370
371
372
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessDir];
373
374
					noaccess_val=i+1; 
				}
375
376
377
				break;
			case AR_DIRCODE:
				if(curdirnum>=cfg.total_dirs
rswindell's avatar
rswindell committed
378
					|| !findstr_in_string(cfg.dir[curdirnum]->code,(char *)*ptrptr))
379
					result=_not;
380
				else
381
					result=!_not;
382
383
384
385
386
387
388
389
				while(*(*ptrptr))
					(*ptrptr)++;
				if(!result)
					noaccess_str=text[NoAccessSub];
				break;
			case AR_EXPIRE:
				now=time(NULL);
				if(!user->expire || now+((long)i*24L*60L*60L)>user->expire)
390
					result=_not;
391
				else
392
					result=!_not;
393
394
395
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessExpire];
396
397
					noaccess_val=i; 
				}
398
399
				break;
			case AR_RANDOM:
400
				n=sbbs_random(i+1);
401
				if((equal && n!=i) || (!equal && n<i))
402
					result=_not;
403
				else
404
					result=!_not;
405
406
407
408
409
				(*ptrptr)++;
				break;
			case AR_LASTON:
				now=time(NULL);
				if((now-user->laston)/(24L*60L*60L)<(long)i)
410
					result=_not;
411
				else
412
					result=!_not;
413
414
415
416
				(*ptrptr)++;
				break;
			case AR_LOGONS:
				if((equal && user->logons!=i) || (!equal && user->logons<i))
417
					result=_not;
418
				else
419
					result=!_not;
420
421
422
423
				(*ptrptr)++;
				break;
			case AR_MAIN_CMDS:
				if((equal && main_cmds!=i) || (!equal && main_cmds<i))
424
					result=_not;
425
				else
426
					result=!_not;
427
428
429
430
				(*ptrptr)++;
				break;
			case AR_FILE_CMDS:
				if((equal && xfer_cmds!=i) || (!equal && xfer_cmds<i))
431
					result=_not;
432
				else
433
					result=!_not;
434
435
436
437
				(*ptrptr)++;
				break;
			case AR_TLEFT:
				if(timeleft/60<(ulong)n)
438
					result=_not;
439
				else
440
					result=!_not;
441
442
				if(!result) {
					noaccess_str=text[NoAccessTimeLeft];
443
444
					noaccess_val=n; 
				}
445
446
447
				break;
			case AR_TUSED:
				if((time(NULL)-logontime)/60<(long)n)
448
					result=_not;
449
				else
450
					result=!_not;
451
452
				if(!result) {
					noaccess_str=text[NoAccessTimeUsed];
453
454
					noaccess_val=n; 
				}
455
456
457
				break;
			case AR_TIME:
				now=time(NULL);
458
459
				localtime_r(&now,&tm);
				if((tm.tm_hour*60)+tm.tm_min<(int)i)
460
					result=_not;
461
				else
462
					result=!_not;
463
464
465
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessTime];
466
467
					noaccess_val=i; 
				}
468
				break;
469
			case AR_PCR:	/* post/call ratio (by percentage) */
470
				if(user->logons>user->posts
471
					&& (!user->posts || (100/((float)user->logons/user->posts))<(long)n))
472
					result=_not;
473
				else
474
					result=!_not;
475
476
				if(!result) {
					noaccess_str=text[NoAccessPCR];
477
478
					noaccess_val=n; 
				}
479
				break;
480
			case AR_UDR:	/* up/download byte ratio (by percentage) */
481
482
483
				l=user->dlb;
				if(!l) l=1;
				if(user->dlb>user->ulb
484
					&& (!user->ulb || (100/((float)l/user->ulb))<n))
485
					result=_not;
486
				else
487
					result=!_not;
488
489
				if(!result) {
					noaccess_str=text[NoAccessUDR];
490
491
					noaccess_val=n; 
				}
492
				break;
493
			case AR_UDFR:	/* up/download file ratio (in percentage) */
494
495
496
				i=user->dls;
				if(!i) i=1;
				if(user->dls>user->uls
497
					&& (!user->uls || (100/((float)i/user->uls))<n))
498
					result=_not;
499
				else
500
					result=!_not;
501
502
				if(!result) {
					noaccess_str=text[NoAccessUDFR];
503
504
					noaccess_val=n; 
				}
505
				break;
rswindell's avatar
rswindell committed
506
507
508
509
510
511
512
			case AR_ULS:
				if((equal && user->uls!=i) || (!equal && user->uls<i))
					result=_not;
				else
					result=!_not;
				(*ptrptr)++;
				break;
513
514
515
516
517
518
519
520
521
			case AR_ULK:
				if((equal && (user->ulb/1024)!=i) || (!equal && (user->ulb/1024)<i))
					result=_not;
				else
					result=!_not;
				(*ptrptr)++;
				break;
			case AR_ULM:
				if((equal && (user->ulb/(1024*1024))!=i) || (!equal && (user->ulb/(1024*1024))<i))
rswindell's avatar
rswindell committed
522
523
524
525
526
527
528
529
530
531
532
533
					result=_not;
				else
					result=!_not;
				(*ptrptr)++;
				break;
			case AR_DLS:
				if((equal && user->dls!=i) || (!equal && user->dls<i))
					result=_not;
				else
					result=!_not;
				(*ptrptr)++;
				break;
534
535
536
537
538
539
540
541
542
			case AR_DLK:
				if((equal && user->dlb/1024!=i) || (!equal && user->dlb/1024<i))
					result=_not;
				else
					result=!_not;
				(*ptrptr)++;
				break;
			case AR_DLM:
				if((equal && user->dlb/(1024*1024)!=i) || (!equal && user->dlb/(1024*1024)<i))
rswindell's avatar
rswindell committed
543
544
545
546
547
					result=_not;
				else
					result=!_not;
				(*ptrptr)++;
				break;
548
549
550
			case AR_FLAG1:
				if((!equal && !(user->flags1&FLAG(n)))
					|| (equal && user->flags1!=FLAG(n)))
551
					result=_not;
552
				else
553
					result=!_not;
554
555
				if(!result) {
					noaccess_str=text[NoAccessFlag1];
556
557
					noaccess_val=n; 
				}
558
559
560
561
				break;
			case AR_FLAG2:
				if((!equal && !(user->flags2&FLAG(n)))
					|| (equal && user->flags2!=FLAG(n)))
562
					result=_not;
563
				else
564
					result=!_not;
565
566
				if(!result) {
					noaccess_str=text[NoAccessFlag2];
567
568
					noaccess_val=n; 
				}
569
570
571
572
				break;
			case AR_FLAG3:
				if((!equal && !(user->flags3&FLAG(n)))
					|| (equal && user->flags3!=FLAG(n)))
573
					result=_not;
574
				else
575
					result=!_not;
576
577
				if(!result) {
					noaccess_str=text[NoAccessFlag3];
578
579
					noaccess_val=n; 
				}
580
581
582
583
				break;
			case AR_FLAG4:
				if((!equal && !(user->flags4&FLAG(n)))
					|| (equal && user->flags4!=FLAG(n)))
584
					result=_not;
585
				else
586
					result=!_not;
587
588
				if(!result) {
					noaccess_str=text[NoAccessFlag4];
589
590
					noaccess_val=n; 
				}
591
592
593
594
				break;
			case AR_REST:
				if((!equal && !(user->rest&FLAG(n)))
					|| (equal && user->rest!=FLAG(n)))
595
					result=_not;
596
				else
597
					result=!_not;
598
599
				if(!result) {
					noaccess_str=text[NoAccessRest];
600
601
					noaccess_val=n; 
				}
602
603
604
605
				break;
			case AR_EXEMPT:
				if((!equal && !(user->exempt&FLAG(n)))
					|| (equal && user->exempt!=FLAG(n)))
606
					result=_not;
607
				else
608
					result=!_not;
609
610
				if(!result) {
					noaccess_str=text[NoAccessExempt];
611
612
					noaccess_val=n; 
				}
613
614
615
				break;
			case AR_SEX:
				if(user->sex!=n)
616
					result=_not;
617
				else
618
					result=!_not;
619
620
				if(!result) {
					noaccess_str=text[NoAccessSex];
621
622
					noaccess_val=n; 
				}
623
624
625
				break; 
			case AR_SHELL:
				if(user->shell>=cfg.total_shells
rswindell's avatar
rswindell committed
626
					|| !findstr_in_string(cfg.shell[user->shell]->code,(char*)*ptrptr))
627
628
629
630
631
632
					result=_not;
				else
					result=!_not;
				while(*(*ptrptr))
					(*ptrptr)++;
				break;
633
			case AR_PROT:
rswindell's avatar
rswindell committed
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
				if(client!=NULL)
					p=client->protocol;
				else
					p=user->modem;
				if(!findstr_in_string(p,(char*)*ptrptr))
					result=_not;
				else
					result=!_not;
				while(*(*ptrptr))
					(*ptrptr)++;
				break;
			case AR_HOST:
				if(client!=NULL)
					p=client->host;
				else
					p=user->comp;
				if(!findstr_in_string(p,(char*)*ptrptr))
					result=_not;
				else
					result=!_not;
				while(*(*ptrptr))
					(*ptrptr)++;
				break;
			case AR_IP:
				if(client!=NULL)
					p=client->addr;
				else
deuce's avatar
deuce committed
661
					p=user->ipaddr;
rswindell's avatar
rswindell committed
662
				if(!findstr_in_string(p,(char*)*ptrptr))
663
664
665
666
667
668
					result=_not;
				else
					result=!_not;
				while(*(*ptrptr))
					(*ptrptr)++;
				break;
rswindell's avatar
rswindell committed
669
670
671
672
673
674
675
676
677
678
679
680
681
			case AR_TERM:
				if(!findstr_in_string(terminal, (char*)*ptrptr))
					result=_not;
				else
					result=!_not;
				while(*(*ptrptr))
					(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessTerminal];
					noaccess_val=0; 
				}
				break;
			case AR_COLS:
682
				if((equal && cols != (long)n) || (!equal && cols < (long)n))
rswindell's avatar
rswindell committed
683
684
685
686
687
688
689
690
691
					result=_not;
				else
					result=!_not;
				if(!result) {
					noaccess_str=text[NoAccessTerminal];
					noaccess_val=n; 
				}
				break;
			case AR_ROWS:
692
				if((equal && rows != (long)n) || (!equal && rows < (long)n))
rswindell's avatar
rswindell committed
693
694
695
696
697
698
699
700
					result=_not;
				else
					result=!_not;
				if(!result) {
					noaccess_str=text[NoAccessTerminal];
					noaccess_val=n; 
				}
				break;
701
702
		}
	}
703
704
705
	return(result);
}

rswindell's avatar
rswindell committed
706
bool sbbs_t::chk_ar(const uchar *ar, user_t* user, client_t* client)
707
{
708
	const uchar *p;
709
710
711
712

	if(ar==NULL)
		return(true);
	p=ar;
rswindell's avatar
rswindell committed
713
	return(ar_exp(&p,user,client));
714
715
716
717
718
719
720
721
722
723
724
725
}


/****************************************************************************/
/* This function fills the usrsub, usrsubs, usrgrps, curgrp, and cursub     */
/* variables based on the security clearance of the current user (useron)   */
/****************************************************************************/
void sbbs_t::getusrsubs()
{
    uint i,j,k,l;

	for(j=0,i=0;i<cfg.total_grps;i++) {
rswindell's avatar
rswindell committed
726
		if(!chk_ar(cfg.grp[i]->ar,&useron,&client))
727
728
729
			continue;
		for(k=0,l=0;l<cfg.total_subs;l++) {
			if(cfg.sub[l]->grp!=i) continue;
rswindell's avatar
rswindell committed
730
			if(!chk_ar(cfg.sub[l]->ar,&useron,&client))
731
				continue;
732
733
			usrsub[j][k++]=l; 
		}
734
735
736
		usrsubs[j]=k;
		if(!k)          /* No subs accessible in group */
			continue;
737
738
		usrgrp[j++]=i; 
	}
739
	usrgrps=j;
740
741
	if(usrgrps==0)
		return;
742
743
744
745
746
747
748
749
750
751
752
753
754
755
	while((curgrp>=usrgrps || !usrsubs[curgrp]) && curgrp) curgrp--;
	while(cursub[curgrp]>=usrsubs[curgrp] && cursub[curgrp]) cursub[curgrp]--;
}

/****************************************************************************/
/* This function fills the usrdir, usrdirs, usrlibs, curlib, and curdir     */
/* variables based on the security clearance of the current user (useron)   */
/****************************************************************************/
void sbbs_t::getusrdirs()
{
    uint i,j,k,l;

	if(useron.rest&FLAG('T')) {
		usrlibs=0;
756
757
		return; 
	}
758
	for(j=0,i=0;i<cfg.total_libs;i++) {
rswindell's avatar
rswindell committed
759
		if(!chk_ar(cfg.lib[i]->ar,&useron,&client))
760
761
762
			continue;
		for(k=0,l=0;l<cfg.total_dirs;l++) {
			if(cfg.dir[l]->lib!=i) continue;
rswindell's avatar
rswindell committed
763
			if(!chk_ar(cfg.dir[l]->ar,&useron,&client))
764
				continue;
765
766
			usrdir[j][k++]=l; 
		}
767
768
769
		usrdirs[j]=k;
		if(!k)          /* No dirs accessible in lib */
			continue;
770
771
		usrlib[j++]=i; 
	}
772
	usrlibs=j;
773
774
	if(usrlibs==0)
		return;
775
776
777
778
	while((curlib>=usrlibs || !usrdirs[curlib]) && curlib) curlib--;
	while(curdir[curlib]>=usrdirs[curlib] && curdir[curlib]) curdir[curlib]--;
}

779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
uint sbbs_t::getusrgrp(uint subnum)
{
	uint	ugrp;

	if(subnum==INVALID_SUB)
		return(0);

	if(usrgrps<=0)
		return(0);

	for(ugrp=0;ugrp<usrgrps;ugrp++)
		if(usrgrp[ugrp]==cfg.sub[subnum]->grp)
			break;

	return(ugrp+1);
}

uint sbbs_t::getusrsub(uint subnum)
{
	uint	usub;
	uint	ugrp;

	ugrp = getusrgrp(subnum);
	if(ugrp<=0)
		return(0);
804
	ugrp--;
805
806
807
808
809
810
811
	for(usub=0;usub<usrsubs[ugrp];usub++)
		if(usrsub[ugrp][usub]==subnum)
			break;

	return(usub+1);
}

812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
uint sbbs_t::getusrlib(uint dirnum)
{
	uint	ulib;

	if(dirnum == INVALID_DIR)
		return 0;

	if(usrlibs <= 0)
		return 0;

	for(ulib=0; ulib < usrlibs; ulib++)
		if(usrlib[ulib] == cfg.dir[dirnum]->lib)
			break;

	return ulib+1;
}

uint sbbs_t::getusrdir(uint dirnum)
{
	uint	udir;
	uint	ulib;

	ulib = getusrlib(dirnum);
	if(ulib <= 0)
		return 0;
	ulib--;
	for(udir=0; udir < usrdirs[ulib]; udir++)
		if(usrdir[ulib][udir] == dirnum)
			break;

	return udir+1;
}


846
847
int sbbs_t::dir_op(uint dirnum)
{
848
	return(SYSOP || (cfg.dir[dirnum]->op_ar!=NULL && cfg.dir[dirnum]->op_ar[0] && chk_ar(cfg.dir[dirnum]->op_ar,&useron,&client)));
849
850
851
}