|
|
1.1.1.2 ! root 1: /* scfgxtrn.c */ ! 2: ! 3: /* $Id: scfgxtrn.c,v 1.45 2011/08/26 22:47:30 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 2011 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: /* Synchronet configuration utility */ ! 37: /****************************************************************************/ ! 38: ! 39: #include "scfg.h" ! 40: ! 41: char *daystr(char days); ! 42: static void hotkey_cfg(void); ! 43: ! 44: static char* monthstr(uint16_t months) ! 45: { ! 46: int i; ! 47: static char str[256]; ! 48: ! 49: if(months==0) ! 50: return("Any"); ! 51: ! 52: str[0]=0; ! 53: for(i=0;i<12;i++) { ! 54: if((months&(1<<i))==0) ! 55: continue; ! 56: if(str[0]) ! 57: strcat(str," "); ! 58: strcat(str,mon[i]); ! 59: } ! 60: ! 61: return(str); ! 62: } ! 63: ! 64: static char* mdaystr(long mdays) ! 65: { ! 66: int i; ! 67: char tmp[16]; ! 68: static char str[256]; ! 69: ! 70: if(mdays==0 || mdays==1) ! 71: return("Any"); ! 72: ! 73: str[0]=0; ! 74: for(i=1;i<32;i++) { ! 75: if((mdays&(1<<i))==0) ! 76: continue; ! 77: if(str[0]) ! 78: strcat(str," "); ! 79: sprintf(tmp,"%u",i); ! 80: strcat(str,tmp); ! 81: } ! 82: ! 83: return(str); ! 84: } ! 85: ! 86: static char* dropfile(int type, ulong misc) ! 87: { ! 88: static char str[128]; ! 89: char fname[64]=""; ! 90: ! 91: switch(type) { ! 92: case XTRN_SBBS: ! 93: strcpy(fname,"XTRN.DAT"); ! 94: break; ! 95: case XTRN_WWIV: ! 96: strcpy(fname,"CHAIN.TXT"); ! 97: break; ! 98: case XTRN_GAP: ! 99: strcpy(fname,"DOOR.SYS"); ! 100: break; ! 101: case XTRN_RBBS: ! 102: strcpy(fname,"DORINFO#.DEF"); ! 103: break; ! 104: case XTRN_RBBS1: ! 105: strcpy(fname,"DORINFO1.DEF"); ! 106: break; ! 107: case XTRN_WILDCAT: ! 108: strcpy(fname,"CALLINFO.BBS"); ! 109: break; ! 110: case XTRN_PCBOARD: ! 111: strcpy(fname,"PCBOARD.SYS"); ! 112: break; ! 113: case XTRN_SPITFIRE: ! 114: strcpy(fname,"SFDOORS.DAT"); ! 115: break; ! 116: case XTRN_UTI: ! 117: strcpy(fname,"UTIDOOR.TXT"); ! 118: break; ! 119: case XTRN_SR: ! 120: strcpy(fname,"DOORFILE.SR"); ! 121: break; ! 122: case XTRN_TRIBBS: ! 123: strcpy(fname,"TRIBBS.SYS"); ! 124: break; ! 125: case XTRN_DOOR32: ! 126: strcpy(fname,"DOOR32.SYS"); ! 127: break; ! 128: } ! 129: ! 130: if(misc&XTRN_LWRCASE) ! 131: strlwr(fname); ! 132: ! 133: switch(type) { ! 134: case XTRN_SBBS: ! 135: sprintf(str,"%-15s %s","Synchronet",fname); ! 136: break; ! 137: case XTRN_WWIV: ! 138: sprintf(str,"%-15s %s","WWIV",fname); ! 139: break; ! 140: case XTRN_GAP: ! 141: sprintf(str,"%-15s %s","GAP",fname); ! 142: break; ! 143: case XTRN_RBBS: ! 144: sprintf(str,"%-15s %s","RBBS/QuickBBS",fname); ! 145: break; ! 146: case XTRN_RBBS1: ! 147: sprintf(str,"%-15s %s","RBBS/QuickBBS",fname); ! 148: break; ! 149: case XTRN_WILDCAT: ! 150: sprintf(str,"%-15s %s","Wildcat",fname); ! 151: break; ! 152: case XTRN_PCBOARD: ! 153: sprintf(str,"%-15s %s","PCBoard",fname); ! 154: break; ! 155: case XTRN_SPITFIRE: ! 156: sprintf(str,"%-15s %s","SpitFire",fname); ! 157: break; ! 158: case XTRN_UTI: ! 159: sprintf(str,"%-15s %s","MegaMail",fname); ! 160: break; ! 161: case XTRN_SR: ! 162: sprintf(str,"%-15s %s","Solar Realms",fname); ! 163: break; ! 164: case XTRN_TRIBBS: ! 165: sprintf(str,"%-15s %s","TriBBS",fname); ! 166: break; ! 167: case XTRN_DOOR32: ! 168: sprintf(str,"%-15s %s","Mystic",fname); ! 169: break; ! 170: default: ! 171: strcpy(str,"None"); ! 172: break; ! 173: } ! 174: return(str); ! 175: } ! 176: ! 177: void xprogs_cfg() ! 178: { ! 179: static int xprogs_dflt; ! 180: int i; ! 181: ! 182: while(1) { ! 183: i=0; ! 184: strcpy(opt[i++],"Fixed Events"); ! 185: strcpy(opt[i++],"Timed Events"); ! 186: strcpy(opt[i++],"Native Program List"); ! 187: strcpy(opt[i++],"External Editors"); ! 188: strcpy(opt[i++],"Global Hot Key Events"); ! 189: strcpy(opt[i++],"Online Programs (Doors)"); ! 190: opt[i][0]=0; ! 191: SETHELP(WHERE); ! 192: /* ! 193: `Online External Programs:` ! 194: ! 195: From this menu, you can configure external events, external editors, or ! 196: online external programs (doors). ! 197: */ ! 198: switch(uifc.list(WIN_ORG|WIN_CHE|WIN_ACT,0,0,0,&xprogs_dflt,0 ! 199: ,"External Programs",opt)) { ! 200: case -1: ! 201: i=save_changes(WIN_MID); ! 202: if(i==-1) ! 203: break; ! 204: if(!i) { ! 205: cfg.new_install=new_install; ! 206: write_xtrn_cfg(&cfg,backup_level); ! 207: write_main_cfg(&cfg,backup_level); ! 208: refresh_cfg(&cfg); ! 209: } ! 210: return; ! 211: case 0: ! 212: fevents_cfg(); ! 213: break; ! 214: case 1: ! 215: tevents_cfg(); ! 216: break; ! 217: case 2: ! 218: natvpgm_cfg(); ! 219: break; ! 220: case 3: ! 221: xedit_cfg(); ! 222: break; ! 223: case 4: ! 224: hotkey_cfg(); ! 225: break; ! 226: case 5: ! 227: xtrnsec_cfg(); ! 228: break; ! 229: } ! 230: } ! 231: } ! 232: ! 233: void fevents_cfg() ! 234: { ! 235: static int event_dflt; ! 236: int i; ! 237: ! 238: while(1) { ! 239: i=0; ! 240: sprintf(opt[i++],"%-32.32s%.40s","Logon Event",cfg.sys_logon); ! 241: sprintf(opt[i++],"%-32.32s%.40s","Logout Event",cfg.sys_logout); ! 242: sprintf(opt[i++],"%-32.32s%.40s","Daily Event",cfg.sys_daily); ! 243: opt[i][0]=0; ! 244: SETHELP(WHERE); ! 245: /* ! 246: `External Events:` ! 247: ! 248: From this menu, you can configure the logon and logout events, and the ! 249: system daily event. ! 250: */ ! 251: switch(uifc.list(WIN_ACT|WIN_SAV|WIN_CHE|WIN_BOT|WIN_RHT,0,0,60,&event_dflt,0 ! 252: ,"Fixed Events",opt)) { ! 253: case -1: ! 254: return; ! 255: case 0: ! 256: SETHELP(WHERE); ! 257: /* ! 258: `Logon Event:` ! 259: ! 260: This is the command line for a program that will execute during the ! 261: logon sequence of every user. The program cannot have user interaction. ! 262: The program will be executed after the LOGON message is displayed and ! 263: before the logon user list is displayed. If you wish to place a program ! 264: in the logon sequence of users that includes interaction or requires ! 265: account information, you probably want to use an online external ! 266: program configured to run as a logon event. ! 267: */ ! 268: uifc.input(WIN_MID|WIN_SAV,0,0,"Logon Event" ! 269: ,cfg.sys_logon,sizeof(cfg.sys_logon)-1,K_EDIT); ! 270: break; ! 271: case 1: ! 272: SETHELP(WHERE); ! 273: /* ! 274: `Logout Event:` ! 275: ! 276: This is the command line for a program that will execute during the ! 277: logout sequence of every user. This program cannot have user ! 278: interaction because it is executed after carrier is dropped. If you ! 279: wish to have a program execute before carrier is dropped, you probably ! 280: want to use an `Online External Program` configured to run as a logoff ! 281: event. ! 282: */ ! 283: uifc.input(WIN_MID|WIN_SAV,0,0,"Logout Event" ! 284: ,cfg.sys_logout,sizeof(cfg.sys_logout)-1,K_EDIT); ! 285: break; ! 286: case 2: ! 287: SETHELP(WHERE); ! 288: /* ! 289: `Daily Event:` ! 290: ! 291: This is the command line for a program that will run after the first ! 292: user that logs on after midnight, logs off (regardless of what node). ! 293: */ ! 294: uifc.input(WIN_MID|WIN_SAV,0,0,"Daily Event" ! 295: ,cfg.sys_daily,sizeof(cfg.sys_daily)-1,K_EDIT); ! 296: ! 297: break; ! 298: } ! 299: } ! 300: } ! 301: ! 302: void tevents_cfg() ! 303: { ! 304: static int dflt,dfltopt,bar; ! 305: char str[81],done=0,*p; ! 306: int j,k; ! 307: uint i; ! 308: static event_t savevent; ! 309: ! 310: while(1) { ! 311: for(i=0;i<cfg.total_events && i<MAX_OPTS;i++) ! 312: sprintf(opt[i],"%-8.8s %.50s",cfg.event[i]->code,cfg.event[i]->cmd); ! 313: opt[i][0]=0; ! 314: j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_RHT; ! 315: if(cfg.total_events) ! 316: j|=WIN_DEL|WIN_GET; ! 317: if(cfg.total_events<MAX_OPTS) ! 318: j|=WIN_INS|WIN_INSACT|WIN_XTR; ! 319: if(savevent.code[0]) ! 320: j|=WIN_PUT; ! 321: SETHELP(WHERE); ! 322: /* ! 323: `Timed Events:` ! 324: ! 325: This is a list of the configured timed external events. ! 326: ! 327: To add an event hit ~ INS ~. ! 328: ! 329: To delete an event, select it and hit ~ DEL ~. ! 330: ! 331: To configure an event, select it and hit ~ ENTER ~. ! 332: */ ! 333: i=uifc.list(j,0,0,45,&dflt,&bar,"Timed Events",opt); ! 334: if((signed)i==-1) ! 335: return; ! 336: if((i&MSK_ON)==MSK_INS) { ! 337: i=cfg.total_events; ! 338: SETHELP(WHERE); ! 339: /* ! 340: `Timed Event Internal Code:` ! 341: ! 342: This is the internal code for the timed event. ! 343: */ ! 344: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Event Internal Code",str,LEN_CODE ! 345: ,K_UPPER)<1) ! 346: continue; ! 347: if((cfg.event=(event_t **)realloc(cfg.event ! 348: ,sizeof(event_t *)*(cfg.total_events+1)))==NULL) { ! 349: errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_events+1); ! 350: cfg.total_events=0; ! 351: bail(1); ! 352: continue; ! 353: } ! 354: if((cfg.event[i]=(event_t *)malloc(sizeof(event_t)))==NULL) { ! 355: errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(event_t)); ! 356: continue; ! 357: } ! 358: memset((event_t *)cfg.event[i],0,sizeof(event_t)); ! 359: strcpy(cfg.event[i]->code,str); ! 360: cfg.event[i]->node=1; ! 361: cfg.event[i]->days=(uchar)0xff; ! 362: cfg.total_events++; ! 363: uifc.changes=1; ! 364: continue; ! 365: } ! 366: if((i&MSK_ON)==MSK_DEL) { ! 367: i&=MSK_OFF; ! 368: free(cfg.event[i]); ! 369: cfg.total_events--; ! 370: for(j=i;j<cfg.total_events;j++) ! 371: cfg.event[j]=cfg.event[j+1]; ! 372: uifc.changes=1; ! 373: continue; ! 374: } ! 375: if((i&MSK_ON)==MSK_GET) { ! 376: i&=MSK_OFF; ! 377: savevent=*cfg.event[i]; ! 378: continue; ! 379: } ! 380: if((i&MSK_ON)==MSK_PUT) { ! 381: i&=MSK_OFF; ! 382: *cfg.event[i]=savevent; ! 383: uifc.changes=1; ! 384: continue; ! 385: } ! 386: done=0; ! 387: while(!done) { ! 388: k=0; ! 389: sprintf(opt[k++],"%-32.32s%s","Internal Code",cfg.event[i]->code); ! 390: sprintf(opt[k++],"%-32.32s%.40s","Start-up Directory",cfg.event[i]->dir); ! 391: sprintf(opt[k++],"%-32.32s%.40s","Command Line",cfg.event[i]->cmd); ! 392: sprintf(opt[k++],"%-32.32s%s","Enabled" ! 393: ,cfg.event[i]->misc&EVENT_DISABLED ? "No":"Yes"); ! 394: sprintf(opt[k++],"%-32.32s%u","Execution Node",cfg.event[i]->node); ! 395: sprintf(opt[k++],"%-32.32s%s","Execution Months" ! 396: ,monthstr(cfg.event[i]->months)); ! 397: sprintf(opt[k++],"%-32.32s%s","Execution Days of Month" ! 398: ,mdaystr(cfg.event[i]->mdays)); ! 399: sprintf(opt[k++],"%-32.32s%s","Execution Days of Week",daystr(cfg.event[i]->days)); ! 400: if(cfg.event[i]->freq) { ! 401: sprintf(str,"%u times a day",1440/cfg.event[i]->freq); ! 402: sprintf(opt[k++],"%-32.32s%s","Execution Frequency",str); ! 403: } else { ! 404: sprintf(str,"%2.2u:%2.2u" ! 405: ,cfg.event[i]->time/60,cfg.event[i]->time%60); ! 406: sprintf(opt[k++],"%-32.32s%s","Execution Time",str); ! 407: } ! 408: sprintf(opt[k++],"%-32.32s%s","Requires Exclusive Execution" ! 409: ,cfg.event[i]->misc&EVENT_EXCL ? "Yes":"No"); ! 410: sprintf(opt[k++],"%-32.32s%s","Force Users Off-line For Event" ! 411: ,cfg.event[i]->misc&EVENT_FORCE ? "Yes":"No"); ! 412: sprintf(opt[k++],"%-32.32s%s","Native Executable" ! 413: ,cfg.event[i]->misc&EX_NATIVE ? "Yes" : "No"); ! 414: sprintf(opt[k++],"%-32.32s%s","Use Shell to Execute" ! 415: ,cfg.event[i]->misc&XTRN_SH ? "Yes" : "No"); ! 416: sprintf(opt[k++],"%-32.32s%s","Background Execution" ! 417: ,cfg.event[i]->misc&EX_BG ? "Yes" : "No"); ! 418: sprintf(opt[k++],"%-32.32s%s","Always Run After Init/Re-init" ! 419: ,cfg.event[i]->misc&EVENT_INIT ? "Yes":"No"); ! 420: ! 421: opt[k][0]=0; ! 422: SETHELP(WHERE); ! 423: /* ! 424: `Timed Event:` ! 425: ! 426: This is the configuration menu for a timed event. An event is an ! 427: external program that performs some type of automated function on the ! 428: system. Use this menu to configure how and when this event will be ! 429: executed. ! 430: ! 431: If you need the BBS to swap out of memory for this event (to make more ! 432: available memory), add the program name (first word of the command line) ! 433: to `Global Swap List` from the `External Programs` menu. ! 434: */ ! 435: sprintf(str,"%s Timed Event",cfg.event[i]->code); ! 436: switch(uifc.list(WIN_SAV|WIN_ACT|WIN_L2R|WIN_BOT,0,0,70,&dfltopt,0 ! 437: ,str,opt)) { ! 438: case -1: ! 439: done=1; ! 440: break; ! 441: case 0: ! 442: strcpy(str,cfg.event[i]->code); ! 443: SETHELP(WHERE); ! 444: /* ! 445: `Timed Event Internal Code:` ! 446: ! 447: Every timed event must have its own unique internal code for Synchronet ! 448: to reference it by. It is helpful if this code is an abreviation of the ! 449: command line. ! 450: */ ! 451: uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code (unique)" ! 452: ,str,LEN_CODE,K_EDIT|K_UPPER); ! 453: if(code_ok(str)) ! 454: strcpy(cfg.event[i]->code,str); ! 455: else { ! 456: uifc.helpbuf=invalid_code; ! 457: uifc.msg("Invalid Code"); ! 458: uifc.helpbuf=0; ! 459: } ! 460: break; ! 461: case 1: ! 462: SETHELP(WHERE); ! 463: /* ! 464: `Timed Event Start-up Directory:` ! 465: ! 466: This is the DOS drive/directory where the event program is located. ! 467: If a path is specified here, it will be made the current directory ! 468: before the event's command line is executed. This eliminates the need ! 469: for batch files that just change the current drive and directory before ! 470: executing the event. ! 471: ! 472: If this option is not used, the current NODE's directory will be the ! 473: current DOS drive/directory before the command line is executed. ! 474: */ ! 475: uifc.input(WIN_MID|WIN_SAV,0,10,"Directory" ! 476: ,cfg.event[i]->dir,sizeof(cfg.event[i]->dir)-1,K_EDIT); ! 477: break; ! 478: case 2: ! 479: SETHELP(WHERE); ! 480: /* ! 481: `Timed Event Command Line:` ! 482: ! 483: This is the command line to execute upon this timed event. ! 484: */ ! 485: uifc.input(WIN_MID|WIN_SAV,0,10,"Command" ! 486: ,cfg.event[i]->cmd,sizeof(cfg.event[i]->cmd)-1,K_EDIT); ! 487: break; ! 488: ! 489: case 3: ! 490: k=(cfg.event[i]->misc&EVENT_DISABLED) ? 1:0; ! 491: SETHELP(WHERE); ! 492: /* ! 493: `Event Enabled:` ! 494: ! 495: If you want disable this event from executing, set this option to ~No~. ! 496: */ ! 497: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 498: ,"Enabled",uifcYesNoOpts); ! 499: if((k==0 && cfg.event[i]->misc&EVENT_DISABLED) ! 500: || (k==1 && !(cfg.event[i]->misc&EVENT_DISABLED))) { ! 501: cfg.event[i]->misc^=EVENT_DISABLED; ! 502: uifc.changes=1; ! 503: } ! 504: break; ! 505: ! 506: case 4: ! 507: SETHELP(WHERE); ! 508: /* ! 509: `Timed Event Node:` ! 510: ! 511: This is the node number to execute the timed event. ! 512: */ ! 513: sprintf(str,"%u",cfg.event[i]->node); ! 514: uifc.input(WIN_MID|WIN_SAV,0,0,"Node Number" ! 515: ,str,3,K_EDIT|K_NUMBER); ! 516: cfg.event[i]->node=atoi(str); ! 517: break; ! 518: case 5: ! 519: SETHELP(WHERE); ! 520: /* ! 521: `Months to Execute Event:` ! 522: ! 523: Specifies the months (`Jan`-`Dec`, separated by spaces) on which ! 524: to execute this event, or `Any` to execute event for any/all months. ! 525: */ ! 526: SAFECOPY(str,monthstr(cfg.event[i]->months)); ! 527: uifc.input(WIN_MID|WIN_SAV,0,0,"Months to Execute Event (or Any)" ! 528: ,str,50,K_EDIT); ! 529: cfg.event[i]->months=0; ! 530: for(p=str;*p;p++) { ! 531: if(atoi(p)) { ! 532: cfg.event[i]->months|=(1<<(atoi(p)-1)); ! 533: while(*p && isdigit(*p)) ! 534: p++; ! 535: } else { ! 536: for(j=0;j<12;j++) ! 537: if(strnicmp(mon[j],p,3)==0) { ! 538: cfg.event[i]->months|=(1<<j); ! 539: p+=2; ! 540: break; ! 541: } ! 542: p++; ! 543: } ! 544: } ! 545: break; ! 546: case 6: ! 547: SETHELP(WHERE); ! 548: /* ! 549: `Days of Month to Execute Event:` ! 550: ! 551: Specifies the days of the month (`1-31`, separated by spaces) on which ! 552: to execute this event, or `Any` to execute event on any and all days of ! 553: the month. ! 554: */ ! 555: SAFECOPY(str,mdaystr(cfg.event[i]->mdays)); ! 556: uifc.input(WIN_MID|WIN_SAV,0,0,"Days of Month to Execute Event (or Any)" ! 557: ,str,16,K_EDIT); ! 558: cfg.event[i]->mdays=0; ! 559: for(p=str;*p;p++) { ! 560: if(!isdigit(*p)) ! 561: continue; ! 562: cfg.event[i]->mdays|=(1<<atoi(p)); ! 563: while(*p && isdigit(*p)) ! 564: p++; ! 565: } ! 566: break; ! 567: case 7: ! 568: j=0; ! 569: while(1) { ! 570: for(k=0;k<7;k++) ! 571: sprintf(opt[k],"%-30s %3s" ! 572: ,wday[k],(cfg.event[i]->days&(1<<k)) ? "Yes":"No"); ! 573: strcpy(opt[k++],"All"); ! 574: strcpy(opt[k++],"None"); ! 575: opt[k][0]=0; ! 576: SETHELP(WHERE); ! 577: /* ! 578: `Days of Week to Execute Event:` ! 579: ! 580: These are the days of the week that this event will be executed. ! 581: */ ! 582: k=uifc.list(WIN_MID|WIN_SAV|WIN_ACT,0,0,0,&j,0 ! 583: ,"Days of Week to Execute Event",opt); ! 584: if(k==-1) ! 585: break; ! 586: if(k==7) ! 587: cfg.event[i]->days=(uchar)0xff; ! 588: else if(k==8) ! 589: cfg.event[i]->days=0; ! 590: else ! 591: cfg.event[i]->days^=(1<<k); ! 592: uifc.changes=1; ! 593: } ! 594: break; ! 595: case 8: ! 596: if(cfg.event[i]->freq==0) ! 597: k=0; ! 598: else ! 599: k=1; ! 600: SETHELP(WHERE); ! 601: /* ! 602: `Execute Event at a Specific Time:` ! 603: ! 604: If you want the system execute this event at a specific time, set ! 605: this option to `Yes`. If you want the system to execute this event more ! 606: than once a day at predetermined intervals, set this option to `No`. ! 607: */ ! 608: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 609: ,"Execute Event at a Specific Time",uifcYesNoOpts); ! 610: if(k==0) { ! 611: sprintf(str,"%2.2u:%2.2u",cfg.event[i]->time/60 ! 612: ,cfg.event[i]->time%60); ! 613: SETHELP(WHERE); ! 614: /* ! 615: `Time to Execute Event:` ! 616: ! 617: This is the time (in 24 hour HH:MM format) to execute the event. ! 618: */ ! 619: if(uifc.input(WIN_MID|WIN_SAV,0,0 ! 620: ,"Time to Execute Event (HH:MM)" ! 621: ,str,5,K_UPPER|K_EDIT)>0) { ! 622: cfg.event[i]->freq=0; ! 623: cfg.event[i]->time=atoi(str)*60; ! 624: if((p=strchr(str,':'))!=NULL) ! 625: cfg.event[i]->time+=atoi(p+1); ! 626: } ! 627: } ! 628: else if(k==1) { ! 629: sprintf(str,"%u" ! 630: ,cfg.event[i]->freq && cfg.event[i]->freq<=1440 ! 631: ? 1440/cfg.event[i]->freq : 0); ! 632: SETHELP(WHERE); ! 633: /* ! 634: `Number of Executions Per Day:` ! 635: ! 636: This is the maximum number of times the system will execute this event ! 637: per day. ! 638: */ ! 639: if(uifc.input(WIN_MID|WIN_SAV,0,0 ! 640: ,"Number of Executions Per Day" ! 641: ,str,4,K_NUMBER|K_EDIT)>0) { ! 642: cfg.event[i]->time=0; ! 643: k=atoi(str); ! 644: if(k && k<=1440) ! 645: cfg.event[i]->freq=1440/k; ! 646: else ! 647: cfg.event[i]->freq=0; ! 648: } ! 649: } ! 650: break; ! 651: case 9: ! 652: k=(cfg.event[i]->misc&EVENT_EXCL) ? 0:1; ! 653: SETHELP(WHERE); ! 654: /* ! 655: `Exclusive Event Execution:` ! 656: ! 657: If this event must be run exclusively (all nodes inactive), set this ! 658: option to `Yes`. ! 659: */ ! 660: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Exclusive Execution" ! 661: ,uifcYesNoOpts); ! 662: if(!k && !(cfg.event[i]->misc&EVENT_EXCL)) { ! 663: cfg.event[i]->misc|=EVENT_EXCL; ! 664: uifc.changes=1; ! 665: } ! 666: else if(k==1 && cfg.event[i]->misc&EVENT_EXCL) { ! 667: cfg.event[i]->misc&=~EVENT_EXCL; ! 668: uifc.changes=1; ! 669: } ! 670: break; ! 671: case 10: ! 672: k=(cfg.event[i]->misc&EVENT_FORCE) ? 0:1; ! 673: SETHELP(WHERE); ! 674: /* ! 675: `Force Users Off-line for Event:` ! 676: ! 677: If you want to have your users' on-line time reduced so the event can ! 678: execute precisely on time, set this option to `Yes`. ! 679: */ ! 680: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 681: ,"Force Users Off-line for Event",uifcYesNoOpts); ! 682: if(!k && !(cfg.event[i]->misc&EVENT_FORCE)) { ! 683: cfg.event[i]->misc|=EVENT_FORCE; ! 684: uifc.changes=1; ! 685: } ! 686: else if(k==1 && (cfg.event[i]->misc&EVENT_FORCE)) { ! 687: cfg.event[i]->misc&=~EVENT_FORCE; ! 688: uifc.changes=1; ! 689: } ! 690: break; ! 691: ! 692: case 11: ! 693: k=(cfg.event[i]->misc&EX_NATIVE) ? 0:1; ! 694: SETHELP(WHERE); ! 695: /* ! 696: `Native Executable:` ! 697: ! 698: If this event program is a native (e.g. non-DOS) executable, ! 699: set this option to `Yes`. ! 700: */ ! 701: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 702: ,"Native",uifcYesNoOpts); ! 703: if(!k && !(cfg.event[i]->misc&EX_NATIVE)) { ! 704: cfg.event[i]->misc|=EX_NATIVE; ! 705: uifc.changes=TRUE; ! 706: } ! 707: else if(k==1 && (cfg.event[i]->misc&EX_NATIVE)) { ! 708: cfg.event[i]->misc&=~EX_NATIVE; ! 709: uifc.changes=TRUE; ! 710: } ! 711: break; ! 712: ! 713: case 12: ! 714: k=(cfg.event[i]->misc&XTRN_SH) ? 0:1; ! 715: SETHELP(WHERE); ! 716: /* ! 717: `Use Shell to Execute Command:` ! 718: ! 719: If this command-line requires the system command shell to execute, (Unix ! 720: shell script or DOS batch file), set this option to ~Yes~. ! 721: */ ! 722: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 723: ,"Use Shell",uifcYesNoOpts); ! 724: if(!k && !(cfg.event[i]->misc&XTRN_SH)) { ! 725: cfg.event[i]->misc|=XTRN_SH; ! 726: uifc.changes=TRUE; ! 727: } ! 728: else if(k==1 && (cfg.event[i]->misc&XTRN_SH)) { ! 729: cfg.event[i]->misc&=~XTRN_SH; ! 730: uifc.changes=TRUE; ! 731: } ! 732: break; ! 733: ! 734: case 13: ! 735: k=(cfg.event[i]->misc&EX_BG) ? 0:1; ! 736: SETHELP(WHERE); ! 737: /* ! 738: `Execute Event in Background (Asynchronously):` ! 739: ! 740: If you would like this event to run simultaneously with other events, ! 741: set this option to `Yes`. Exclusive events will not run in the background. ! 742: */ ! 743: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 744: ,"Background (Asynchronous) Execution",uifcYesNoOpts); ! 745: if(!k && !(cfg.event[i]->misc&EX_BG)) { ! 746: cfg.event[i]->misc|=EX_BG; ! 747: uifc.changes=TRUE; ! 748: } ! 749: else if(k==1 && (cfg.event[i]->misc&EX_BG)) { ! 750: cfg.event[i]->misc&=~EX_BG; ! 751: uifc.changes=TRUE; ! 752: } ! 753: break; ! 754: ! 755: case 14: ! 756: k=(cfg.event[i]->misc&EVENT_INIT) ? 0:1; ! 757: SETHELP(WHERE); ! 758: /* ! 759: `Always Run After Initialization or Re-initialization:` ! 760: ! 761: If you want this event to always run after the BBS is initialized or ! 762: re-initialized, set this option to ~Yes~. ! 763: */ ! 764: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 765: ,"Always Run After Initialization or Re-initialization",uifcYesNoOpts); ! 766: if(!k && !(cfg.event[i]->misc&EVENT_INIT)) { ! 767: cfg.event[i]->misc|=EVENT_INIT; ! 768: uifc.changes=1; ! 769: } ! 770: else if(k==1 && (cfg.event[i]->misc&EVENT_INIT)) { ! 771: cfg.event[i]->misc&=~EVENT_INIT; ! 772: uifc.changes=1; ! 773: } ! 774: break; ! 775: } ! 776: } ! 777: } ! 778: } ! 779: ! 780: ! 781: void xtrn_cfg(uint section) ! 782: { ! 783: static int ext_dflt,ext_bar,sub_bar,opt_dflt,time_dflt; ! 784: char str[128],code[9],done=0,*p; ! 785: int j,k; ! 786: uint i,n,xtrnnum[MAX_OPTS+1]; ! 787: static xtrn_t savxtrn; ! 788: ! 789: sub_bar=0; ! 790: opt_dflt=0; ! 791: ! 792: while(1) { ! 793: for(i=0,j=0;i<cfg.total_xtrns && j<MAX_OPTS;i++) ! 794: if(cfg.xtrn[i]->sec==section) { ! 795: sprintf(opt[j],"%-25s",cfg.xtrn[i]->name); ! 796: xtrnnum[j++]=i; ! 797: } ! 798: xtrnnum[j]=cfg.total_xtrns; ! 799: opt[j][0]=0; ! 800: i=WIN_ACT|WIN_CHE|WIN_SAV|WIN_RHT; ! 801: if(j) ! 802: i|=WIN_DEL|WIN_GET; ! 803: if(cfg.total_xtrns<MAX_OPTS) ! 804: i|=WIN_INS|WIN_INSACT|WIN_XTR; ! 805: if(savxtrn.name[0]) ! 806: i|=WIN_PUT; ! 807: SETHELP(WHERE); ! 808: /* ! 809: `Online External Programs:` ! 810: ! 811: This is a list of the configured online external programs (doors). ! 812: ! 813: To add a program, select the desired location with the arrow keys and ! 814: hit ~ INS ~. ! 815: ! 816: To delete a program, select it with the arrow keys and hit ~ DEL ~. ! 817: ! 818: To configure a program, select it with the arrow keys and hit ~ ENTER ~. ! 819: */ ! 820: sprintf(str,"%s Online Programs",cfg.xtrnsec[section]->name); ! 821: i=uifc.list(i,0,0,45,&ext_dflt,&ext_bar,str,opt); ! 822: if((signed)i==-1) ! 823: return; ! 824: if((i&MSK_ON)==MSK_INS) { ! 825: i&=MSK_OFF; ! 826: SETHELP(WHERE); ! 827: /* ! 828: `Online Program Name:` ! 829: ! 830: This is the name or description of the online program (door). ! 831: */ ! 832: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Online Program Name",str,25 ! 833: ,0)<1) ! 834: continue; ! 835: sprintf(code,"%.8s",str); ! 836: p=strchr(code,' '); ! 837: if(p) *p=0; ! 838: strupr(code); ! 839: SETHELP(WHERE); ! 840: /* ! 841: `Online Program Internal Code:` ! 842: ! 843: Every online program must have its own unique code for Synchronet to ! 844: refer to it internally. This code is usually an abreviation of the ! 845: online program name. ! 846: */ ! 847: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Internal Code" ! 848: ,code,LEN_CODE,K_EDIT|K_UPPER)<1) ! 849: continue; ! 850: if(!code_ok(code)) { ! 851: uifc.helpbuf=invalid_code; ! 852: uifc.msg("Invalid Code"); ! 853: uifc.helpbuf=0; ! 854: continue; ! 855: } ! 856: if((cfg.xtrn=(xtrn_t **)realloc(cfg.xtrn,sizeof(xtrn_t *)*(cfg.total_xtrns+1))) ! 857: ==NULL) { ! 858: errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_xtrns+1); ! 859: cfg.total_xtrns=0; ! 860: bail(1); ! 861: continue; ! 862: } ! 863: if(j) ! 864: for(n=cfg.total_xtrns;n>xtrnnum[i];n--) ! 865: cfg.xtrn[n]=cfg.xtrn[n-1]; ! 866: if((cfg.xtrn[xtrnnum[i]]=(xtrn_t *)malloc(sizeof(xtrn_t)))==NULL) { ! 867: errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(xtrn_t)); ! 868: continue; ! 869: } ! 870: memset((xtrn_t *)cfg.xtrn[xtrnnum[i]],0,sizeof(xtrn_t)); ! 871: strcpy(cfg.xtrn[xtrnnum[i]]->name,str); ! 872: strcpy(cfg.xtrn[xtrnnum[i]]->code,code); ! 873: cfg.xtrn[xtrnnum[i]]->sec=section; ! 874: cfg.total_xtrns++; ! 875: uifc.changes=TRUE; ! 876: continue; ! 877: } ! 878: if((i&MSK_ON)==MSK_DEL) { ! 879: i&=MSK_OFF; ! 880: free(cfg.xtrn[xtrnnum[i]]); ! 881: cfg.total_xtrns--; ! 882: for(j=xtrnnum[i];j<cfg.total_xtrns;j++) ! 883: cfg.xtrn[j]=cfg.xtrn[j+1]; ! 884: uifc.changes=TRUE; ! 885: continue; ! 886: } ! 887: if((i&MSK_ON)==MSK_GET) { ! 888: i&=MSK_OFF; ! 889: savxtrn=*cfg.xtrn[xtrnnum[i]]; ! 890: continue; ! 891: } ! 892: if((i&MSK_ON)==MSK_PUT) { ! 893: i&=MSK_OFF; ! 894: *cfg.xtrn[xtrnnum[i]]=savxtrn; ! 895: cfg.xtrn[xtrnnum[i]]->sec=section; ! 896: uifc.changes=TRUE; ! 897: continue; ! 898: } ! 899: done=0; ! 900: i=xtrnnum[i]; ! 901: while(!done) { ! 902: k=0; ! 903: sprintf(opt[k++],"%-27.27s%s","Name",cfg.xtrn[i]->name); ! 904: sprintf(opt[k++],"%-27.27s%s","Internal Code",cfg.xtrn[i]->code); ! 905: sprintf(opt[k++],"%-27.27s%.40s","Start-up Directory",cfg.xtrn[i]->path); ! 906: sprintf(opt[k++],"%-27.27s%.40s","Command Line",cfg.xtrn[i]->cmd); ! 907: sprintf(opt[k++],"%-27.27s%.40s","Clean-up Command Line",cfg.xtrn[i]->clean); ! 908: if(cfg.xtrn[i]->cost) ! 909: sprintf(str,"%lu credits",cfg.xtrn[i]->cost); ! 910: else ! 911: strcpy(str,"None"); ! 912: sprintf(opt[k++],"%-27.27s%s","Execution Cost",str); ! 913: sprintf(opt[k++],"%-27.27s%.40s","Access Requirements",cfg.xtrn[i]->arstr); ! 914: sprintf(opt[k++],"%-27.27s%.40s","Execution Requirements" ! 915: ,cfg.xtrn[i]->run_arstr); ! 916: sprintf(opt[k++],"%-27.27s%s","Multiple Concurrent Users" ! 917: ,cfg.xtrn[i]->misc&MULTIUSER ? "Yes" : "No"); ! 918: sprintf(opt[k++],"%-27.27s%s%s%s","Intercept I/O" ! 919: ,cfg.xtrn[i]->misc&XTRN_STDIO ? "Standard" ! 920: : cfg.xtrn[i]->misc&XTRN_CONIO ? "Console":"No" ! 921: ,(cfg.xtrn[i]->misc&(XTRN_STDIO|WWIVCOLOR)) ! 922: ==(XTRN_STDIO|WWIVCOLOR) ? ", WWIV Color" : nulstr ! 923: ,(cfg.xtrn[i]->misc&(XTRN_STDIO|XTRN_NOECHO)) ! 924: ==(XTRN_STDIO|XTRN_NOECHO) ? ", No Echo" : nulstr); ! 925: sprintf(opt[k++],"%-27.27s%s","Native Executable" ! 926: ,cfg.xtrn[i]->misc&XTRN_NATIVE ? "Yes" : "No"); ! 927: sprintf(opt[k++],"%-27.27s%s","Use Shell to Execute" ! 928: ,cfg.xtrn[i]->misc&XTRN_SH ? "Yes" : "No"); ! 929: sprintf(opt[k++],"%-27.27s%s","Modify User Data" ! 930: ,cfg.xtrn[i]->misc&MODUSERDAT ? "Yes" : "No"); ! 931: switch(cfg.xtrn[i]->event) { ! 932: case EVENT_LOGON: ! 933: strcpy(str,"Logon"); ! 934: break; ! 935: case EVENT_LOGOFF: ! 936: strcpy(str,"Logoff"); ! 937: break; ! 938: case EVENT_NEWUSER: ! 939: strcpy(str,"New User"); ! 940: break; ! 941: case EVENT_BIRTHDAY: ! 942: strcpy(str,"Birthday"); ! 943: break; ! 944: case EVENT_POST: ! 945: strcpy(str,"Message Posted"); ! 946: break; ! 947: case EVENT_UPLOAD: ! 948: strcpy(str,"File Uploaded"); ! 949: break; ! 950: case EVENT_DOWNLOAD: ! 951: strcpy(str,"File Downloaded"); ! 952: break; ! 953: default: ! 954: strcpy(str,"No"); ! 955: break; ! 956: } ! 957: if((cfg.xtrn[i]->misc&EVENTONLY) && cfg.xtrn[i]->event) ! 958: strcat(str,", Only"); ! 959: sprintf(opt[k++],"%-27.27s%s","Execute on Event",str); ! 960: sprintf(opt[k++],"%-27.27s%s","Pause After Execution" ! 961: ,cfg.xtrn[i]->misc&XTRN_PAUSE ? "Yes" : "No"); ! 962: sprintf(opt[k++],"%-23.23s%-4s%s","BBS Drop File Type" ! 963: ,cfg.xtrn[i]->misc&REALNAME ? "(R)":nulstr ! 964: ,dropfile(cfg.xtrn[i]->type,cfg.xtrn[i]->misc)); ! 965: sprintf(opt[k++],"%-27.27s%s","Place Drop File In" ! 966: ,cfg.xtrn[i]->misc&STARTUPDIR ? "Start-Up Directory":"Node Directory"); ! 967: sprintf(opt[k++],"Time Options..."); ! 968: opt[k][0]=0; ! 969: SETHELP(WHERE); ! 970: /* ! 971: `Online Program Configuration:` ! 972: ! 973: This menu is for configuring the selected online program. ! 974: */ ! 975: switch(uifc.list(WIN_SAV|WIN_ACT|WIN_MID,0,0,60,&opt_dflt,&sub_bar,cfg.xtrn[i]->name ! 976: ,opt)) { ! 977: case -1: ! 978: done=1; ! 979: break; ! 980: case 0: ! 981: SETHELP(WHERE); ! 982: /* ! 983: `Online Program Name:` ! 984: ! 985: This is the name or description of the online program (door). ! 986: */ ! 987: strcpy(str,cfg.xtrn[i]->name); ! 988: if(!uifc.input(WIN_MID|WIN_SAV,0,10,"Online Program Name" ! 989: ,cfg.xtrn[i]->name,sizeof(cfg.xtrn[i]->name)-1,K_EDIT)) ! 990: strcpy(cfg.xtrn[i]->name,str); ! 991: break; ! 992: case 1: ! 993: SETHELP(WHERE); ! 994: /* ! 995: `Online Program Internal Code:` ! 996: ! 997: Every online program must have its own unique code for Synchronet to ! 998: refer to it internally. This code is usually an abreviation of the ! 999: online program name. ! 1000: */ ! 1001: strcpy(str,cfg.xtrn[i]->code); ! 1002: uifc.input(WIN_MID|WIN_SAV,0,10,"Internal Code" ! 1003: ,str,LEN_CODE,K_UPPER|K_EDIT); ! 1004: if(code_ok(str)) ! 1005: strcpy(cfg.xtrn[i]->code,str); ! 1006: else { ! 1007: uifc.helpbuf=invalid_code; ! 1008: uifc.msg("Invalid Code"); ! 1009: uifc.helpbuf=0; ! 1010: } ! 1011: break; ! 1012: case 2: ! 1013: SETHELP(WHERE); ! 1014: /* ! 1015: `Online Program Start-up Directory:` ! 1016: ! 1017: This is the DOS drive/directory where the online program is located. ! 1018: If a path is specified here, it will be made the current directory ! 1019: before the program's command line is executed. This eliminates the need ! 1020: for batch files that just change the current drive and directory before ! 1021: executing the program. ! 1022: ! 1023: If this option is not used, the current NODE's directory will be the ! 1024: current DOS drive/directory before the command line is executed. ! 1025: */ ! 1026: uifc.input(WIN_MID|WIN_SAV,0,10,"" ! 1027: ,cfg.xtrn[i]->path,sizeof(cfg.xtrn[i]->path)-1,K_EDIT); ! 1028: break; ! 1029: case 3: ! 1030: SETHELP(WHERE); ! 1031: /* ! 1032: `Online Program Command Line:` ! 1033: ! 1034: This is the command line to execute to run the online program. ! 1035: */ ! 1036: uifc.input(WIN_MID|WIN_SAV,0,10,"Command" ! 1037: ,cfg.xtrn[i]->cmd,sizeof(cfg.xtrn[i]->cmd)-1,K_EDIT); ! 1038: break; ! 1039: case 4: ! 1040: SETHELP(WHERE); ! 1041: /* ! 1042: `Online Program Clean-up Command:` ! 1043: ! 1044: This is the command line to execute after the main command line. This ! 1045: option is usually only used for multiuser online programs. ! 1046: */ ! 1047: uifc.input(WIN_MID|WIN_SAV,0,10,"Clean-up" ! 1048: ,cfg.xtrn[i]->clean,sizeof(cfg.xtrn[i]->clean)-1,K_EDIT); ! 1049: break; ! 1050: case 5: ! 1051: ultoa(cfg.xtrn[i]->cost,str,10); ! 1052: SETHELP(WHERE); ! 1053: /* ! 1054: `Online Program Cost to Run:` ! 1055: ! 1056: If you want users to be charged credits to run this online program, ! 1057: set this value to the number of credits to charge. If you want this ! 1058: online program to be free, set this value to `0`. ! 1059: */ ! 1060: uifc.input(WIN_MID|WIN_SAV,0,0,"Cost to Run (in Credits)" ! 1061: ,str,10,K_EDIT|K_NUMBER); ! 1062: cfg.xtrn[i]->cost=atol(str); ! 1063: break; ! 1064: case 6: ! 1065: sprintf(str,"%s Access",cfg.xtrn[i]->name); ! 1066: getar(str,cfg.xtrn[i]->arstr); ! 1067: break; ! 1068: case 7: ! 1069: sprintf(str,"%s Execution",cfg.xtrn[i]->name); ! 1070: getar(str,cfg.xtrn[i]->run_arstr); ! 1071: break; ! 1072: case 8: ! 1073: k=(cfg.xtrn[i]->misc&MULTIUSER) ? 0:1; ! 1074: SETHELP(WHERE); ! 1075: /* ! 1076: `Supports Multiple Users:` ! 1077: ! 1078: If this online program supports multiple simultaneous users (nodes), ! 1079: set this option to `Yes`. ! 1080: */ ! 1081: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Supports Multiple Users" ! 1082: ,uifcYesNoOpts); ! 1083: if(!k && !(cfg.xtrn[i]->misc&MULTIUSER)) { ! 1084: cfg.xtrn[i]->misc|=MULTIUSER; ! 1085: uifc.changes=TRUE; ! 1086: } ! 1087: else if(k==1 && (cfg.xtrn[i]->misc&MULTIUSER)) { ! 1088: cfg.xtrn[i]->misc&=~MULTIUSER; ! 1089: uifc.changes=TRUE; ! 1090: } ! 1091: break; ! 1092: case 9: ! 1093: switch(cfg.xtrn[i]->misc&(XTRN_STDIO|XTRN_CONIO)) { ! 1094: case XTRN_STDIO: ! 1095: k=0; ! 1096: break; ! 1097: case XTRN_CONIO: ! 1098: k=1; ! 1099: break; ! 1100: default: ! 1101: k=2; ! 1102: } ! 1103: strcpy(opt[0],"Standard"); ! 1104: strcpy(opt[1],"Console"); ! 1105: strcpy(opt[2],"No"); ! 1106: opt[3][0]=0; ! 1107: SETHELP(WHERE); ! 1108: /* ! 1109: `Intercept I/O:` ! 1110: ! 1111: If this online program uses a FOSSIL driver or SOCKET communications, ! 1112: set this option to `No`. ! 1113: */ ! 1114: switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Intercept I/O" ! 1115: ,opt)) { ! 1116: case 0: /* Standard I/O */ ! 1117: if((cfg.xtrn[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != XTRN_STDIO) { ! 1118: cfg.xtrn[i]->misc|=XTRN_STDIO; ! 1119: cfg.xtrn[i]->misc&=~XTRN_CONIO; ! 1120: uifc.changes=1; ! 1121: } ! 1122: k=(cfg.xtrn[i]->misc&WWIVCOLOR) ? 0:1; ! 1123: SETHELP(WHERE); ! 1124: /* ! 1125: .Program Uses WWIV Color Codes:. ! 1126: ! 1127: If this program was written for use exclusively under WWIV, set this ! 1128: option to .Yes.. ! 1129: */ ! 1130: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 1131: ,"Program Uses WWIV Color Codes" ! 1132: ,uifcYesNoOpts); ! 1133: if(!k && !(cfg.xtrn[i]->misc&WWIVCOLOR)) { ! 1134: cfg.xtrn[i]->misc|=WWIVCOLOR; ! 1135: uifc.changes=TRUE; ! 1136: } ! 1137: else if(k==1 && (cfg.xtrn[i]->misc&WWIVCOLOR)) { ! 1138: cfg.xtrn[i]->misc&=~WWIVCOLOR; ! 1139: uifc.changes=TRUE; ! 1140: } ! 1141: k=(cfg.xtrn[i]->misc&XTRN_NOECHO) ? 1:0; ! 1142: SETHELP(WHERE); ! 1143: /* ! 1144: `Echo Input:` ! 1145: ! 1146: If you want the BBS to copy ("echo") all keyboard input to the screen ! 1147: output, set this option to ~Yes~ (for native Win32 programs only). ! 1148: */ ! 1149: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 1150: ,"Echo Keyboard Input" ! 1151: ,uifcYesNoOpts); ! 1152: if(!k && (cfg.xtrn[i]->misc&XTRN_NOECHO)) { ! 1153: cfg.xtrn[i]->misc&=~XTRN_NOECHO; ! 1154: uifc.changes=TRUE; ! 1155: } else if(k==1 && !(cfg.xtrn[i]->misc&XTRN_NOECHO)) { ! 1156: cfg.xtrn[i]->misc|=XTRN_NOECHO; ! 1157: uifc.changes=TRUE; ! 1158: } ! 1159: break; ! 1160: case 1: /* Console I/O */ ! 1161: if((cfg.xtrn[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != XTRN_CONIO) { ! 1162: cfg.xtrn[i]->misc|=XTRN_CONIO; ! 1163: cfg.xtrn[i]->misc&=~(XTRN_STDIO|WWIVCOLOR|XTRN_NOECHO); ! 1164: uifc.changes=TRUE; ! 1165: } ! 1166: break; ! 1167: case 2: /* No */ ! 1168: if((cfg.xtrn[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != 0) { ! 1169: cfg.xtrn[i]->misc&=~(XTRN_CONIO|XTRN_STDIO|WWIVCOLOR|XTRN_NOECHO); ! 1170: uifc.changes=TRUE; ! 1171: } ! 1172: break; ! 1173: } ! 1174: break; ! 1175: case 10: ! 1176: k=(cfg.xtrn[i]->misc&XTRN_NATIVE) ? 0:1; ! 1177: SETHELP(WHERE); ! 1178: /* ! 1179: `Native Executable:` ! 1180: ! 1181: If this online program is a native (e.g. non-DOS) executable, ! 1182: set this option to `Yes`. ! 1183: */ ! 1184: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 1185: ,"Native",uifcYesNoOpts); ! 1186: if(!k && !(cfg.xtrn[i]->misc&XTRN_NATIVE)) { ! 1187: cfg.xtrn[i]->misc|=XTRN_NATIVE; ! 1188: uifc.changes=TRUE; ! 1189: } ! 1190: else if(k==1 && (cfg.xtrn[i]->misc&XTRN_NATIVE)) { ! 1191: cfg.xtrn[i]->misc&=~XTRN_NATIVE; ! 1192: uifc.changes=TRUE; ! 1193: } ! 1194: break; ! 1195: case 11: ! 1196: k=(cfg.xtrn[i]->misc&XTRN_SH) ? 0:1; ! 1197: SETHELP(WHERE); ! 1198: /* ! 1199: `Use Shell to Execute Command:` ! 1200: ! 1201: If this command-line requires the system command shell to execute, (Unix ! 1202: shell script or DOS batch file), set this option to ~Yes~. ! 1203: */ ! 1204: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 1205: ,"Use Shell",uifcYesNoOpts); ! 1206: if(!k && !(cfg.xtrn[i]->misc&XTRN_SH)) { ! 1207: cfg.xtrn[i]->misc|=XTRN_SH; ! 1208: uifc.changes=TRUE; ! 1209: } ! 1210: else if(k==1 && (cfg.xtrn[i]->misc&XTRN_SH)) { ! 1211: cfg.xtrn[i]->misc&=~XTRN_SH; ! 1212: uifc.changes=TRUE; ! 1213: } ! 1214: break; ! 1215: case 12: ! 1216: k=(cfg.xtrn[i]->misc&MODUSERDAT) ? 0:1; ! 1217: SETHELP(WHERE); ! 1218: /* ! 1219: `Program Can Modify User Data:` ! 1220: ! 1221: If this online programs recognizes the Synchronet MODUSER.DAT format ! 1222: or the RBBS/QuickBBS EXITINFO.BBS format and you want it to be able to ! 1223: modify the data of users who run the program, set this option to `Yes`. ! 1224: */ ! 1225: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 1226: ,"Program Can Modify User Data",uifcYesNoOpts); ! 1227: if(!k && !(cfg.xtrn[i]->misc&MODUSERDAT)) { ! 1228: cfg.xtrn[i]->misc|=MODUSERDAT; ! 1229: uifc.changes=TRUE; ! 1230: } ! 1231: else if(k==1 && (cfg.xtrn[i]->misc&MODUSERDAT)) { ! 1232: cfg.xtrn[i]->misc&=~MODUSERDAT; ! 1233: uifc.changes=TRUE; ! 1234: } ! 1235: break; ! 1236: case 13: ! 1237: k=0; ! 1238: strcpy(opt[k++],"No"); ! 1239: strcpy(opt[k++],"Logon"); ! 1240: strcpy(opt[k++],"Logoff"); ! 1241: strcpy(opt[k++],"New User"); ! 1242: strcpy(opt[k++],"Birthday"); ! 1243: strcpy(opt[k++],"Message Posted"); ! 1244: strcpy(opt[k++],"File Uploaded"); ! 1245: strcpy(opt[k++],"File Downloaded"); ! 1246: opt[k][0]=0; ! 1247: k=cfg.xtrn[i]->event; ! 1248: SETHELP(WHERE); ! 1249: /* ! 1250: `Execute Online Program on Event:` ! 1251: ! 1252: If you would like this online program to automatically execute on a ! 1253: specific user event, select the event. Otherwise, select `No`. ! 1254: */ ! 1255: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 1256: ,"Execute on Event",opt); ! 1257: if(k==-1) ! 1258: break; ! 1259: if(cfg.xtrn[i]->event!=k) { ! 1260: cfg.xtrn[i]->event=k; ! 1261: uifc.changes=TRUE; ! 1262: } ! 1263: if(!cfg.xtrn[i]->event) { ! 1264: if(cfg.xtrn[i]->misc&EVENTONLY) { ! 1265: cfg.xtrn[i]->misc&=~EVENTONLY; ! 1266: uifc.changes=TRUE; ! 1267: } ! 1268: break; ! 1269: } ! 1270: k=(cfg.xtrn[i]->misc&EVENTONLY) ? 0:1; ! 1271: SETHELP(WHERE); ! 1272: /* ! 1273: `Execute Online Program as Event Only:` ! 1274: ! 1275: If you would like this online program to execute as an event only ! 1276: (not available to users on the online program menu), set this option ! 1277: to `Yes`. ! 1278: */ ! 1279: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k ! 1280: ,0,"Execute as Event Only" ! 1281: ,uifcYesNoOpts); ! 1282: if(!k && !(cfg.xtrn[i]->misc&EVENTONLY)) { ! 1283: cfg.xtrn[i]->misc|=EVENTONLY; ! 1284: uifc.changes=TRUE; ! 1285: } ! 1286: else if(k==1 && (cfg.xtrn[i]->misc&EVENTONLY)) { ! 1287: cfg.xtrn[i]->misc&=~EVENTONLY; ! 1288: uifc.changes=TRUE; ! 1289: } ! 1290: break; ! 1291: case 14: ! 1292: k=(cfg.xtrn[i]->misc&XTRN_PAUSE) ? 0:1; ! 1293: SETHELP(WHERE); ! 1294: /* ! 1295: `Pause Screen After Execution:` ! 1296: ! 1297: Set this option to ~Yes~ if you would like an automatic screen pause ! 1298: (`[Hit a key]` prompt) to appear after the program executes. ! 1299: ! 1300: This can be useful if the program displays information just before exiting ! 1301: or you want to debug a program with a program not running correctly. ! 1302: */ ! 1303: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 1304: ,"Pause After Execution",uifcYesNoOpts); ! 1305: if((!k && !(cfg.xtrn[i]->misc&XTRN_PAUSE)) ! 1306: || (k && (cfg.xtrn[i]->misc&XTRN_PAUSE))) { ! 1307: cfg.xtrn[i]->misc^=XTRN_PAUSE; ! 1308: uifc.changes=TRUE; ! 1309: } ! 1310: break; ! 1311: case 15: ! 1312: k=0; ! 1313: strcpy(opt[k++],"None"); ! 1314: sprintf(opt[k++],"%-15s %s","Synchronet","XTRN.DAT"); ! 1315: sprintf(opt[k++],"%-15s %s","WWIV","CHAIN.TXT"); ! 1316: sprintf(opt[k++],"%-15s %s","GAP","DOOR.SYS"); ! 1317: sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO#.DEF"); ! 1318: sprintf(opt[k++],"%-15s %s","Wildcat","CALLINFO.BBS"); ! 1319: sprintf(opt[k++],"%-15s %s","PCBoard","PCBOARD.SYS"); ! 1320: sprintf(opt[k++],"%-15s %s","SpitFire","SFDOORS.DAT"); ! 1321: sprintf(opt[k++],"%-15s %s","MegaMail","UTIDOOR.TXT"); ! 1322: sprintf(opt[k++],"%-15s %s","Solar Realms","DOORFILE.SR"); ! 1323: sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO1.DEF"); ! 1324: sprintf(opt[k++],"%-15s %s","TriBBS","TRIBBS.SYS"); ! 1325: sprintf(opt[k++],"%-15s %s","Mystic","DOOR32.SYS"); ! 1326: opt[k][0]=0; ! 1327: k=cfg.xtrn[i]->type; ! 1328: SETHELP(WHERE); ! 1329: /* ! 1330: `Online Program BBS Drop File Type:` ! 1331: ! 1332: If this online program requires a specific BBS data (drop) file ! 1333: format, select the file format from the list. ! 1334: */ ! 1335: k=uifc.list(WIN_MID|WIN_ACT,0,0,0,&k,0 ! 1336: ,"BBS Drop File Type",opt); ! 1337: if(k==-1) ! 1338: break; ! 1339: if(cfg.xtrn[i]->type!=k) { ! 1340: cfg.xtrn[i]->type=k; ! 1341: if(cfg.xtrn[i]->type==XTRN_DOOR32) ! 1342: cfg.xtrn[i]->misc|=XTRN_NATIVE; ! 1343: uifc.changes=TRUE; ! 1344: } ! 1345: if(cfg.xtrn[i]->type && cfg.uq&UQ_ALIASES) { ! 1346: k=(cfg.xtrn[i]->misc&REALNAME) ? 0:1; ! 1347: k=uifc.list(WIN_MID,0,0,0,&k,0,"Use Real Names",uifcYesNoOpts); ! 1348: if(k==0 && !(cfg.xtrn[i]->misc&REALNAME)) { ! 1349: cfg.xtrn[i]->misc|=REALNAME; ! 1350: uifc.changes=TRUE; ! 1351: } ! 1352: else if(k==1 && (cfg.xtrn[i]->misc&REALNAME)) { ! 1353: cfg.xtrn[i]->misc&=~REALNAME; ! 1354: uifc.changes=TRUE; ! 1355: } ! 1356: } ! 1357: if(cfg.xtrn[i]->type) { ! 1358: k=(cfg.xtrn[i]->misc&XTRN_LWRCASE) ? 0:1; ! 1359: k=uifc.list(WIN_MID,0,0,0,&k,0,"Lowercase Filename",uifcYesNoOpts); ! 1360: if(k==0 && !(cfg.xtrn[i]->misc&XTRN_LWRCASE)) { ! 1361: cfg.xtrn[i]->misc|=XTRN_LWRCASE; ! 1362: uifc.changes=TRUE; ! 1363: } ! 1364: else if(k==1 && (cfg.xtrn[i]->misc&XTRN_LWRCASE)) { ! 1365: cfg.xtrn[i]->misc&=~XTRN_LWRCASE; ! 1366: uifc.changes=TRUE; ! 1367: } ! 1368: } ! 1369: break; ! 1370: case 16: ! 1371: k=0; ! 1372: strcpy(opt[0],"Node Directory"); ! 1373: strcpy(opt[1],"Start-up Directory"); ! 1374: opt[2][0]=0; ! 1375: SETHELP(WHERE); ! 1376: /* ! 1377: `Directory for Drop File:` ! 1378: ! 1379: You can have the data file created in the current `Node Directory` or the ! 1380: `Start-up Directory` (if one is specified). ! 1381: */ ! 1382: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Create Drop File In" ! 1383: ,opt); ! 1384: if(!k && cfg.xtrn[i]->misc&STARTUPDIR) { ! 1385: cfg.xtrn[i]->misc&=~STARTUPDIR; ! 1386: uifc.changes=TRUE; ! 1387: } ! 1388: else if(k==1 && !(cfg.xtrn[i]->misc&STARTUPDIR)) { ! 1389: cfg.xtrn[i]->misc|=STARTUPDIR; ! 1390: uifc.changes=TRUE; ! 1391: } ! 1392: break; ! 1393: case 17: ! 1394: while(1) { ! 1395: k=0; ! 1396: if(cfg.xtrn[i]->textra) ! 1397: sprintf(str,"%u minutes",cfg.xtrn[i]->textra); ! 1398: else ! 1399: strcpy(str,"None"); ! 1400: sprintf(opt[k++],"%-25.25s%s","Extra Time",str); ! 1401: if(cfg.xtrn[i]->maxtime) ! 1402: sprintf(str,"%u minutes",cfg.xtrn[i]->maxtime); ! 1403: else ! 1404: strcpy(str,"None"); ! 1405: sprintf(opt[k++],"%-25.25s%s","Maximum Time",str); ! 1406: sprintf(opt[k++],"%-25.25s%s","Suspended (Free) Time" ! 1407: ,cfg.xtrn[i]->misc&FREETIME ? "Yes" : "No"); ! 1408: sprintf(opt[k++],"%-25.25s%s","Monitor Time Left" ! 1409: ,cfg.xtrn[i]->misc&XTRN_CHKTIME ? "Yes" : "No"); ! 1410: opt[k][0]=0; ! 1411: SETHELP(WHERE); ! 1412: /* ! 1413: `Online Program Time Options:` ! 1414: ! 1415: This sub-menu allows you to define specific preferences regarding the ! 1416: time users spend running this program. ! 1417: */ ! 1418: k=uifc.list(WIN_SAV|WIN_ACT|WIN_RHT|WIN_BOT,0,0,40 ! 1419: ,&time_dflt,0 ! 1420: ,"Online Program Time Options",opt); ! 1421: if(k==-1) ! 1422: break; ! 1423: switch(k) { ! 1424: case 0: ! 1425: ultoa(cfg.xtrn[i]->textra,str,10); ! 1426: SETHELP(WHERE); ! 1427: /* ! 1428: `Extra Time to Give User in Program:` ! 1429: ! 1430: If you want to give users extra time while in this online program, ! 1431: set this value to the number of minutes to add to their current time ! 1432: left online. ! 1433: */ ! 1434: uifc.input(WIN_MID|WIN_SAV,0,0 ! 1435: ,"Extra Time to Give User (in minutes)" ! 1436: ,str,2,K_EDIT|K_NUMBER); ! 1437: cfg.xtrn[i]->textra=atoi(str); ! 1438: break; ! 1439: case 1: ! 1440: ultoa(cfg.xtrn[i]->maxtime,str,10); ! 1441: SETHELP(WHERE); ! 1442: /* ! 1443: `Maximum Time Allowed in Program:` ! 1444: ! 1445: If this program supports a drop file that contains the number of minutes ! 1446: left online for the current user, this option allows the sysop to set ! 1447: the maximum number of minutes that will be allowed in the drop file. ! 1448: ! 1449: Setting this option to `0`, disables this feature. ! 1450: */ ! 1451: uifc.input(WIN_MID|WIN_SAV,0,0 ! 1452: ,"Maximum Time (in minutes, 0=disabled)" ! 1453: ,str,2,K_EDIT|K_NUMBER); ! 1454: cfg.xtrn[i]->maxtime=atoi(str); ! 1455: break; ! 1456: case 2: ! 1457: k=(cfg.xtrn[i]->misc&FREETIME) ? 0:1; ! 1458: SETHELP(WHERE); ! 1459: /* ! 1460: `Suspended (Free) Time:` ! 1461: ! 1462: If you want the user's time online to be suspended while running this ! 1463: online program (e.g. Free Time), set this option to `Yes`. ! 1464: */ ! 1465: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 1466: ,"Suspended (Free) Time",uifcYesNoOpts); ! 1467: if(!k && !(cfg.xtrn[i]->misc&FREETIME)) { ! 1468: cfg.xtrn[i]->misc|=FREETIME; ! 1469: uifc.changes=TRUE; ! 1470: } ! 1471: else if(k==1 && (cfg.xtrn[i]->misc&FREETIME)) { ! 1472: cfg.xtrn[i]->misc&=~FREETIME; ! 1473: uifc.changes=TRUE; ! 1474: } ! 1475: break; ! 1476: case 3: ! 1477: k=(cfg.xtrn[i]->misc&XTRN_CHKTIME) ? 0:1; ! 1478: SETHELP(WHERE); ! 1479: /* ! 1480: `Monitor Time Left:` ! 1481: ! 1482: If you want Synchronet to monitor the user's time left online while this ! 1483: program runs (and disconnect the user if their time runs out), set this ! 1484: option to `Yes`. ! 1485: */ ! 1486: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 1487: ,"Monitor Time Left",uifcYesNoOpts); ! 1488: if(!k && !(cfg.xtrn[i]->misc&XTRN_CHKTIME)) { ! 1489: cfg.xtrn[i]->misc|=XTRN_CHKTIME; ! 1490: uifc.changes=TRUE; ! 1491: } ! 1492: else if(k==1 && (cfg.xtrn[i]->misc&XTRN_CHKTIME)) { ! 1493: cfg.xtrn[i]->misc&=~XTRN_CHKTIME; ! 1494: uifc.changes=TRUE; ! 1495: } ! 1496: break; ! 1497: } ! 1498: } ! 1499: break; ! 1500: } ! 1501: } ! 1502: } ! 1503: } ! 1504: ! 1505: void xedit_cfg() ! 1506: { ! 1507: static int dflt,dfltopt,bar; ! 1508: char str[81],code[81],done=0,*p; ! 1509: int j,k; ! 1510: uint i; ! 1511: static xedit_t savxedit; ! 1512: ! 1513: while(1) { ! 1514: for(i=0;i<cfg.total_xedits && i<MAX_OPTS;i++) ! 1515: sprintf(opt[i],"%-8.8s %.40s",cfg.xedit[i]->code,cfg.xedit[i]->rcmd); ! 1516: opt[i][0]=0; ! 1517: j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_RHT; ! 1518: if(cfg.total_xedits) ! 1519: j|=WIN_DEL|WIN_GET; ! 1520: if(cfg.total_xedits<MAX_OPTS) ! 1521: j|=WIN_INS|WIN_INSACT|WIN_XTR; ! 1522: if(savxedit.name[0]) ! 1523: j|=WIN_PUT; ! 1524: SETHELP(WHERE); ! 1525: /* ! 1526: `External Editors:` ! 1527: ! 1528: This is a list of the configured external editors. ! 1529: ! 1530: To add an editor, select the desired location and hit ~ INS ~. ! 1531: ! 1532: To delete an editor, select it and hit ~ DEL ~. ! 1533: ! 1534: To configure an editor, select it and hit ~ ENTER ~. ! 1535: */ ! 1536: i=uifc.list(j,0,0,45,&dflt,&bar,"External Editors",opt); ! 1537: if((signed)i==-1) ! 1538: return; ! 1539: if((i&MSK_ON)==MSK_INS) { ! 1540: i&=MSK_OFF; ! 1541: SETHELP(WHERE); ! 1542: /* ! 1543: `External Editor Name:` ! 1544: ! 1545: This is the name or description of the external editor. ! 1546: */ ! 1547: if(uifc.input(WIN_MID|WIN_SAV,0,0,"External Editor Name",str,40 ! 1548: ,0)<1) ! 1549: continue; ! 1550: sprintf(code,"%.8s",str); ! 1551: p=strchr(code,' '); ! 1552: if(p) *p=0; ! 1553: strupr(code); ! 1554: SETHELP(WHERE); ! 1555: /* ! 1556: `External Editor Internal Code:` ! 1557: ! 1558: This is the internal code for the external editor. ! 1559: */ ! 1560: if(uifc.input(WIN_MID|WIN_SAV,0,0,"External Editor Internal Code",code,8 ! 1561: ,K_UPPER|K_EDIT)<1) ! 1562: continue; ! 1563: if(!code_ok(code)) { ! 1564: uifc.helpbuf=invalid_code; ! 1565: uifc.msg("Invalid Code"); ! 1566: uifc.helpbuf=0; ! 1567: continue; ! 1568: } ! 1569: ! 1570: if((cfg.xedit=(xedit_t **)realloc(cfg.xedit ! 1571: ,sizeof(xedit_t *)*(cfg.total_xedits+1)))==NULL) { ! 1572: errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_xedits+1); ! 1573: cfg.total_xedits=0; ! 1574: bail(1); ! 1575: continue; ! 1576: } ! 1577: if(cfg.total_xedits) ! 1578: for(j=cfg.total_xedits;j>i;j--) ! 1579: cfg.xedit[j]=cfg.xedit[j-1]; ! 1580: if((cfg.xedit[i]=(xedit_t *)malloc(sizeof(xedit_t)))==NULL) { ! 1581: errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(xedit_t)); ! 1582: continue; ! 1583: } ! 1584: memset((xedit_t *)cfg.xedit[i],0,sizeof(xedit_t)); ! 1585: strcpy(cfg.xedit[i]->name,str); ! 1586: strcpy(cfg.xedit[i]->code,code); ! 1587: cfg.total_xedits++; ! 1588: uifc.changes=TRUE; ! 1589: continue; ! 1590: } ! 1591: if((i&MSK_ON)==MSK_DEL) { ! 1592: i&=MSK_OFF; ! 1593: free(cfg.xedit[i]); ! 1594: cfg.total_xedits--; ! 1595: for(j=i;j<cfg.total_xedits;j++) ! 1596: cfg.xedit[j]=cfg.xedit[j+1]; ! 1597: uifc.changes=TRUE; ! 1598: continue; ! 1599: } ! 1600: if((i&MSK_ON)==MSK_GET) { ! 1601: i&=MSK_OFF; ! 1602: savxedit=*cfg.xedit[i]; ! 1603: continue; ! 1604: } ! 1605: if((i&MSK_ON)==MSK_PUT) { ! 1606: i&=MSK_OFF; ! 1607: *cfg.xedit[i]=savxedit; ! 1608: uifc.changes=TRUE; ! 1609: continue; ! 1610: } ! 1611: done=0; ! 1612: while(!done) { ! 1613: k=0; ! 1614: sprintf(opt[k++],"%-32.32s%s","Name",cfg.xedit[i]->name); ! 1615: sprintf(opt[k++],"%-32.32s%s","Internal Code",cfg.xedit[i]->code); ! 1616: sprintf(opt[k++],"%-32.32s%.40s","Command Line",cfg.xedit[i]->rcmd); ! 1617: sprintf(opt[k++],"%-32.32s%.40s","Access Requirements",cfg.xedit[i]->arstr); ! 1618: sprintf(opt[k++],"%-32.32s%s%s","Intercept I/O" ! 1619: ,cfg.xedit[i]->misc&XTRN_STDIO ? "Standard" ! 1620: :cfg.xedit[i]->misc&XTRN_CONIO ? "Console":"No" ! 1621: ,(cfg.xedit[i]->misc&(XTRN_STDIO|WWIVCOLOR)) ! 1622: ==(XTRN_STDIO|WWIVCOLOR) ? ", WWIV Color" : nulstr); ! 1623: sprintf(opt[k++],"%-32.32s%s","Native Executable" ! 1624: ,cfg.xedit[i]->misc&XTRN_NATIVE ? "Yes" : "No"); ! 1625: sprintf(opt[k++],"%-32.32s%s","Use Shell to Execute" ! 1626: ,cfg.xedit[i]->misc&XTRN_SH ? "Yes" : "No"); ! 1627: sprintf(opt[k++],"%-32.32s%s","Word Wrap Quoted Text" ! 1628: ,cfg.xedit[i]->misc"EWRAP ? "Yes":"No"); ! 1629: sprintf(opt[k++],"%-32.32s%s","Automatically Quoted Text" ! 1630: ,cfg.xedit[i]->misc"EALL ? "All":cfg.xedit[i]->misc"ENONE ! 1631: ? "None" : "Prompt User"); ! 1632: sprintf(opt[k++],"%-32.32s%s","Editor Information Files" ! 1633: ,cfg.xedit[i]->misc&QUICKBBS ? "QuickBBS MSGINF/MSGTMP":"WWIV EDITOR.INF/RESULT.ED"); ! 1634: sprintf(opt[k++],"%-32.32s%s","Expand Line Feeds to CRLF" ! 1635: ,cfg.xedit[i]->misc&EXPANDLF ? "Yes":"No"); ! 1636: sprintf(opt[k++],"%-32.32s%s","Strip FidoNet Kludge Lines" ! 1637: ,cfg.xedit[i]->misc&STRIPKLUDGE ? "Yes":"No"); ! 1638: sprintf(opt[k++],"%-32.32s%s","BBS Drop File Type" ! 1639: ,dropfile(cfg.xedit[i]->type,cfg.xedit[i]->misc)); ! 1640: opt[k][0]=0; ! 1641: SETHELP(WHERE); ! 1642: /* ! 1643: `External Editor Configuration:` ! 1644: ! 1645: This menu allows you to change the settings for the selected external ! 1646: message editor. External message editors are very common on BBSs. Some ! 1647: popular editors include `SyncEdit`, `WWIVedit`, `FEdit`, `GEdit`, `IceEdit`, ! 1648: and many others. ! 1649: */ ! 1650: ! 1651: sprintf(str,"%s Editor",cfg.xedit[i]->name); ! 1652: switch(uifc.list(WIN_SAV|WIN_ACT|WIN_L2R|WIN_BOT,0,0,70,&dfltopt,0 ! 1653: ,str,opt)) { ! 1654: case -1: ! 1655: done=1; ! 1656: break; ! 1657: case 0: ! 1658: SETHELP(WHERE); ! 1659: /* ! 1660: `External Editor Name:` ! 1661: ! 1662: This is the name or description of the external editor. ! 1663: */ ! 1664: strcpy(str,cfg.xedit[i]->name); ! 1665: if(!uifc.input(WIN_MID|WIN_SAV,0,10,"External Editor Name" ! 1666: ,cfg.xedit[i]->name,sizeof(cfg.xedit[i]->name)-1,K_EDIT)) ! 1667: strcpy(cfg.xedit[i]->name,str); ! 1668: break; ! 1669: case 1: ! 1670: strcpy(str,cfg.xedit[i]->code); ! 1671: SETHELP(WHERE); ! 1672: /* ! 1673: `External Editor Internal Code:` ! 1674: ! 1675: Every external editor must have its own unique internal code for ! 1676: Synchronet to reference it by. It is helpful if this code is an ! 1677: abreviation of the name. ! 1678: */ ! 1679: uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code (unique)" ! 1680: ,str,LEN_CODE,K_EDIT|K_UPPER); ! 1681: if(code_ok(str)) ! 1682: strcpy(cfg.xedit[i]->code,str); ! 1683: else { ! 1684: uifc.helpbuf=invalid_code; ! 1685: uifc.msg("Invalid Code"); ! 1686: uifc.helpbuf=0; ! 1687: } ! 1688: break; ! 1689: case 2: ! 1690: SETHELP(WHERE); ! 1691: /* ! 1692: `External Editor Command Line:` ! 1693: ! 1694: This is the command line to execute when using this editor. ! 1695: */ ! 1696: uifc.input(WIN_MID|WIN_SAV,0,10,"Command" ! 1697: ,cfg.xedit[i]->rcmd,sizeof(cfg.xedit[i]->rcmd)-1,K_EDIT); ! 1698: break; ! 1699: case 3: ! 1700: sprintf(str,"%s External Editor",cfg.xedit[i]->name); ! 1701: getar(str,cfg.xedit[i]->arstr); ! 1702: break; ! 1703: case 4: ! 1704: switch(cfg.xedit[i]->misc&(XTRN_STDIO|XTRN_CONIO)) { ! 1705: case XTRN_STDIO: ! 1706: k=0; ! 1707: break; ! 1708: case XTRN_CONIO: ! 1709: k=1; ! 1710: break; ! 1711: default: ! 1712: k=2; ! 1713: break; ! 1714: } ! 1715: strcpy(opt[0],"Standard"); ! 1716: strcpy(opt[1],"Console"); ! 1717: strcpy(opt[2],"No"); ! 1718: opt[3][0]=0; ! 1719: SETHELP(WHERE); ! 1720: /* ! 1721: `Intercept I/O:` ! 1722: ! 1723: If this program uses FOSSIL, Socket, or UART communications, ! 1724: set this option to `No`. ! 1725: */ ! 1726: switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Intercept I/O" ,opt)) { ! 1727: case 0: /* Standard */ ! 1728: if((cfg.xedit[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != XTRN_STDIO) { ! 1729: cfg.xedit[i]->misc|=XTRN_STDIO; ! 1730: cfg.xedit[i]->misc&=~XTRN_CONIO; ! 1731: uifc.changes=TRUE; ! 1732: } ! 1733: k=(cfg.xedit[i]->misc&WWIVCOLOR) ? 0:1; ! 1734: SETHELP(WHERE); ! 1735: /* ! 1736: .Editor Uses WWIV Color Codes:. ! 1737: ! 1738: If this editor was written for use exclusively under WWIV, set this ! 1739: option to .Yes.. ! 1740: */ ! 1741: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 1742: ,"Editor Uses WWIV Color Codes",uifcYesNoOpts); ! 1743: if(!k && !(cfg.xedit[i]->misc&WWIVCOLOR)) { ! 1744: cfg.xedit[i]->misc|=WWIVCOLOR; ! 1745: uifc.changes=TRUE; ! 1746: } ! 1747: else if(k==1 && (cfg.xedit[i]->misc&WWIVCOLOR)) { ! 1748: cfg.xedit[i]->misc&=~WWIVCOLOR; ! 1749: uifc.changes=TRUE; ! 1750: } ! 1751: break; ! 1752: case 1: /* Console */ ! 1753: if((cfg.xedit[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != XTRN_CONIO) { ! 1754: cfg.xedit[i]->misc|=XTRN_CONIO; ! 1755: cfg.xedit[i]->misc&=~(XTRN_STDIO|WWIVCOLOR); ! 1756: uifc.changes=TRUE; ! 1757: } ! 1758: break; ! 1759: case 2: /* No */ ! 1760: if((cfg.xedit[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != 0) { ! 1761: cfg.xedit[i]->misc&=~(XTRN_CONIO|XTRN_STDIO|WWIVCOLOR); ! 1762: uifc.changes=TRUE; ! 1763: } ! 1764: break; ! 1765: } ! 1766: break; ! 1767: case 5: ! 1768: k=(cfg.xedit[i]->misc&XTRN_NATIVE) ? 0:1; ! 1769: SETHELP(WHERE); ! 1770: /* ! 1771: `Native Executable:` ! 1772: ! 1773: If this editor is a native (non-DOS) executable, set this option to `Yes`. ! 1774: */ ! 1775: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 1776: ,"Native",uifcYesNoOpts); ! 1777: if(!k && !(cfg.xedit[i]->misc&XTRN_NATIVE)) { ! 1778: cfg.xedit[i]->misc|=XTRN_NATIVE; ! 1779: uifc.changes=TRUE; ! 1780: } ! 1781: else if(k==1 && (cfg.xedit[i]->misc&XTRN_NATIVE)) { ! 1782: cfg.xedit[i]->misc&=~XTRN_NATIVE; ! 1783: uifc.changes=TRUE; ! 1784: } ! 1785: break; ! 1786: case 6: ! 1787: k=(cfg.xedit[i]->misc&XTRN_SH) ? 0:1; ! 1788: SETHELP(WHERE); ! 1789: /* ! 1790: `Use Shell to Execute Command:` ! 1791: ! 1792: If this command-line requires the system command shell to execute, (Unix ! 1793: shell script or DOS batch file), set this option to ~Yes~. ! 1794: */ ! 1795: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 1796: ,"Use Shell",uifcYesNoOpts); ! 1797: if(!k && !(cfg.xedit[i]->misc&XTRN_SH)) { ! 1798: cfg.xedit[i]->misc|=XTRN_SH; ! 1799: uifc.changes=TRUE; ! 1800: } else if(k==1 && (cfg.xedit[i]->misc&XTRN_SH)) { ! 1801: cfg.xedit[i]->misc&=~XTRN_SH; ! 1802: uifc.changes=TRUE; ! 1803: } ! 1804: break; ! 1805: case 7: ! 1806: k=(cfg.xedit[i]->misc"EWRAP) ? 0:1; ! 1807: SETHELP(WHERE); ! 1808: /* ! 1809: `Word Wrap Quoted Text:` ! 1810: ! 1811: FIXME ! 1812: */ ! 1813: switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 1814: ,"Word Wrap Quoted Text",uifcYesNoOpts)) { ! 1815: case 0: ! 1816: if(!(cfg.xedit[i]->misc"EWRAP)) { ! 1817: cfg.xedit[i]->misc|=QUOTEWRAP; ! 1818: uifc.changes=TRUE; ! 1819: } ! 1820: break; ! 1821: case 1: ! 1822: if(cfg.xedit[i]->misc"EWRAP) { ! 1823: cfg.xedit[i]->misc&=~QUOTEWRAP; ! 1824: uifc.changes=TRUE; ! 1825: } ! 1826: break; ! 1827: } ! 1828: break; ! 1829: case 8: ! 1830: k=3; ! 1831: strcpy(opt[0],"All"); ! 1832: strcpy(opt[1],"None"); ! 1833: strcpy(opt[2],"Prompt User"); ! 1834: opt[3][0]=0; ! 1835: SETHELP(WHERE); ! 1836: /* ! 1837: `Automatically Quoted Text:` ! 1838: ! 1839: If you want all the message text to be automatically entered into the ! 1840: message input file (e.g. `INPUT.MSG` or `MSGTMP`), select `All`. ! 1841: ! 1842: If you want the user to be prompted for which lines to quote before ! 1843: running the editor, select `Prompt User`. ! 1844: ! 1845: If you want none of the lines to be automatically quoted, select `None`. ! 1846: This option is mainly for use with editors that support the `QUOTES.TXT` ! 1847: drop file (like `SyncEdit v2.x`). ! 1848: */ ! 1849: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Automatically Quoted Text" ! 1850: ,opt); ! 1851: if(!k && !(cfg.xedit[i]->misc"EALL)) { ! 1852: cfg.xedit[i]->misc|=QUOTEALL; ! 1853: cfg.xedit[i]->misc&=~QUOTENONE; ! 1854: uifc.changes=TRUE; ! 1855: } ! 1856: else if(k==1 && !(cfg.xedit[i]->misc"ENONE)) { ! 1857: cfg.xedit[i]->misc|=QUOTENONE; ! 1858: cfg.xedit[i]->misc&=~QUOTEALL; ! 1859: uifc.changes=TRUE; ! 1860: } ! 1861: else if(k==2 && cfg.xedit[i]->misc&(QUOTENONE|QUOTEALL)) { ! 1862: cfg.xedit[i]->misc&=~(QUOTENONE|QUOTEALL); ! 1863: uifc.changes=TRUE; ! 1864: } ! 1865: break; ! 1866: case 9: ! 1867: k=cfg.xedit[i]->misc&QUICKBBS ? 0:1; ! 1868: strcpy(opt[0],"QuickBBS MSGINF/MSGTMP"); ! 1869: strcpy(opt[1],"WWIV EDITOR.INF/RESULT.ED"); ! 1870: opt[2][0]=0; ! 1871: SETHELP(WHERE); ! 1872: /* ! 1873: `Editor Information File:` ! 1874: ! 1875: If this external editor uses the QuickBBS style MSGTMP interface, set ! 1876: this option to ~QuickBBS MSGINF/MSGTMP~, otherwise set to ~WWIV EDITOR.INF/RESULT.ED~. ! 1877: */ ! 1878: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Editor Information Files" ! 1879: ,opt); ! 1880: if(!k && !(cfg.xedit[i]->misc&QUICKBBS)) { ! 1881: cfg.xedit[i]->misc|=QUICKBBS; ! 1882: uifc.changes=TRUE; ! 1883: } ! 1884: else if(k==1 && (cfg.xedit[i]->misc&QUICKBBS)) { ! 1885: cfg.xedit[i]->misc&=~QUICKBBS; ! 1886: uifc.changes=TRUE; ! 1887: } ! 1888: break; ! 1889: case 10: ! 1890: k=(cfg.xedit[i]->misc&EXPANDLF) ? 0:1; ! 1891: SETHELP(WHERE); ! 1892: /* ! 1893: `Expand Line Feeds to Carriage Return/Line Feed Pairs:` ! 1894: ! 1895: If this external editor saves new lines as a single line feed character ! 1896: instead of a carriage return/line feed pair, set this option to `Yes`. ! 1897: */ ! 1898: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Expand LF to CRLF" ! 1899: ,uifcYesNoOpts); ! 1900: if(!k && !(cfg.xedit[i]->misc&EXPANDLF)) { ! 1901: cfg.xedit[i]->misc|=EXPANDLF; ! 1902: uifc.changes=TRUE; ! 1903: } ! 1904: else if(k==1 && (cfg.xedit[i]->misc&EXPANDLF)) { ! 1905: cfg.xedit[i]->misc&=~EXPANDLF; ! 1906: uifc.changes=TRUE; ! 1907: } ! 1908: break; ! 1909: case 11: ! 1910: k=(cfg.xedit[i]->misc&STRIPKLUDGE) ? 0:1; ! 1911: SETHELP(WHERE); ! 1912: /* ! 1913: `Strip FidoNet Kludge Lines From Messages:` ! 1914: ! 1915: If this external editor adds FidoNet Kludge lines to the message text, ! 1916: set this option to `Yes` to strip those lines from the message. ! 1917: */ ! 1918: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 1919: ,"Strip FidoNet Kludge Lines" ! 1920: ,uifcYesNoOpts); ! 1921: if(!k && !(cfg.xedit[i]->misc&STRIPKLUDGE)) { ! 1922: cfg.xedit[i]->misc|=STRIPKLUDGE; ! 1923: uifc.changes=TRUE; ! 1924: } ! 1925: else if(k==1 && (cfg.xedit[i]->misc&STRIPKLUDGE)) { ! 1926: cfg.xedit[i]->misc&=~STRIPKLUDGE; ! 1927: uifc.changes=TRUE; ! 1928: } ! 1929: break; ! 1930: case 12: ! 1931: k=0; ! 1932: strcpy(opt[k++],"None"); ! 1933: sprintf(opt[k++],"%-15s %s","Synchronet","XTRN.DAT"); ! 1934: sprintf(opt[k++],"%-15s %s","WWIV","CHAIN.TXT"); ! 1935: sprintf(opt[k++],"%-15s %s","GAP","DOOR.SYS"); ! 1936: sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO#.DEF"); ! 1937: sprintf(opt[k++],"%-15s %s","Wildcat","CALLINFO.BBS"); ! 1938: sprintf(opt[k++],"%-15s %s","PCBoard","PCBOARD.SYS"); ! 1939: sprintf(opt[k++],"%-15s %s","SpitFire","SFDOORS.DAT"); ! 1940: sprintf(opt[k++],"%-15s %s","MegaMail","UTIDOOR.TXT"); ! 1941: sprintf(opt[k++],"%-15s %s","Solar Realms","DOORFILE.SR"); ! 1942: sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO1.DEF"); ! 1943: sprintf(opt[k++],"%-15s %s","TriBBS","TRIBBS.SYS"); ! 1944: sprintf(opt[k++],"%-15s %s","Mystic","DOOR32.SYS"); ! 1945: opt[k][0]=0; ! 1946: k=cfg.xedit[i]->type; ! 1947: SETHELP(WHERE); ! 1948: /* ! 1949: `External Program BBS Drop File Type:` ! 1950: ! 1951: If this external editor requires a specific BBS data (drop) file ! 1952: format, select the file format from the list. ! 1953: */ ! 1954: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 ! 1955: ,"BBS Drop File Type",opt); ! 1956: if(k==-1) ! 1957: break; ! 1958: if(cfg.xedit[i]->type!=k) { ! 1959: cfg.xedit[i]->type=k; ! 1960: if(cfg.xedit[i]->type==XTRN_DOOR32) ! 1961: cfg.xedit[i]->misc|=XTRN_NATIVE; ! 1962: uifc.changes=TRUE; ! 1963: } ! 1964: if(cfg.xedit[i]->type) { ! 1965: k=(cfg.xedit[i]->misc&XTRN_LWRCASE) ? 0:1; ! 1966: k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Lowercase Filename",uifcYesNoOpts); ! 1967: if(k==0 && !(cfg.xedit[i]->misc&XTRN_LWRCASE)) { ! 1968: cfg.xedit[i]->misc|=XTRN_LWRCASE; ! 1969: uifc.changes=TRUE; ! 1970: } ! 1971: else if(k==1 && (cfg.xedit[i]->misc&XTRN_LWRCASE)) { ! 1972: cfg.xedit[i]->misc&=~XTRN_LWRCASE; ! 1973: uifc.changes=TRUE; ! 1974: } ! 1975: } ! 1976: break; ! 1977: } ! 1978: } ! 1979: } ! 1980: } ! 1981: ! 1982: int natvpgm_cfg() ! 1983: { ! 1984: static int dflt,bar; ! 1985: char str[81]; ! 1986: int j; ! 1987: uint i; ! 1988: ! 1989: while(1) { ! 1990: for(i=0;i<MAX_OPTS && i<cfg.total_natvpgms;i++) ! 1991: sprintf(opt[i],"%-12s",cfg.natvpgm[i]->name); ! 1992: opt[i][0]=0; ! 1993: j=WIN_ACT|WIN_CHE|WIN_L2R|WIN_SAV; ! 1994: if(cfg.total_natvpgms) ! 1995: j|=WIN_DEL; ! 1996: if(cfg.total_natvpgms<MAX_OPTS) ! 1997: j|=WIN_INS|WIN_INSACT|WIN_XTR; ! 1998: SETHELP(WHERE); ! 1999: /* ! 2000: `Native Program List:` ! 2001: ! 2002: This is a list of all native (non-DOS) external program (executable file) ! 2003: names that you may execute under `Synchronet`. This list is not ! 2004: used in Synchronet for DOS. Any programs not listed here will be assumed ! 2005: to be DOS programs and executed accordingly. ! 2006: ! 2007: Use ~ INS ~ and ~ DELETE ~ to add and remove native program names. ! 2008: ! 2009: To change the filename of a program, hit ~ ENTER ~. ! 2010: */ ! 2011: i=uifc.list(j,0,0,30,&dflt,&bar,"Native Program List",opt); ! 2012: if((signed)i==-1) ! 2013: break; ! 2014: if((i&MSK_ON)==MSK_INS) { ! 2015: i&=MSK_OFF; ! 2016: SETHELP(WHERE); ! 2017: /* ! 2018: `Native Program Name:` ! 2019: ! 2020: This is the executable filename of the native external program. ! 2021: */ ! 2022: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Native Program Name",str,12 ! 2023: ,0)<1) ! 2024: continue; ! 2025: if((cfg.natvpgm=(natvpgm_t **)realloc(cfg.natvpgm ! 2026: ,sizeof(natvpgm_t *)*(cfg.total_natvpgms+1)))==NULL) { ! 2027: errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_natvpgms+1); ! 2028: cfg.total_natvpgms=0; ! 2029: bail(1); ! 2030: continue; ! 2031: } ! 2032: if(cfg.total_natvpgms) ! 2033: for(j=cfg.total_natvpgms;j>i;j--) ! 2034: cfg.natvpgm[j]=cfg.natvpgm[j-1]; ! 2035: if((cfg.natvpgm[i]=(natvpgm_t *)malloc(sizeof(natvpgm_t)))==NULL) { ! 2036: errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(natvpgm_t)); ! 2037: continue; ! 2038: } ! 2039: memset((natvpgm_t *)cfg.natvpgm[i],0,sizeof(natvpgm_t)); ! 2040: strcpy(cfg.natvpgm[i]->name,str); ! 2041: cfg.total_natvpgms++; ! 2042: uifc.changes=TRUE; ! 2043: continue; ! 2044: } ! 2045: if((i&MSK_ON)==MSK_DEL) { ! 2046: i&=MSK_OFF; ! 2047: free(cfg.natvpgm[i]); ! 2048: cfg.total_natvpgms--; ! 2049: for(j=i;j<cfg.total_natvpgms;j++) ! 2050: cfg.natvpgm[j]=cfg.natvpgm[j+1]; ! 2051: uifc.changes=TRUE; ! 2052: continue; ! 2053: } ! 2054: SETHELP(WHERE); ! 2055: /* ! 2056: `Native Program Name:` ! 2057: ! 2058: This is the executable filename of the Native external program. ! 2059: */ ! 2060: strcpy(str,cfg.natvpgm[i]->name); ! 2061: if(uifc.input(WIN_MID|WIN_SAV,0,5,"Native Program Name",str,12 ! 2062: ,K_EDIT)>0) ! 2063: strcpy(cfg.natvpgm[i]->name,str); ! 2064: } ! 2065: return(0); ! 2066: } ! 2067: ! 2068: ! 2069: void xtrnsec_cfg() ! 2070: { ! 2071: static int xtrnsec_dflt,xtrnsec_opt; ! 2072: char str[81],code[9],done=0,*p; ! 2073: int j,k; ! 2074: uint i; ! 2075: static xtrnsec_t savxtrnsec; ! 2076: ! 2077: while(1) { ! 2078: for(i=0;i<cfg.total_xtrnsecs && i<MAX_OPTS;i++) ! 2079: sprintf(opt[i],"%-25s",cfg.xtrnsec[i]->name); ! 2080: opt[i][0]=0; ! 2081: j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_BOT; ! 2082: if(cfg.total_xtrnsecs) ! 2083: j|=WIN_DEL|WIN_GET; ! 2084: if(cfg.total_xtrnsecs<MAX_OPTS) ! 2085: j|=WIN_INS|WIN_INSACT|WIN_XTR; ! 2086: if(savxtrnsec.name[0]) ! 2087: j|=WIN_PUT; ! 2088: SETHELP(WHERE); ! 2089: /* ! 2090: `Online Program Sections:` ! 2091: ! 2092: This is a list of `Online Program Sections` configured for your system. ! 2093: ! 2094: To add an online program section, select the desired location with the ! 2095: arrow keys and hit ~ INS ~. ! 2096: ! 2097: To delete an online program section, select it and hit ~ DEL ~. ! 2098: ! 2099: To configure an online program section, select it and hit ~ ENTER ~. ! 2100: */ ! 2101: i=uifc.list(j,0,0,45,&xtrnsec_dflt,0,"Online Program Sections",opt); ! 2102: if((signed)i==-1) ! 2103: return; ! 2104: if((i&MSK_ON)==MSK_INS) { ! 2105: i&=MSK_OFF; ! 2106: SETHELP(WHERE); ! 2107: /* ! 2108: `Online Program Section Name:` ! 2109: ! 2110: This is the name of this section. ! 2111: */ ! 2112: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Online Program Section Name",str,40 ! 2113: ,0)<1) ! 2114: continue; ! 2115: sprintf(code,"%.8s",str); ! 2116: p=strchr(code,' '); ! 2117: if(p) *p=0; ! 2118: strupr(code); ! 2119: SETHELP(WHERE); ! 2120: /* ! 2121: `Online Program Section Internal Code:` ! 2122: ! 2123: Every online program section must have its own unique internal code ! 2124: for Synchronet to reference it by. It is helpful if this code is an ! 2125: abreviation of the name. ! 2126: */ ! 2127: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Online Program Section Internal Code" ! 2128: ,code,LEN_CODE,K_EDIT|K_UPPER)<1) ! 2129: continue; ! 2130: if(!code_ok(code)) { ! 2131: uifc.helpbuf=invalid_code; ! 2132: uifc.msg("Invalid Code"); ! 2133: uifc.helpbuf=0; ! 2134: continue; ! 2135: } ! 2136: if((cfg.xtrnsec=(xtrnsec_t **)realloc(cfg.xtrnsec ! 2137: ,sizeof(xtrnsec_t *)*(cfg.total_xtrnsecs+1)))==NULL) { ! 2138: errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_xtrnsecs+1); ! 2139: cfg.total_xtrnsecs=0; ! 2140: bail(1); ! 2141: continue; ! 2142: } ! 2143: if(cfg.total_xtrnsecs) { ! 2144: for(j=cfg.total_xtrnsecs;j>i;j--) ! 2145: cfg.xtrnsec[j]=cfg.xtrnsec[j-1]; ! 2146: for(j=0;j<cfg.total_xtrns;j++) ! 2147: if(cfg.xtrn[j]->sec>=i) ! 2148: cfg.xtrn[j]->sec++; ! 2149: } ! 2150: ! 2151: ! 2152: if((cfg.xtrnsec[i]=(xtrnsec_t *)malloc(sizeof(xtrnsec_t)))==NULL) { ! 2153: errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(xtrnsec_t)); ! 2154: continue; ! 2155: } ! 2156: memset((xtrnsec_t *)cfg.xtrnsec[i],0,sizeof(xtrnsec_t)); ! 2157: strcpy(cfg.xtrnsec[i]->name,str); ! 2158: strcpy(cfg.xtrnsec[i]->code,code); ! 2159: cfg.total_xtrnsecs++; ! 2160: uifc.changes=TRUE; ! 2161: continue; ! 2162: } ! 2163: if((i&MSK_ON)==MSK_DEL) { ! 2164: i&=MSK_OFF; ! 2165: free(cfg.xtrnsec[i]); ! 2166: for(j=0;j<cfg.total_xtrns;) { ! 2167: if(cfg.xtrn[j]->sec==i) { /* delete xtrns of this group */ ! 2168: free(cfg.xtrn[j]); ! 2169: cfg.total_xtrns--; ! 2170: k=j; ! 2171: while(k<cfg.total_xtrns) { /* move all xtrns down */ ! 2172: cfg.xtrn[k]=cfg.xtrn[k+1]; ! 2173: k++; ! 2174: } ! 2175: } ! 2176: else j++; ! 2177: } ! 2178: for(j=0;j<cfg.total_xtrns;j++) /* move xtrn group numbers down */ ! 2179: if(cfg.xtrn[j]->sec>i) ! 2180: cfg.xtrn[j]->sec--; ! 2181: cfg.total_xtrnsecs--; ! 2182: while(i<cfg.total_xtrnsecs) { ! 2183: cfg.xtrnsec[i]=cfg.xtrnsec[i+1]; ! 2184: i++; ! 2185: } ! 2186: uifc.changes=TRUE; ! 2187: continue; ! 2188: } ! 2189: if((i&MSK_ON)==MSK_GET) { ! 2190: i&=MSK_OFF; ! 2191: savxtrnsec=*cfg.xtrnsec[i]; ! 2192: continue; ! 2193: } ! 2194: if((i&MSK_ON)==MSK_PUT) { ! 2195: i&=MSK_OFF; ! 2196: *cfg.xtrnsec[i]=savxtrnsec; ! 2197: uifc.changes=TRUE; ! 2198: continue; ! 2199: } ! 2200: done=0; ! 2201: while(!done) { ! 2202: k=0; ! 2203: sprintf(opt[k++],"%-27.27s%s","Name",cfg.xtrnsec[i]->name); ! 2204: sprintf(opt[k++],"%-27.27s%s","Internal Code",cfg.xtrnsec[i]->code); ! 2205: sprintf(opt[k++],"%-27.27s%.40s","Access Requirements" ! 2206: ,cfg.xtrnsec[i]->arstr); ! 2207: sprintf(opt[k++],"%s","Available Online Programs..."); ! 2208: opt[k][0]=0; ! 2209: sprintf(str,"%s Program Section",cfg.xtrnsec[i]->name); ! 2210: switch(uifc.list(WIN_SAV|WIN_ACT|WIN_MID,0,0,60,&xtrnsec_opt,0,str ! 2211: ,opt)) { ! 2212: case -1: ! 2213: done=1; ! 2214: break; ! 2215: case 0: ! 2216: SETHELP(WHERE); ! 2217: /* ! 2218: `Online Program Section Name:` ! 2219: ! 2220: This is the name of this section. ! 2221: */ ! 2222: strcpy(str,cfg.xtrnsec[i]->name); /* save */ ! 2223: if(!uifc.input(WIN_MID|WIN_SAV,0,10 ! 2224: ,"Program Section Name" ! 2225: ,cfg.xtrnsec[i]->name,sizeof(cfg.xtrnsec[i]->name)-1,K_EDIT)) ! 2226: strcpy(cfg.xtrnsec[i]->name,str); ! 2227: break; ! 2228: case 1: ! 2229: strcpy(str,cfg.xtrnsec[i]->code); ! 2230: SETHELP(WHERE); ! 2231: /* ! 2232: `Online Program Section Internal Code:` ! 2233: ! 2234: Every online program section must have its own unique internal code ! 2235: for Synchronet to reference it by. It is helpful if this code is an ! 2236: abreviation of the name. ! 2237: */ ! 2238: uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code (unique)" ! 2239: ,str,LEN_CODE,K_EDIT|K_UPPER); ! 2240: if(code_ok(str)) ! 2241: strcpy(cfg.xtrnsec[i]->code,str); ! 2242: else { ! 2243: uifc.helpbuf=invalid_code; ! 2244: uifc.msg("Invalid Code"); ! 2245: uifc.helpbuf=0; ! 2246: } ! 2247: break; ! 2248: case 2: ! 2249: getar(cfg.xtrnsec[i]->name,cfg.xtrnsec[i]->arstr); ! 2250: break; ! 2251: case 3: ! 2252: xtrn_cfg(i); ! 2253: break; ! 2254: } ! 2255: } ! 2256: } ! 2257: } ! 2258: ! 2259: void hotkey_cfg(void) ! 2260: { ! 2261: static int dflt,dfltopt,bar; ! 2262: char str[81],done=0; ! 2263: int j,k; ! 2264: uint i; ! 2265: static hotkey_t savhotkey; ! 2266: ! 2267: while(1) { ! 2268: for(i=0;i<cfg.total_hotkeys && i<MAX_OPTS;i++) ! 2269: sprintf(opt[i],"Ctrl-%c %.40s" ! 2270: ,cfg.hotkey[i]->key+'@' ! 2271: ,cfg.hotkey[i]->cmd); ! 2272: opt[i][0]=0; ! 2273: j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_RHT; ! 2274: if(cfg.total_hotkeys) ! 2275: j|=WIN_DEL|WIN_GET; ! 2276: if(cfg.total_hotkeys<MAX_OPTS) ! 2277: j|=WIN_INS|WIN_INSACT|WIN_XTR; ! 2278: if(savhotkey.cmd[0]) ! 2279: j|=WIN_PUT; ! 2280: SETHELP(WHERE); ! 2281: /* ! 2282: `Global Hot Key Events:` ! 2283: ! 2284: This is a list of programs or loadable modules that can be executed by ! 2285: anyone on the BBS at any time (while the BBS has control of user input). ! 2286: ! 2287: To add a hot key event, select the desired location and hit ~ INS ~. ! 2288: ! 2289: To delete a hot key event, select it and hit ~ DEL ~. ! 2290: ! 2291: To configure a hot key event, select it and hit ~ ENTER ~. ! 2292: */ ! 2293: i=uifc.list(j,0,0,45,&dflt,&bar,"Global Hot Key Events",opt); ! 2294: if((signed)i==-1) ! 2295: return; ! 2296: if((i&MSK_ON)==MSK_INS) { ! 2297: i&=MSK_OFF; ! 2298: SETHELP(WHERE); ! 2299: /* ! 2300: `Global Hot Key:` ! 2301: ! 2302: This is the control key used to trigger the hot key event. Example, A ! 2303: indicates a Ctrl-A hot key event. ! 2304: */ ! 2305: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Control Key",str,1 ! 2306: ,K_UPPER)<1) ! 2307: continue; ! 2308: ! 2309: if((cfg.hotkey=(hotkey_t **)realloc(cfg.hotkey ! 2310: ,sizeof(hotkey_t *)*(cfg.total_hotkeys+1)))==NULL) { ! 2311: errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_hotkeys+1); ! 2312: cfg.total_hotkeys=0; ! 2313: bail(1); ! 2314: continue; ! 2315: } ! 2316: if(cfg.total_hotkeys) ! 2317: for(j=cfg.total_hotkeys;j>i;j--) ! 2318: cfg.hotkey[j]=cfg.hotkey[j-1]; ! 2319: if((cfg.hotkey[i]=(hotkey_t *)malloc(sizeof(hotkey_t)))==NULL) { ! 2320: errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(hotkey_t)); ! 2321: continue; ! 2322: } ! 2323: memset((hotkey_t *)cfg.hotkey[i],0,sizeof(hotkey_t)); ! 2324: cfg.hotkey[i]->key=str[0]-'@'; ! 2325: cfg.total_hotkeys++; ! 2326: uifc.changes=TRUE; ! 2327: continue; ! 2328: } ! 2329: if((i&MSK_ON)==MSK_DEL) { ! 2330: i&=MSK_OFF; ! 2331: free(cfg.hotkey[i]); ! 2332: cfg.total_hotkeys--; ! 2333: for(j=i;j<cfg.total_hotkeys;j++) ! 2334: cfg.hotkey[j]=cfg.hotkey[j+1]; ! 2335: uifc.changes=TRUE; ! 2336: continue; ! 2337: } ! 2338: if((i&MSK_ON)==MSK_GET) { ! 2339: i&=MSK_OFF; ! 2340: savhotkey=*cfg.hotkey[i]; ! 2341: continue; ! 2342: } ! 2343: if((i&MSK_ON)==MSK_PUT) { ! 2344: i&=MSK_OFF; ! 2345: *cfg.hotkey[i]=savhotkey; ! 2346: uifc.changes=TRUE; ! 2347: continue; ! 2348: } ! 2349: done=0; ! 2350: while(!done) { ! 2351: k=0; ! 2352: sprintf(opt[k++],"%-27.27sCtrl-%c","Global Hot Key" ! 2353: ,cfg.hotkey[i]->key+'@'); ! 2354: sprintf(opt[k++],"%-27.27s%.40s","Command Line",cfg.hotkey[i]->cmd); ! 2355: opt[k][0]=0; ! 2356: SETHELP(WHERE); ! 2357: /* ! 2358: `Global Hot Key Event:` ! 2359: ! 2360: This menu allows you to change the settings for the selected global ! 2361: hot key event. Hot key events are control characters that are used to ! 2362: execute an external program or module anywhere in the BBS. ! 2363: */ ! 2364: sprintf(str,"Ctrl-%c Hot Key Event",cfg.hotkey[i]->key+'@'); ! 2365: switch(uifc.list(WIN_SAV|WIN_ACT|WIN_L2R|WIN_BOT,0,0,60,&dfltopt,0 ! 2366: ,str,opt)) { ! 2367: case -1: ! 2368: done=1; ! 2369: break; ! 2370: case 0: ! 2371: SETHELP(WHERE); ! 2372: /* ! 2373: `Global Hot-Ctrl Key:` ! 2374: ! 2375: This is the global control key used to execute this event. ! 2376: */ ! 2377: sprintf(str,"%c",cfg.hotkey[i]->key+'@'); ! 2378: if(uifc.input(WIN_MID|WIN_SAV,0,10,"Global Hot Ctrl-Key" ! 2379: ,str,1,K_EDIT|K_UPPER)>0) ! 2380: cfg.hotkey[i]->key=str[0]-'@'; ! 2381: break; ! 2382: case 1: ! 2383: SETHELP(WHERE); ! 2384: /* ! 2385: `Hot Key Event Command Line:` ! 2386: ! 2387: This is the command line to execute when this hot key is pressed. ! 2388: */ ! 2389: uifc.input(WIN_MID|WIN_SAV,0,10,"Command" ! 2390: ,cfg.hotkey[i]->cmd,sizeof(cfg.hotkey[i]->cmd)-1,K_EDIT); ! 2391: break; ! 2392: } } } ! 2393: ! 2394: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.