|
|
1.1 ! root 1: /* menuedit.c */ ! 2: ! 3: /* Synchronet Menu Editor */ ! 4: ! 5: /* $Id: menuedit.c,v 1.4 2005/02/20 20:51:40 deuce Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This program is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU General Public License for more details: gpl.txt or * ! 18: * http://www.fsf.org/copyleft/gpl.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: #include <stdlib.h> ! 39: #include <malloc.h> /* alloca */ ! 40: #include "genwrap.h" ! 41: #include "uifc.h" ! 42: #include "dirwrap.h" ! 43: #include "ini_file.h" ! 44: ! 45: uifcapi_t uifc; /* User Interface (UIFC) Library API */ ! 46: ! 47: static int yesno(char *prompt, BOOL dflt) ! 48: { ! 49: char* opt[]={"Yes","No",NULL}; ! 50: int i=!dflt; /* reverse logic */ ! 51: ! 52: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0,prompt,opt); ! 53: if(i>=0) { ! 54: i=!i; /* reverse logic */ ! 55: if(i!=dflt) ! 56: uifc.changes=TRUE; ! 57: } ! 58: return(i); ! 59: } ! 60: ! 61: static const char* boolstr(BOOL val) ! 62: { ! 63: return(val?"Yes":"No"); ! 64: } ! 65: ! 66: static void edit_menu(char* path) ! 67: { ! 68: char str[MAX_PATH*2]; ! 69: FILE* fp; ! 70: int i; ! 71: static dflt; ! 72: char title[MAX_PATH+1]; ! 73: char value[INI_MAX_VALUE_LEN]; ! 74: char* p; ! 75: char* opt[MAX_OPTS+1]; ! 76: char exec[INI_MAX_VALUE_LEN]; ! 77: char prompt[INI_MAX_VALUE_LEN]; ! 78: char menu_file[MAX_PATH+1]; ! 79: char menu_format[INI_MAX_VALUE_LEN]; ! 80: size_t menu_column_width; ! 81: BOOL menu_reverse; ! 82: BOOL hotkeys; ! 83: BOOL expert; ! 84: const char* opt_fmt = "%-25.25s %s"; ! 85: str_list_t list; ! 86: ini_style_t style; ! 87: ! 88: /* Open menu file */ ! 89: if((fp=fopen(path,"r"))==NULL) { ! 90: sprintf(str,"ERROR %u opening %s",errno,path); ! 91: uifc.msg(str); ! 92: return; ! 93: } ! 94: ! 95: /* Read menu file */ ! 96: SAFECOPY(prompt,iniGetString(fp,ROOT_SECTION, "prompt", "'Command: '", value)); ! 97: SAFECOPY(exec,iniGetString(fp,ROOT_SECTION, "exec", "", value)); ! 98: SAFECOPY(menu_file,iniGetString(fp,ROOT_SECTION, "menu_file", "", value)); ! 99: SAFECOPY(menu_format,iniGetString(fp,ROOT_SECTION, "menu_format", "\1n\1h\1w%s \1b%s", value)); ! 100: menu_column_width=iniGetInteger(fp,ROOT_SECTION,"menu_column_width", 39); ! 101: menu_reverse=iniGetBool(fp,ROOT_SECTION,"menu_reverse", FALSE); ! 102: ! 103: hotkeys=iniGetBool(fp,ROOT_SECTION,"hotkeys",TRUE); ! 104: expert=iniGetBool(fp,ROOT_SECTION,"expert",TRUE); ! 105: ! 106: fclose(fp); ! 107: ! 108: ! 109: for(i=0;i<MAX_OPTS+1;i++) ! 110: opt[i]=(char *)alloca(MAX_OPLN+1); ! 111: ! 112: SAFECOPY(str,getfname(path)); ! 113: if((p=getfext(str))!=NULL) ! 114: *p=0; ! 115: SAFEPRINTF(title, "Menu: %s", str); ! 116: uifc.changes=0; ! 117: while(1) { ! 118: ! 119: /* Create option list */ ! 120: i=0; ! 121: safe_snprintf(opt[i++],MAX_OPLN,opt_fmt,"Menu File", menu_file[0] ? menu_file : "<Dynamic>"); ! 122: safe_snprintf(opt[i++],MAX_OPLN,opt_fmt,"Execute (JS Expression)",exec[0] ? exec : "<nothing>"); ! 123: safe_snprintf(opt[i++],MAX_OPLN,opt_fmt,"Prompt (JS String)",prompt[0] ? prompt : "<none>"); ! 124: safe_snprintf(opt[i++],MAX_OPLN,opt_fmt,"Hot Key Input",boolstr(hotkeys)); ! 125: safe_snprintf(opt[i++],MAX_OPLN,opt_fmt,"Display Menu" ! 126: ,expert ? "Based on User \"Expert\" Setting" ! 127: : "Always"); ! 128: safe_snprintf(opt[i++],MAX_OPLN,"Commands..."); ! 129: ! 130: opt[i][0]=0; ! 131: ! 132: i=uifc.list(WIN_ACT|WIN_CHE|WIN_RHT|WIN_BOT,0,0,10,&dflt,0 ! 133: ,title,opt); ! 134: if(i==-1) { ! 135: if(uifc.changes) { ! 136: i=yesno("Save Changes",TRUE); ! 137: if(i==-1) ! 138: continue; ! 139: if(i==FALSE) ! 140: uifc.changes=0; ! 141: } ! 142: break; ! 143: } ! 144: switch(i) { ! 145: case 0: ! 146: i=yesno("Use Static Menu File", menu_file[0]); ! 147: if(i==-1) ! 148: break; ! 149: if(i==TRUE) ! 150: uifc.input(WIN_MID|WIN_SAV,0,0,"Base Filename" ! 151: ,menu_file,sizeof(menu_file)-1,K_EDIT); ! 152: else { ! 153: menu_file[0]=0; ! 154: } ! 155: break; ! 156: case 1: ! 157: uifc.input(WIN_MID|WIN_SAV,0,0,"Execute (JS Expression)",exec,sizeof(exec)-1,K_EDIT); ! 158: break; ! 159: case 2: ! 160: uifc.input(WIN_MID|WIN_SAV,0,0,"Prompt (JS String)",prompt,sizeof(prompt)-1,K_EDIT); ! 161: break; ! 162: case 3: ! 163: i=yesno("Use Hot Key Input (ENTER key not used)",hotkeys); ! 164: if(i>=0) hotkeys=i; ! 165: break; ! 166: case 4: ! 167: i=yesno("Display Menu Always (Ignore \"Expert\" User Setting)",!expert); ! 168: if(i>=0) expert=!i; ! 169: break; ! 170: } ! 171: } ! 172: ! 173: if(uifc.changes) { /* Saving changes? */ ! 174: ! 175: /* Open menu file */ ! 176: if((fp=fopen(path,"r+"))==NULL) { ! 177: sprintf(str,"ERROR %u opening %s",errno,path); ! 178: uifc.msg(str); ! 179: return; ! 180: } ! 181: ! 182: /* Set .ini style */ ! 183: memset(&style, 0, sizeof(style)); ! 184: style.value_separator=": "; ! 185: ! 186: /* Read menu file */ ! 187: if((list=iniReadFile(fp))!=NULL) { ! 188: ! 189: /* Update options */ ! 190: iniSetString(&list,ROOT_SECTION,"prompt",prompt,&style); ! 191: iniSetString(&list,ROOT_SECTION,"menu_file",menu_file,&style); ! 192: iniSetString(&list,ROOT_SECTION,"menu_format",menu_format,&style); ! 193: iniSetInteger(&list,ROOT_SECTION,"menu_column_width",menu_column_width,&style); ! 194: iniSetBool(&list,ROOT_SECTION,"menu_reverse",menu_reverse,&style); ! 195: ! 196: iniSetBool(&list,ROOT_SECTION,"hotkeys",hotkeys,&style); ! 197: iniSetBool(&list,ROOT_SECTION,"expert",expert,&style); ! 198: ! 199: /* Write menu file */ ! 200: iniWriteFile(fp,list); ! 201: strListFree(&list); ! 202: } ! 203: ! 204: fclose(fp); ! 205: } ! 206: } ! 207: ! 208: int main(int argc, char **argv) ! 209: { ! 210: char* p; ! 211: char str[128]; ! 212: char path[MAX_PATH+1]; ! 213: char exec_dir[MAX_PATH/2]; ! 214: char revision[16]; ! 215: char* opt[MAX_OPTS]; ! 216: int i; ! 217: int dflt=0; ! 218: BOOL door_mode=FALSE; ! 219: glob_t g; ! 220: size_t gi; ! 221: ! 222: sscanf("$Revision: 1.4 $", "%*s %s", revision); ! 223: ! 224: printf("\r\nSynchronet Menu Editor (%s) %s Copyright 2004 " ! 225: "Rob Swindell\r\n",PLATFORM_DESC,revision); ! 226: ! 227: exec_dir[0]=0; ! 228: if((p=getenv("SBBSEXEC"))!=NULL) ! 229: SAFECOPY(exec_dir,p); ! 230: ! 231: for(i=1;i<argc;i++) { ! 232: if(argv[i][0] != '-') ! 233: SAFECOPY(exec_dir,argv[i]); ! 234: } ! 235: if(exec_dir[0]==0) { ! 236: printf("!ERROR: SBBSEXEC environment variable must be set or specified on command-line.\n"); ! 237: return(1); ! 238: } ! 239: ! 240: backslash(exec_dir); ! 241: ! 242: uifc.esc_delay=25; ! 243: ! 244: uifc.size=sizeof(uifc); ! 245: #if defined(USE_UIFC32) ! 246: if(!door_mode) ! 247: i=uifcini32(&uifc); /* curses/conio */ ! 248: else ! 249: #endif ! 250: i=uifcinix(&uifc); /* stdio */ ! 251: if(i!=0) { ! 252: printf("!ERROR: UIFC library init returned: %d\n",i); ! 253: exit(1); ! 254: } ! 255: ! 256: atexit(uifc.bail); ! 257: ! 258: sprintf(str,"Synchronet Menu Editor %s",revision); ! 259: if(uifc.scrn(str)) { ! 260: printf(" USCRN (len=%d) failed!\r\n",uifc.scrn_len+1); ! 261: return(2); ! 262: } ! 263: ! 264: while(1) { ! 265: sprintf(path,"%s*.mnu",exec_dir); ! 266: glob(path,0,NULL,&g); ! 267: for(gi=0;gi<g.gl_pathc && gi<MAX_OPTS;gi++) ! 268: opt[gi]=getfname(g.gl_pathv[gi]); ! 269: opt[gi]=NULL; ! 270: uifc.helpbuf="Sorry, no help available yet"; ! 271: i=uifc.list(WIN_ORG|WIN_ACT|WIN_INS|WIN_DEL,0,0,10,&dflt,0 ! 272: ,"Edit Menu",opt); ! 273: if(i==-1) ! 274: break; ! 275: if(i>=0 && i<(int)g.gl_pathc) ! 276: edit_menu(g.gl_pathv[i]); ! 277: globfree(&g); ! 278: } ! 279: ! 280: return(0); ! 281: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.