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

scfgxfr2.c 46.8 KB
Newer Older
rswindell's avatar
rswindell committed
1 2
/* scfgxfr2.c */

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
/* $Id$ */

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

#include "scfg.h"

38 39
#define DEFAULT_DIR_OPTIONS (DIR_FCHK|DIR_MULT|DIR_DUPES|DIR_CDTUL|DIR_CDTDL|DIR_DIZ)

rswindell's avatar
rswindell committed
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
void xfer_cfg()
{
	static int libs_dflt,libs_bar,dflt;
	char str[256],str2[81],done=0,*p;
	int file,j,k,q;
	uint i;
	long ported;
	static lib_t savlib;
	dir_t tmpdir;
	FILE *stream;

while(1) {
	for(i=0;i<cfg.total_libs && i<MAX_OPTS;i++)
		sprintf(opt[i],"%-25s",cfg.lib[i]->lname);
	opt[i][0]=0;
	j=WIN_ACT|WIN_CHE|WIN_ORG;
	if(cfg.total_libs)
		j|=WIN_DEL|WIN_GET|WIN_DELACT;
	if(cfg.total_libs<MAX_OPTS)
		j|=WIN_INS|WIN_INSACT|WIN_XTR;
	if(savlib.sname[0])
		j|=WIN_PUT;
	SETHELP(WHERE);
/*
File Libraries:

This is a listing of file libraries for your BBS. File Libraries are
used to logically separate your file directories into groups. Every
directory belongs to a file library.

One popular use for file libraries is to separate CD-ROM and hard disk
directories. One might have an Uploads file library that contains
uploads to the hard disk directories and also have a PC-SIG file
library that contains directories from a PC-SIG CD-ROM. Some sysops
separate directories into more specific areas such as Main, Graphics,
or Adult. If you have many directories that have a common subject
denominator, you may want to have a separate file library for those
directories for a more organized file structure.
*/
79
	i=uifc.list(j,0,0,45,&libs_dflt,&libs_bar,"File Libraries",opt);
rswindell's avatar
rswindell committed
80 81 82 83
	if((signed)i==-1) {
		j=save_changes(WIN_MID);
		if(j==-1)
			continue;
84
		if(!j) {
rswindell's avatar
rswindell committed
85
			write_file_cfg(&cfg,backup_level);
86
            refresh_cfg(&cfg);
87
        }
rswindell's avatar
rswindell committed
88 89 90 91 92 93 94 95 96 97 98
		return; }
	if((i&MSK_ON)==MSK_INS) {
		i&=MSK_OFF;
		strcpy(str,"Main");
		SETHELP(WHERE);
/*
Library Long Name:

This is a description of the file library which is displayed when a
user of the system uses the /* command from the file transfer menu.
*/
99
		if(uifc.input(WIN_MID|WIN_SAV,0,0,"Library Long Name",str,LEN_GLNAME
rswindell's avatar
rswindell committed
100 101 102 103 104 105 106 107 108 109
			,K_EDIT)<1)
			continue;
		sprintf(str2,"%.*s",LEN_GSNAME,str);
		SETHELP(WHERE);
/*
Library Short Name:

This is a short description of the file library which is used for the
file transfer menu prompt.
*/
110
		if(uifc.input(WIN_MID|WIN_SAV,0,0,"Library Short Name",str2,LEN_GSNAME
rswindell's avatar
rswindell committed
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
			,K_EDIT)<1)
			continue;
		if((cfg.lib=(lib_t **)REALLOC(cfg.lib,sizeof(lib_t *)*(cfg.total_libs+1)))==NULL) {
			errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_libs+1);
			cfg.total_libs=0;
			bail(1);
            continue; }

		if(cfg.total_libs) {
			for(j=cfg.total_libs;j>i;j--)
                cfg.lib[j]=cfg.lib[j-1];
			for(j=0;j<cfg.total_dirs;j++)
				if(cfg.dir[j]->lib>=i)
					cfg.dir[j]->lib++; }
		if((cfg.lib[i]=(lib_t *)MALLOC(sizeof(lib_t)))==NULL) {
			errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(lib_t));
			continue; }
		memset((lib_t *)cfg.lib[i],0,sizeof(lib_t));
		strcpy(cfg.lib[i]->lname,str);
		strcpy(cfg.lib[i]->sname,str2);
		cfg.total_libs++;
132
		uifc.changes=1;
rswindell's avatar
rswindell committed
133 134 135 136 137 138 139 140 141 142 143 144 145 146
		continue; }
	if((i&MSK_ON)==MSK_DEL) {
		i&=MSK_OFF;
		SETHELP(WHERE);
/*
Delete All Data in Library:

If you wish to delete the database files for all directories in this
library, select Yes.
*/
		j=1;
		strcpy(opt[0],"Yes");
		strcpy(opt[1],"No");
		opt[2][0]=0;
147
		j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0
rswindell's avatar
rswindell committed
148 149 150 151 152 153 154
			,"Delete All Library Data Files",opt);
		if(j==-1)
			continue;
		if(j==0)
			for(j=0;j<cfg.total_dirs;j++)
				if(cfg.dir[j]->lib==i) {
					sprintf(str,"%s.*",cfg.dir[j]->code);
155
					strlwr(str);
rswindell's avatar
rswindell committed
156
					if(!cfg.dir[j]->data_dir[0])
rswindell's avatar
rswindell committed
157
						sprintf(tmp,"%sdirs/",cfg.data_dir);
rswindell's avatar
rswindell committed
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
					else
						strcpy(tmp,cfg.dir[j]->data_dir);
					delfiles(tmp,str); }
		FREE(cfg.lib[i]);
		for(j=0;j<cfg.total_dirs;) {
			if(cfg.dir[j]->lib==i) {
				FREE(cfg.dir[j]);
				cfg.total_dirs--;
				k=j;
				while(k<cfg.total_dirs) {
					cfg.dir[k]=cfg.dir[k+1];
					k++; } }
			else j++; }
		for(j=0;j<cfg.total_dirs;j++)
			if(cfg.dir[j]->lib>i)
				cfg.dir[j]->lib--;
		cfg.total_libs--;
		while(i<cfg.total_libs) {
			cfg.lib[i]=cfg.lib[i+1];
			i++; }
178
		uifc.changes=1;
