|
|
1.1 root 1: /* scfgmsg.c */
2:
3: /* $Id: scfgmsg.c,v 1.32 2006/07/12 06:41:50 rswindell 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 2003 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: char *utos(char *str)
39: {
40: static char out[128];
41: int i;
42:
43: for(i=0;str[i] && i<sizeof(out)-1;i++)
44: if(str[i]=='_')
45: out[i]=' ';
46: else
47: out[i]=str[i];
48: out[i]=0;
49: return(out);
50: }
51:
52: char *stou(char *str)
53: {
54: static char out[128];
55: int i;
56:
57: for(i=0;str[i];i++)
58: if(str[i]==' ')
59: out[i]='_';
60: else
61: out[i]=str[i];
62: out[i]=0;
63: return(out);
64: }
65:
66: void clearptrs(int subnum)
67: {
68: char str[256];
69: ushort idx,scancfg;
70: int file,i,gi;
71: long l=0L;
72: glob_t g;
73:
74: uifc.pop("Clearing Pointers...");
75: sprintf(str,"%suser/ptrs/*.ixb",cfg.data_dir);
76:
77: glob(str,0,NULL,&g);
78: for(gi=0;gi<g.gl_pathc;gi++) {
79:
80: if(flength(g.gl_pathv[gi])>=((long)cfg.sub[subnum]->ptridx+1L)*10L) {
81: if((file=nopen(g.gl_pathv[gi],O_WRONLY))==-1) {
82: errormsg(WHERE,ERR_OPEN,g.gl_pathv[gi],O_WRONLY);
83: bail(1);
84: }
85: while(filelength(file)<(long)(cfg.sub[subnum]->ptridx)*10) {
86: lseek(file,0L,SEEK_END);
87: idx=tell(file)/10;
88: for(i=0;i<cfg.total_subs;i++)
89: if(cfg.sub[i]->ptridx==idx)
90: break;
91: write(file,&l,sizeof(l));
92: write(file,&l,sizeof(l));
93: scancfg=0xff;
94: if(i<cfg.total_subs) {
95: if(!(cfg.sub[i]->misc&SUB_NSDEF))
96: scancfg&=~SUB_CFG_NSCAN;
97: if(!(cfg.sub[i]->misc&SUB_SSDEF))
98: scancfg&=~SUB_CFG_SSCAN;
99: } else /* Default to scan OFF for unknown sub */
100: scancfg&=~(SUB_CFG_NSCAN|SUB_CFG_SSCAN);
101: write(file,&scancfg,sizeof(scancfg));
102: }
103: lseek(file,((long)cfg.sub[subnum]->ptridx)*10L,SEEK_SET);
104: write(file,&l,sizeof(l)); /* date set to null */
105: write(file,&l,sizeof(l)); /* date set to null */
106: scancfg=0xff;
107: if(!(cfg.sub[subnum]->misc&SUB_NSDEF))
108: scancfg&=~SUB_CFG_NSCAN;
109: if(!(cfg.sub[subnum]->misc&SUB_SSDEF))
110: scancfg&=~SUB_CFG_SSCAN;
111: write(file,&scancfg,sizeof(scancfg));
112: close(file);
113: }
114: }
115: globfree(&g);
116: uifc.pop(0);
117: }
118:
119: void msgs_cfg()
120: {
121: static int dflt,msgs_dflt,bar;
122: char str[256],str2[256],done=0;
123: char* p;
124: char* tp;
125: char tmp[128];
126: char tmp_code[16];
127: int j,k,l,q,s;
128: int i,file,ptridx,n;
129: unsigned total_subs;
130: long ported;
131: sub_t tmpsub;
132: static grp_t savgrp;
133: FILE* stream;
134:
135: while(1) {
136: for(i=0;i<cfg.total_grps && i<MAX_OPTS;i++)
137: sprintf(opt[i],"%-25s",cfg.grp[i]->lname);
138: opt[i][0]=0;
139: j=WIN_ORG|WIN_ACT|WIN_CHE;
140: if(cfg.total_grps)
141: j|=WIN_DEL|WIN_DELACT|WIN_GET;
142: if(cfg.total_grps<MAX_OPTS)
143: j|=WIN_INS|WIN_INSACT|WIN_XTR;
144: if(savgrp.sname[0])
145: j|=WIN_PUT;
146: SETHELP(WHERE);
147: /*
148: &Message Groups:&
149:
150: This is a listing of message groups for your BBS. Message groups are
151: used to logically separate your message &sub-boards& into groups. Every
152: sub-board belongs to a message group. You must have at least one message
153: group and one sub-board configured.
154:
155: One popular use for message groups is to separate local sub-boards and
156: networked sub-boards. One might have a &Local& message group that contains
157: non-networked sub-boards of various topics and also have a &FidoNet&
158: message group that contains sub-boards that are echoed across FidoNet.
159: Some sysops separate sub-boards into more specific areas such as &Main&,
160: &Technical&, or &Adult&. If you have many sub-boards that have a common
161: subject denominator, you may want to have a separate message group for
162: those sub-boards for a more organized message structure.
163: */
164: i=uifc.list(j,0,0,45,&msgs_dflt,&bar,"Message Groups",opt);
165: if(i==-1) {
166: j=save_changes(WIN_MID);
167: if(j==-1)
168: continue;
169: if(!j) {
170: write_msgs_cfg(&cfg,backup_level);
171: refresh_cfg(&cfg);
172: }
173: return;
174: }
175: if((i&MSK_ON)==MSK_INS) {
176: i&=MSK_OFF;
177: SETHELP(WHERE);
178: /*
179: &Group Long Name:&
180:
181: This is a description of the message group which is displayed when a
182: user of the system uses the &/*& command from the main menu.
183: */
184: strcpy(str,"Main");
185: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Group Long Name",str,LEN_GLNAME
186: ,K_EDIT)<1)
187: continue;
188: SETHELP(WHERE);
189: /*
190: &Group Short Name:&
191:
192: This is a short description of the message group which is used for the
193: main menu and reading message prompts.
194: */
195: sprintf(str2,"%.*s",LEN_GSNAME,str);
196: if(uifc.input(WIN_MID,0,0,"Group Short Name",str2,LEN_GSNAME,K_EDIT)<1)
197: continue;
198: if((cfg.grp=(grp_t **)realloc(cfg.grp,sizeof(grp_t *)*(cfg.total_grps+1)))==NULL) {
199: errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_grps+1);
200: cfg.total_grps=0;
201: bail(1);
202: continue; }
203:
204: if(cfg.total_grps) { /* was cfg.total_subs (?) */
205: for(j=cfg.total_grps;j>i;j--) /* insert above */
206: cfg.grp[j]=cfg.grp[j-1];
207: for(j=0;j<cfg.total_subs;j++) /* move sub group numbers */
208: if(cfg.sub[j]->grp>=i)
209: cfg.sub[j]->grp++; }
210:
211: if((cfg.grp[i]=(grp_t *)malloc(sizeof(grp_t)))==NULL) {
212: errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(grp_t));
213: continue; }
214: memset((grp_t *)cfg.grp[i],0,sizeof(grp_t));
215: strcpy(cfg.grp[i]->lname,str);
216: strcpy(cfg.grp[i]->sname,str2);
217: cfg.total_grps++;
218: uifc.changes=1;
219: continue; }
220: if((i&MSK_ON)==MSK_DEL) {
221: i&=MSK_OFF;
222: SETHELP(WHERE);
223: /*
224: &Delete All Data in Group:&
225:
226: If you wish to delete the messages in all the sub-boards in this group,
227: select &Yes&.
228: */
229: j=1;
230: strcpy(opt[0],"Yes");
231: strcpy(opt[1],"No");
232: opt[2][0]=0;
233: j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0,"Delete All Data in Group",opt);
234: if(j==-1)
235: continue;
236: if(j==0)
237: for(j=0;j<cfg.total_subs;j++)
238: if(cfg.sub[j]->grp==i) {
239: sprintf(str,"%s%s.s*"
240: ,cfg.grp[cfg.sub[j]->grp]->code_prefix
241: ,cfg.sub[j]->code_suffix);
242: strlwr(str);
243: if(!cfg.sub[j]->data_dir[0])
244: sprintf(tmp,"%ssubs/",cfg.data_dir);
245: else
246: strcpy(tmp,cfg.sub[j]->data_dir);
247: delfiles(tmp,str);
248: clearptrs(j); }
249: free(cfg.grp[i]);
250: for(j=0;j<cfg.total_subs;) {
251: if(cfg.sub[j]->grp==i) { /* delete subs of this group */
252: free(cfg.sub[j]);
253: cfg.total_subs--;
254: k=j;
255: while(k<cfg.total_subs) { /* move all subs down */
256: cfg.sub[k]=cfg.sub[k+1];
257: for(q=0;q<cfg.total_qhubs;q++)
258: for(s=0;s<cfg.qhub[q]->subs;s++)
259: if(cfg.qhub[q]->sub[s]==k)
260: cfg.qhub[q]->sub[s]--;
261: k++; } }
262: else j++; }
263: for(j=0;j<cfg.total_subs;j++) /* move sub group numbers down */
264: if(cfg.sub[j]->grp>i)
265: cfg.sub[j]->grp--;
266: cfg.total_grps--;
267: while(i<cfg.total_grps) {
268: cfg.grp[i]=cfg.grp[i+1];
269: i++; }
270: uifc.changes=1;
271: continue; }
272: if((i&MSK_ON)==MSK_GET) {
273: i&=MSK_OFF;
274: savgrp=*cfg.grp[i];
275: continue; }
276: if((i&MSK_ON)==MSK_PUT) {
277: i&=MSK_OFF;
278: *cfg.grp[i]=savgrp;
279: uifc.changes=1;
280: continue; }
281: done=0;
282: while(!done) {
283: j=0;
284: sprintf(opt[j++],"%-27.27s%s","Long Name",cfg.grp[i]->lname);
285: sprintf(opt[j++],"%-27.27s%s","Short Name",cfg.grp[i]->sname);
286: sprintf(opt[j++],"%-27.27s%s","Internal Code Prefix",cfg.grp[i]->code_prefix);
287: sprintf(opt[j++],"%-27.27s%.40s","Access Requirements"
288: ,cfg.grp[i]->arstr);
289: strcpy(opt[j++],"Clone Options");
290: strcpy(opt[j++],"Export Areas...");
291: strcpy(opt[j++],"Import Areas...");
292: strcpy(opt[j++],"Message Sub-boards...");
293: opt[j][0]=0;
294: sprintf(str,"%s Group",cfg.grp[i]->sname);
295: SETHELP(WHERE);
296: /*
297: &Message Group Configuration:&
298:
299: This menu allows you to configure the security requirements for access
300: to this message group. You can also add, delete, and configure the
301: sub-boards of this group by selecting the &Messages Sub-boards...& option.
302: */
303: switch(uifc.list(WIN_ACT,6,4,60,&dflt,0,str,opt)) {
304: case -1:
305: done=1;
306: break;
307: case 0:
308: SETHELP(WHERE);
309: /*
310: &Group Long Name:&
311:
312: This is a description of the message group which is displayed when a
313: user of the system uses the &/*& command from the main menu.
314: */
315: strcpy(str,cfg.grp[i]->lname); /* save incase setting to null */
316: if(!uifc.input(WIN_MID|WIN_SAV,0,17,"Name to use for Listings"
317: ,cfg.grp[i]->lname,LEN_GLNAME,K_EDIT))
318: strcpy(cfg.grp[i]->lname,str);
319: break;
320: case 1:
321: SETHELP(WHERE);
322: /*
323: &Group Short Name:&
324:
325: This is a short description of the message group which is used for
326: main menu and reading messages prompts.
327: */
328: uifc.input(WIN_MID|WIN_SAV,0,17,"Name to use for Prompts"
329: ,cfg.grp[i]->sname,LEN_GSNAME,K_EDIT);
330: break;
331: case 2:
332: SETHELP(WHERE);
333: /*
334: `Internal Code Prefix:`
335:
336: This is an `optional` code prefix used to help generate unique internal
337: codes for the sub-boards in this message group. If this option
338: is used, sub-board internal codes will be made up of this prefix and the
339: specified code suffix for each sub-board.
340: */
341: uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code Prefix"
342: ,cfg.grp[i]->code_prefix,LEN_CODE,K_EDIT|K_UPPER);
343: break;
344: case 3:
345: sprintf(str,"%s Group",cfg.grp[i]->sname);
346: getar(str,cfg.grp[i]->arstr);
347: break;
348: case 4: /* Clone Options */
349: j=0;
350: strcpy(opt[0],"Yes");
351: strcpy(opt[1],"No");
352: opt[2][0]=0;
353: SETHELP(WHERE);
354: /*
355: &Clone Sub-board Options:&
356:
357: If you want to clone the options of the first sub-board of this group
358: into all sub-boards of this group, select &Yes&.
359:
360: The options cloned are posting requirements, reading requirements,
361: operator requirments, moderated user requirments, toggle options,
362: network options (including EchoMail origin line, EchoMail address,
363: and QWK Network tagline), maximum number of messages, maximum number
364: of CRCs, maximum age of messages, storage method, and data directory.
365: */
366: j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0
367: ,"Clone Options of First Sub-board into All of Group",opt);
368: if(j==0) {
369: k=-1;
370: for(j=0;j<cfg.total_subs;j++)
371: if(cfg.sub[j]->grp==i) {
372: if(k==-1)
373: k=j;
374: else {
375: uifc.changes=1;
376: cfg.sub[j]->misc=(cfg.sub[k]->misc|SUB_HDRMOD);
377: strcpy(cfg.sub[j]->post_arstr,cfg.sub[k]->post_arstr);
378: strcpy(cfg.sub[j]->read_arstr,cfg.sub[k]->read_arstr);
379: strcpy(cfg.sub[j]->op_arstr,cfg.sub[k]->op_arstr);
380: strcpy(cfg.sub[j]->mod_arstr,cfg.sub[k]->mod_arstr);
381: strcpy(cfg.sub[j]->origline,cfg.sub[k]->origline);
382: strcpy(cfg.sub[j]->tagline,cfg.sub[k]->tagline);
383: strcpy(cfg.sub[j]->data_dir,cfg.sub[k]->data_dir);
384: strcpy(cfg.sub[j]->post_sem,cfg.sub[k]->post_sem);
385: cfg.sub[j]->maxmsgs=cfg.sub[k]->maxmsgs;
386: cfg.sub[j]->maxcrcs=cfg.sub[k]->maxcrcs;
387: cfg.sub[j]->maxage=cfg.sub[k]->maxage;
388:
389: cfg.sub[j]->faddr=cfg.sub[k]->faddr; } } }
390: break;
391: case 5:
392: k=0;
393: ported=0;
394: q=uifc.changes;
395: strcpy(opt[k++],"SUBS.TXT (Synchronet)");
396: strcpy(opt[k++],"AREAS.BBS (MSG)");
397: strcpy(opt[k++],"AREAS.BBS (SBBSecho)");
398: strcpy(opt[k++],"FIDONET.NA (Fido)");
399: opt[k][0]=0;
400: SETHELP(WHERE);
401: /*
402: &Export Area File Format:&
403:
404: This menu allows you to choose the format of the area file you wish to
405: export the current message group into.
406: */
407: k=0;
408: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
409: ,"Export Area File Format",opt);
410: if(k==-1)
411: break;
412: if(k==0)
413: sprintf(str,"%sSUBS.TXT",cfg.ctrl_dir);
414: else if(k==1)
415: sprintf(str,"AREAS.BBS");
416: else if(k==2)
417: sprintf(str,"%sAREAS.BBS",cfg.data_dir);
418: else if(k==3)
419: sprintf(str,"FIDONET.NA");
420: if(k && k<3)
421: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Uplinks"
422: ,str2,sizeof(str2)-1,0)<=0) {
423: uifc.changes=q;
424: break; }
425: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Filename"
426: ,str,sizeof(str)-1,K_EDIT)<=0) {
427: uifc.changes=q;
428: break; }
429: if(fexist(str)) {
430: strcpy(opt[0],"Overwrite");
431: strcpy(opt[1],"Append");
432: opt[2][0]=0;
433: j=0;
434: j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0
435: ,"File Exists",opt);
436: if(j==-1)
437: break;
438: if(j==0) j=O_WRONLY|O_TRUNC;
439: else j=O_WRONLY|O_APPEND; }
440: else
441: j=O_WRONLY|O_CREAT;
442: if((stream=fnopen(&file,str,j))==NULL) {
443: sprintf(str,"Open Failure: %d (%s)"
444: ,errno,strerror(errno));
445: uifc.msg(str);
446: uifc.changes=q;
447: break;
448: }
449: uifc.pop("Exporting Areas...");
450: for(j=0;j<cfg.total_subs;j++) {
451: if(cfg.sub[j]->grp!=i)
452: continue;
453: ported++;
454: if(k==1) { /* AREAS.BBS *.MSG */
455: sprintf(str,"%s%s%s/"
456: ,cfg.echomail_dir
457: ,cfg.grp[cfg.sub[j]->grp]->code_prefix
458: ,cfg.sub[j]->code_suffix);
459: fprintf(stream,"%-30s %-20s %s\r\n"
460: ,str,stou(cfg.sub[j]->sname),str2);
461: continue; }
462: if(k==2) { /* AREAS.BBS SBBSecho */
463: fprintf(stream,"%s%-30s %-20s %s\r\n"
464: ,cfg.grp[cfg.sub[j]->grp]->code_prefix
465: ,cfg.sub[j]->code_suffix
466: ,stou(cfg.sub[j]->sname)
467: ,str2);
468: continue; }
469: if(k==3) { /* FIDONET.NA */
470: fprintf(stream,"%-20s %s\r\n"
471: ,stou(cfg.sub[j]->sname),cfg.sub[j]->lname);
472: continue; }
473: fprintf(stream,"%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n"
474: "%s\r\n%s\r\n%s\r\n"
475: ,cfg.sub[j]->lname
476: ,cfg.sub[j]->sname
477: ,cfg.sub[j]->qwkname
478: ,cfg.sub[j]->code_suffix
479: ,cfg.sub[j]->data_dir
480: ,cfg.sub[j]->arstr
481: ,cfg.sub[j]->read_arstr
482: ,cfg.sub[j]->post_arstr
483: ,cfg.sub[j]->op_arstr
484: );
485: fprintf(stream,"%lX\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n"
486: ,cfg.sub[j]->misc
487: ,cfg.sub[j]->tagline
488: ,cfg.sub[j]->origline
489: ,cfg.sub[j]->post_sem
490: ,cfg.sub[j]->newsgroup
491: ,smb_faddrtoa(&cfg.sub[j]->faddr,tmp)
492: );
493: fprintf(stream,"%lu\r\n%lu\r\n%u\r\n%u\r\n%s\r\n"
494: ,cfg.sub[j]->maxmsgs
495: ,cfg.sub[j]->maxcrcs
496: ,cfg.sub[j]->maxage
497: ,cfg.sub[j]->ptridx
498: ,cfg.sub[j]->mod_arstr
499: );
500: fprintf(stream,"***END-OF-SUB***\r\n\r\n"); }
501: fclose(stream);
502: uifc.pop(0);
503: sprintf(str,"%lu Message Areas Exported Successfully",ported);
504: uifc.msg(str);
505: uifc.changes=q;
506: break;
507: case 6:
508: ported=0;
509: k=0;
510: strcpy(opt[k++],"SUBS.TXT (Synchronet)");
511: strcpy(opt[k++],"AREAS.BBS (Generic)");
512: strcpy(opt[k++],"AREAS.BBS (SBBSecho)");
513: strcpy(opt[k++],"FIDONET.NA (Fido)");
514: opt[k][0]=0;
515: SETHELP(WHERE);
516: /*
517: &Import Area File Format:&
518:
519: This menu allows you to choose the format of the area file you wish to
520: import into the current message group.
521: */
522: k=0;
523: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
524: ,"Import Area File Format",opt);
525: if(k==-1)
526: break;
527: if(k==0)
528: sprintf(str,"%sSUBS.TXT",cfg.ctrl_dir);
529: else if(k==1)
530: sprintf(str,"AREAS.BBS");
531: else if(k==2)
532: sprintf(str,"%sAREAS.BBS",cfg.data_dir);
533: else if(k==3)
534: sprintf(str,"FIDONET.NA");
535: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Filename"
536: ,str,sizeof(str)-1,K_EDIT)<=0)
537: break;
538: if((stream=fnopen(&file,str,O_RDONLY))==NULL) {
539: uifc.msg("Open Failure");
540: break; }
541: uifc.pop("Importing Areas...");
542: total_subs = cfg.total_subs; /* Save original number of subs */
543: ptridx = 0;
544: while(!feof(stream)) {
545: if(!fgets(str,sizeof(str),stream)) break;
546: truncsp(str);
547: if(!str[0])
548: continue;
549: if(k) {
550: p=str;
551: while(*p && *p<=' ') p++;
552: if(!*p || *p==';')
553: continue;
554: memset(&tmpsub,0,sizeof(sub_t));
555: tmpsub.misc|=
556: (SUB_FIDO|SUB_NAME|SUB_TOUSER|SUB_QUOTE|SUB_HYPER);
557: if(k==1) { /* AREAS.BBS Generic/*.MSG */
558: p=str;
559: SKIP_WHITESPACE(p); /* Find path */
560: FIND_WHITESPACE(p); /* Skip path */
561: SKIP_WHITESPACE(p); /* Find tag */
562: truncstr(p," \t"); /* Truncate tag */
563: SAFECOPY(tmp_code,p); /* Copy tag to internal code */
564: SAFECOPY(tmpsub.lname,utos(p));
565: SAFECOPY(tmpsub.sname,tmpsub.lname);
566: SAFECOPY(tmpsub.qwkname,tmpsub.qwkname);
567: }
568: else if(k==2) { /* AREAS.BBS SBBSecho */
569: p=str;
570: SKIP_WHITESPACE(p); /* Find internal code */
571: tp=p;
572: FIND_WHITESPACE(tp);
573: *tp=0; /* Truncate internal code */
574: SAFECOPY(tmp_code,p); /* Copy internal code suffix */
575: p=tp+1;
576: SKIP_WHITESPACE(p); /* Find echo tag */
577: truncstr(p," \t"); /* Truncate tag */
578: SAFECOPY(tmpsub.lname,utos(p));
579: SAFECOPY(tmpsub.sname,tmpsub.lname);
580: SAFECOPY(tmpsub.qwkname,tmpsub.sname);
581: }
582: else if(k==3) { /* FIDONET.NA */
583: p=str;
584: SKIP_WHITESPACE(p); /* Find echo tag */
585: tp=p;
586: FIND_WHITESPACE(tp); /* Find end of tag */
587: *tp=0; /* Truncate echo tag */
588: SAFECOPY(tmp_code,p); /* Copy tag to internal code suffix */
589: SAFECOPY(tmpsub.sname,utos(p)); /* ... to short name, converting underscores to spaces */
590: SAFECOPY(tmpsub.qwkname,tmpsub.sname); /* ... to QWK name .... */
591: p=tp+1;
592: SKIP_WHITESPACE(p); /* Find description */
593: SAFECOPY(tmpsub.lname,p); /* Copy description to long name */
594: }
595: }
596: else {
597: memset(&tmpsub,0,sizeof(sub_t));
598: tmpsub.grp=i;
599: sprintf(tmpsub.lname,"%.*s",LEN_SLNAME,str);
600: if(!fgets(str,128,stream)) break;
601: truncsp(str);
602: sprintf(tmpsub.sname,"%.*s",LEN_SSNAME,str);
603: if(!fgets(str,128,stream)) break;
604: truncsp(str);
605: sprintf(tmpsub.qwkname,"%.*s",10,str);
606: if(!fgets(str,128,stream)) break;
607: truncsp(str);
608: SAFECOPY(tmp_code,str);
609: if(!fgets(str,128,stream)) break;
610: truncsp(str);
611: sprintf(tmpsub.data_dir,"%.*s",LEN_DIR,str);
612: if(!fgets(str,128,stream)) break;
613: truncsp(str);
614: sprintf(tmpsub.arstr,"%.*s",LEN_ARSTR,str);
615: if(!fgets(str,128,stream)) break;
616: truncsp(str);
617: sprintf(tmpsub.read_arstr,"%.*s",LEN_ARSTR,str);
618: if(!fgets(str,128,stream)) break;
619: truncsp(str);
620: sprintf(tmpsub.post_arstr,"%.*s",LEN_ARSTR,str);
621: if(!fgets(str,128,stream)) break;
622: truncsp(str);
623: sprintf(tmpsub.op_arstr,"%.*s",LEN_ARSTR,str);
624: if(!fgets(str,128,stream)) break;
625: truncsp(str);
626: tmpsub.misc=ahtoul(str);
627: if(!fgets(str,128,stream)) break;
628: truncsp(str);
629: sprintf(tmpsub.tagline,"%.*s",80,str);
630: if(!fgets(str,128,stream)) break;
631: truncsp(str);
632: sprintf(tmpsub.origline,"%.*s",50,str);
633: if(!fgets(str,128,stream)) break;
634: truncsp(str);
635: sprintf(tmpsub.post_sem,"%.*s",LEN_DIR,str);
636: if(!fgets(str,128,stream)) break;
637: truncsp(str);
638: SAFECOPY(tmpsub.newsgroup,str);
639: if(!fgets(str,128,stream)) break;
640: truncsp(str);
641: tmpsub.faddr=atofaddr(str);
642: if(!fgets(str,128,stream)) break;
643: truncsp(str);
644: tmpsub.maxmsgs=atol(str);
645: if(!fgets(str,128,stream)) break;
646: truncsp(str);
647: tmpsub.maxcrcs=atol(str);
648: if(!fgets(str,128,stream)) break;
649: truncsp(str);
650: tmpsub.maxage=atoi(str);
651: if(!fgets(str,128,stream)) break;
652: truncsp(str);
653: tmpsub.ptridx=atoi(str);
654: if(!fgets(str,128,stream)) break;
655: truncsp(str);
656: sprintf(tmpsub.mod_arstr,"%.*s",LEN_ARSTR,str);
657:
658: while(!feof(stream)
659: && strcmp(str,"***END-OF-SUB***")) {
660: if(!fgets(str,128,stream)) break;
661: truncsp(str);
662: }
663: }
664:
665: p=tmp_code;
666: l=strlen(cfg.grp[i]->code_prefix);
667: if(l && strnicmp(p,cfg.grp[i]->code_prefix,l)==0 && strlen(p)!=l)
668: p+=l; /* Skip code prefix, if supplied */
669: prep_code(p); /* Strip invalid chars */
670: SAFECOPY(tmpsub.code_suffix,p); /* THEN truncate to valid length */
671:
672: truncsp(tmpsub.sname);
673: truncsp(tmpsub.lname);
674: truncsp(tmpsub.qwkname);
675:
676: if(tmpsub.code_suffix[0]==0
677: || tmpsub.sname[0]==0
678: || tmpsub.lname[0]==0
679: || tmpsub.qwkname[0]==0)
680: continue;
681:
682: for(j=0;j<total_subs;j++) {
683: if(cfg.sub[j]->grp!=i)
684: continue;
685: if(!stricmp(cfg.sub[j]->code_suffix,tmpsub.code_suffix))
686: break; }
687: if(j==total_subs) {
688: j=cfg.total_subs;
689: if((cfg.sub=(sub_t **)realloc(cfg.sub
690: ,sizeof(sub_t *)*(cfg.total_subs+1)))==NULL) {
691: errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_subs+1);
692: cfg.total_subs=0;
693: bail(1);
694: break;
695: }
696:
697: if((cfg.sub[j]=(sub_t *)malloc(sizeof(sub_t)))
698: ==NULL) {
699: errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(sub_t));
700: break;
701: }
702: memset(cfg.sub[j],0,sizeof(sub_t)); }
703: if(!k) {
704: n=cfg.sub[j]->ptridx; /* save original ptridx */
705: memcpy(cfg.sub[j],&tmpsub,sizeof(sub_t));
706: cfg.sub[j]->ptridx=n; /* restore original ptridx */
707: } else {
708: cfg.sub[j]->grp=i;
709: if(cfg.total_faddrs)
710: cfg.sub[j]->faddr=cfg.faddr[0];
711: strcpy(cfg.sub[j]->code_suffix,tmpsub.code_suffix);
712: strcpy(cfg.sub[j]->sname,tmpsub.sname);
713: strcpy(cfg.sub[j]->lname,tmpsub.lname);
714: strcpy(cfg.sub[j]->qwkname,tmpsub.qwkname);
715: strcpy(cfg.sub[j]->data_dir,tmpsub.data_dir);
716: if(j==cfg.total_subs)
717: cfg.sub[j]->maxmsgs=1000;
718: }
719: if(j==cfg.total_subs) { /* adding new sub-board */
720: for(;ptridx<USHRT_MAX;ptridx++) {
721: for(n=0;n<total_subs;n++)
722: if(cfg.sub[n]->ptridx==ptridx)
723: break;
724: if(n==total_subs)
725: break;
726: }
727: cfg.sub[j]->ptridx=ptridx; /* use new ptridx */
728: cfg.sub[j]->misc=tmpsub.misc;
729: cfg.total_subs++;
730: ptridx++; /* don't use the same ptridx for next sub */
731: }
732: uifc.changes=1;
733: ported++;
734: }
735: fclose(stream);
736: uifc.pop(0);
737: sprintf(str,"%lu Message Areas Imported Successfully",ported);
738: uifc.msg(str);
739: break;
740:
741: case 7:
742: sub_cfg(i);
743: break; } } }
744:
745: }
746:
747: void msg_opts()
748: {
749: char str[128],*p;
750: static int msg_dflt;
751: int i,j;
752:
753: while(1) {
754: i=0;
755: sprintf(opt[i++],"%-33.33s%s"
756: ,"BBS ID for QWK Packets",cfg.sys_id);
757: sprintf(opt[i++],"%-33.33s%s"
758: ,"Local Time Zone",smb_zonestr(cfg.sys_timezone,NULL));
759: sprintf(opt[i++],"%-33.33s%u seconds"
760: ,"Maximum Retry Time",cfg.smb_retry_time);
761: if(cfg.max_qwkmsgs)
762: sprintf(str,"%lu",cfg.max_qwkmsgs);
763: else
764: sprintf(str,"Unlimited");
765: sprintf(opt[i++],"%-33.33s%s"
766: ,"Maximum QWK Messages",str);
767: sprintf(opt[i++],"%-33.33s%s","Pre-pack QWK Requirements",cfg.preqwk_arstr);
768: if(cfg.mail_maxage)
769: sprintf(str,"Enabled (%u days old)",cfg.mail_maxage);
770: else
771: strcpy(str,"Disabled");
772: sprintf(opt[i++],"%-33.33s%s","Purge E-mail by Age",str);
773: if(cfg.sys_misc&SM_DELEMAIL)
774: strcpy(str,"Immediately");
775: else
776: strcpy(str,"Daily");
777: sprintf(opt[i++],"%-33.33s%s","Purge Deleted E-mail",str);
778: if(cfg.mail_maxcrcs)
779: sprintf(str,"Enabled (%lu mail CRCs)",cfg.mail_maxcrcs);
780: else
781: strcpy(str,"Disabled");
782: sprintf(opt[i++],"%-33.33s%s","Duplicate E-mail Checking",str);
783: sprintf(opt[i++],"%-33.33s%s","Allow Anonymous E-mail"
784: ,cfg.sys_misc&SM_ANON_EM ? "Yes" : "No");
785: sprintf(opt[i++],"%-33.33s%s","Allow Quoting in E-mail"
786: ,cfg.sys_misc&SM_QUOTE_EM ? "Yes" : "No");
787: sprintf(opt[i++],"%-33.33s%s","Allow Uploads in E-mail"
788: ,cfg.sys_misc&SM_FILE_EM ? "Yes" : "No");
789: sprintf(opt[i++],"%-33.33s%s","Allow Forwarding to NetMail"
790: ,cfg.sys_misc&SM_FWDTONET ? "Yes" : "No");
791: sprintf(opt[i++],"%-33.33s%s","Kill Read E-mail"
792: ,cfg.sys_misc&SM_DELREADM ? "Yes" : "No");
793: sprintf(opt[i++],"%-33.33s%s","Receive E-mail by Real Name"
794: ,cfg.msg_misc&MM_REALNAME ? "Yes" : "No");
795: sprintf(opt[i++],"%-33.33s%s","Users Can View Deleted Messages"
796: ,cfg.sys_misc&SM_USRVDELM ? "Yes" : cfg.sys_misc&SM_SYSVDELM
797: ? "Sysops Only":"No");
798: strcpy(opt[i++],"Extra Attribute Codes...");
799: opt[i][0]=0;
800: SETHELP(WHERE);
801: /*
802: &Message Options:&
803:
804: This is a menu of system-wide message related options. Messages include
805: E-mail and public posts (on sub-boards).
806: */
807:
808: switch(uifc.list(WIN_ORG|WIN_ACT|WIN_MID|WIN_CHE,0,0,72,&msg_dflt,0
809: ,"Message Options",opt)) {
810: case -1:
811: i=save_changes(WIN_MID);
812: if(i==-1)
813: continue;
814: if(!i) {
815: cfg.new_install=new_install;
816: write_msgs_cfg(&cfg,backup_level);
817: write_main_cfg(&cfg,backup_level);
818: refresh_cfg(&cfg);
819: }
820: return;
821: case 0:
822: strcpy(str,cfg.sys_id);
823: SETHELP(WHERE);
824: /*
825: &BBS ID for QWK Packets:&
826:
827: This is a short system ID for your BBS that is used for QWK packets.
828: It should be an abbreviation of your BBS name or other related string.
829: This ID will be used for your outgoing and incoming QWK packets. If
830: you plan on networking via QWK packets with another Synchronet BBS,
831: this ID should not begin with a number. The maximum length of the ID
832: is eight characters and cannot contain spaces or other invalid DOS
833: filename characters. In a QWK packet network, each system must have
834: a unique QWK system ID.
835: */
836:
837: uifc.input(WIN_MID|WIN_SAV,0,0,"BBS ID for QWK Packets"
838: ,str,LEN_QWKID,K_EDIT|K_UPPER);
839: if(code_ok(str))
840: strcpy(cfg.sys_id,str);
841: else
842: uifc.msg("Invalid ID");
843: break;
844: case 1:
845: strcpy(opt[0],"Yes");
846: strcpy(opt[1],"No");
847: opt[2][0]=0;
848: i=0;
849: SETHELP(WHERE);
850: /*
851: &United States Time Zone:&
852:
853: If your local time zone is the United States, select &Yes&.
854: */
855:
856: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
857: ,"United States Time Zone",opt);
858: if(i==-1)
859: break;
860: if(i==0) {
861: strcpy(opt[i++],"Atlantic");
862: strcpy(opt[i++],"Eastern");
863: strcpy(opt[i++],"Central");
864: strcpy(opt[i++],"Mountain");
865: strcpy(opt[i++],"Pacific");
866: strcpy(opt[i++],"Yukon");
867: strcpy(opt[i++],"Hawaii/Alaska");
868: strcpy(opt[i++],"Bering");
869: opt[i][0]=0;
870: i=0;
871: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
872: ,"Time Zone",opt);
873: if(i==-1)
874: break;
875: uifc.changes=1;
876: switch(i) {
877: case 0:
878: cfg.sys_timezone=AST;
879: break;
880: case 1:
881: cfg.sys_timezone=EST;
882: break;
883: case 2:
884: cfg.sys_timezone=CST;
885: break;
886: case 3:
887: cfg.sys_timezone=MST;
888: break;
889: case 4:
890: cfg.sys_timezone=PST;
891: break;
892: case 5:
893: cfg.sys_timezone=YST;
894: break;
895: case 6:
896: cfg.sys_timezone=HST;
897: break;
898: case 7:
899: cfg.sys_timezone=BST;
900: break; }
901: strcpy(opt[0],"Yes");
902: strcpy(opt[1],"No");
903: opt[2][0]=0;
904: i=1;
905: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
906: ,"Daylight Savings",opt);
907: if(i==-1)
908: break;
909: if(!i)
910: cfg.sys_timezone|=DAYLIGHT;
911: break; }
912: i=0;
913: strcpy(opt[i++],"Midway");
914: strcpy(opt[i++],"Vancouver");
915: strcpy(opt[i++],"Edmonton");
916: strcpy(opt[i++],"Winnipeg");
917: strcpy(opt[i++],"Bogota");
918: strcpy(opt[i++],"Caracas");
919: strcpy(opt[i++],"Rio de Janeiro");
920: strcpy(opt[i++],"Fernando de Noronha");
921: strcpy(opt[i++],"Azores");
922: strcpy(opt[i++],"London");
923: strcpy(opt[i++],"Berlin");
924: strcpy(opt[i++],"Athens");
925: strcpy(opt[i++],"Moscow");
926: strcpy(opt[i++],"Dubai");
927: strcpy(opt[i++],"Kabul");
928: strcpy(opt[i++],"Karachi");
929: strcpy(opt[i++],"Bombay");
930: strcpy(opt[i++],"Kathmandu");
931: strcpy(opt[i++],"Dhaka");
932: strcpy(opt[i++],"Bangkok");
933: strcpy(opt[i++],"Hong Kong");
934: strcpy(opt[i++],"Tokyo");
935: strcpy(opt[i++],"Sydney");
936: strcpy(opt[i++],"Noumea");
937: strcpy(opt[i++],"Wellington");
938: strcpy(opt[i++],"Other...");
939: opt[i][0]=0;
940: i=0;
941: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
942: ,"Time Zone",opt);
943: if(i==-1)
944: break;
945: uifc.changes=1;
946: switch(i) {
947: case 0:
948: cfg.sys_timezone=MID;
949: break;
950: case 1:
951: cfg.sys_timezone=VAN;
952: break;
953: case 2:
954: cfg.sys_timezone=EDM;
955: break;
956: case 3:
957: cfg.sys_timezone=WIN;
958: break;
959: case 4:
960: cfg.sys_timezone=BOG;
961: break;
962: case 5:
963: cfg.sys_timezone=CAR;
964: break;
965: case 6:
966: cfg.sys_timezone=RIO;
967: break;
968: case 7:
969: cfg.sys_timezone=FER;
970: break;
971: case 8:
972: cfg.sys_timezone=AZO;
973: break;
974: case 9:
975: cfg.sys_timezone=LON;
976: break;
977: case 10:
978: cfg.sys_timezone=BER;
979: break;
980: case 11:
981: cfg.sys_timezone=ATH;
982: break;
983: case 12:
984: cfg.sys_timezone=MOS;
985: break;
986: case 13:
987: cfg.sys_timezone=DUB;
988: break;
989: case 14:
990: cfg.sys_timezone=KAB;
991: break;
992: case 15:
993: cfg.sys_timezone=KAR;
994: break;
995: case 16:
996: cfg.sys_timezone=BOM;
997: break;
998: case 17:
999: cfg.sys_timezone=KAT;
1000: break;
1001: case 18:
1002: cfg.sys_timezone=DHA;
1003: break;
1004: case 19:
1005: cfg.sys_timezone=BAN;
1006: break;
1007: case 20:
1008: cfg.sys_timezone=HON;
1009: break;
1010: case 21:
1011: cfg.sys_timezone=TOK;
1012: break;
1013: case 22:
1014: cfg.sys_timezone=SYD;
1015: break;
1016: case 23:
1017: cfg.sys_timezone=NOU;
1018: break;
1019: case 24:
1020: cfg.sys_timezone=WEL;
1021: break;
1022: default:
1023: if(cfg.sys_timezone>720 || cfg.sys_timezone<-720)
1024: cfg.sys_timezone=0;
1025: sprintf(str,"%02d:%02d"
1026: ,cfg.sys_timezone/60,cfg.sys_timezone<0
1027: ? (-cfg.sys_timezone)%60 : cfg.sys_timezone%60);
1028: uifc.input(WIN_MID|WIN_SAV,0,0
1029: ,"Time (HH:MM) East (+) or West (-) of Universal "
1030: "Time"
1031: ,str,6,K_EDIT|K_UPPER);
1032: cfg.sys_timezone=atoi(str)*60;
1033: p=strchr(str,':');
1034: if(p) {
1035: if(cfg.sys_timezone<0)
1036: cfg.sys_timezone-=atoi(p+1);
1037: else
1038: cfg.sys_timezone+=atoi(p+1); }
1039: break;
1040: }
1041: break;
1042: case 2:
1043: SETHELP(WHERE);
1044: /*
1045: &Maximum Message Base Retry Time:&
1046:
1047: This is the maximum number of seconds to allow while attempting to open
1048: or lock a message base (a value in the range of 10 to 45 seconds should
1049: be fine).
1050: */
1051: ultoa(cfg.smb_retry_time,str,10);
1052: uifc.input(WIN_MID|WIN_SAV,0,0
1053: ,"Maximum Message Base Retry Time (in seconds)"
1054: ,str,2,K_NUMBER|K_EDIT);
1055: cfg.smb_retry_time=atoi(str);
1056: break;
1057: case 3:
1058: SETHELP(WHERE);
1059: /*
1060: &Maximum Messages Per QWK Packet:&
1061:
1062: This is the maximum number of messages (excluding E-mail), that a user
1063: can have in one QWK packet for download. This limit does not effect
1064: QWK network nodes (&Q& restriction). If set to &0&, no limit is imposed.
1065: */
1066:
1067: ultoa(cfg.max_qwkmsgs,str,10);
1068: uifc.input(WIN_MID|WIN_SAV,0,0
1069: ,"Maximum Messages Per QWK Packet (0=No Limit)"
1070: ,str,6,K_NUMBER|K_EDIT);
1071: cfg.max_qwkmsgs=atol(str);
1072: break;
1073: case 4:
1074: SETHELP(WHERE);
1075: /*
1076: &Pre-pack QWK Requirements:&
1077:
1078: ALL user accounts on the BBS meeting this requirmenet will have a QWK
1079: packet automatically created for them every day after midnight
1080: (during the internal daily event).
1081:
1082: This is mainly intended for QWK network nodes that wish to save connect
1083: time by having their packets pre-packed. If a large number of users meet
1084: this requirement, it can take up a large amount of disk space on your
1085: system (in the &DATA\FILE& directory).
1086: */
1087: getar("Pre-pack QWK (Use with caution!)",cfg.preqwk_arstr);
1088: break;
1089: case 5:
1090: sprintf(str,"%u",cfg.mail_maxage);
1091: SETHELP(WHERE);
1092: /*
1093: &Maximum Age of Mail:&
1094:
1095: This value is the maximum number of days that mail will be kept.
1096: */
1097: uifc.input(WIN_MID|WIN_SAV,0,17,"Maximum Age of Mail "
1098: "(in days)",str,5,K_EDIT|K_NUMBER);
1099: cfg.mail_maxage=atoi(str);
1100: break;
1101: case 6:
1102: strcpy(opt[0],"Daily");
1103: strcpy(opt[1],"Immediately");
1104: opt[2][0]=0;
1105: i=cfg.sys_misc&SM_DELEMAIL ? 0:1;
1106: SETHELP(WHERE);
1107: /*
1108: &Purge Deleted E-mail:&
1109:
1110: If you wish to have deleted e-mail physically (and permanently) removed
1111: from your e-mail database immediately after a users exits the reading
1112: e-mail prompt, set this option to &Immediately&.
1113:
1114: For the best system performance and to avoid delays when deleting e-mail
1115: from a large e-mail database, set this option to &Daily& (the default).
1116: Your system maintenance will automatically purge deleted e-mail once a
1117: day.
1118: */
1119:
1120: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
1121: ,"Purge Deleted E-mail",opt);
1122: if(!i && cfg.sys_misc&SM_DELEMAIL) {
1123: cfg.sys_misc&=~SM_DELEMAIL;
1124: uifc.changes=1; }
1125: else if(i==1 && !(cfg.sys_misc&SM_DELEMAIL)) {
1126: cfg.sys_misc|=SM_DELEMAIL;
1127: uifc.changes=1; }
1128: break;
1129: case 7:
1130: sprintf(str,"%lu",cfg.mail_maxcrcs);
1131: SETHELP(WHERE);
1132: /*
1133: &Maximum Number of Mail CRCs:&
1134:
1135: This value is the maximum number of CRCs that will be kept for duplicate
1136: mail checking. Once this maximum number of CRCs is reached, the oldest
1137: CRCs will be automatically purged.
1138: */
1139: uifc.input(WIN_MID|WIN_SAV,0,17,"Maximum Number of Mail "
1140: "CRCs",str,5,K_EDIT|K_NUMBER);
1141: cfg.mail_maxcrcs=atol(str);
1142: break;
1143: case 8:
1144: strcpy(opt[0],"Yes");
1145: strcpy(opt[1],"No");
1146: opt[2][0]=0;
1147: i=cfg.sys_misc&SM_ANON_EM ? 0:1;
1148: SETHELP(WHERE);
1149: /*
1150: &Allow Anonymous E-mail:&
1151:
1152: If you want users with the &A& exemption to be able to send E-mail
1153: anonymously, set this option to &Yes&.
1154: */
1155:
1156: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
1157: ,"Allow Anonymous E-mail",opt);
1158: if(!i && !(cfg.sys_misc&SM_ANON_EM)) {
1159: cfg.sys_misc|=SM_ANON_EM;
1160: uifc.changes=1; }
1161: else if(i==1 && cfg.sys_misc&SM_ANON_EM) {
1162: cfg.sys_misc&=~SM_ANON_EM;
1163: uifc.changes=1; }
1164: break;
1165: case 9:
1166: strcpy(opt[0],"Yes");
1167: strcpy(opt[1],"No");
1168: opt[2][0]=0;
1169: i=cfg.sys_misc&SM_QUOTE_EM ? 0:1;
1170: SETHELP(WHERE);
1171: /*
1172: &Allow Quoting in E-mail:&
1173:
1174: If you want your users to be allowed to use message quoting when
1175: responding in E-mail, set this option to &Yes&.
1176: */
1177:
1178: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
1179: ,"Allow Quoting in E-mail",opt);
1180: if(!i && !(cfg.sys_misc&SM_QUOTE_EM)) {
1181: cfg.sys_misc|=SM_QUOTE_EM;
1182: uifc.changes=1; }
1183: else if(i==1 && cfg.sys_misc&SM_QUOTE_EM) {
1184: cfg.sys_misc&=~SM_QUOTE_EM;
1185: uifc.changes=1; }
1186: break;
1187: case 10:
1188: strcpy(opt[0],"Yes");
1189: strcpy(opt[1],"No");
1190: opt[2][0]=0;
1191: i=cfg.sys_misc&SM_FILE_EM ? 0:1;
1192: SETHELP(WHERE);
1193: /*
1194: &Allow File Attachment Uploads in E-mail:&
1195:
1196: If you want your users to be allowed to attach an uploaded file to
1197: an E-mail message, set this option to &Yes&.
1198: */
1199:
1200: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
1201: ,"Allow File Attachment Uploads in E-mail",opt);
1202: if(!i && !(cfg.sys_misc&SM_FILE_EM)) {
1203: cfg.sys_misc|=SM_FILE_EM;
1204: uifc.changes=1; }
1205: else if(i==1 && cfg.sys_misc&SM_FILE_EM) {
1206: cfg.sys_misc&=~SM_FILE_EM;
1207: uifc.changes=1; }
1208: break;
1209: case 11:
1210: strcpy(opt[0],"Yes");
1211: strcpy(opt[1],"No");
1212: opt[2][0]=0;
1213: i=cfg.sys_misc&SM_FWDTONET ? 0:1;
1214: SETHELP(WHERE);
1215: /*
1216: &Allow Users to Have Their E-mail Forwarded to NetMail:&
1217:
1218: If you want your users to be able to have any e-mail sent to them
1219: optionally (at the sender's discretion) forwarded to a NetMail address,
1220: set this option to &Yes&.
1221: */
1222:
1223: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
1224: ,"Allow Forwarding of E-mail to NetMail",opt);
1225: if(!i && !(cfg.sys_misc&SM_FWDTONET)) {
1226: cfg.sys_misc|=SM_FWDTONET;
1227: uifc.changes=1; }
1228: else if(i==1 && cfg.sys_misc&SM_FWDTONET) {
1229: cfg.sys_misc&=~SM_FWDTONET;
1230: uifc.changes=1; }
1231: break;
1232: case 12:
1233: strcpy(opt[0],"Yes");
1234: strcpy(opt[1],"No");
1235: opt[2][0]=0;
1236: i=cfg.sys_misc&SM_DELREADM ? 0:1;
1237: SETHELP(WHERE);
1238: /*
1239: &Kill Read E-mail Automatically:&
1240:
1241: If this option is set to &Yes&, e-mail that has been read will be
1242: automatically deleted when message base maintenance is run.
1243: */
1244:
1245: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
1246: ,"Kill Read E-mail Automatically",opt);
1247: if(!i && !(cfg.sys_misc&SM_DELREADM)) {
1248: cfg.sys_misc|=SM_DELREADM;
1249: uifc.changes=1; }
1250: else if(i==1 && cfg.sys_misc&SM_DELREADM) {
1251: cfg.sys_misc&=~SM_DELREADM;
1252: uifc.changes=1; }
1253: break;
1254: case 13:
1255: strcpy(opt[0],"Yes");
1256: strcpy(opt[1],"No");
1257: opt[2][0]=0;
1258: i=cfg.msg_misc&MM_REALNAME ? 0:1;
1259: SETHELP(WHERE);
1260: /*
1261: `Receive E-mail by Real Name:`
1262:
1263: If this option is set to ~Yes~, e-mail messages may be received when
1264: addressed to a user's real name (rather than their alias).
1265: */
1266:
1267: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
1268: ,"Receive E-mail by Real Name",opt);
1269: if(!i && !(cfg.msg_misc&MM_REALNAME)) {
1270: cfg.msg_misc|=MM_REALNAME;
1271: uifc.changes=1;
1272: }
1273: else if(i==1 && cfg.msg_misc&MM_REALNAME) {
1274: cfg.msg_misc&=~MM_REALNAME;
1275: uifc.changes=1;
1276: }
1277: break;
1278: case 14:
1279: strcpy(opt[0],"Yes");
1280: strcpy(opt[1],"No");
1281: strcpy(opt[2],"Sysops Only");
1282: opt[3][0]=0;
1283: i=1;
1284: SETHELP(WHERE);
1285: /*
1286: &Users Can View Deleted Messages:&
1287:
1288: If this option is set to &Yes&, then users will be able to view messages
1289: they've sent and deleted or messages sent to them and they've deleted
1290: with the option of un-deleting the message before the message is
1291: physically purged from the e-mail database.
1292:
1293: If this option is set to &No&, then when a message is deleted, it is no
1294: longer viewable (with SBBS) by anyone.
1295:
1296: If this option is set to &Sysops Only&, then only sysops and sub-ops (when
1297: appropriate) can view deleted messages.
1298: */
1299:
1300: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
1301: ,"Users Can View Deleted Messages",opt);
1302: if(!i && (cfg.sys_misc&(SM_USRVDELM|SM_SYSVDELM))
1303: !=(SM_USRVDELM|SM_SYSVDELM)) {
1304: cfg.sys_misc|=(SM_USRVDELM|SM_SYSVDELM);
1305: uifc.changes=1; }
1306: else if(i==1 && cfg.sys_misc&(SM_USRVDELM|SM_SYSVDELM)) {
1307: cfg.sys_misc&=~(SM_USRVDELM|SM_SYSVDELM);
1308: uifc.changes=1; }
1309: else if(i==2 && (cfg.sys_misc&(SM_USRVDELM|SM_SYSVDELM))
1310: !=SM_SYSVDELM) {
1311: cfg.sys_misc|=SM_SYSVDELM;
1312: cfg.sys_misc&=~SM_USRVDELM;
1313: uifc.changes=1; }
1314: break;
1315: case 15:
1316: SETHELP(WHERE);
1317: /*
1318: &Extra Attribute Codes...&
1319:
1320: Synchronet can suppport the native text attribute codes of other BBS
1321: programs in messages (menus, posts, e-mail, etc.) To enable the extra
1322: attribute codes for another BBS program, set the corresponding option
1323: to &Yes&.
1324: */
1325:
1326: j=0;
1327: while(1) {
1328: i=0;
1329: sprintf(opt[i++],"%-15.15s %-3.3s","WWIV"
1330: ,cfg.sys_misc&SM_WWIV ? "Yes":"No");
1331: sprintf(opt[i++],"%-15.15s %-3.3s","PCBoard"
1332: ,cfg.sys_misc&SM_PCBOARD ? "Yes":"No");
1333: sprintf(opt[i++],"%-15.15s %-3.3s","Wildcat"
1334: ,cfg.sys_misc&SM_WILDCAT ? "Yes":"No");
1335: sprintf(opt[i++],"%-15.15s %-3.3s","Celerity"
1336: ,cfg.sys_misc&SM_CELERITY ? "Yes":"No");
1337: sprintf(opt[i++],"%-15.15s %-3.3s","Renegade"
1338: ,cfg.sys_misc&SM_RENEGADE ? "Yes":"No");
1339: opt[i][0]=0;
1340: j=uifc.list(WIN_BOT|WIN_RHT|WIN_SAV,2,2,0,&j,0
1341: ,"Extra Attribute Codes",opt);
1342: if(j==-1)
1343: break;
1344:
1345: uifc.changes=1;
1346: switch(j) {
1347: case 0:
1348: cfg.sys_misc^=SM_WWIV;
1349: break;
1350: case 1:
1351: cfg.sys_misc^=SM_PCBOARD;
1352: break;
1353: case 2:
1354: cfg.sys_misc^=SM_WILDCAT;
1355: break;
1356: case 3:
1357: cfg.sys_misc^=SM_CELERITY;
1358: break;
1359: case 4:
1360: cfg.sys_misc^=SM_RENEGADE;
1361: break; } } } }
1362: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.