Newer
Older
char* opt[] = {"Delete after Sent", "Truncate after Sent", NULL };
switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
,"Outbound Bundles",opt)) {
case 0: cfg.trunc_bundles = false; break;
case 1: cfg.trunc_bundles = true; break;
}
break;
case 12:
k = !cfg.zone_blind;
switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Zone Blind",uifcYesNoOpts)) {
case 0:
cfg.zone_blind = true;
uifc.helpbuf=
"Zone Blind Threshold";
sprintf(str,"%u",cfg.zone_blind_threshold);
if(uifc.input(WIN_MID|WIN_SAV,0,0
,"Zone Blind Threshold (highest zone in the blind range)"
, str, 5, K_EDIT|K_NUMBER) >= 0)
cfg.zone_blind_threshold = (uint16_t)atol(str);
break;
case 1:
cfg.zone_blind = false;
break;
}
break;
case 13:
"~ Maximum Age of Imported EchoMail ~\n\n"
"Maximum age of EchoMail that may be imported. The age is based\n"
"on the date supplied in the message header and may be incorrect in some\n"
"conditions (e.g. erroneous software or incorrect system date).\n"
"Set this value to `0` to disable this feature (no maximum age imposed)."
;
if(cfg.max_echomail_age)
if(uifc.input(WIN_MID|WIN_BOT|WIN_SAV,0,0,"Maximum EchoMail Age"
,str, 10, K_EDIT) >= 0)
cfg.max_echomail_age = (ulong)parse_duration(str);
break;
}
"~ Archive Types ~\n\n"
"These are the archive file types that have been configured along with\n"
"their corresponding archive programs and command-lines for the packing\n"
"and unpacking of EchoMail bundle files.\n"
"\n"
"The corresponding archive programs are sometimes referred to as `packers`."
;
for(u=0;u<cfg.arcdefs;u++)
int mode = WIN_SAV | WIN_INS | WIN_DEL | WIN_ACT
| WIN_INSACT | WIN_DELACT | WIN_XTR;
if(cfg.arcdefs)
mode |= WIN_COPY | WIN_CUT;
if(savarcdef.name[0])
mode |= WIN_PASTE | WIN_PASTEXTR;
i=uifc.list(mode,0,0,0,&archive_opt,&archive_bar,"Archive Types",opt);
int msk = i & MSK_ON;
i &= MSK_OFF;
if (msk == MSK_INS) {
str[0]=0;
uifc.helpbuf=
"~ Archive Type ~\n\n"
"This is the identifying name of the archiving program (packer).\n";
if(uifc.input(WIN_MID|WIN_SAV,0,0
if(!new_arcdef(i)) {
printf("\nMemory Allocation Error\n");
}
SAFECOPY(cfg.arcdef[i].name,str);
}
if (msk == MSK_DEL || msk == MSK_CUT) {
if (msk == MSK_CUT)
memcpy(&savarcdef, &cfg.arcdef[i], sizeof(arcdef_t));
cfg.arcdefs--;
if(cfg.arcdefs<=0) {
cfg.arcdefs=0;
}
for(u=i;u<cfg.arcdefs;u++)
memcpy(&cfg.arcdef[u],&cfg.arcdef[u+1]
}
if (msk == MSK_COPY) {
memcpy(&savarcdef,&cfg.arcdef[i],sizeof(arcdef_t));
}
if (msk == MSK_PASTE) {
if(!new_arcdef(i))
continue;
memcpy(&cfg.arcdef[i],&savarcdef,sizeof(arcdef_t));
}
if (msk != 0)
continue;
uifc.helpbuf=
"Archive Type and Program configuration";
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %u","Signature Offset"
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","Pack Command Line"
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","Unpack Command Line"
,cfg.arcdef[i].unpack);
opt[j][0]=0;
k=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,0,0,0,&packop,0,str,opt);
if(k==-1)
break;
switch(k) {
case 0:
"~ Archive Type ~\n\n"
"This is the identifying name of the archive file type. Usually this name\n"
"corresponds with the common file extension or suffix denoting this type\n"
uifc.input(WIN_MID|WIN_SAV,0,0
,"Archive Type"
,cfg.arcdef[i].name,sizeof(cfg.arcdef[i].name)-1
,K_EDIT|K_UPPER);
break;
case 1:
"~ Archive Signature ~\n\n"
"This is the identifying signature of the archive file format (in\n"
"hexadecimal notation). This signature is used in combination with the\n"
"Archive `Signature Offset` for the automatic detection of proper archive\n"
"program to extract (unarchive) inbound EchoMail bundle files."
;
uifc.input(WIN_MID|WIN_SAV,0,0
,"Archive Signature"
,cfg.arcdef[i].hexid,sizeof(cfg.arcdef[i].hexid)-1
,K_EDIT|K_UPPER);
break;
case 2:
"~ Archive Signature Offset ~\n\n"
"This is the byte-offset of the identifying signature of the archive file\n"
"format. This offset is used in combination with the Archive `Signature`\n"
"for the automatic detection of proper archive program to extract\n"
sprintf(str,"%u",cfg.arcdef[i].byteloc);
if(uifc.input(WIN_MID|WIN_SAV,0,0
,"Archive Signature Offset",str,5
,K_NUMBER|K_EDIT) > 0)
cfg.arcdef[i].byteloc=atoi(str);
"~ Pack Command Line ~\n\n"
"This is the command-line to execute to create an archive file of the\n"
"selected type. The following command-line specifiers may be used for\n"
"dynamic variable replacement:\n"
"\n"
" `%f` The path/filename of the archive file to be created\n"
" `%s` The path/filename of the file(s) to be added to the archive\n"
" `%!` The Synchronet `exec` directory\n"
" `%@` The Synchronet `exec` directory only for non-Unix systems\n"
" `%.` Blank for Unix systems, '`.exe`' otherwise\n"
" `%?` The current platform description (e.g. 'linux', 'win32')\n"
" `%j` The Synchronet `data` directory\n"
" `%k` The Synchronet `ctrl` directory\n"
" `%o` The configured system operator name\n"
" `%q` The configured system QWK-ID\n"
" `%g` The configured temporary file directory\n"
uifc.input(WIN_MID|WIN_SAV,0,0
,"Pack Command Line"
,cfg.arcdef[i].pack,sizeof(cfg.arcdef[i].pack)-1
,K_EDIT);
break;
case 4:
"~ Unpack Command Line ~\n\n"
"This is the command-line to execute to extract an archive file of the\n"
"selected type. The following command-line specifiers may be used for\n"
"dynamic variable replacement:\n"
"\n"
" `%f` The path/filename of the archive file to be extracted\n"
" `%s` The destination directory for files extracted from the archive\n"
" `%!` The Synchronet `exec` directory\n"
" `%@` The Synchronet `exec` directory only for non-Unix systems\n"
" `%.` Blank for Unix systems, '`.exe`' otherwise\n"
" `%?` The current platform description (e.g. 'linux', 'win32')\n"
" `%j` The Synchronet `data` directory\n"
" `%k` The Synchronet `ctrl` directory\n"
" `%o` The configured system operator name\n"
" `%q` The configured system QWK-ID\n"
" `%g` The configured temporary file directory\n"
uifc.input(WIN_MID|WIN_SAV,0,0
,"Unpack Command Line"
,cfg.arcdef[i].unpack,sizeof(cfg.arcdef[i].unpack)-1
}
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
uifc.helpbuf=
"~ Robots ~\n\n"
"The `Robots` sub-menu is where NetMail Robots are configured.\n"
"\n"
"When a NetMail message is received addressed to one of the configured\n"
"Robot `Names`, it will be stored in the `mail` message base and the\n"
"associated `Semaphore File` (if non-blank) will be touched.\n"
"\n"
"If the NetMail message has the `In-Transit` attribute flag set, it\n"
"will not be exported by SBBSecho back into a stored message (*.msg)\n"
"file. Therefore, it is recommended to include the In-Transit attribute\n"
"flag (0x20) in the Robot's `Attributes` value if the Robot (e.g. script)\n"
"is going to expect the message to be in the mail base.\n"
;
i=0;
while(1) {
for(u=0; u < cfg.robot_count; u++)
snprintf(opt[u], MAX_OPLN-1, "%-*s %s"
,FIDO_DOMAIN_LEN, cfg.robot_list[u].name, cfg.robot_list[u].semfile);
opt[u][0]=0;
int mode = WIN_SAV | WIN_INS | WIN_DEL | WIN_ACT
| WIN_INSACT | WIN_DELACT | WIN_XTR;
if(cfg.robot_count)
mode |= WIN_COPY | WIN_CUT;
if(saverobot.name[0])
mode |= WIN_PASTE | WIN_PASTEXTR;
i=uifc.list(mode,0,0,0,&robot_opt,&robot_bar,"Robots",opt);
if(i==-1)
break;
int msk = i&MSK_ON;
i &= MSK_OFF;
if (msk == MSK_INS) {
str[0]=0;
if(uifc.input(WIN_MID|WIN_SAV,0,0
,"NetMail Robot Name", str, FIDO_DOMAIN_LEN, K_EDIT)<1)
continue;
if(!new_robot(i)) {
printf("\nMemory Allocation Error\n");
exit(1);
}
SAFECOPY(cfg.robot_list[i].name, str);
continue;
}
if (msk == MSK_DEL || msk == MSK_CUT) {
if(msk == MSK_CUT)
memcpy(&saverobot, &cfg.robot_list[i], sizeof(saverobot));
cfg.robot_count--;
if(cfg.robot_count <= 0) {
cfg.robot_count = 0;
continue;
}
for(u=i; u < cfg.robot_count; u++)
memcpy(&cfg.robot_list[u], &cfg.robot_list[u+1], sizeof(struct robot));
continue;
}
if (msk == MSK_COPY) {
memcpy(&saverobot, &cfg.robot_list[i], sizeof(saverobot));
continue;
}
if (msk == MSK_PASTE) {
if(!new_robot(i))
continue;
memcpy(&cfg.robot_list[i], &saverobot, sizeof(saverobot));
continue;
}
if (msk != 0)
continue;
while(1) {
j=0;
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","Name"
,cfg.robot_list[i].name);
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","Semaphore File"
,cfg.robot_list[i].semfile);
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s 0x%04hX","Attributes"
,cfg.robot_list[i].attr);
opt[j][0]=0;
SAFEPRINTF(str, "Robot - %s", cfg.robot_list[i].name);
k=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,0,0,0,&listop,0,str,opt);
if(k==-1)
break;
switch(k) {
case 0:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Robot Name"
,cfg.robot_list[i].name,sizeof(cfg.robot_list[i].name)-1
,K_EDIT);
break;
case 1:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Semaphore Path/Filename"
,cfg.robot_list[i].semfile,sizeof(cfg.robot_list[i].semfile)-1
,K_EDIT);
break;
case 2:
sprintf(str, "%04hX", cfg.robot_list[i].attr);
if(uifc.input(WIN_MID|WIN_SAV,0,0
,"NetMail Attributes (in hexadecimal)"
,str, sizeof(str), K_EDIT) > 0)
cfg.robot_list[i].attr = (uint16_t)strtoul(str, NULL, 16);
break;
}
}
}
break;
uifc.helpbuf=
"~ Domains ~\n\n"
"The `Domains` sub-menu is where FidoNet-style domains (the '@domain'\n"
"of 5D FTN address) are mapped to zone numbers, DNS suffixes, NodeLists\n"
"and BSO root directories for use by the BinkIT mailer.\n"
;
i=0;
while(1) {
for(u=0; u < cfg.domain_count; u++)
snprintf(opt[u], MAX_OPLN-1, "%-*s %s"
,FIDO_DOMAIN_LEN, cfg.domain_list[u].name, cfg.domain_list[u].dns_suffix);
opt[u][0]=0;
int mode = WIN_SAV | WIN_INS | WIN_DEL | WIN_ACT
| WIN_INSACT | WIN_DELACT | WIN_XTR;
if(cfg.domain_count)
mode |= WIN_COPY | WIN_CUT;
if(savedomain.name[0])
mode |= WIN_PASTE | WIN_PASTEXTR;
i=uifc.list(mode,0,0,0,&domain_opt,&domain_bar,"Domains",opt);
if(i==-1)
break;
int msk = i&MSK_ON;
i &= MSK_OFF;
if (msk == MSK_INS) {
str[0]=0;
if(uifc.input(WIN_MID|WIN_SAV,0,0
,"FTN Domain Name", str, FIDO_DOMAIN_LEN, K_EDIT)<1)
continue;
if(!new_domain(i)) {
printf("\nMemory Allocation Error\n");
}
SAFECOPY(cfg.domain_list[i].name, str);
}
if (msk == MSK_DEL || msk == MSK_CUT) {
if(msk == MSK_CUT)
memcpy(&savedomain, &cfg.domain_list[i], sizeof(savedomain));
cfg.domain_count--;
if(cfg.domain_count <= 0) {
cfg.domain_count = 0;
}
for(u=i; u < cfg.domain_count; u++)
memcpy(&cfg.domain_list[u], &cfg.domain_list[u+1], sizeof(struct fido_domain));
}
if (msk == MSK_COPY) {
memcpy(&savedomain, &cfg.domain_list[i], sizeof(savedomain));
}
if (msk == MSK_PASTE) {
if(!new_domain(i))
continue;
memcpy(&cfg.domain_list[i], &savedomain, sizeof(savedomain));
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
}
if (msk != 0)
continue;
while(1) {
j=0;
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","Name"
,cfg.domain_list[i].name);
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","Zones"
,int_list(cfg.domain_list[i].zone_list, cfg.domain_list[i].zone_count));
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","DNS Suffix"
,cfg.domain_list[i].dns_suffix);
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","Outbound Root"
,cfg.domain_list[i].root);
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","NodeList"
,cfg.domain_list[i].nodelist);
opt[j][0]=0;
SAFEPRINTF(str, "Domain - %s", cfg.domain_list[i].name);
k=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,0,0,0,&listop,0,str,opt);
if(k==-1)
break;
switch(k) {
case 0:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Domain Name"
,cfg.domain_list[i].name,sizeof(cfg.domain_list[i].name)-1
,K_EDIT);
break;
case 1:
SAFECOPY(str, int_list(cfg.domain_list[i].zone_list, cfg.domain_list[i].zone_count));
if(uifc.input(WIN_MID|WIN_SAV, 0, 0
,"Zone List (comma-separated)"
,str, 40, K_EDIT) >= 0) {
FREE_AND_NULL(cfg.domain_list[i].zone_list);
cfg.domain_list[i].zone_list = parseIntList(str, ",", &cfg.domain_list[i].zone_count);
uifc.changes = TRUE;
}
break;
case 2:
uifc.input(WIN_MID|WIN_SAV,0,0
,"DNS Suffix"
,cfg.domain_list[i].dns_suffix,sizeof(cfg.domain_list[i].dns_suffix)-1
,K_EDIT);
break;
case 3:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Outbound Root Directory"
,cfg.domain_list[i].root,sizeof(cfg.domain_list[i].root)-1
,K_EDIT);
break;
case 4:
uifc.input(WIN_MID|WIN_SAV,0,0
,"NodeList"
,cfg.domain_list[i].nodelist,sizeof(cfg.domain_list[i].nodelist)-1
,K_EDIT);
break;
}
break;
while(1) {
uifc.helpbuf=
"~ EchoLists ~\n\n"
"This feature allows you to specify lists of echoes, in `BACKBONE.NA`\n"
"format, which are utilized in `addition` to your Area File (e.g. \n"
"`areas.bbs`) for advanced AreaFix (Area Management) operations.\n";
for(u=0;u<cfg.listcfgs;u++)
int mode = WIN_SAV | WIN_INS | WIN_DEL | WIN_ACT
| WIN_INSACT | WIN_DELACT | WIN_XTR;
if(cfg.listcfgs)
mode |= WIN_COPY | WIN_CUT;
if(savlistcfg.listpath[0])
mode |= WIN_PASTE | WIN_PASTEXTR;
i=uifc.list(mode,0,0,0,&echolist_opt,&echolist_bar,"EchoLists",opt);
break;
int msk = i&MSK_ON;
i &= MSK_OFF;
if (msk == MSK_INS) {
str[0]=0;
uifc.helpbuf=
"~ EchoList ~\n\n"
"This is the path and filename of the echolist file you wish\n"
"to add.\n";
if(uifc.input(WIN_MID|WIN_SAV,0,0
if(!new_list(i)) {
printf("\nMemory Allocation Error\n");
}
SAFECOPY(cfg.listcfg[i].listpath,str);
}
if (msk == MSK_DEL || msk == MSK_CUT) {
if(msk == MSK_CUT)
memcpy(&savlistcfg, &cfg.listcfg[i], sizeof(echolist_t));
cfg.listcfgs--;
if(cfg.listcfgs<=0) {
cfg.listcfgs=0;
}
for(u=i;u<cfg.listcfgs;u++)
memcpy(&cfg.listcfg[u],&cfg.listcfg[u+1]
}
if (msk == MSK_COPY) {
memcpy(&savlistcfg,&cfg.listcfg[i],sizeof(echolist_t));
}
if (msk == MSK_PASTE) {
if(!new_list(i))
continue;
memcpy(&cfg.listcfg[i],&savlistcfg,sizeof(echolist_t));
}
if (msk != 0)
continue;
"~ Configuring an EchoList ~\n\n"
"The `EchoList Path/Name`, `Required Key` and `Hub Address` must be configured\n"
"correctly and any one of the Required Keys added to the `EchoList Keys`\n"
"of the `Linked Nodes` of interest.\n"
"\n"
"The other settings are only for forwarding received Area Manager\n"
"requests 'upstream' (to your hub) when needed.\n"
;
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","EchoList Path/Name"
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","Required Key"
,strListCombine(cfg.listcfg[i].keys, str, sizeof(str), ","));
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","Hub Address"
,(cfg.listcfg[i].hub.zone) ?
faddrtoa(&cfg.listcfg[i].hub) : "None");
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","Forward AreaMgr Requests"
if(cfg.listcfg[i].forward) {
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","AreaMgr Name"
,cfg.listcfg[i].areamgr);
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","AreaMgr Password"
,cfg.listcfg[i].password);
}
SAFEPRINTF(str, "EchoList - %s", getfname(cfg.listcfg[i].listpath));
k=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,0,0,0,&listop,0,str,opt);
break;
uifc.input(WIN_MID|WIN_SAV,0,0
,"EchoList Path/Name"
,cfg.listcfg[i].listpath,sizeof(cfg.listcfg[i].listpath)-1
,K_EDIT);
"~ Required Key ~\n\n"
"These keys determine which linked nodes have access to the selected\n"
"echolist file via AreaFix requests (e.g. query, add, remove).\n"
"\n"
"A linked node need only have one of the required keys to have access\n"
"the echolist."
;
for(u=0; cfg.listcfg[i].keys!=NULL && cfg.listcfg[i].keys[u] != NULL;u++)
strcpy(opt[u],cfg.listcfg[i].keys[u]);
x=uifc.list(WIN_SAV|WIN_INS|WIN_DEL|WIN_ACT|
WIN_XTR|WIN_INSACT|WIN_DELACT|WIN_RHT
if(x==-1)
break;
if((x&MSK_ON)==MSK_INS) {
x&=MSK_OFF;
str[0]=0;
if(uifc.input(WIN_MID|WIN_SAV,0,0
,K_EDIT|K_UPPER)<1)
continue;
}
if((x&MSK_ON)==MSK_DEL) {
x&=MSK_OFF;
}
,str,SBBSECHO_MAX_KEY_LEN,K_EDIT|K_UPPER);
strListReplace(cfg.listcfg[i].keys,x,str);
}
SAFECOPY(str,faddrtoa(&cfg.listcfg[i].hub));
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
else
str[0]=0;
uifc.input(WIN_MID|WIN_SAV,0,0
,"Hub Address",str
,25,K_EDIT);
if(str[0])
cfg.listcfg[i].hub=atofaddr(str);
else
memset(&cfg.listcfg[i].hub,0
,sizeof(faddr_t));
break;
case 3:
cfg.listcfg[i].forward = !cfg.listcfg[i].forward;
break;
case 4:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Name to use when forwarding AreaMgr requests"
,cfg.listcfg[i].areamgr,sizeof(cfg.listcfg[i].areamgr)-1
,K_EDIT);
break;
case 5:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Password to use when forwarding AreaMgr requests"
,cfg.listcfg[i].password,sizeof(cfg.listcfg[i].password)-1
,K_EDIT|K_UPPER);
break;
}
uifc.pop("Writing config ...");
bool success = sbbsecho_write_ini(&cfg);
uifc.pop(NULL);
if(!success)
uifc.msg("Error saving configuration file");
else {
orig_cfg = cfg;
uifc.changes = FALSE;
}
if(cfg.used_include) {
if(uifc.msg("Changes made will not be saved"))
break;
} else {
uifc.helpbuf=
"~ Save Configuration File ~\n\n"
"Select `Yes` to save the config file, `No` to quit without saving,\n"
"or hit ~ ESC ~ to go back to the menu.\n\n";
i=0;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0,"Save Config File",uifcYesNoOpts);
if(i==-1) break;
if(i == 0) {
uifc.pop("Writing config ...");
bool success = sbbsecho_write_ini(&cfg);
uifc.pop(NULL);
if(!success)
uifc.msg("Error saving configuration file");
}
}
uifc.pop("Exiting");
break;