rswindell's avatar
rswindell committed
179 180 181 182 183 184 185 186
		continue; }
	if((i&MSK_ON)==MSK_GET) {
		i&=MSK_OFF;
		savlib=*cfg.lib[i];
		continue; }
	if((i&MSK_ON)==MSK_PUT) {
		i&=MSK_OFF;
		*cfg.lib[i]=savlib;
187
		uifc.changes=1;
rswindell's avatar
rswindell committed
188 189 190 191 192 193
        continue; }
	done=0;
	while(!done) {
		j=0;
		sprintf(opt[j++],"%-27.27s%s","Long Name",cfg.lib[i]->lname);
		sprintf(opt[j++],"%-27.27s%s","Short Name",cfg.lib[i]->sname);
194 195
		sprintf(opt[j++],"%-27.27s%.40s","Parent Directory"
			,cfg.lib[i]->parent_path);
rswindell's avatar
rswindell committed
196 197 198 199 200 201 202
		sprintf(opt[j++],"%-27.27s%.40s","Access Requirements"
			,cfg.lib[i]->arstr);
		strcpy(opt[j++],"Clone Options");
		strcpy(opt[j++],"Export Areas...");
		strcpy(opt[j++],"Import Areas...");
		strcpy(opt[j++],"File Directories...");
		opt[j][0]=0;
203
		uifc.savnum=0;
rswindell's avatar
rswindell committed
204 205 206 207 208 209 210 211 212
		sprintf(str,"%s Library",cfg.lib[i]->sname);
		SETHELP(WHERE);
/*
File Library Configuration:

This menu allows you to configure the security requirments for access
to this file library. You can also add, delete, and configure the
directories of this library by selecting the File Directories... option.
*/
213
		switch(uifc.list(WIN_ACT,6,4,60,&dflt,0,str,opt)) {
rswindell's avatar
rswindell committed
214 215 216 217 218 219 220 221 222 223 224 225
			case -1:
				done=1;
				break;
			case 0:
				SETHELP(WHERE);
/*
Library Long Name:

This is a description of the file library which is displayed when a
user of the system uses the /* command from the file transfer menu.
*/
				strcpy(str,cfg.lib[i]->lname);	/* save */
226
				if(!uifc.input(WIN_MID|WIN_SAV,0,0,"Name to use for Listings"
rswindell's avatar
rswindell committed
227 228 229 230 231 232 233 234 235 236 237
					,cfg.lib[i]->lname,LEN_GLNAME,K_EDIT))
					strcpy(cfg.lib[i]->lname,str);	/* restore */
				break;
			case 1:
				SETHELP(WHERE);
/*
Library Short Name:

This is a short description of the file librarly which is used for the
file transfer menu prompt.
*/
238
				uifc.input(WIN_MID|WIN_SAV,0,0,"Name to use for Prompts"
rswindell's avatar
rswindell committed
239 240 241
					,cfg.lib[i]->sname,LEN_GSNAME,K_EDIT);
				break;
			case 2:
242 243
				SETHELP(WHERE);
/*
244
Parent Directory:
245

246 247 248 249 250 251 252 253 254
This an optional path to be used as the physical "parent" directory for 
all logical directories in this library. This parent directory will be
used in combination with each directory's storage path to create the
full physical storage path for files in this directory.

This option is convenient for adding libraries with many directories
that share a common parent directory (e.g. CD-ROMs) and gives you the
option of easily changing the common parent directory location later, if
desired.
255
*/
256 257
				uifc.input(WIN_MID|WIN_SAV,0,0,"Parent Directory"
					,cfg.lib[i]->parent_path,sizeof(cfg.lib[i]->parent_path)-1,K_EDIT);
258 259
				break;
			case 3:
rswindell's avatar
rswindell committed
260 261 262
				sprintf(str,"%s Library",cfg.lib[i]->sname);
				getar(str,cfg.lib[i]->arstr);
				break;
263
			case 4: /* clone options */
rswindell's avatar
rswindell committed
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
				j=0;
				strcpy(opt[0],"Yes");
				strcpy(opt[1],"No");
				opt[2][0]=0;
				SETHELP(WHERE);
/*
Clone Directory Options:

If you want to clone the options of the first directory of this library
into all directories of this library, select Yes.

The options cloned are upload requirments, download requirments,
operator requirements, exempted user requirements, toggle options,
maximum number of files, allowed file extensions, default file
extension, and sort type.
*/
280
				j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0
rswindell's avatar
rswindell committed
281 282 283 284 285 286 287 288 289
					,"Clone Options of First Directory into All of Library"
					,opt);
				if(j==0) {
					k=-1;
					for(j=0;j<cfg.total_dirs;j++)
						if(cfg.dir[j]->lib==i) {
							if(k==-1)
								k=j;
							else {
290
								uifc.changes=1;
rswindell's avatar
rswindell committed
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
								cfg.dir[j]->misc=cfg.dir[k]->misc;
								strcpy(cfg.dir[j]->ul_arstr,cfg.dir[k]->ul_arstr);
								strcpy(cfg.dir[j]->dl_arstr,cfg.dir[k]->dl_arstr);
								strcpy(cfg.dir[j]->op_arstr,cfg.dir[k]->op_arstr);
								strcpy(cfg.dir[j]->ex_arstr,cfg.dir[k]->ex_arstr);
								strcpy(cfg.dir[j]->exts,cfg.dir[k]->exts);
								strcpy(cfg.dir[j]->data_dir,cfg.dir[k]->data_dir);
								strcpy(cfg.dir[j]->upload_sem,cfg.dir[k]->upload_sem);
								cfg.dir[j]->maxfiles=cfg.dir[k]->maxfiles;
								cfg.dir[j]->maxage=cfg.dir[k]->maxage;
								cfg.dir[j]->up_pct=cfg.dir[k]->up_pct;
								cfg.dir[j]->dn_pct=cfg.dir[k]->dn_pct;
								cfg.dir[j]->seqdev=cfg.dir[k]->seqdev;
								cfg.dir[j]->sort=cfg.dir[k]->sort; } } }
                break;
306
			case 5:
rswindell's avatar
rswindell committed
307 308
				k=0;
				ported=0;
309
				q=uifc.changes;
rswindell's avatar
rswindell committed
310 311 312 313 314 315 316 317 318 319 320
				strcpy(opt[k++],"DIRS.TXT    (Synchronet)");
				strcpy(opt[k++],"FILEBONE.NA (Fido)");
				opt[k][0]=0;
				SETHELP(WHERE);
/*
Export Area File Format:

This menu allows you to choose the format of the area file you wish to
export to.
*/
				k=0;
321
				k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
rswindell's avatar
rswindell committed
322 323 324 325 326 327 328
					,"Export Area File Format",opt);
				if(k==-1)
					break;
				if(k==0)
					sprintf(str,"%sDIRS.TXT",cfg.ctrl_dir);
				else if(k==1)
					sprintf(str,"FILEBONE.NA");
