|
|
1.1 root 1: /* scfgxfr2.c */
2:
3: /* $Id: scfgxfr2.c,v 1.27 2006/05/07 10:28:42 deuce Exp $ */
4:
5: /****************************************************************************
6: * @format.tab-size 4 (Plain Text/Source Code File Header) *
7: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
8: * *
9: * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html *
10: * *
11: * This program is free software; you can redistribute it and/or *
12: * modify it under the terms of the GNU General Public License *
13: * as published by the Free Software Foundation; either version 2 *
14: * of the License, or (at your option) any later version. *
15: * See the GNU General Public License for more details: gpl.txt or *
16: * http://www.fsf.org/copyleft/gpl.html *
17: * *
18: * Anonymous FTP access to the most recent released source is available at *
19: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
20: * *
21: * Anonymous CVS access to the development source and modification history *
22: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
23: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
24: * (just hit return, no password is necessary) *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
26: * *
27: * For Synchronet coding style and modification guidelines, see *
28: * http://www.synchro.net/source.html *
29: * *
30: * You are encouraged to submit any modifications (preferably in Unix diff *
31: * format) via e-mail to [email protected] *
32: * *
33: * Note: If this box doesn't appear square, then you need to fix your tabs. *
34: ****************************************************************************/
35:
36: #include "scfg.h"
37:
38: #define DEFAULT_DIR_OPTIONS (DIR_FCHK|DIR_MULT|DIR_DUPES|DIR_CDTUL|DIR_CDTDL|DIR_DIZ)
39:
40: void create_raw_dir_list(const char* list_file)
41: {
42: char path[MAX_PATH+1];
43: char* p;
44: glob_t g;
45: int gi;
46: FILE* fp;
47:
48: SAFECOPY(path, list_file);
49: if((p=getfname(path))!=NULL)
50: *p=0;
51: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Parent Directory",path,sizeof(path)-1
52: ,K_EDIT)<1)
53: return;
54: strcat(path,ALLFILES);
55: if((fp=fopen(list_file,"w"))==NULL) {
56: SAFEPRINTF2(path,"Create Failure (%u): %s", errno, list_file);
57: uifc.msg(path);
58: return;
59: }
60: glob(path,0,NULL,&g);
61: for(gi=0;gi<g.gl_pathc;gi++) {
62: if(isdir(g.gl_pathv[gi]))
63: fprintf(fp,"%s\n",getfname(g.gl_pathv[gi]));
64: }
65: globfree(&g);
66: fclose(fp);
67: }
68:
69:
70: void xfer_cfg()
71: {
72: static int libs_dflt,libs_bar,dflt;
73: char str[256],str2[81],done=0,*p;
74: char tmp_code[16];
75: int file,j,k,q;
76: uint i;
77: long ported;
78: static lib_t savlib;
79: dir_t tmpdir;
80: FILE *stream;
81:
82: while(1) {
83: for(i=0;i<cfg.total_libs && i<MAX_OPTS;i++)
84: sprintf(opt[i],"%-25s",cfg.lib[i]->lname);
85: opt[i][0]=0;
86: j=WIN_ACT|WIN_CHE|WIN_ORG;
87: if(cfg.total_libs)
88: j|=WIN_DEL|WIN_GET|WIN_DELACT;
89: if(cfg.total_libs<MAX_OPTS)
90: j|=WIN_INS|WIN_INSACT|WIN_XTR;
91: if(savlib.sname[0])
92: j|=WIN_PUT;
93: SETHELP(WHERE);
94: /*
95: &File Libraries:&
96:
97: This is a listing of file libraries for your BBS. File Libraries are
98: used to logically separate your file &directories& into groups. Every
99: directory belongs to a file library.
100:
101: One popular use for file libraries is to separate CD-ROM and hard disk
102: directories. One might have an &Uploads& file library that contains
103: uploads to the hard disk directories and also have a &PC-SIG& file
104: library that contains directories from a PC-SIG CD-ROM. Some sysops
105: separate directories into more specific areas such as &Main&, &Graphics&,
106: or &Adult&. If you have many directories that have a common subject
107: denominator, you may want to have a separate file library for those
108: directories for a more organized file structure.
109: */
110: i=uifc.list(j,0,0,45,&libs_dflt,&libs_bar,"File Libraries",opt);
111: if((signed)i==-1) {
112: j=save_changes(WIN_MID);
113: if(j==-1)
114: continue;
115: if(!j) {
116: write_file_cfg(&cfg,backup_level);
117: refresh_cfg(&cfg);
118: }
119: return; }
120: if((i&MSK_ON)==MSK_INS) {
121: i&=MSK_OFF;
122: strcpy(str,"Main");
123: SETHELP(WHERE);
124: /*
125: &Library Long Name:&
126:
127: This is a description of the file library which is displayed when a
128: user of the system uses the &/*& command from the file transfer menu.
129: */
130: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Library Long Name",str,LEN_GLNAME
131: ,K_EDIT)<1)
132: continue;
133: sprintf(str2,"%.*s",LEN_GSNAME,str);
134: SETHELP(WHERE);
135: /*
136: &Library Short Name:&
137:
138: This is a short description of the file library which is used for the
139: file transfer menu prompt.
140: */
141: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Library Short Name",str2,LEN_GSNAME
142: ,K_EDIT)<1)
143: continue;
144: if((cfg.lib=(lib_t **)realloc(cfg.lib,sizeof(lib_t *)*(cfg.total_libs+1)))==NULL) {
145: errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_libs+1);
146: cfg.total_libs=0;
147: bail(1);
148: continue; }
149:
150: if(cfg.total_libs) {
151: for(j=cfg.total_libs;j>i;j--)
152: cfg.lib[j]=cfg.lib[j-1];
153: for(j=0;j<cfg.total_dirs;j++)
154: if(cfg.dir[j]->lib>=i)
155: cfg.dir[j]->lib++; }
156: if((cfg.lib[i]=(lib_t *)malloc(sizeof(lib_t)))==NULL) {
157: errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(lib_t));
158: continue; }
159: memset((lib_t *)cfg.lib[i],0,sizeof(lib_t));
160: strcpy(cfg.lib[i]->lname,str);
161: strcpy(cfg.lib[i]->sname,str2);
162: cfg.total_libs++;
163: uifc.changes=1;
164: continue; }
165: if((i&MSK_ON)==MSK_DEL) {
166: i&=MSK_OFF;
167: SETHELP(WHERE);
168: /*
169: &Delete All Data in Library:&
170:
171: If you wish to delete the database files for all directories in this
172: library, select &Yes&.
173: */
174: j=1;
175: strcpy(opt[0],"Yes");
176: strcpy(opt[1],"No");
177: opt[2][0]=0;
178: j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0
179: ,"Delete All Library Data Files",opt);
180: if(j==-1)
181: continue;
182: if(j==0)
183: for(j=0;j<cfg.total_dirs;j++)
184: if(cfg.dir[j]->lib==i) {
185: sprintf(str,"%s%s.*"
186: ,cfg.lib[cfg.dir[j]->lib]->code_prefix
187: ,cfg.dir[j]->code_suffix);
188: strlwr(str);
189: if(!cfg.dir[j]->data_dir[0])
190: sprintf(tmp,"%sdirs/",cfg.data_dir);
191: else
192: strcpy(tmp,cfg.dir[j]->data_dir);
193: delfiles(tmp,str); }
194: free(cfg.lib[i]);
195: for(j=0;j<cfg.total_dirs;) {
196: if(cfg.dir[j]->lib==i) {
197: free(cfg.dir[j]);
198: cfg.total_dirs--;
199: k=j;
200: while(k<cfg.total_dirs) {
201: cfg.dir[k]=cfg.dir[k+1];
202: k++; } }
203: else j++; }
204: for(j=0;j<cfg.total_dirs;j++)
205: if(cfg.dir[j]->lib>i)
206: cfg.dir[j]->lib--;
207: cfg.total_libs--;
208: while(i<cfg.total_libs) {
209: cfg.lib[i]=cfg.lib[i+1];
210: i++; }
211: uifc.changes=1;
212: continue; }
213: if((i&MSK_ON)==MSK_GET) {
214: i&=MSK_OFF;
215: savlib=*cfg.lib[i];
216: continue; }
217: if((i&MSK_ON)==MSK_PUT) {
218: i&=MSK_OFF;
219: *cfg.lib[i]=savlib;
220: uifc.changes=1;
221: continue; }
222: done=0;
223: while(!done) {
224: j=0;
225: sprintf(opt[j++],"%-27.27s%s","Long Name",cfg.lib[i]->lname);
226: sprintf(opt[j++],"%-27.27s%s","Short Name",cfg.lib[i]->sname);
227: sprintf(opt[j++],"%-27.27s%s","Internal Code Prefix",cfg.lib[i]->code_prefix);
228: sprintf(opt[j++],"%-27.27s%.40s","Parent Directory"
229: ,cfg.lib[i]->parent_path);
230: sprintf(opt[j++],"%-27.27s%.40s","Access Requirements"
231: ,cfg.lib[i]->arstr);
232: strcpy(opt[j++],"Clone Options");
233: strcpy(opt[j++],"Export Areas...");
234: strcpy(opt[j++],"Import Areas...");
235: strcpy(opt[j++],"File Directories...");
236: opt[j][0]=0;
237: sprintf(str,"%s Library",cfg.lib[i]->sname);
238: SETHELP(WHERE);
239: /*
240: &File Library Configuration:&
241:
242: This menu allows you to configure the security requirments for access
243: to this file library. You can also add, delete, and configure the
244: directories of this library by selecting the &File Directories...& option.
245: */
246: switch(uifc.list(WIN_ACT,6,4,60,&dflt,0,str,opt)) {
247: case -1:
248: done=1;
249: break;
250: case 0:
251: SETHELP(WHERE);
252: /*
253: &Library Long Name:&
254:
255: This is a description of the file library which is displayed when a
256: user of the system uses the &/*& command from the file transfer menu.
257: */
258: strcpy(str,cfg.lib[i]->lname); /* save */
259: if(!uifc.input(WIN_MID|WIN_SAV,0,0,"Name to use for Listings"
260: ,cfg.lib[i]->lname,LEN_GLNAME,K_EDIT))
261: strcpy(cfg.lib[i]->lname,str); /* restore */
262: break;
263: case 1:
264: SETHELP(WHERE);
265: /*
266: &Library Short Name:&
267:
268: This is a short description of the file librarly which is used for the
269: file transfer menu prompt.
270: */
271: uifc.input(WIN_MID|WIN_SAV,0,0,"Name to use for Prompts"
272: ,cfg.lib[i]->sname,LEN_GSNAME,K_EDIT);
273: break;
274: case 2:
275: SETHELP(WHERE);
276: /*
277: `Internal Code Prefix:`
278:
279: This is an `optional` code prefix that may be used to help generate unique
280: internal codes for the directories in this file library. If this option
281: is used, directory internal codes will be made up of this prefix and the
282: specified code suffix for each directory.
283: */
284: uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code Prefix"
285: ,cfg.lib[i]->code_prefix,LEN_CODE,K_EDIT|K_UPPER);
286: break;
287: case 3:
288: SETHELP(WHERE);
289: /*
290: &Parent Directory:&
291:
292: This an optional path to be used as the physical "parent" directory for
293: all logical directories in this library. This parent directory will be
294: used in combination with each directory's storage path to create the
295: full physical storage path for files in this directory.
296:
297: This option is convenient for adding libraries with many directories
298: that share a common parent directory (e.g. CD-ROMs) and gives you the
299: option of easily changing the common parent directory location later, if
300: desired.
301: */
302: uifc.input(WIN_MID|WIN_SAV,0,0,"Parent Directory"
303: ,cfg.lib[i]->parent_path,sizeof(cfg.lib[i]->parent_path)-1,K_EDIT);
304: break;
305: case 4:
306: sprintf(str,"%s Library",cfg.lib[i]->sname);
307: getar(str,cfg.lib[i]->arstr);
308: break;
309: case 5: /* clone options */
310: j=0;
311: strcpy(opt[0],"Yes");
312: strcpy(opt[1],"No");
313: opt[2][0]=0;
314: SETHELP(WHERE);
315: /*
316: &Clone Directory Options:&
317:
318: If you want to clone the options of the first directory of this library
319: into all directories of this library, select &Yes&.
320:
321: The options cloned are upload requirments, download requirments,
322: operator requirements, exempted user requirements, toggle options,
323: maximum number of files, allowed file extensions, default file
324: extension, and sort type.
325: */
326: j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0
327: ,"Clone Options of First Directory into All of Library"
328: ,opt);
329: if(j==0) {
330: k=-1;
331: for(j=0;j<cfg.total_dirs;j++)
332: if(cfg.dir[j]->lib==i) {
333: if(k==-1)
334: k=j;
335: else {
336: uifc.changes=1;
337: cfg.dir[j]->misc=cfg.dir[k]->misc;
338: strcpy(cfg.dir[j]->ul_arstr,cfg.dir[k]->ul_arstr);
339: strcpy(cfg.dir[j]->dl_arstr,cfg.dir[k]->dl_arstr);
340: strcpy(cfg.dir[j]->op_arstr,cfg.dir[k]->op_arstr);
341: strcpy(cfg.dir[j]->ex_arstr,cfg.dir[k]->ex_arstr);
342: strcpy(cfg.dir[j]->exts,cfg.dir[k]->exts);
343: strcpy(cfg.dir[j]->data_dir,cfg.dir[k]->data_dir);
344: strcpy(cfg.dir[j]->upload_sem,cfg.dir[k]->upload_sem);
345: cfg.dir[j]->maxfiles=cfg.dir[k]->maxfiles;
346: cfg.dir[j]->maxage=cfg.dir[k]->maxage;
347: cfg.dir[j]->up_pct=cfg.dir[k]->up_pct;
348: cfg.dir[j]->dn_pct=cfg.dir[k]->dn_pct;
349: cfg.dir[j]->seqdev=cfg.dir[k]->seqdev;
350: cfg.dir[j]->sort=cfg.dir[k]->sort; } } }
351: break;
352: case 6:
353: k=0;
354: ported=0;
355: q=uifc.changes;
356: strcpy(opt[k++],"DIRS.TXT (Synchronet)");
357: strcpy(opt[k++],"FILEBONE.NA (Fido)");
358: opt[k][0]=0;
359: SETHELP(WHERE);
360: /*
361: &Export Area File Format:&
362:
363: This menu allows you to choose the format of the area file you wish to
364: export to.
365: */
366: k=0;
367: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
368: ,"Export Area File Format",opt);
369: if(k==-1)
370: break;
371: if(k==0)
372: sprintf(str,"%sDIRS.TXT",cfg.ctrl_dir);
373: else if(k==1)
374: sprintf(str,"FILEBONE.NA");
375: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Filename"
376: ,str,sizeof(str)-1,K_EDIT)<=0) {
377: uifc.changes=q;
378: break; }
379: if(fexist(str)) {
380: strcpy(opt[0],"Overwrite");
381: strcpy(opt[1],"Append");
382: opt[2][0]=0;
383: j=0;
384: j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0
385: ,"File Exists",opt);
386: if(j==-1)
387: break;
388: if(j==0) j=O_WRONLY|O_TRUNC;
389: else j=O_WRONLY|O_APPEND; }
390: else
391: j=O_WRONLY|O_CREAT;
392: if((stream=fnopen(&file,str,j))==NULL) {
393: uifc.msg("Open Failure");
394: break; }
395: uifc.pop("Exporting Areas...");
396: for(j=0;j<cfg.total_dirs;j++) {
397: if(cfg.dir[j]->lib!=i)
398: continue;
399: ported++;
400: if(k==1) {
401: fprintf(stream,"Area %-8s 0 ! %s\r\n"
402: ,cfg.dir[j]->code_suffix,cfg.dir[j]->lname);
403: continue; }
404: fprintf(stream,"%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n"
405: "%s\r\n%s\r\n"
406: ,cfg.dir[j]->lname
407: ,cfg.dir[j]->sname
408: ,cfg.dir[j]->code_suffix
409: ,cfg.dir[j]->data_dir
410: ,cfg.dir[j]->arstr
411: ,cfg.dir[j]->ul_arstr
412: ,cfg.dir[j]->dl_arstr
413: ,cfg.dir[j]->op_arstr
414: );
415: fprintf(stream,"%s\r\n%s\r\n%u\r\n%s\r\n%lX\r\n%u\r\n"
416: "%u\r\n"
417: ,cfg.dir[j]->path
418: ,cfg.dir[j]->upload_sem
419: ,cfg.dir[j]->maxfiles
420: ,cfg.dir[j]->exts
421: ,cfg.dir[j]->misc
422: ,cfg.dir[j]->seqdev
423: ,cfg.dir[j]->sort
424: );
425: fprintf(stream,"%s\r\n%u\r\n%u\r\n%u\r\n"
426: ,cfg.dir[j]->ex_arstr
427: ,cfg.dir[j]->maxage
428: ,cfg.dir[j]->up_pct
429: ,cfg.dir[j]->dn_pct
430: );
431: fprintf(stream,"***END-OF-DIR***\r\n\r\n"); }
432: fclose(stream);
433: uifc.pop(0);
434: sprintf(str,"%lu File Areas Exported Successfully",ported);
435: uifc.msg(str);
436: uifc.changes=q;
437: break;
438:
439: case 7:
440: ported=0;
441: k=0;
442: SETHELP(WHERE);
443: /*
444: &Import Area File Format:&
445:
446: This menu allows you to choose the format of the area file you wish to
447: import into the current file library.
448:
449: A "raw" directory listing can be created in DOS with the following
450: command: &DIR /ON /AD /B > DIRS.RAW&
451: */
452: strcpy(opt[k++],"DIRS.TXT (Synchronet)");
453: strcpy(opt[k++],"FILEBONE.NA (Fido)");
454: strcpy(opt[k++],"DIRS.RAW (Raw)");
455: strcpy(opt[k++],"Directory Listing...");
456: opt[k][0]=0;
457: k=0;
458: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
459: ,"Import Area File Format",opt);
460: if(k==-1)
461: break;
462: if(k==0)
463: sprintf(str,"%sDIRS.TXT",cfg.ctrl_dir);
464: else if(k==1)
465: sprintf(str,"FILEBONE.NA");
466: else {
467: strcpy(str,cfg.lib[i]->parent_path);
468: backslash(str);
469: strcat(str,"dirs.raw");
470: }
471: if(k==3)
472: create_raw_dir_list(tmpnam(str));
473: else {
474: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Filename"
475: ,str,sizeof(str)-1,K_EDIT)<=0)
476: break;
477: if(k==2 && !fexistcase(str)) {
478: strcpy(opt[0],"Yes");
479: strcpy(opt[1],"No");
480: opt[2][0]=0;
481: j=0;
482: if(uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0
483: ,"File doesn't exist, create it?",opt)==0)
484: create_raw_dir_list(str);
485: }
486: }
487: if(!fexistcase(str))
488: break;
489: if((stream=fnopen(&file,str,O_RDONLY))==NULL) {
490: uifc.msg("Open Failure");
491: break;
492: }
493: uifc.pop("Importing Areas...");
494: while(!feof(stream)) {
495: if(!fgets(str,128,stream)) break;
496: truncsp(str);
497: if(!str[0])
498: continue;
499: memset(&tmpdir,0,sizeof(dir_t));
500: tmpdir.misc=DEFAULT_DIR_OPTIONS;
501: tmpdir.maxfiles=1000;
502: tmpdir.up_pct=cfg.cdt_up_pct;
503: tmpdir.dn_pct=cfg.cdt_dn_pct;
504:
505: p=str;
506: while(*p && *p<=' ') p++;
507:
508: if(k>=2) { /* raw */
509: SAFECOPY(tmp_code,p);
510: SAFECOPY(tmpdir.lname,p);
511: SAFECOPY(tmpdir.sname,p);
512: SAFECOPY(tmpdir.path,p);
513: ported++;
514: }
515: else if(k==1) {
516: if(strnicmp(p,"AREA ",5))
517: continue;
518: p+=5;
519: while(*p && *p<=' ') p++;
520: SAFECOPY(tmp_code,p);
521: while(*p>' ') p++; /* Skip areaname */
522: while(*p && *p<=' ') p++; /* Skip space */
523: while(*p>' ') p++; /* Skip level */
524: while(*p && *p<=' ') p++; /* Skip space */
525: while(*p>' ') p++; /* Skip flags */
526: while(*p && *p<=' ') p++; /* Skip space */
527: SAFECOPY(tmpdir.sname,p);
528: SAFECOPY(tmpdir.lname,p);
529: ported++;
530: }
531: else {
532: sprintf(tmpdir.lname,"%.*s",LEN_SLNAME,str);
533: if(!fgets(str,128,stream)) break;
534: truncsp(str);
535: sprintf(tmpdir.sname,"%.*s",LEN_SSNAME,str);
536: if(!fgets(str,128,stream)) break;
537: truncsp(str);
538: SAFECOPY(tmp_code,str);
539: if(!fgets(str,128,stream)) break;
540: truncsp(str);
541: sprintf(tmpdir.data_dir,"%.*s",LEN_DIR,str);
542: if(!fgets(str,128,stream)) break;
543: truncsp(str);
544: sprintf(tmpdir.arstr,"%.*s",LEN_ARSTR,str);
545: if(!fgets(str,128,stream)) break;
546: truncsp(str);
547: sprintf(tmpdir.ul_arstr,"%.*s",LEN_ARSTR,str);
548: if(!fgets(str,128,stream)) break;
549: truncsp(str);
550: sprintf(tmpdir.dl_arstr,"%.*s",LEN_ARSTR,str);
551: if(!fgets(str,128,stream)) break;
552: truncsp(str);
553: sprintf(tmpdir.op_arstr,"%.*s",LEN_ARSTR,str);
554: if(!fgets(str,128,stream)) break;
555: truncsp(str);
556: sprintf(tmpdir.path,"%.*s",LEN_DIR,str);
557: if(!fgets(str,128,stream)) break;
558: truncsp(str);
559: sprintf(tmpdir.upload_sem,"%.*s",LEN_DIR,str);
560: if(!fgets(str,128,stream)) break;
561: truncsp(str);
562: tmpdir.maxfiles=atoi(str);
563: if(!fgets(str,128,stream)) break;
564: truncsp(str);
565: sprintf(tmpdir.exts,"%.*s",40,str);
566: if(!fgets(str,128,stream)) break;
567: truncsp(str);
568: tmpdir.misc=ahtoul(str);
569: if(!fgets(str,128,stream)) break;
570: truncsp(str);
571: tmpdir.seqdev=atoi(str);
572: if(!fgets(str,128,stream)) break;
573: truncsp(str);
574: tmpdir.sort=atoi(str);
575: if(!fgets(str,128,stream)) break;
576: truncsp(str);
577: sprintf(tmpdir.ex_arstr,"%.*s",LEN_ARSTR,str);
578: if(!fgets(str,128,stream)) break;
579: truncsp(str);
580: tmpdir.maxage=atoi(str);
581: if(!fgets(str,128,stream)) break;
582: truncsp(str);
583: tmpdir.up_pct=atoi(str);
584: if(!fgets(str,128,stream)) break;
585: truncsp(str);
586: tmpdir.dn_pct=atoi(str);
587:
588: ported++;
589: while(!feof(stream)
590: && strcmp(str,"***END-OF-DIR***")) {
591: if(!fgets(str,128,stream)) break;
592: truncsp(str);
593: }
594: }
595:
596: prep_code(tmp_code); /* Strip invalid chars */
597: SAFECOPY(tmpdir.code_suffix,tmp_code); /* THEN truncate to valid length */
598:
599: for(j=0;j<cfg.total_dirs;j++) {
600: if(cfg.dir[j]->lib!=i)
601: continue;
602: if(!stricmp(cfg.dir[j]->code_suffix,tmpdir.code_suffix))
603: break; }
604: if(j==cfg.total_dirs) {
605:
606: if((cfg.dir=(dir_t **)realloc(cfg.dir
607: ,sizeof(dir_t *)*(cfg.total_dirs+1)))==NULL) {
608: errormsg(WHERE,ERR_ALLOC,"dir",cfg.total_dirs+1);
609: cfg.total_dirs=0;
610: bail(1);
611: break; }
612:
613: if((cfg.dir[j]=(dir_t *)malloc(sizeof(dir_t)))
614: ==NULL) {
615: errormsg(WHERE,ERR_ALLOC,"dir",sizeof(dir_t));
616: break; }
617: memset(cfg.dir[j],0,sizeof(dir_t)); }
618: if(k==1) {
619: SAFECOPY(cfg.dir[j]->code_suffix,tmpdir.code_suffix);
620: SAFECOPY(cfg.dir[j]->sname,tmpdir.code_suffix);
621: SAFECOPY(cfg.dir[j]->lname,tmpdir.lname);
622: if(j==cfg.total_dirs) {
623: cfg.dir[j]->maxfiles=1000;
624: cfg.dir[j]->up_pct=cfg.cdt_up_pct;
625: cfg.dir[j]->dn_pct=cfg.cdt_dn_pct;
626: }
627: } else
628: memcpy(cfg.dir[j],&tmpdir,sizeof(dir_t));
629: cfg.dir[j]->lib=i;
630: if(j==cfg.total_dirs) {
631: cfg.dir[j]->misc=tmpdir.misc;
632: cfg.total_dirs++;
633: }
634: uifc.changes=1;
635: }
636: fclose(stream);
637: uifc.pop(0);
638: sprintf(str,"%lu File Areas Imported Successfully",ported);
639: uifc.msg(str);
640: break;
641:
642: case 8:
643: dir_cfg(i);
644: break; } } }
645:
646: }
647:
648: void dir_cfg(uint libnum)
649: {
650: static int dflt,bar,tog_dflt,tog_bar,adv_dflt,opt_dflt;
651: char str[81],str2[81],code[9],path[128],done=0,*p;
652: int j,n;
653: uint i,dirnum[MAX_OPTS+1];
654: static dir_t savdir;
655:
656: while(1) {
657: for(i=0,j=0;i<cfg.total_dirs && j<MAX_OPTS;i++)
658: if(cfg.dir[i]->lib==libnum) {
659: sprintf(opt[j],"%-25s",cfg.dir[i]->lname);
660: dirnum[j++]=i; }
661: dirnum[j]=cfg.total_dirs;
662: opt[j][0]=0;
663: sprintf(str,"%s Directories",cfg.lib[libnum]->sname);
664: i=WIN_SAV|WIN_ACT;
665: if(j)
666: i|=WIN_DEL|WIN_GET|WIN_DELACT;
667: if(j<MAX_OPTS)
668: i|=WIN_INS|WIN_INSACT|WIN_XTR;
669: if(savdir.sname[0])
670: i|=WIN_PUT;
671: SETHELP(WHERE);
672: /*
673: &File Directories:&
674:
675: This is a list of file directories that have been configured for the
676: selected file library.
677:
678: To add a directory, select the desired position with the arrow keys and
679: hit INS .
680:
681: To delete a directory, select it with the arrow keys and hit DEL .
682:
683: To configure a directory, select it with the arrow keys and hit ENTER .
684: */
685: i=uifc.list(i,24,1,45,&dflt,&bar,str,opt);
686: if((signed)i==-1)
687: return;
688: if((i&MSK_ON)==MSK_INS) {
689: i&=MSK_OFF;
690: strcpy(str,"Games");
691: SETHELP(WHERE);
692: /*
693: &Directory Long Name:&
694:
695: This is a description of the file directory which is displayed in all
696: directory listings.
697: */
698: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Directory Long Name",str,LEN_SLNAME
699: ,K_EDIT)<1)
700: continue;
701: sprintf(str2,"%.*s",LEN_SSNAME,str);
702: SETHELP(WHERE);
703: /*
704: &Directory Short Name:&
705:
706: This is a short description of the file directory which is displayed at
707: the file transfer prompt.
708: */
709: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Directory Short Name",str2,LEN_SSNAME
710: ,K_EDIT)<1)
711: continue;
712: sprintf(code,"%.8s",str2);
713: p=strchr(code,' ');
714: if(p) *p=0;
715: strupr(code);
716: SETHELP(WHERE);
717: /*
718: &Directory Internal Code Suffix:&
719:
720: Every directory must have its own unique code for Synchronet to refer to
721: it internally. This code should be descriptive of the directory's
722: contents, usually an abreviation of the directory's name.
723: */
724: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Directory Internal Code Suffix",code,LEN_CODE
725: ,K_EDIT|K_UPPER)<1)
726: continue;
727: if(!code_ok(code)) {
728: uifc.helpbuf=invalid_code;
729: uifc.msg("Invalid Code");
730: uifc.helpbuf=0;
731: continue; }
732: if(cfg.lib[libnum]->parent_path[0])
733: SAFECOPY(path,code);
734: else
735: sprintf(path,"%sdirs/%s",cfg.data_dir,code);
736: SETHELP(WHERE);
737: /*
738: &Directory File Path:&
739:
740: This is the drive and directory where your uploads to and downloads from
741: this directory will be stored. Example: &C:\XFER\GAMES&
742: */
743: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Directory File Path",path,50
744: ,K_EDIT)<1)
745: continue;
746: if((cfg.dir=(dir_t **)realloc(cfg.dir,sizeof(dir_t *)*(cfg.total_dirs+1)))==NULL) {
747: errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_dirs+1);
748: cfg.total_dirs=0;
749: bail(1);
750: continue; }
751:
752: if(j)
753: for(n=cfg.total_dirs;n>dirnum[i];n--)
754: cfg.dir[n]=cfg.dir[n-1];
755: if((cfg.dir[dirnum[i]]=(dir_t *)malloc(sizeof(dir_t)))==NULL) {
756: errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(dir_t));
757: continue; }
758: memset((dir_t *)cfg.dir[dirnum[i]],0,sizeof(dir_t));
759: cfg.dir[dirnum[i]]->lib=libnum;
760: cfg.dir[dirnum[i]]->maxfiles=MAX_FILES<500 ? MAX_FILES:500;
761: if(stricmp(str2,"OFFLINE"))
762: cfg.dir[dirnum[i]]->misc=DEFAULT_DIR_OPTIONS;
763: strcpy(cfg.dir[dirnum[i]]->code_suffix,code);
764: strcpy(cfg.dir[dirnum[i]]->lname,str);
765: strcpy(cfg.dir[dirnum[i]]->sname,str2);
766: strcpy(cfg.dir[dirnum[i]]->path,path);
767: cfg.dir[dirnum[i]]->up_pct=cfg.cdt_up_pct;
768: cfg.dir[dirnum[i]]->dn_pct=cfg.cdt_dn_pct;
769: cfg.total_dirs++;
770: uifc.changes=1;
771: continue; }
772: if((i&MSK_ON)==MSK_DEL) {
773: i&=MSK_OFF;
774: SETHELP(WHERE);
775: /*
776: &Delete Directory Data Files:&
777:
778: If you want to delete all the database files for this directory,
779: select &Yes&.
780: */
781: j=1;
782: strcpy(opt[0],"Yes");
783: strcpy(opt[1],"No");
784: opt[2][0]=0;
785: j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0
786: ,"Delete Data in Sub-board",opt);
787: if(j==-1)
788: continue;
789: if(j==0) {
790: sprintf(str,"%s%s.*"
791: ,cfg.lib[cfg.dir[dirnum[i]]->lib]->code_prefix
792: ,cfg.dir[dirnum[i]]->code_suffix);
793: strlwr(str);
794: if(!cfg.dir[dirnum[i]]->data_dir[0])
795: sprintf(tmp,"%sdirs/",cfg.data_dir);
796: else
797: strcpy(tmp,cfg.dir[dirnum[i]]->data_dir);
798: delfiles(tmp,str); }
799: free(cfg.dir[dirnum[i]]);
800: cfg.total_dirs--;
801: for(j=dirnum[i];j<cfg.total_dirs;j++)
802: cfg.dir[j]=cfg.dir[j+1];
803: uifc.changes=1;
804: continue; }
805: if((i&MSK_ON)==MSK_GET) {
806: i&=MSK_OFF;
807: savdir=*cfg.dir[dirnum[i]];
808: continue; }
809: if((i&MSK_ON)==MSK_PUT) {
810: i&=MSK_OFF;
811: *cfg.dir[dirnum[i]]=savdir;
812: cfg.dir[dirnum[i]]->lib=libnum;
813: uifc.changes=1;
814: continue; }
815: i=dirnum[dflt];
816: j=0;
817: done=0;
818: while(!done) {
819: n=0;
820: sprintf(opt[n++],"%-27.27s%s","Long Name",cfg.dir[i]->lname);
821: sprintf(opt[n++],"%-27.27s%s","Short Name",cfg.dir[i]->sname);
822: sprintf(opt[n++],"%-27.27s%s%s","Internal Code"
823: ,cfg.lib[cfg.dir[i]->lib]->code_prefix, cfg.dir[i]->code_suffix);
824: sprintf(opt[n++],"%-27.27s%.40s","Access Requirements"
825: ,cfg.dir[i]->arstr);
826: sprintf(opt[n++],"%-27.27s%.40s","Upload Requirements"
827: ,cfg.dir[i]->ul_arstr);
828: sprintf(opt[n++],"%-27.27s%.40s","Download Requirements"
829: ,cfg.dir[i]->dl_arstr);
830: sprintf(opt[n++],"%-27.27s%.40s","Operator Requirements"
831: ,cfg.dir[i]->op_arstr);
832: sprintf(opt[n++],"%-27.27s%.40s","Exemption Requirements"
833: ,cfg.dir[i]->ex_arstr);
834: sprintf(opt[n++],"%-27.27s%.40s","Transfer File Path"
835: ,cfg.dir[i]->path);
836: sprintf(opt[n++],"%-27.27s%u","Maximum Number of Files"
837: ,cfg.dir[i]->maxfiles);
838: if(cfg.dir[i]->maxage)
839: sprintf(str,"Enabled (%u days old)",cfg.dir[i]->maxage);
840: else
841: strcpy(str,"Disabled");
842: sprintf(opt[n++],"%-27.27s%s","Purge by Age",str);
843: sprintf(opt[n++],"%-27.27s%u%%","Credit on Upload"
844: ,cfg.dir[i]->up_pct);
845: sprintf(opt[n++],"%-27.27s%u%%","Credit on Download"
846: ,cfg.dir[i]->dn_pct);
847: strcpy(opt[n++],"Toggle Options...");
848: strcpy(opt[n++],"Advanced Options...");
849: opt[n][0]=0;
850: sprintf(str,"%s Directory",cfg.dir[i]->sname);
851: SETHELP(WHERE);
852: /*
853: &Directory Configuration:&
854:
855: This menu allows you to configure the individual selected directory.
856: Options with a trailing &...& provide a sub-menu of more options.
857: */
858: switch(uifc.list(WIN_SAV|WIN_ACT|WIN_RHT|WIN_BOT
859: ,0,0,60,&opt_dflt,0,str,opt)) {
860: case -1:
861: done=1;
862: break;
863: case 0:
864: SETHELP(WHERE);
865: /*
866: &Directory Long Name:&
867:
868: This is a description of the file directory which is displayed in all
869: directory listings.
870: */
871: strcpy(str,cfg.dir[i]->lname); /* save */
872: if(!uifc.input(WIN_L2R|WIN_SAV,0,17,"Name to use for Listings"
873: ,cfg.dir[i]->lname,LEN_SLNAME,K_EDIT))
874: strcpy(cfg.dir[i]->lname,str);
875: break;
876: case 1:
877: SETHELP(WHERE);
878: /*
879: &Directory Short Name:&
880:
881: This is a short description of the file directory which is displayed at
882: the file transfer prompt.
883: */
884: uifc.input(WIN_L2R|WIN_SAV,0,17,"Name to use for Prompts"
885: ,cfg.dir[i]->sname,LEN_SSNAME,K_EDIT);
886: break;
887: case 2:
888: SETHELP(WHERE);
889: /*
890: &Directory Internal Code Suffix:&
891:
892: Every directory must have its own unique code for Synchronet to refer to
893: it internally. This code should be descriptive of the directory's
894: contents, usually an abreviation of the directory's name.
895: */
896: strcpy(str,cfg.dir[i]->code_suffix);
897: uifc.input(WIN_L2R|WIN_SAV,0,17,"Internal Code Suffix (unique)"
898: ,str,LEN_CODE,K_EDIT|K_UPPER);
899: if(code_ok(str))
900: strcpy(cfg.dir[i]->code_suffix,str);
901: else {
902: uifc.helpbuf=invalid_code;
903: uifc.msg("Invalid Code");
904: uifc.helpbuf=0;
905: }
906: break;
907: case 3:
908: sprintf(str,"%s Access",cfg.dir[i]->sname);
909: getar(str,cfg.dir[i]->arstr);
910: break;
911: case 4:
912: sprintf(str,"%s Upload",cfg.dir[i]->sname);
913: getar(str,cfg.dir[i]->ul_arstr);
914: break;
915: case 5:
916: sprintf(str,"%s Download",cfg.dir[i]->sname);
917: getar(str,cfg.dir[i]->dl_arstr);
918: break;
919: case 6:
920: sprintf(str,"%s Operator",cfg.dir[i]->sname);
921: getar(str,cfg.dir[i]->op_arstr);
922: break;
923: case 7:
924: sprintf(str,"%s Exemption",cfg.dir[i]->sname);
925: getar(str,cfg.dir[i]->ex_arstr);
926: break;
927: case 8:
928: SETHELP(WHERE);
929: /*
930: &File Path:&
931:
932: This is the default storage path for files uploaded to this directory.
933: If this path is blank, files are stored in a directory off of the
934: DATA\DIRS directory using the internal code of this directory as the
935: name of the dirdirectory (i.e. DATA\DIRS\<CODE>).
936:
937: This path can be overridden on a per file basis using &Alternate File
938: Paths&.
939: */
940: uifc.input(WIN_L2R|WIN_SAV,0,17,"File Path"
941: ,cfg.dir[i]->path,sizeof(cfg.dir[i]->path)-1,K_EDIT);
942: break;
943: case 9:
944: SETHELP(WHERE);
945: /*
946: &Maximum Number of Files:&
947:
948: This value is the maximum number of files allowed in this directory.
949: */
950: sprintf(str,"%u",cfg.dir[i]->maxfiles);
951: uifc.input(WIN_L2R|WIN_SAV,0,17,"Maximum Number of Files"
952: ,str,5,K_EDIT|K_NUMBER);
953: n=atoi(str);
954: if(n>MAX_FILES) {
955: sprintf(str,"Maximum Files is %u",MAX_FILES);
956: uifc.msg(str); }
957: else
958: cfg.dir[i]->maxfiles=n;
959: break;
960: case 10:
961: sprintf(str,"%u",cfg.dir[i]->maxage);
962: SETHELP(WHERE);
963: /*
964: &Maximum Age of Files:&
965:
966: This value is the maximum number of days that files will be kept in
967: the directory based on the date the file was uploaded or last
968: downloaded (If the &Purge by Last Download& toggle option is used).
969:
970: The Synchronet file base maintenance program (&DELFILES&) must be used
971: to automatically remove files based on age.
972: */
973: uifc.input(WIN_MID|WIN_SAV,0,17,"Maximum Age of Files (in days)"
974: ,str,5,K_EDIT|K_NUMBER);
975: cfg.dir[i]->maxage=atoi(str);
976: break;
977: case 11:
978: SETHELP(WHERE);
979: /*
980: &Percentage of Credits to Credit Uploader on Upload:&
981:
982: This is the percentage of a file's credit value that is given to users
983: when they upload files. Most often, this value will be set to &100& to
984: give full credit value (100%) for uploads.
985:
986: If you want uploaders to receive no credits upon upload, set this value
987: to &0&.
988: */
989: uifc.input(WIN_MID|WIN_SAV,0,0
990: ,"Percentage of Credits to Credit Uploader on Upload"
991: ,ultoa(cfg.dir[i]->up_pct,tmp,10),4,K_EDIT|K_NUMBER);
992: cfg.dir[i]->up_pct=atoi(tmp);
993: break;
994: case 12:
995: SETHELP(WHERE);
996: /*
997: &Percentage of Credits to Credit Uploader on Download:&
998:
999: This is the percentage of a file's credit value that is given to users
1000: who upload a file that is later downloaded by another user. This is an
1001: award type system where more popular files will generate more credits
1002: for the uploader.
1003:
1004: If you do not want uploaders to receive credit when files they upload
1005: are later downloaded, set this value to &0&.
1006: */
1007: uifc.input(WIN_MID|WIN_SAV,0,0
1008: ,"Percentage of Credits to Credit Uploader on Download"
1009: ,ultoa(cfg.dir[i]->dn_pct,tmp,10),4,K_EDIT|K_NUMBER);
1010: cfg.dir[i]->dn_pct=atoi(tmp);
1011: break;
1012: case 13:
1013: while(1) {
1014: n=0;
1015: sprintf(opt[n++],"%-27.27s%s","Check for File Existence"
1016: ,cfg.dir[i]->misc&DIR_FCHK ? "Yes":"No");
1017: strcpy(str,"Slow Media Device");
1018: if(cfg.dir[i]->seqdev) {
1019: sprintf(tmp," #%u",cfg.dir[i]->seqdev);
1020: strcat(str,tmp); }
1021: sprintf(opt[n++],"%-27.27s%s",str
1022: ,cfg.dir[i]->seqdev ? "Yes":"No");
1023: sprintf(opt[n++],"%-27.27s%s","Force Content Ratings"
1024: ,cfg.dir[i]->misc&DIR_RATE ? "Yes":"No");
1025: sprintf(opt[n++],"%-27.27s%s","Upload Date in Listings"
1026: ,cfg.dir[i]->misc&DIR_ULDATE ? "Yes":"No");
1027: sprintf(opt[n++],"%-27.27s%s","Multiple File Numberings"
1028: ,cfg.dir[i]->misc&DIR_MULT ? "Yes":"No");
1029: sprintf(opt[n++],"%-27.27s%s","Search for Duplicates"
1030: ,cfg.dir[i]->misc&DIR_DUPES ? "Yes":"No");
1031: sprintf(opt[n++],"%-27.27s%s","Search for New Files"
1032: ,cfg.dir[i]->misc&DIR_NOSCAN ? "No":"Yes");
1033: sprintf(opt[n++],"%-27.27s%s","Search for Auto-ADDFILES"
1034: ,cfg.dir[i]->misc&DIR_NOAUTO ? "No":"Yes");
1035: sprintf(opt[n++],"%-27.27s%s","Import FILE_ID.DIZ"
1036: ,cfg.dir[i]->misc&DIR_DIZ ? "Yes":"No");
1037: sprintf(opt[n++],"%-27.27s%s","Free Downloads"
1038: ,cfg.dir[i]->misc&DIR_FREE ? "Yes":"No");
1039: sprintf(opt[n++],"%-27.27s%s","Free Download Time"
1040: ,cfg.dir[i]->misc&DIR_TFREE ? "Yes":"No");
1041: sprintf(opt[n++],"%-27.27s%s","Deduct Upload Time"
1042: ,cfg.dir[i]->misc&DIR_ULTIME ? "Yes":"No");
1043: sprintf(opt[n++],"%-27.27s%s","Credit Uploads"
1044: ,cfg.dir[i]->misc&DIR_CDTUL ? "Yes":"No");
1045: sprintf(opt[n++],"%-27.27s%s","Credit Downloads"
1046: ,cfg.dir[i]->misc&DIR_CDTDL ? "Yes":"No");
1047: sprintf(opt[n++],"%-27.27s%s","Credit with Minutes"
1048: ,cfg.dir[i]->misc&DIR_CDTMIN ? "Yes":"No");
1049: sprintf(opt[n++],"%-27.27s%s","Download Notifications"
1050: ,cfg.dir[i]->misc&DIR_QUIET ? "No":"Yes");
1051: sprintf(opt[n++],"%-27.27s%s","Anonymous Uploads"
1052: ,cfg.dir[i]->misc&DIR_ANON ? cfg.dir[i]->misc&DIR_AONLY
1053: ? "Only":"Yes":"No");
1054: sprintf(opt[n++],"%-27.27s%s","Purge by Last Download"
1055: ,cfg.dir[i]->misc&DIR_SINCEDL ? "Yes":"No");
1056: sprintf(opt[n++],"%-27.27s%s","Mark Moved Files as New"
1057: ,cfg.dir[i]->misc&DIR_MOVENEW ? "Yes":"No");
1058: sprintf(opt[n++],"%-27.27s%s","Include Transfers In Stats"
1059: ,cfg.dir[i]->misc&DIR_NOSTAT ? "No":"Yes");
1060: opt[n][0]=0;
1061: SETHELP(WHERE);
1062: /*
1063: &Directory Toggle Options:&
1064:
1065: This is the toggle options menu for the selected file directory.
1066:
1067: The available options from this menu can all be toggled between two or
1068: more states, such as &Yes& and &No&.
1069: */
1070: n=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,3,2,36,&tog_dflt
1071: ,&tog_bar,"Toggle Options",opt);
1072: if(n==-1)
1073: break;
1074: switch(n) {
1075: case 0:
1076: n=cfg.dir[i]->misc&DIR_FCHK ? 0:1;
1077: strcpy(opt[0],"Yes");
1078: strcpy(opt[1],"No");
1079: opt[2][0]=0;
1080: SETHELP(WHERE);
1081: /*
1082: &Check for File Existence When Listing:&
1083:
1084: If you want the actual existence of files to be verified while listing
1085: directories, set this value to &Yes&.
1086:
1087: Directories with files located on CD-ROM or other slow media should have
1088: this option set to &No&.
1089: */
1090: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1091: ,"Check for File Existence When Listing",opt);
1092: if(n==0 && !(cfg.dir[i]->misc&DIR_FCHK)) {
1093: cfg.dir[i]->misc|=DIR_FCHK;
1094: uifc.changes=1; }
1095: else if(n==1 && (cfg.dir[i]->misc&DIR_FCHK)) {
1096: cfg.dir[i]->misc&=~DIR_FCHK;
1097: uifc.changes=1; }
1098: break;
1099: case 1:
1100: n=cfg.dir[i]->seqdev ? 0:1;
1101: strcpy(opt[0],"Yes");
1102: strcpy(opt[1],"No");
1103: opt[2][0]=0;
1104: SETHELP(WHERE);
1105: /*
1106: &Slow Media Device:&
1107:
1108: If this directory contains files located on CD-ROM or other slow media
1109: device, you should set this option to &Yes&. Each slow media device on
1110: your system should have a unique &Device Number&. If you only have one
1111: slow media device, then this number should be set to &1&.
1112:
1113: &CD-ROM multidisk changers& are considered &one& device and all the
1114: directories on all the CD-ROMs in each changer should be set to the same
1115: device number.
1116: */
1117: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1118: ,"Slow Media Device"
1119: ,opt);
1120: if(n==0) {
1121: if(!cfg.dir[i]->seqdev) {
1122: uifc.changes=1;
1123: strcpy(str,"1"); }
1124: else
1125: sprintf(str,"%u",cfg.dir[i]->seqdev);
1126: uifc.input(WIN_MID|WIN_SAV,0,0
1127: ,"Device Number"
1128: ,str,2,K_EDIT|K_UPPER);
1129: cfg.dir[i]->seqdev=atoi(str); }
1130: else if(n==1 && cfg.dir[i]->seqdev) {
1131: cfg.dir[i]->seqdev=0;
1132: uifc.changes=1; }
1133: break;
1134: case 2:
1135: n=cfg.dir[i]->misc&DIR_RATE ? 0:1;
1136: strcpy(opt[0],"Yes");
1137: strcpy(opt[1],"No");
1138: opt[2][0]=0;
1139: SETHELP(WHERE);
1140: /*
1141: &Force Content Ratings in Descriptions:&
1142:
1143: If you would like all uploads to this directory to be prompted for
1144: content rating (G, R, or X), set this value to &Yes&.
1145: */
1146: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1147: ,"Force Content Ratings in Descriptions",opt);
1148: if(n==0 && !(cfg.dir[i]->misc&DIR_RATE)) {
1149: cfg.dir[i]->misc|=DIR_RATE;
1150: uifc.changes=1; }
1151: else if(n==1 && (cfg.dir[i]->misc&DIR_RATE)) {
1152: cfg.dir[i]->misc&=~DIR_RATE;
1153: uifc.changes=1; }
1154: break;
1155: case 3:
1156: n=cfg.dir[i]->misc&DIR_ULDATE ? 0:1;
1157: strcpy(opt[0],"Yes");
1158: strcpy(opt[1],"No");
1159: opt[2][0]=0;
1160: SETHELP(WHERE);
1161: /*
1162: &Include Upload Date in File Descriptions:&
1163:
1164: If you wish the upload date of each file in this directory to be
1165: automatically included in the file description, set this option to
1166: &Yes&.
1167: */
1168: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1169: ,"Include Upload Date in Descriptions",opt);
1170: if(n==0 && !(cfg.dir[i]->misc&DIR_ULDATE)) {
1171: cfg.dir[i]->misc|=DIR_ULDATE;
1172: uifc.changes=1; }
1173: else if(n==1 && (cfg.dir[i]->misc&DIR_ULDATE)) {
1174: cfg.dir[i]->misc&=~DIR_ULDATE;
1175: uifc.changes=1; }
1176: break;
1177: case 4:
1178: n=cfg.dir[i]->misc&DIR_MULT ? 0:1;
1179: strcpy(opt[0],"Yes");
1180: strcpy(opt[1],"No");
1181: opt[2][0]=0;
1182: SETHELP(WHERE);
1183: /*
1184: &Ask for Multiple File Numberings:&
1185:
1186: If you would like uploads to this directory to be prompted for multiple
1187: file (disk) numbers, set this value to &Yes&.
1188: */
1189: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1190: ,"Ask for Multiple File Numberings",opt);
1191: if(n==0 && !(cfg.dir[i]->misc&DIR_MULT)) {
1192: cfg.dir[i]->misc|=DIR_MULT;
1193: uifc.changes=1; }
1194: else if(n==1 && (cfg.dir[i]->misc&DIR_MULT)) {
1195: cfg.dir[i]->misc&=~DIR_MULT;
1196: uifc.changes=1; }
1197: break;
1198: case 5:
1199: n=cfg.dir[i]->misc&DIR_DUPES ? 0:1;
1200: strcpy(opt[0],"Yes");
1201: strcpy(opt[1],"No");
1202: opt[2][0]=0;
1203: SETHELP(WHERE);
1204: /*
1205: &Search Directory for Duplicate Filenames:&
1206:
1207: If you would like to have this directory searched for duplicate
1208: filenames when a user attempts to upload a file, set this option to &Yes&.
1209: */
1210: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1211: ,"Search for Duplicate Filenames",opt);
1212: if(n==0 && !(cfg.dir[i]->misc&DIR_DUPES)) {
1213: cfg.dir[i]->misc|=DIR_DUPES;
1214: uifc.changes=1; }
1215: else if(n==1 && (cfg.dir[i]->misc&DIR_DUPES)) {
1216: cfg.dir[i]->misc&=~DIR_DUPES;
1217: uifc.changes=1; }
1218: break;
1219: case 6:
1220: n=cfg.dir[i]->misc&DIR_NOSCAN ? 1:0;
1221: strcpy(opt[0],"Yes");
1222: strcpy(opt[1],"No");
1223: opt[2][0]=0;
1224: SETHELP(WHERE);
1225: /*
1226: &Search Directory for New Files:&
1227:
1228: If you would like to have this directory searched for newly uploaded
1229: files when a user scans &All& libraries for new files, set this option to
1230: &Yes&.
1231:
1232: If this directory is located on &CD-ROM& or other read only media
1233: (where uploads are unlikely to occur), it will improve new file scans
1234: if this option is set to &No&.
1235: */
1236: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1237: ,"Search for New files",opt);
1238: if(n==0 && cfg.dir[i]->misc&DIR_NOSCAN) {
1239: cfg.dir[i]->misc&=~DIR_NOSCAN;
1240: uifc.changes=1; }
1241: else if(n==1 && !(cfg.dir[i]->misc&DIR_NOSCAN)) {
1242: cfg.dir[i]->misc|=DIR_NOSCAN;
1243: uifc.changes=1; }
1244: break;
1245: case 7:
1246: n=cfg.dir[i]->misc&DIR_NOAUTO ? 1:0;
1247: strcpy(opt[0],"Yes");
1248: strcpy(opt[1],"No");
1249: opt[2][0]=0;
1250: SETHELP(WHERE);
1251: /*
1252: &Search Directory for Auto-ADDFILES:&
1253:
1254: If you would like to have this directory searched for a file list to
1255: import automatically when using the &ADDFILES *& (Auto-ADD) feature,
1256: set this option to &Yes&.
1257: */
1258: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1259: ,"Search for Auto-ADDFILES",opt);
1260: if(n==0 && cfg.dir[i]->misc&DIR_NOAUTO) {
1261: cfg.dir[i]->misc&=~DIR_NOAUTO;
1262: uifc.changes=1; }
1263: else if(n==1 && !(cfg.dir[i]->misc&DIR_NOAUTO)) {
1264: cfg.dir[i]->misc|=DIR_NOAUTO;
1265: uifc.changes=1; }
1266: break;
1267: case 8:
1268: n=cfg.dir[i]->misc&DIR_DIZ ? 0:1;
1269: strcpy(opt[0],"Yes");
1270: strcpy(opt[1],"No");
1271: opt[2][0]=0;
1272: SETHELP(WHERE);
1273: /*
1274: &Import FILE_ID.DIZ and DESC.SDI Descriptions:&
1275:
1276: If you would like archived descriptions (&FILE_ID.DIZ& and &DESC.SDI&)
1277: of uploaded files to be automatically imported as the extended
1278: description, set this option to &Yes&.
1279: */
1280: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1281: ,"Import FILE_ID.DIZ and DESC.SDI",opt);
1282: if(n==0 && !(cfg.dir[i]->misc&DIR_DIZ)) {
1283: cfg.dir[i]->misc|=DIR_DIZ;
1284: uifc.changes=1; }
1285: else if(n==1 && (cfg.dir[i]->misc&DIR_DIZ)) {
1286: cfg.dir[i]->misc&=~DIR_DIZ;
1287: uifc.changes=1; }
1288: break;
1289: case 9:
1290: n=cfg.dir[i]->misc&DIR_FREE ? 0:1;
1291: strcpy(opt[0],"Yes");
1292: strcpy(opt[1],"No");
1293: opt[2][0]=0;
1294: SETHELP(WHERE);
1295: /*
1296: &Downloads are Free:&
1297:
1298: If you would like all downloads from this directory to be free (cost
1299: no credits), set this option to &Yes&.
1300: */
1301: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1302: ,"Downloads are Free",opt);
1303: if(n==0 && !(cfg.dir[i]->misc&DIR_FREE)) {
1304: cfg.dir[i]->misc|=DIR_FREE;
1305: uifc.changes=1; }
1306: else if(n==1 && (cfg.dir[i]->misc&DIR_FREE)) {
1307: cfg.dir[i]->misc&=~DIR_FREE;
1308: uifc.changes=1; }
1309: break;
1310: case 10:
1311: n=cfg.dir[i]->misc&DIR_TFREE ? 0:1;
1312: strcpy(opt[0],"Yes");
1313: strcpy(opt[1],"No");
1314: opt[2][0]=0;
1315: SETHELP(WHERE);
1316: /*
1317: &Free Download Time:&
1318:
1319: If you would like all downloads from this directory to not subtract
1320: time from the user, set this option to &Yes&.
1321: */
1322: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1323: ,"Free Download Time",opt);
1324: if(n==0 && !(cfg.dir[i]->misc&DIR_TFREE)) {
1325: cfg.dir[i]->misc|=DIR_TFREE;
1326: uifc.changes=1; }
1327: else if(n==1 && (cfg.dir[i]->misc&DIR_TFREE)) {
1328: cfg.dir[i]->misc&=~DIR_TFREE;
1329: uifc.changes=1; }
1330: break;
1331: case 11:
1332: n=cfg.dir[i]->misc&DIR_ULTIME ? 0:1;
1333: strcpy(opt[0],"Yes");
1334: strcpy(opt[1],"No");
1335: opt[2][0]=0;
1336: SETHELP(WHERE);
1337: /*
1338: &Deduct Upload Time:&
1339:
1340: If you would like all uploads to this directory to have the time spent
1341: uploading subtracted from their time online, set this option to &Yes&.
1342: */
1343: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1344: ,"Deduct Upload Time",opt);
1345: if(n==0 && !(cfg.dir[i]->misc&DIR_ULTIME)) {
1346: cfg.dir[i]->misc|=DIR_ULTIME;
1347: uifc.changes=1; }
1348: else if(n==1 && (cfg.dir[i]->misc&DIR_ULTIME)) {
1349: cfg.dir[i]->misc&=~DIR_ULTIME;
1350: uifc.changes=1; }
1351: break;
1352: case 12:
1353: n=cfg.dir[i]->misc&DIR_CDTUL ? 0:1;
1354: strcpy(opt[0],"Yes");
1355: strcpy(opt[1],"No");
1356: opt[2][0]=0;
1357: SETHELP(WHERE);
1358: /*
1359: &Give Credit for Uploads:&
1360:
1361: If you want users who upload to this directory to get credit for their
1362: initial upload, set this option to &Yes&.
1363: */
1364: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1365: ,"Give Credit for Uploads",opt);
1366: if(n==0 && !(cfg.dir[i]->misc&DIR_CDTUL)) {
1367: cfg.dir[i]->misc|=DIR_CDTUL;
1368: uifc.changes=1; }
1369: else if(n==1 && (cfg.dir[i]->misc&DIR_CDTUL)) {
1370: cfg.dir[i]->misc&=~DIR_CDTUL;
1371: uifc.changes=1; }
1372: break;
1373: case 13:
1374: n=cfg.dir[i]->misc&DIR_CDTDL ? 0:1;
1375: strcpy(opt[0],"Yes");
1376: strcpy(opt[1],"No");
1377: opt[2][0]=0;
1378: SETHELP(WHERE);
1379: /*
1380: &Give Uploader Credit for Downloads:&
1381:
1382: If you want users who upload to this directory to get credit when their
1383: files are downloaded, set this optin to &Yes&.
1384: */
1385: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1386: ,"Give Uploader Credit for Downloads",opt);
1387: if(n==0 && !(cfg.dir[i]->misc&DIR_CDTDL)) {
1388: cfg.dir[i]->misc|=DIR_CDTDL;
1389: uifc.changes=1; }
1390: else if(n==1 && (cfg.dir[i]->misc&DIR_CDTDL)) {
1391: cfg.dir[i]->misc&=~DIR_CDTDL;
1392: uifc.changes=1; }
1393: break;
1394: case 14:
1395: n=cfg.dir[i]->misc&DIR_CDTMIN ? 0:1;
1396: strcpy(opt[0],"Yes");
1397: strcpy(opt[1],"No");
1398: opt[2][0]=0;
1399: SETHELP(WHERE);
1400: /*
1401: `Credit Uploader with Minutes instead of Credits:`
1402:
1403: If you wish to give the uploader of files to this directory minutes,
1404: intead of credits, set this option to `Yes`.
1405: */
1406: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1407: ,"Credit Uploader with Minutes",opt);
1408: if(n==0 && !(cfg.dir[i]->misc&DIR_CDTMIN)) {
1409: cfg.dir[i]->misc|=DIR_CDTMIN;
1410: uifc.changes=1; }
1411: else if(n==1 && cfg.dir[i]->misc&DIR_CDTMIN){
1412: cfg.dir[i]->misc&=~DIR_CDTMIN;
1413: uifc.changes=1; }
1414: break;
1415: case 15:
1416: n=cfg.dir[i]->misc&DIR_QUIET ? 1:0;
1417: strcpy(opt[0],"Yes");
1418: strcpy(opt[1],"No");
1419: opt[2][0]=0;
1420: SETHELP(WHERE);
1421: /*
1422: `Send Download Notifications:`
1423:
1424: If you wish the BBS to send download notification messages to the
1425: uploader of a file to this directory, set this option to `Yes`.
1426: */
1427: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1428: ,"Send Download Notifications",opt);
1429: if(n==1 && !(cfg.dir[i]->misc&DIR_QUIET)) {
1430: cfg.dir[i]->misc|=DIR_QUIET;
1431: uifc.changes=1;
1432: } else if(n==0 && cfg.dir[i]->misc&DIR_QUIET){
1433: cfg.dir[i]->misc&=~DIR_QUIET;
1434: uifc.changes=1;
1435: }
1436: break;
1437:
1438:
1439: case 16:
1440: n=cfg.dir[i]->misc&DIR_ANON ? (cfg.dir[i]->misc&DIR_AONLY ? 2:0):1;
1441: strcpy(opt[0],"Yes");
1442: strcpy(opt[1],"No");
1443: strcpy(opt[2],"Only");
1444: opt[3][0]=0;
1445: SETHELP(WHERE);
1446: /*
1447: &Allow Anonymous Uploads:&
1448:
1449: If you want users with the &A& exemption to be able to upload anonymously
1450: to this directory, set this option to &Yes&. If you want all uploads to
1451: this directory to be forced anonymous, set this option to &Only&.
1452: */
1453: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1454: ,"Allow Anonymous Uploads",opt);
1455: if(n==0 && (cfg.dir[i]->misc&(DIR_ANON|DIR_AONLY))
1456: !=DIR_ANON) {
1457: cfg.dir[i]->misc|=DIR_ANON;
1458: cfg.dir[i]->misc&=~DIR_AONLY;
1459: uifc.changes=1; }
1460: else if(n==1 && cfg.dir[i]->misc&(DIR_ANON|DIR_AONLY)){
1461: cfg.dir[i]->misc&=~(DIR_ANON|DIR_AONLY);
1462: uifc.changes=1; }
1463: else if(n==2 && (cfg.dir[i]->misc&(DIR_ANON|DIR_AONLY))
1464: !=(DIR_ANON|DIR_AONLY)) {
1465: cfg.dir[i]->misc|=(DIR_ANON|DIR_AONLY);
1466: uifc.changes=1; }
1467: break;
1468: case 17:
1469: n=cfg.dir[i]->misc&DIR_SINCEDL ? 0:1;
1470: strcpy(opt[0],"Yes");
1471: strcpy(opt[1],"No");
1472: opt[2][0]=0;
1473: SETHELP(WHERE);
1474: /*
1475: &Purge Files Based on Date of Last Download:&
1476:
1477: Using the Synchronet file base maintenance utility (&DELFILES&), you can
1478: have files removed based on the number of days since last downloaded
1479: rather than the number of days since the file was uploaded (default),
1480: by setting this option to &Yes&.
1481: */
1482: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1483: ,"Purge Files Based on Date of Last Download"
1484: ,opt);
1485: if(n==0 && !(cfg.dir[i]->misc&DIR_SINCEDL)) {
1486: cfg.dir[i]->misc|=DIR_SINCEDL;
1487: uifc.changes=1; }
1488: else if(n==1 && (cfg.dir[i]->misc&DIR_SINCEDL)) {
1489: cfg.dir[i]->misc&=~DIR_SINCEDL;
1490: uifc.changes=1; }
1491: break;
1492: case 18:
1493: n=cfg.dir[i]->misc&DIR_MOVENEW ? 0:1;
1494: strcpy(opt[0],"Yes");
1495: strcpy(opt[1],"No");
1496: opt[2][0]=0;
1497: SETHELP(WHERE);
1498: /*
1499: &Mark Moved Files as New:&
1500:
1501: If this option is set to &Yes&, then all files moved &from& this directory
1502: will have their upload date changed to the current date so the file will
1503: appear in users' new-file scans again.
1504: */
1505: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1506: ,"Mark Moved Files as New"
1507: ,opt);
1508: if(n==0 && !(cfg.dir[i]->misc&DIR_MOVENEW)) {
1509: cfg.dir[i]->misc|=DIR_MOVENEW;
1510: uifc.changes=1; }
1511: else if(n==1 && (cfg.dir[i]->misc&DIR_MOVENEW)) {
1512: cfg.dir[i]->misc&=~DIR_MOVENEW;
1513: uifc.changes=1; }
1514: break;
1515: case 19:
1516: n=cfg.dir[i]->misc&DIR_NOSTAT ? 1:0;
1517: strcpy(opt[0],"Yes");
1518: strcpy(opt[1],"No");
1519: opt[2][0]=0;
1520: SETHELP(WHERE);
1521: /*
1522: `Include Transfers In System Statistics:`
1523:
1524: If this option is set to ~Yes~, then all files uploaded to or downloaded
1525: from this directory will be included in the system's daily and
1526: cumulative statistics.
1527: */
1528: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1529: ,"Include Transfers In System Statistics"
1530: ,opt);
1531: if(n==1 && !(cfg.dir[i]->misc&DIR_NOSTAT)) {
1532: cfg.dir[i]->misc|=DIR_NOSTAT;
1533: uifc.changes=1;
1534: } else if(n==0 && cfg.dir[i]->misc&DIR_NOSTAT){
1535: cfg.dir[i]->misc&=~DIR_NOSTAT;
1536: uifc.changes=1;
1537: }
1538: break;
1539: }
1540: }
1541: break;
1542: case 14:
1543: while(1) {
1544: n=0;
1545: sprintf(opt[n++],"%-27.27s%s","Extensions Allowed"
1546: ,cfg.dir[i]->exts);
1547: if(!cfg.dir[i]->data_dir[0])
1548: sprintf(str,"%sdirs/",cfg.data_dir);
1549: else
1550: strcpy(str,cfg.dir[i]->data_dir);
1551: sprintf(opt[n++],"%-27.27s%.40s","Data Directory"
1552: ,str);
1553: sprintf(opt[n++],"%-27.27s%.40s","Upload Semaphore File"
1554: ,cfg.dir[i]->upload_sem);
1555: sprintf(opt[n++],"%-27.27s%s","Sort Value and Direction"
1556: , cfg.dir[i]->sort==SORT_NAME_A ? "Name Ascending"
1557: : cfg.dir[i]->sort==SORT_NAME_D ? "Name Descending"
1558: : cfg.dir[i]->sort==SORT_DATE_A ? "Date Ascending"
1559: : "Date Descending");
1560: opt[n][0]=0;
1561: SETHELP(WHERE);
1562: /*
1563: &Directory Advanced Options:&
1564:
1565: This is the advanced options menu for the selected file directory.
1566: */
1567: n=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,3,4,60,&adv_dflt,0
1568: ,"Advanced Options",opt);
1569: if(n==-1)
1570: break;
1571: switch(n) {
1572: case 0:
1573: SETHELP(WHERE);
1574: /*
1575: &File Extensions Allowed:&
1576:
1577: This option allows you to limit the types of files uploaded to this
1578: directory. This is a list of file extensions that are allowed, each
1579: separated by a comma (Example: &ZIP,EXE&). If this option is left
1580: blank, all file extensions will be allowed to be uploaded.
1581: */
1582: uifc.input(WIN_L2R|WIN_SAV,0,17
1583: ,"File Extensions Allowed"
1584: ,cfg.dir[i]->exts,sizeof(cfg.dir[i]->exts)-1,K_EDIT);
1585: break;
1586: case 1:
1587: SETHELP(WHERE);
1588: /*
1589: &Data Directory:&
1590:
1591: Use this if you wish to place the data directory for this directory
1592: on another drive or in another directory besides the default setting.
1593: */
1594: uifc.input(WIN_MID|WIN_SAV,0,17,"Data"
1595: ,cfg.dir[i]->data_dir,sizeof(cfg.dir[i]->data_dir)-1,K_EDIT);
1596: break;
1597: case 2:
1598: SETHELP(WHERE);
1599: /*
1600: &Upload Semaphore File:&
1601:
1602: This is a filename that will be used as a semaphore (signal) to your
1603: FidoNet front-end that new files are ready to be hatched for export.
1604: */
1605: uifc.input(WIN_MID|WIN_SAV,0,17,"Upload Semaphore"
1606: ,cfg.dir[i]->upload_sem,sizeof(cfg.dir[i]->upload_sem)-1,K_EDIT);
1607: break;
1608: case 3:
1609: n=0;
1610: strcpy(opt[0],"Name Ascending");
1611: strcpy(opt[1],"Name Descending");
1612: strcpy(opt[2],"Date Ascending");
1613: strcpy(opt[3],"Date Descending");
1614: opt[4][0]=0;
1615: SETHELP(WHERE);
1616: /*
1617: &Sort Value and Direction:&
1618:
1619: This option allows you to determine the sort value and direction. Files
1620: that are uploaded are automatically sorted by filename or upload date,
1621: ascending or descending. If you change the sort value or direction after
1622: a directory already has files in it, use the sysop transfer menu &;RESORT&
1623: command to resort the directory with the new sort parameters.
1624: */
1625: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
1626: ,"Sort Value and Direction",opt);
1627: if(n==0 && cfg.dir[i]->sort!=SORT_NAME_A) {
1628: cfg.dir[i]->sort=SORT_NAME_A;
1629: uifc.changes=1; }
1630: else if(n==1 && cfg.dir[i]->sort!=SORT_NAME_D) {
1631: cfg.dir[i]->sort=SORT_NAME_D;
1632: uifc.changes=1; }
1633: else if(n==2 && cfg.dir[i]->sort!=SORT_DATE_A) {
1634: cfg.dir[i]->sort=SORT_DATE_A;
1635: uifc.changes=1; }
1636: else if(n==3 && cfg.dir[i]->sort!=SORT_DATE_D) {
1637: cfg.dir[i]->sort=SORT_DATE_D;
1638: uifc.changes=1; }
1639: break; } }
1640: break;
1641: } } }
1642:
1643: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.