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