329
				if(uifc.input(WIN_MID|WIN_SAV,0,0,"Filename"
rswindell's avatar
rswindell committed
330
					,str,40,K_EDIT)<=0) {
331
					uifc.changes=q;
rswindell's avatar
rswindell committed
332 333 334 335 336 337
					break; }
				if(fexist(str)) {
					strcpy(opt[0],"Overwrite");
					strcpy(opt[1],"Append");
					opt[2][0]=0;
					j=0;
338
					j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0
rswindell's avatar
rswindell committed
339 340 341 342 343 344 345 346
						,"File Exists",opt);
					if(j==-1)
						break;
					if(j==0) j=O_WRONLY|O_TRUNC;
					else	 j=O_WRONLY|O_APPEND; }
				else
					j=O_WRONLY|O_CREAT;
				if((stream=fnopen(&file,str,j))==NULL) {
347
					uifc.msg("Open Failure");
rswindell's avatar
rswindell committed
348
					break; }
349
				uifc.pop("Exporting Areas...");
rswindell's avatar
rswindell committed
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386
				for(j=0;j<cfg.total_dirs;j++) {
					if(cfg.dir[j]->lib!=i)
						continue;
					ported++;
					if(k==1) {
						fprintf(stream,"Area %-8s  0     !      %s\r\n"
							,cfg.dir[j]->code,cfg.dir[j]->lname);
						continue; }
					fprintf(stream,"%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n"
							"%s\r\n%s\r\n"
						,cfg.dir[j]->lname
						,cfg.dir[j]->sname
						,cfg.dir[j]->code
						,cfg.dir[j]->data_dir
						,cfg.dir[j]->arstr
						,cfg.dir[j]->ul_arstr
						,cfg.dir[j]->dl_arstr
						,cfg.dir[j]->op_arstr
						);
					fprintf(stream,"%s\r\n%s\r\n%u\r\n%s\r\n%lX\r\n%u\r\n"
							"%u\r\n"
						,cfg.dir[j]->path
						,cfg.dir[j]->upload_sem
						,cfg.dir[j]->maxfiles
						,cfg.dir[j]->exts
						,cfg.dir[j]->misc
						,cfg.dir[j]->seqdev
						,cfg.dir[j]->sort
						);
					fprintf(stream,"%s\r\n%u\r\n%u\r\n%u\r\n"
						,cfg.dir[j]->ex_arstr
						,cfg.dir[j]->maxage
						,cfg.dir[j]->up_pct
						,cfg.dir[j]->dn_pct
						);
					fprintf(stream,"***END-OF-DIR***\r\n\r\n"); }
				fclose(stream);
387
				uifc.pop(0);
rswindell's avatar
rswindell committed
388
				sprintf(str,"%lu File Areas Exported Successfully",ported);
389 390
				uifc.msg(str);
				uifc.changes=q;
rswindell's avatar
rswindell committed
391 392
				break;

393
			case 6:
rswindell's avatar
rswindell committed
394 395 396 397 398 399 400 401
				ported=0;
				k=0;
				SETHELP(WHERE);
/*
Import Area File Format:

This menu allows you to choose the format of the area file you wish to
import into the current file library.
402 403 404

A "raw" directory listing can be created in DOS with the following
command: DIR /ON /AD /B > DIRS.RAW
rswindell's avatar
rswindell committed
405 406 407
*/
				strcpy(opt[k++],"DIRS.TXT    (Synchronet)");
                strcpy(opt[k++],"FILEBONE.NA (Fido)");
408
				strcpy(opt[k++],"DIRS.RAW    (Raw)");
rswindell's avatar
rswindell committed
409 410
				opt[k][0]=0;
				k=0;
411
				k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
rswindell's avatar
rswindell committed
412 413 414 415 416 417 418
					,"Import Area File Format",opt);
				if(k==-1)
					break;
				if(k==0)
					sprintf(str,"%sDIRS.TXT",cfg.ctrl_dir);
				else if(k==1)
					sprintf(str,"FILEBONE.NA");
419
				else {
420
					strcpy(str,cfg.lib[i]->parent_path);
421 422 423
					backslash(str);
					strcat(str,"dirs.raw");
				}
424
				if(uifc.input(WIN_MID|WIN_SAV,0,0,"Filename"
rswindell's avatar
rswindell committed
425 426 427
					,str,40,K_EDIT)<=0)
                    break;
				if((stream=fnopen(&file,str,O_RDONLY))==NULL) {
428
					uifc.msg("Open Failure");
rswindell's avatar
rswindell committed
429
                    break; }
430
				uifc.pop("Importing Areas...");
