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