rswindell's avatar
rswindell committed
431 432 433 434 435
				while(!feof(stream)) {
					if(!fgets(str,128,stream)) break;
					truncsp(str);
					if(!str[0])
						continue;
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
					memset(&tmpdir,0,sizeof(dir_t));
					tmpdir.misc=DEFAULT_DIR_OPTIONS;
					tmpdir.maxfiles=1000;
					tmpdir.up_pct=cfg.cdt_up_pct;
					tmpdir.dn_pct=cfg.cdt_dn_pct; 

					p=str;
					while(*p && *p<=SP) p++;

					if(k==2) { /* raw */
						SAFECOPY(tmpdir.code,p);
						SAFECOPY(tmpdir.lname,p);
						SAFECOPY(tmpdir.sname,p);
						SAFECOPY(tmpdir.path,p);
						ported++;
					}
					else if(k==1) {
rswindell's avatar
rswindell committed
453 454
						if(strnicmp(p,"AREA ",5))
							continue;
455 456 457 458 459 460 461 462 463 464 465 466 467 468
						p+=5;
						while(*p && *p<=SP) p++;
						sprintf(tmpdir.code,"%.8s",p);
						truncsp(tmpdir.code);
						while(*p>SP) p++;			/* Skip areaname */
						while(*p && *p<=SP) p++;	/* Skip space */
						while(*p>SP) p++;			/* Skip level */
						while(*p && *p<=SP) p++;	/* Skip space */
						while(*p>SP) p++;			/* Skip flags */
						while(*p && *p<=SP) p++;	/* Skip space */
						SAFECOPY(tmpdir.sname,p); 
						SAFECOPY(tmpdir.lname,p); 
						ported++; 
					}
rswindell's avatar
rswindell committed
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
					else {
						sprintf(tmpdir.lname,"%.*s",LEN_SLNAME,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpdir.sname,"%.*s",LEN_SSNAME,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpdir.code,"%.*s",8,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpdir.data_dir,"%.*s",LEN_DIR,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpdir.arstr,"%.*s",LEN_ARSTR,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpdir.ul_arstr,"%.*s",LEN_ARSTR,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpdir.dl_arstr,"%.*s",LEN_ARSTR,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpdir.op_arstr,"%.*s",LEN_ARSTR,str);
						if(!fgets(str,128,stream)) break;
                        truncsp(str);
                        sprintf(tmpdir.path,"%.*s",LEN_DIR,str);
						if(!fgets(str,128,stream)) break;
                        truncsp(str);
                        sprintf(tmpdir.upload_sem,"%.*s",LEN_DIR,str);
						if(!fgets(str,128,stream)) break;
                        truncsp(str);
						tmpdir.maxfiles=atoi(str);
						if(!fgets(str,128,stream)) break;
                        truncsp(str);
						sprintf(tmpdir.exts,"%.*s",40,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						tmpdir.misc=ahtoul(str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						tmpdir.seqdev=atoi(str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						tmpdir.sort=atoi(str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpdir.ex_arstr,"%.*s",LEN_ARSTR,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						tmpdir.maxage=atoi(str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						tmpdir.up_pct=atoi(str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						tmpdir.dn_pct=atoi(str);

						ported++;
						while(!feof(stream)
							&& strcmp(str,"***END-OF-DIR***")) {
							if(!fgets(str,128,stream)) break;
530 531 532
							truncsp(str); 
						} 
					}
rswindell's avatar
rswindell committed
533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552

					for(j=0;j<cfg.total_dirs;j++) {
						if(cfg.dir[j]->lib!=i)
							continue;
						if(!stricmp(cfg.dir[j]->code,tmpdir.code))
							break; }
					if(j==cfg.total_dirs) {

						if((cfg.dir=(dir_t **)REALLOC(cfg.dir
							,sizeof(dir_t *)*(cfg.total_dirs+1)))==NULL) {
							errormsg(WHERE,ERR_ALLOC,"dir",cfg.total_dirs+1);
							cfg.total_dirs=0;
							bail(1);
							break; }

						if((cfg.dir[j]=(dir_t *)MALLOC(sizeof(dir_t)))
							==NULL) {
							errormsg(WHERE,ERR_ALLOC,"dir",sizeof(dir_t));
							break; }
						memset(cfg.dir[j],0,sizeof(dir_t)); }
553
					if(k==1) {
rswindell's avatar
rswindell committed
554 555 556 557 558 559
						strcpy(cfg.dir[j]->code,tmpdir.code);
						strcpy(cfg.dir[j]->sname,tmpdir.code);
						strcpy(cfg.dir[j]->lname,tmpdir.lname);
						if(j==cfg.total_dirs) {
							cfg.dir[j]->maxfiles=1000;
							cfg.dir[j]->up_pct=cfg.cdt_up_pct;
560
							cfg.dir[j]->dn_pct=cfg.cdt_dn_pct; 
rswindell's avatar
rswindell committed
561
						}
562 563
					} else
						memcpy(cfg.dir[j],&tmpdir,sizeof(dir_t));
rswindell's avatar
rswindell committed
564 565 566
					cfg.dir[j]->lib=i;
					if(j==cfg.total_dirs) {
						cfg.dir[j]->misc=tmpdir.misc;
567 568 569 570
						cfg.total_dirs++; 
					}
					uifc.changes=1; 
				}
rswindell's avatar
rswindell committed
571
				fclose(stream);
572
				uifc.pop(0);
rswindell's avatar
rswindell committed
573
				sprintf(str,"%lu File Areas Imported Successfully",ported);
574
                uifc.msg(str);
rswindell's avatar
rswindell committed
575 576
                break;

577
			case 7:
rswindell's avatar
rswindell committed
578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598
				dir_cfg(i);
				break; } } }

}

void dir_cfg(uint libnum)
{
	static int dflt,bar,tog_dflt,tog_bar,adv_dflt,opt_dflt;
	char str[81],str2[81],code[9],path[128],done=0,*p;
	int j,n;
	uint i,dirnum[MAX_OPTS+1];
	static dir_t savdir;

while(1) {
	for(i=0,j=0;i<cfg.total_dirs && j<MAX_OPTS;i++)
		if(cfg.dir[i]->lib==libnum) {
			sprintf(opt[j],"%-25s",cfg.dir[i]->lname);
			dirnum[j++]=i; }
	dirnum[j]=cfg.total_dirs;
	opt[j][0]=0;
	sprintf(str,"%s Directories",cfg.lib[libnum]->sname);
599
	uifc.savnum=0;
rswindell's avatar
rswindell committed
600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620
	i=WIN_SAV|WIN_ACT;
	if(j)
		i|=WIN_DEL|WIN_GET|WIN_DELACT;
	if(j<MAX_OPTS)
		i|=WIN_INS|WIN_INSACT|WIN_XTR;
	if(savdir.sname[0])
		i|=WIN_PUT;
	SETHELP(WHERE);
/*
File Directories:

This is a list of file directories that have been configured for the
selected file library.

To add a directory, select the desired position with the arrow keys and
hit  INS .

To delete a directory, select it with the arrow keys and hit  DEL .

To configure a directory, select it with the arrow keys and hit  ENTER .
*/
621 622
	i=uifc.list(i,24,1,45,&dflt,&bar,str,opt);
	uifc.savnum=1;
rswindell's avatar
rswindell committed
623 624 625 626 627 628 629 630 631 632 633 634
	if((signed)i==-1)
		return;
	if((i&MSK_ON)==MSK_INS) {
		i&=MSK_OFF;
		strcpy(str,"Games");
		SETHELP(WHERE);
/*
Directory Long Name:

This is a description of the file directory which is displayed in all
directory listings.
*/
635
		if(uifc.input(WIN_MID|WIN_SAV,0,0,"Directory Long Name",str,LEN_SLNAME
rswindell's avatar
rswindell committed
636 637 638 639 640 641 642 643 644 645
			,K_EDIT)<1)
			continue;
		sprintf(str2,"%.*s",LEN_SSNAME,str);
		SETHELP(WHERE);
/*
Directory Short Name:

This is a short description of the file directory which is displayed at
the file transfer prompt.
*/
646
		if(uifc.input(WIN_MID|WIN_SAV,0,0,"Directory Short Name",str2,LEN_SSNAME
rswindell's avatar
rswindell committed
647 648 649 650 651 652 653 654 655 656 657 658 659 660
			,K_EDIT)<1)
            continue;
		sprintf(code,"%.8s",str2);
		p=strchr(code,SP);
		if(p) *p=0;
		strupr(code);
		SETHELP(WHERE);
/*
Directory Internal Code:

Every directory must have its own unique code for Synchronet to refer to
it internally. This code should be descriptive of the directory's
contents, usually an abreviation of the directory's name.
*/
661
		if(uifc.input(WIN_MID|WIN_SAV,0,0,"Directory Internal Code",code,8
rswindell's avatar
rswindell committed
662 663 664
			,K_EDIT|K_UPPER)<1)
            continue;
		if(!code_ok(code)) {
665 666 667
			uifc.helpbuf=invalid_code;
			uifc.msg("Invalid Code");
			uifc.helpbuf=0;
rswindell's avatar
rswindell committed
668
			continue; }
rswindell's avatar
rswindell committed
669
		sprintf(path,"%sdirs/%s",cfg.data_dir,code);
rswindell's avatar
rswindell committed
670 671 672 673 674 675 676
		SETHELP(WHERE);
/*
Directory File Path:

This is the drive and directory where your uploads to and downloads from
this directory will be stored. Example: C:\XFER\GAMES
*/
677
		if(uifc.input(WIN_MID|WIN_SAV,0,0,"Directory File Path",path,50
rswindell's avatar
rswindell committed
678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694
			,K_EDIT)<1)
			continue;
		if((cfg.dir=(dir_t **)REALLOC(cfg.dir,sizeof(dir_t *)*(cfg.total_dirs+1)))==NULL) {
			errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_dirs+1);
			cfg.total_dirs=0;
			bail(1);
            continue; }

		if(j)
			for(n=cfg.total_dirs;n>dirnum[i];n--)
                cfg.dir[n]=cfg.dir[n-1];
		if((cfg.dir[dirnum[i]]=(dir_t *)MALLOC(sizeof(dir_t)))==NULL) {
			errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(dir_t));
			continue; }
		memset((dir_t *)cfg.dir[dirnum[i]],0,sizeof(dir_t));
		cfg.dir[dirnum[i]]->lib=libnum;
		cfg.dir[dirnum[i]]->maxfiles=MAX_FILES<500 ? MAX_FILES:500;
695
		if(stricmp(str2,"OFFLINE"))
696
			cfg.dir[dirnum[i]]->misc=DEFAULT_DIR_OPTIONS;
rswindell's avatar
rswindell committed
697 698 699 700 701 702 703
		strcpy(cfg.dir[dirnum[i]]->code,code);
		strcpy(cfg.dir[dirnum[i]]->lname,str);
		strcpy(cfg.dir[dirnum[i]]->sname,str2);
		strcpy(cfg.dir[dirnum[i]]->path,path);
		cfg.dir[dirnum[i]]->up_pct=cfg.cdt_up_pct;
		cfg.dir[dirnum[i]]->dn_pct=cfg.cdt_dn_pct;
		cfg.total_dirs++;
704
		uifc.changes=1;
rswindell's avatar
rswindell committed
705 706 707 708 709 710 711 712 713 714 715 716 717 718
		continue; }
	if((i&MSK_ON)==MSK_DEL) {
		i&=MSK_OFF;
		SETHELP(WHERE);
/*
Delete Directory Data Files:

If you want to delete all the database files for this directory,
select Yes.
*/
		j=1;
		strcpy(opt[0],"Yes");
		strcpy(opt[1],"No");
		opt[2][0]=0;
719
		j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0
rswindell's avatar
rswindell committed
720 721 722 723 724
			,"Delete Data in Sub-board",opt);
		if(j==-1)
			continue;
		if(j==0) {
				sprintf(str,"%s.*",cfg.dir[dirnum[i]]->code);
725
				strlwr(str);
rswindell's avatar
rswindell committed
726
				if(!cfg.dir[dirnum[i]]->data_dir[0])
rswindell's avatar
rswindell committed
727
					sprintf(tmp,"%sdirs/",cfg.data_dir);
rswindell's avatar
rswindell committed
728 729 730 731 732 733 734
				else
					strcpy(tmp,cfg.dir[dirnum[i]]->data_dir);
				delfiles(tmp,str); }
		FREE(cfg.dir[dirnum[i]]);
		cfg.total_dirs--;
		for(j=dirnum[i];j<cfg.total_dirs;j++)
			cfg.dir[j]=cfg.dir[j+1];
735
		uifc.changes=1;
rswindell's avatar
rswindell committed
736 737 738 739 740 741 742 743 744
		continue; }
	if((i&MSK_ON)==MSK_GET) {
		i&=MSK_OFF;
		savdir=*cfg.dir[dirnum[i]];
		continue; }
	if((i&MSK_ON)==MSK_PUT) {
		i&=MSK_OFF;
		*cfg.dir[dirnum[i]]=savdir;
		cfg.dir[dirnum[i]]->lib=libnum;
745
		uifc.changes=1;
rswindell's avatar
rswindell committed
746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788
        continue; }
	i=dirnum[dflt];
	j=0;
	done=0;
	while(!done) {
		n=0;
		sprintf(opt[n++],"%-27.27s%s","Long Name",cfg.dir[i]->lname);
		sprintf(opt[n++],"%-27.27s%s","Short Name",cfg.dir[i]->sname);
		sprintf(opt[n++],"%-27.27s%s","Internal Code",cfg.dir[i]->code);
		sprintf(opt[n++],"%-27.27s%.40s","Access Requirements"
			,cfg.dir[i]->arstr);
		sprintf(opt[n++],"%-27.27s%.40s","Upload Requirements"
			,cfg.dir[i]->ul_arstr);
		sprintf(opt[n++],"%-27.27s%.40s","Download Requirements"
			,cfg.dir[i]->dl_arstr);
		sprintf(opt[n++],"%-27.27s%.40s","Operator Requirements"
            ,cfg.dir[i]->op_arstr);
		sprintf(opt[n++],"%-27.27s%.40s","Exemption Requirements"
			,cfg.dir[i]->ex_arstr);
		sprintf(opt[n++],"%-27.27s%.40s","Transfer File Path"
			,cfg.dir[i]->path);
		sprintf(opt[n++],"%-27.27s%u","Maximum Number of Files"
			,cfg.dir[i]->maxfiles);
		if(cfg.dir[i]->maxage)
			sprintf(str,"Enabled (%u days old)",cfg.dir[i]->maxage);
        else
            strcpy(str,"Disabled");
        sprintf(opt[n++],"%-27.27s%s","Purge by Age",str);
		sprintf(opt[n++],"%-27.27s%u%%","Credit on Upload"
			,cfg.dir[i]->up_pct);
		sprintf(opt[n++],"%-27.27s%u%%","Credit on Download"
			,cfg.dir[i]->dn_pct);
		strcpy(opt[n++],"Toggle Options...");
		strcpy(opt[n++],"Advanced Options...");
		opt[n][0]=0;
		sprintf(str,"%s Directory",cfg.dir[i]->sname);
		SETHELP(WHERE);
/*
Directory Configuration:

This menu allows you to configure the individual selected directory.
Options with a trailing ... provide a sub-menu of more options.
*/
789 790
		uifc.savnum=1;
		switch(uifc.list(WIN_SAV|WIN_ACT|WIN_RHT|WIN_BOT
rswindell's avatar
rswindell committed
791 792 793 794 795 796 797 798 799 800 801 802 803
			,0,0,60,&opt_dflt,0,str,opt)) {
			case -1:
				done=1;
				break;
			case 0:
				SETHELP(WHERE);
/*
Directory Long Name:

This is a description of the file directory which is displayed in all
directory listings.
*/
				strcpy(str,cfg.dir[i]->lname);	/* save */
804
				if(!uifc.input(WIN_L2R|WIN_SAV,0,17,"Name to use for Listings"
rswindell's avatar
rswindell committed
805 806 807 808 809 810 811 812 813 814 815
					,cfg.dir[i]->lname,LEN_SLNAME,K_EDIT))
					strcpy(cfg.dir[i]->lname,str);
				break;
			case 1:
				SETHELP(WHERE);
/*
Directory Short Name:

This is a short description of the file directory which is displayed at
the file transfer prompt.
*/
816
				uifc.input(WIN_L2R|WIN_SAV,0,17,"Name to use for Prompts"
rswindell's avatar
rswindell committed
817 818 819 820 821 822 823 824 825 826 827 828
					,cfg.dir[i]->sname,LEN_SSNAME,K_EDIT);
				break;
			case 2:
                SETHELP(WHERE);
/*
Directory Internal Code:

Every directory must have its own unique code for Synchronet to refer to
it internally. This code should be descriptive of the directory's
contents, usually an abreviation of the directory's name.
*/
                strcpy(str,cfg.dir[i]->code);
829
                uifc.input(WIN_L2R|WIN_SAV,0,17,"Internal Code (unique)"
rswindell's avatar
rswindell committed
830 831 832 833
                    ,str,8,K_EDIT|K_UPPER);
                if(code_ok(str))
                    strcpy(cfg.dir[i]->code,str);
                else {
834 835 836
                    uifc.helpbuf=invalid_code;
                    uifc.msg("Invalid Code");
                    uifc.helpbuf=0; }
rswindell's avatar
rswindell committed
837 838
                break;
			case 3:
839
				uifc.savnum=2;
rswindell's avatar
rswindell committed
840 841 842 843
				sprintf(str,"%s Access",cfg.dir[i]->sname);
				getar(str,cfg.dir[i]->arstr);
				break;
			case 4:
844
				uifc.savnum=2;
rswindell's avatar
rswindell committed
845 846 847 848
				sprintf(str,"%s Upload",cfg.dir[i]->sname);
				getar(str,cfg.dir[i]->ul_arstr);
				break;
			case 5:
849
				uifc.savnum=2;
rswindell's avatar
rswindell committed
850 851 852 853
				sprintf(str,"%s Download",cfg.dir[i]->sname);
				getar(str,cfg.dir[i]->dl_arstr);
				break;
			case 6:
854
				uifc.savnum=2;
rswindell's avatar
rswindell committed
855 856 857 858
				sprintf(str,"%s Operator",cfg.dir[i]->sname);
				getar(str,cfg.dir[i]->op_arstr);
                break;
			case 7:
859
				uifc.savnum=2;
rswindell's avatar
rswindell committed
860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875
				sprintf(str,"%s Exemption",cfg.dir[i]->sname);
				getar(str,cfg.dir[i]->ex_arstr);
                break;
			case 8:
				SETHELP(WHERE);
/*
File Path:

This is the default storage path for files uploaded to this directory.
If this path is blank, files are stored in a directory off of the
DATA\DIRS directory using the internal code of this directory as the
name of the dirdirectory (i.e. DATA\DIRS\<CODE>).

This path can be overridden on a per file basis using Alternate File
Paths.
*/
876
				uifc.input(WIN_L2R|WIN_SAV,0,17,"File Path"
rswindell's avatar
rswindell committed
877 878 879 880 881 882 883 884 885 886
					,cfg.dir[i]->path,50,K_EDIT);
				break;
			case 9:
				SETHELP(WHERE);
/*
Maximum Number of Files:

This value is the maximum number of files allowed in this directory.
*/
				sprintf(str,"%u",cfg.dir[i]->maxfiles);
887
				uifc.input(WIN_L2R|WIN_SAV,0,17,"Maximum Number of Files"
rswindell's avatar
rswindell committed
888 889 890 891
					,str,5,K_EDIT|K_NUMBER);
				n=atoi(str);
				if(n>MAX_FILES) {
					sprintf(str,"Maximum Files is %u",MAX_FILES);
892
					uifc.msg(str); }
rswindell's avatar
rswindell committed
893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908
				else
					cfg.dir[i]->maxfiles=n;
				break;
			case 10:
				sprintf(str,"%u",cfg.dir[i]->maxage);
                SETHELP(WHERE);
/*
Maximum Age of Files:

This value is the maximum number of days that files will be kept in
the directory based on the date the file was uploaded or last
downloaded (If the Purge by Last Download toggle option is used).

The Synchronet file base maintenance program (DELFILES) must be used
to automatically remove files based on age.
*/
909
				uifc.input(WIN_MID|WIN_SAV,0,17,"Maximum Age of Files (in days)"
rswindell's avatar
rswindell committed
910 911 912 913 914 915 916 917 918 919 920 921 922 923 924
                    ,str,5,K_EDIT|K_NUMBER);
				cfg.dir[i]->maxage=atoi(str);
                break;
			case 11:
SETHELP(WHERE);
/*
Percentage of Credits to Credit Uploader on Upload:

This is the percentage of a file's credit value that is given to users
when they upload files. Most often, this value will be set to 100 to
give full credit value (100%) for uploads.

If you want uploaders to receive no credits upon upload, set this value
to 0.
*/
925
				uifc.input(WIN_MID|WIN_SAV,0,0
rswindell's avatar
rswindell committed
926
					,"Percentage of Credits to Credit Uploader on Upload"
927
					,ultoa(cfg.dir[i]->up_pct,tmp,10),4,K_EDIT|K_NUMBER);
rswindell's avatar
rswindell committed
928 929 930 931 932 933 934 935 936 937 938 939 940 941 942
				cfg.dir[i]->up_pct=atoi(tmp);
				break;
			case 12:
SETHELP(WHERE);
/*
Percentage of Credits to Credit Uploader on Download:

This is the percentage of a file's credit value that is given to users
who upload a file that is later downloaded by another user. This is an
award type system where more popular files will generate more credits
for the uploader.

If you do not want uploaders to receive credit when files they upload
are later downloaded, set this value to 0.
*/
943
				uifc.input(WIN_MID|WIN_SAV,0,0
rswindell's avatar
rswindell committed
944
					,"Percentage of Credits to Credit Uploader on Download"
945
					,ultoa(cfg.dir[i]->dn_pct,tmp,10),4,K_EDIT|K_NUMBER);
rswindell's avatar
rswindell committed
946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 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
				cfg.dir[i]->dn_pct=atoi(tmp);
				break;
			case 13:
				while(1) {
					n=0;
					sprintf(opt[n++],"%-27.27s%s","Check for File Existence"
						,cfg.dir[i]->misc&DIR_FCHK ? "Yes":"No");
					strcpy(str,"Slow Media Device");
					if(cfg.dir[i]->seqdev) {
						sprintf(tmp," #%u",cfg.dir[i]->seqdev);
						strcat(str,tmp); }
					sprintf(opt[n++],"%-27.27s%s",str
						,cfg.dir[i]->seqdev ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Force Content Ratings"
						,cfg.dir[i]->misc&DIR_RATE ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Upload Date in Listings"
						,cfg.dir[i]->misc&DIR_ULDATE ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Multiple File Numberings"
						,cfg.dir[i]->misc&DIR_MULT ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Search for Duplicates"
						,cfg.dir[i]->misc&DIR_DUPES ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Search for New Files"
						,cfg.dir[i]->misc&DIR_NOSCAN ? "No":"Yes");
					sprintf(opt[n++],"%-27.27s%s","Search for Auto-ADDFILES"
						,cfg.dir[i]->misc&DIR_NOAUTO ? "No":"Yes");
					sprintf(opt[n++],"%-27.27s%s","Import FILE_ID.DIZ"
						,cfg.dir[i]->misc&DIR_DIZ ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Free Downloads"
						,cfg.dir[i]->misc&DIR_FREE ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Free Download Time"
						,cfg.dir[i]->misc&DIR_TFREE ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Deduct Upload Time"
						,cfg.dir[i]->misc&DIR_ULTIME ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Credit Uploads"
						,cfg.dir[i]->misc&DIR_CDTUL ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Credit Downloads"
						,cfg.dir[i]->misc&DIR_CDTDL ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Credit with Minutes"
						,cfg.dir[i]->misc&DIR_CDTMIN ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Anonymous Uploads"
						,cfg.dir[i]->misc&DIR_ANON ? cfg.dir[i]->misc&DIR_AONLY
						? "Only":"Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Purge by Last Download"
						,cfg.dir[i]->misc&DIR_SINCEDL ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Mark Moved Files as New"
						,cfg.dir[i]->misc&DIR_MOVENEW ? "Yes":"No");
					opt[n][0]=0;
993
					uifc.savnum=2;
rswindell's avatar
rswindell committed
994 995 996 997 998 999 1000 1001 1002
					SETHELP(WHERE);
/*
Directory Toggle Options:

This is the toggle options menu for the selected file directory.

The available options from this menu can all be toggled between two or
more states, such as Yes and No.
*/
1003
					n=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,3,2,36,&tog_dflt
rswindell's avatar
rswindell committed
1004 1005 1006
						,&tog_bar,"Toggle Options",opt);
					if(n==-1)
                        break;
1007
					uifc.savnum=3;
rswindell's avatar
rswindell committed
1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023
					switch(n) {
						case 0:
							n=0;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Check for File Existence When Listing:

If you want the actual existence of files to be verified while listing
directories, set this value to Yes.

Directories with files located on CD-ROM or other slow media should have
this option set to No.
*/
1024
							n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
rswindell's avatar
rswindell committed
1025 1026 1027
								,"Check for File Existence When Listing",opt);
							if(n==0 && !(cfg.dir[i]->misc&DIR_FCHK)) {
								cfg.dir[i]->misc|=DIR_FCHK;
1028
								uifc.changes=1; }
rswindell's avatar
rswindell committed
1029 1030
							else if(n==1 && (cfg.dir[i]->misc&DIR_FCHK)) {
								cfg.dir[i]->misc&=~DIR_FCHK;
1031
								uifc.changes=1; }
rswindell's avatar
rswindell committed
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050
							break;
						case 1:
                            n=0;
                            strcpy(opt[0],"Yes");
                            strcpy(opt[1],"No");
                            opt[2][0]=0;
							SETHELP(WHERE);
/*
Slow Media Device:

If this directory contains files located on CD-ROM or other slow media
device, you should set this option to Yes. Each slow media device on
your system should have a unique Device Number. If you only have one
slow media device, then this number should be set to 1.

CD-ROM multidisk changers are considered one device and all the
directories on all the CD-ROMs in each changer should be set to the same
device number.
*/
1051
							n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
rswindell's avatar
rswindell committed
1052 1053 1054 1055
								,"Slow Media Device"
								,opt);
							if(n==0) {
								if(!cfg.dir[i]->seqdev) {
1056
									uifc.changes=1;
rswindell's avatar
rswindell committed
1057 1058 1059
									strcpy(str,"1"); }
								else
									sprintf(str,"%u",cfg.dir[i]->seqdev);
1060
								uifc.input(WIN_MID|WIN_SAV,0,0
rswindell's avatar
rswindell committed
1061 1062 1063 1064 1065
									,"Device Number"
									,str,2,K_EDIT|K_UPPER);
								cfg.dir[i]->seqdev=atoi(str); }
							else if(n==1 && cfg.dir[i]->seqdev) {
								cfg.dir[i]->seqdev=0;
1066
                                uifc.changes=1; }
rswindell's avatar
rswindell committed
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079
                            break;
						case 2:
							n=1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Force Content Ratings in Descriptions:

If you would like all uploads to this directory to be prompted for
content rating (G, R, or X), set this value to Yes.
*/
1080
							n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
rswindell's avatar
rswindell committed
1081 1082 1083
								,"Force Content Ratings in Descriptions",opt);
							if(n==0 && !(cfg.dir[i]->misc&DIR_RATE)) {
								cfg.dir[i]->misc|=DIR_RATE;
1084
								uifc.changes=1; }
rswindell's avatar
rswindell committed
1085 1086
							else if(n==1 && (cfg.dir[i]->misc&DIR_RATE)) {
								cfg.dir[i]->misc&=~DIR_RATE;
1087
								uifc.changes=1; }
rswindell's avatar
rswindell committed
1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101
							break;
						case 3:
							n=1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Include Upload Date in File Descriptions:

If you wish the upload date of each file in this directory to be
automatically included in the file description, set this option to
Yes.
*/
1102
							n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
rswindell's avatar
rswindell committed
1103 1104 1105
								,"Include Upload Date in Descriptions",opt);
							if(n==0 && !(cfg.dir[i]->misc&DIR_ULDATE)) {
								cfg.dir[i]->misc|=DIR_ULDATE;
1106
								uifc.changes=1; }
rswindell's avatar
rswindell committed
1107 1108
							else if(n==1 && (cfg.dir[i]->misc&DIR_ULDATE)) {
								cfg.dir[i]->misc&=~DIR_ULDATE;
1109
								uifc.changes=1; }
rswindell's avatar
rswindell committed
1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122
                            break;
						case 4:
							n=0;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Ask for Multiple File Numberings:

If you would like uploads to this directory to be prompted for multiple
file (disk) numbers, set this value to Yes.
*/
1123
							n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
rswindell's avatar
rswindell committed
1124 1125 1126
								,"Ask for Multiple File Numberings",opt);
							if(n==0 && !(cfg.dir[i]->misc&DIR_MULT)) {
								cfg.dir[i]->misc|=DIR_MULT;
1127
								uifc.changes=1; }
rswindell's avatar
rswindell committed
1128 1129
							else if(n==1 && (cfg.dir[i]->misc&DIR_MULT)) {
								cfg.dir[i]->misc&=~DIR_MULT;
1130
								uifc.changes=1; }
rswindell's avatar
rswindell committed
1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143
							break;
						case 5:
							n=0;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Search Directory for Duplicate Filenames:

If you would like to have this directory searched for duplicate
filenames when a user attempts to upload a file, set this option to Yes.
*/
1144
							n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
rswindell's avatar
rswindell committed
1145 1146 1147
								,"Search for Duplicate Filenames",opt);
							if(n==0 && !(cfg.dir[i]->misc&DIR_DUPES)) {
								cfg.dir[i]->misc|=DIR_DUPES;
1148
								uifc.changes=1; }
rswindell's avatar
rswindell committed
1149 1150
							else if(n==1 && (cfg.dir[i]->misc&DIR_DUPES)) {
								cfg.dir[i]->misc&=~DIR_DUPES;
1151
								uifc.changes=1; }
rswindell's avatar
rswindell committed
1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169
							break;
						case 6:
							n=0;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Search Directory for New Files:

If you would like to have this directory searched for newly uploaded
files when a user scans All libraries for new files, set this option to
Yes.

If this directory is located on CD-ROM or other read only media
(where uploads are unlikely to occur), it will improve new file scans
if this option is set to No.
*/
1170
							n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
rswindell's avatar
rswindell committed
1171 1172 1173
								,"Search for New files",opt);
							if(n==0 && cfg.dir[i]->misc&DIR_NOSCAN) {
								cfg.dir[i]->misc&=~DIR_NOSCAN;
1174
								uifc.changes=1; }
rswindell's avatar
rswindell committed
1175 1176
							else if(n==1 && !(cfg.dir[i]->misc&DIR_NOSCAN)) {
								cfg.dir[i]->misc|=DIR_NOSCAN;
1177
								uifc.changes=1; }
rswindell's avatar
rswindell committed
1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191
                            break;
						case 7:
							n=0;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Search Directory for Auto-ADDFILES:

If you would like to have this directory searched for a file list to
import automatically when using the ADDFILES * (Auto-ADD) feature,
set this option to Yes.
*/
1192
							n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
rswindell's avatar
rswindell committed
1193 1194 1195
								,"Search for Auto-ADDFILES",opt);
							if(n==0 && cfg.dir[i]->misc&DIR_NOAUTO) {
								cfg.dir[i]->misc&=~DIR_NOAUTO;
1196
								uifc.changes=1; }
rswindell's avatar
rswindell committed
1197 1198
							else if(n==1 && !(cfg.dir[i]->misc&DIR_NOAUTO)) {
								cfg.dir[i]->misc|=DIR_NOAUTO;
1199
								uifc.changes=1; }
rswindell's avatar
rswindell committed
1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213
                            break;
						case 8:
							n=0;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Import FILE_ID.DIZ and DESC.SDI Descriptions:

If you would like archived descriptions (FILE_ID.DIZ and DESC.SDI)
of uploaded files to be automatically imported as the extended
description, set this option to Yes.
*/
1214
							n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
rswindell's avatar
rswindell committed
1215 1216 1217
								,"Import FILE_ID.DIZ and DESC.SDI",opt);
							if(n==0 && !(cfg.dir[i]->misc&DIR_DIZ)) {
								cfg.dir[i]->misc|=DIR_DIZ;
1218
								uifc.changes=1; }
rswindell's avatar
rswindell committed
1219 1220
							else if(n==1 && (cfg.dir[i]->misc&DIR_DIZ)) {
								cfg.dir[i]->misc&=~DIR_DIZ;
1221
								uifc.changes=1; }
rswindell's avatar
rswindell committed
1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234
                            break;
						case 9:
							n=1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Downloads are Free:

If you would like all downloads from this directory to be free (cost
no credits), set this option to Yes.
*/
1235
							n=uifc.list<