/* Copyright (c) 2002 * Marko Boomstra (m.boomstra@chello.nl). All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "mudix.h" USER *settings; TRIGGER *global_trigger; NAMING *global_naming; PATH *global_path; VAR *global_variable; int global_alias; char *smash_tilde(char *buf) { char *pBuf = buf; while (*pBuf) { if (*pBuf == '~') *pBuf = '-'; pBuf++; } return buf; } void init_settings(int argc, char **argv) { int i; if (!(settings = (USER *)malloc(sizeof(USER)))) { fprintf(stdout, "No memory for settings?!\n"); exit(1); } fEchoIn = TRUE; fEchoOut = TRUE; settings->trigger_list = NULL; settings->naming_list = NULL; settings->path_list = NULL; settings->tabs_list = NULL; settings->vars_list = NULL; settings->site = NULL; settings->port = 0; settings->state = STATE_READY; settings->sock = 0; for (i=0; ialias[i] = NULL; if (argc != 2) { settings->site = argv[1]; settings->port = atoi(argv[2]); } else if (!load_settings(argv[1])) { printf("Error in userfile!\n"); exit(1); } } SSTATE set_settings(char *input) { char *pIn = input; if (*input == '\0') { if (global_trigger) free_trigger(global_trigger); if (global_naming) free_naming(global_naming); if (global_path) free_path(global_path); if (global_variable) free_var(global_variable); global_trigger = NULL; global_naming = NULL; global_path = NULL; global_variable = NULL; settings->state = STATE_READY; return STATE_ILLPARM; } do { if (!isprint(*pIn)) *pIn = '\0'; } while (*pIn++ != '\0'); switch(settings->state) { default: break; case STATE_CREATE_1: if (!(global_trigger = new_trigger(TRG_LOGIN, FALSE))) { do_status("No memory for trigger?", 3); settings->state = STATE_READY; return STATE_NOMEM; } global_trigger->in = (char *)malloc(strlen(input)+1); global_trigger->inp = global_trigger->in; strcpy(global_trigger->in, input); dialog("What name do you want to login with?"); settings->state = STATE_CREATE_2; break; case STATE_CREATE_2: global_trigger->out = (char *)malloc(strlen(input)+1); strcpy(global_trigger->out, input); global_trigger->out[0] = toupper(global_trigger->out[0]); global_trigger->enabled = TRUE; dialog("What text should trigger the password trigger?"); settings->state = STATE_CREATE_3; break; case STATE_CREATE_3: if (!(global_trigger = new_trigger(TRG_PASSWORD, FALSE))) { do_status("No memory for trigger?", 3); settings->state = STATE_READY; return STATE_NOMEM; } global_trigger->in = (char *)malloc(strlen(input)+1); global_trigger->inp = global_trigger->in; strcpy(global_trigger->in, input); dialog("What password do you want to use to login with?"); settings->state = STATE_CREATE_4; break; case STATE_CREATE_4: global_trigger->out = (char *)malloc(strlen(input)+1); strcpy(global_trigger->out, input); global_trigger->enabled = TRUE; settings->state = STATE_READY; break; case STATE_TABSDELETE: { TABS *tabs; for (tabs = settings->tabs_list; tabs; tabs = tabs->next) { if (!tabs->name) continue; if (strcmp(tabs->name, input)) continue; free_tabs(tabs); do_status("Tab deleted.", 3); break; } settings->state = STATE_READY; break; } case STATE_VDELETE: { VAR *pVar; for (pVar = settings->vars_list; pVar; pVar = pVar->next) { if (!pVar->name || !pVar->value) continue; if (strcmp(pVar->name, input)) continue; free_var(pVar); do_status("Variable deleted.", 3); break; } settings->state = STATE_READY; break; } case STATE_NDELETE: { NAMING *pNm; for (pNm = settings->naming_list; pNm; pNm = pNm->next) { if (!pNm->name || !pNm->string) continue; if (strcmp(pNm->name, input)) continue; free_naming(pNm); do_status("Naming alias deleted.", 3); break; } settings->state = STATE_READY; break; } case STATE_PDELETE: { PATH *path; for (path = settings->path_list; path; path = path->next) { if (!path->name || !path->path) continue; if (strcmp(path->name, input)) continue; free_path(path); do_status("Path deleted.", 3); break; } settings->state = STATE_READY; break; } case STATE_TDELETE: { TRIGGER *trig; int count = atoi(input); for (trig = settings->trigger_list; trig; trig = trig->next) { if (!trig->in || !trig->out) continue; if (--count == 0) { free_trigger(trig); do_status("Trigger deleted.", 3); break; } } settings->state = STATE_READY; break; } case STATE_TTOGGLE: { TRIGGER *trig; int count = atoi(input); for (trig = settings->trigger_list; trig; trig = trig->next) { if (!trig->in || !trig->out) continue; if (--count == 0) { trig->enabled ^= TRUE; if (trig->enabled) do_status("Trigger enabled.", 3); else do_status("Trigger disabled.", 3); break; } } settings->state = STATE_READY; break; } case STATE_TCREATE_1: { int level = atoi(input); if (level < 0) { settings->state = STATE_READY; return STATE_ILLPARM; } if (!(global_trigger = new_trigger(level, FALSE))) { do_status("No memory for trigger?", 3); settings->state = STATE_READY; return STATE_NOMEM; } settings->state = STATE_TCREATE_2; break; } case STATE_TCREATE_2: global_trigger->in = (char *)malloc(strlen(input)+1); global_trigger->inp = global_trigger->in; strcpy(global_trigger->in, input); settings->state = STATE_TCREATE_3; break; case STATE_TCREATE_3: global_trigger->out = (char *)malloc(strlen(input)+1); strcpy(global_trigger->out, input); do_status("Trigger created and enabled.", 3); global_trigger->enabled = TRUE; settings->state = STATE_READY; break; case STATE_TABSCREATE: { TABS *tabs; if (!(tabs = new_tabs(FALSE))) { do_status("No memory for tab?", 3); settings->state = STATE_READY; return STATE_NOMEM; } tabs->name = (char *)malloc(strlen(input)+1); strcpy(tabs->name, input); do_status("Tab created.", 3); settings->state = STATE_READY; break; } case STATE_PCREATE_1: if (!(global_path = new_path(FALSE))) { do_status("No memory for path?", 3); settings->state = STATE_READY; return STATE_NOMEM; } global_path->name = (char *)malloc(strlen(input)+1); strcpy(global_path->name, input); settings->state = STATE_PCREATE_2; break; case STATE_PCREATE_2: global_path->path = (char *)malloc(strlen(input)+1); strcpy(global_path->path, input); do_status("Path created.", 3); settings->state = STATE_READY; break; case STATE_VCREATE_1: if (!(global_variable = var_lookup(input)) && !(global_variable = new_var(FALSE))) { do_status("No memory for variable?", 3); settings->state = STATE_READY; return STATE_NOMEM; } if (!global_variable->name) { global_variable->name = (char *)malloc(strlen(input)+1); strcpy(global_variable->name, input); } settings->state = STATE_VCREATE_2; break; case STATE_VCREATE_2: if (global_variable->value) free(global_variable->value); global_variable->value = (char *)malloc(strlen(input)+1); strcpy(global_variable->value, input); do_status("Variable set.", 3); settings->state = STATE_READY; break; case STATE_ALIAS_1: global_alias = isdigit(*input)? atoi(input)-1: atoi(input+1)-1; if (global_alias < 0 || global_alias > ALIAS_MAX) { do_status("Illegal alias slot.", 3); settings->state = STATE_READY; return STATE_ILLPARM; } settings->state = STATE_ALIAS_2; break; case STATE_ALIAS_2: if (settings->alias[global_alias]) free(settings->alias[global_alias]); settings->alias[global_alias] = (char *)malloc(strlen(input)+1); strcpy(settings->alias[global_alias], input); do_status("Alias created.", 3); settings->state = STATE_READY; break; case STATE_NAMING_1: { NAMING *pNm; for (pNm = settings->naming_list; pNm; pNm = pNm->next) { if (!pNm->name || !pNm->string) continue; if (!strcmp(pNm->name, input)) { do_status("Name alias already exists.", 3); settings->state = STATE_READY; return STATE_READY; } } if (!(global_naming = new_naming(FALSE))) { do_status("No memory for name alias?", 3); settings->state = STATE_READY; return STATE_NOMEM; } global_naming->name = (char *)malloc(strlen(input)+1); strcpy(global_naming->name, input); settings->state = STATE_NAMING_2; break; } case STATE_NAMING_2: global_naming->string = (char *)malloc(strlen(input)+1); strcpy(global_naming->string, input); do_status("Naming alias created.", 3); settings->state = STATE_READY; break; case STATE_QUIT: if (*input == 'y' || *input == 'Y') fDown = TRUE; settings->state = STATE_READY; break; case STATE_SAVE: { TRIGGER *trig; NAMING *pNm; PATH *path; TABS *tabs; VAR *var; FILE *fp; char filename[MAX_STRING]; int i; if (*input == '\0') { do_status("Illegal filename.", 3); settings->state = STATE_READY; return STATE_ILLPARM; } sprintf(filename, "%s.usr", input); if (!(fp = fopen(filename, "w"))) { do_status("Failed to write to file.", 3); settings->state = STATE_READY; return STATE_ERRFILE; } fprintf(fp, "#USER\nsite %s~\nport %d~\n", settings->site, settings->port); for (i=0; ialias[i] || settings->alias[i][0] == '\0') continue; fprintf(fp, "al %d %s~\n", i, smash_tilde(settings->alias[i])); } for (trig = settings->trigger_list; trig; trig = trig->next) { if (!trig->in || !trig->out) continue; fprintf(fp, "trig %d\n%s~\n%s~\n", trig->level, smash_tilde(trig->in), smash_tilde(trig->out)); } for (pNm = settings->naming_list; pNm; pNm = pNm->next) { if (!pNm->name || !pNm->string) continue; fprintf(fp, "nmal\n%s~\n%s~\n", smash_tilde(pNm->name), smash_tilde(pNm->string)); } for (path = settings->path_list; path; path = path->next) { if (!path->name || !path->path) continue; fprintf(fp, "path\n%s~\n%s~\n", smash_tilde(path->name), smash_tilde(path->path)); } for (tabs = settings->tabs_list; tabs; tabs = tabs->next) { if (!tabs->name) continue; fprintf(fp, "tab\n%s~\n", smash_tilde(tabs->name)); } for (var = settings->vars_list; var; var = var->next) { if (!var->name || !var->value) continue; fprintf(fp, "var\n%s~\n%s~\n", smash_tilde(var->name), smash_tilde(var->value)); } fprintf(fp, "#END"); fclose(fp); do_status("Userfile created.", 3); settings->state = STATE_READY; break; } case STATE_WRITE: /* * Write settings in a format that can be read with #read * In most cases this will serve as an example macro file... * Edit the created file to your likings (E) */ { TRIGGER *trig; NAMING *pNm; PATH *path; TABS *tabs; VAR *var; FILE *fp; char filename[MAX_STRING]; int i; if (*input == '\0') { do_status("Illegal filename.", 3); settings->state = STATE_READY; return STATE_ILLPARM; } sprintf(filename, "%s.cmd", input); if (!(fp = fopen(filename, "w"))) { do_status("Failed to write to file.", 3); settings->state = STATE_READY; return STATE_ERRFILE; } for (i=0; ialias[i] || settings->alias[i][0] == '\0') continue; fprintf(fp, "#alias %d {%s}\n", i+1, smash_tilde(settings->alias[i])); } for (trig = settings->trigger_list; trig; trig = trig->next) { if (!trig->in || !trig->out) continue; fprintf(fp, "#trigger %d {%s} {%s}\n", trig->level, smash_tilde(trig->in), smash_tilde(trig->out)); } for (pNm = settings->naming_list; pNm; pNm = pNm->next) { if (!pNm->name || !pNm->string) continue; fprintf(fp, "#nmalias {%s} {%s}\n", smash_tilde(pNm->name), smash_tilde(pNm->string)); } for (path = settings->path_list; path; path = path->next) { if (!path->name || !path->path) continue; fprintf(fp, "#path {%s} {%s}\n", smash_tilde(path->name), smash_tilde(path->path)); } for (tabs = settings->tabs_list; tabs; tabs = tabs->next) { if (!tabs->name) continue; fprintf(fp, "#tab {%s}\n", smash_tilde(tabs->name)); } for (var = settings->vars_list; var; var = var->next) { if (!var->name || !var->value) continue; fprintf(fp, "#variable {%s} {%s}\n", smash_tilde(var->name), smash_tilde(var->value)); } fclose(fp); do_status("Commandfile created.", 3); settings->state = STATE_READY; break; } } if (settings->state == STATE_READY) { hide_panel(pDialog); global_trigger = NULL; global_naming = NULL; global_path = NULL; global_variable = NULL; } return settings->state; } void show_settings(void) { TRIGGER *trig; NAMING *alias; PATH *path; TABS *tabs; VAR *var; char *str; int lines, i, width, height, centre; width = LEN_COL-4; height = 21; centre = ((width-2)/2)-1; wresize(wMsg, height, width); werase(wMsg); move_panel(pMsg, 1, 2); trig = trig_lookup(NULL, TRG_LOGIN); lines = 1; str = "MUDix v"VERSION" by M. Boomstra (enigma@dwizardry.dhs.org)"; mvwprintw(wMsg, lines++, centre-strlen(str)/2, str); mvwhline(wMsg, lines++, 0, ACS_HLINE, LEN_COL-4); mvwprintw(wMsg, lines++, 1, "Username : %s", trig? trig->out: "Unknown"); mvwprintw(wMsg, lines-1, centre, " Host : %s", settings->site); mvwprintw(wMsg, lines++, 1, "Port : %d", settings->port); mvwprintw(wMsg, lines-1, centre, " Socket : %d", settings->sock); mvwprintw(wMsg, lines++, 1, "Sent : %d Bytes", total_sent); mvwprintw(wMsg, lines-1, centre, " Received : %d Bytes", total_recv); mvwprintw(wMsg, lines++, 1, "Echo input: %s", fEchoIn? "On": "Off"); mvwprintw(wMsg, lines-1, centre, " Echo outp.: %s", fEchoOut? "On": "Off"); mvwprintw(wMsg, lines++, 1, "Keypadwalk: %s", fKeypadWalk? "On": "Off"); mvwprintw(wMsg, lines-1, centre, " Status : %s", fStatusReport? "On": "Off"); mvwprintw(wMsg, lines++, 1, "Char. mode: %s", fCharacterMode? "On": "Off"); mvwhline(wMsg, lines++, 0, ACS_HLINE, LEN_COL-4); for (i=0, trig = settings->trigger_list; trig; trig = trig->next, i++); mvwprintw(wMsg, lines++, 1, "Triggers : %d", i); for (i=0, alias = settings->naming_list; alias; alias = alias->next, i++); mvwprintw(wMsg, lines++, 1, "Aliases : %d", i); for (i=0, path = settings->path_list; path; path = path->next, i++); mvwprintw(wMsg, lines++, 1, "Paths : %d", i); for (i=0, tabs = settings->tabs_list; tabs; tabs = tabs->next, i++); mvwprintw(wMsg, lines-3, centre, " Tabs : %d", i); for (i=0, var = settings->vars_list; var; var = var->next, i++); mvwprintw(wMsg, lines-2, centre, " Variables : %d", i); mvwhline(wMsg, lines++, 0, ACS_HLINE, LEN_COL-4); for(i=0; ialias[i] ? settings->alias[i] : ""); lines-=ALIAS_MAX/2; for( ; ialias[i] ? settings->alias[i] : ""); draw_border(wMsg); str = "MUDix Settings"; mvwprintw(wMsg, 0, centre-strlen(str)/2, str); show_panel(pMsg); return; } bool load_settings(char *file) { FILE *fp; bool found; if (!(fp = fopen(file, "r"))) return FALSE; found = FALSE; while (1) { char *word, *string; word = fread_word(fp); if (*word == '\0') break; if (!strcmp(word, "#USER")) { if (feof(fp)) break; } else if (!strcmp(word, "#END")) { found = TRUE; break; } else if (!strcmp(word, "site")) { string = fread_string(fp); settings->site = (char *)malloc(strlen(string)+1); strcpy(settings->site, string); } else if (!strcmp(word, "al")) { int nr = atoi(fread_word(fp)); string = fread_string(fp); settings->alias[nr] = (char *)malloc(strlen(string)+1); strcpy(settings->alias[nr], string); } else if (!strcmp(word, "nmal")) { NAMING *pNm; if (!(pNm = new_naming(TRUE))) break; string = fread_string(fp); pNm->name = (char *)malloc(strlen(string)+1); strcpy(pNm->name, string); string = fread_string(fp); pNm->string = (char *)malloc(strlen(string)+1); strcpy(pNm->string, string); } else if (!strcmp(word, "tab")) { TABS *tabs; if (!(tabs = new_tabs(TRUE))) break; string = fread_string(fp); tabs->name = (char *)malloc(strlen(string)+1); strcpy(tabs->name, string); } else if (!strcmp(word, "path")) { PATH *path; if (!(path = new_path(TRUE))) break; string = fread_string(fp); path->name = (char *)malloc(strlen(string)+1); strcpy(path->name, string); string = fread_string(fp); path->path = (char *)malloc(strlen(string)+1); strcpy(path->path, string); } else if (!strcmp(word, "var")) { VAR *var; if (!(var = new_var(TRUE))) break; string = fread_string(fp); var->name = (char *)malloc(strlen(string)+1); strcpy(var->name, string); string = fread_string(fp); var->value = (char *)malloc(strlen(string)+1); strcpy(var->value, string); } else if (!strcmp(word, "trig")) { TRIGGER *trigger; int level = atoi(fread_word(fp)); if (!(trigger = new_trigger(level, TRUE))) break; string = fread_string(fp); trigger->in = (char *)malloc(strlen(string)+1); trigger->inp = trigger->in; strcpy(trigger->in, string); string = fread_string(fp); trigger->out = (char *)malloc(strlen(string)+1); strcpy(trigger->out, string); trigger->enabled = TRUE; } else if (!strcmp(word, "port")) { string = fread_string(fp); settings->port = atoi(string); } else continue; } fclose(fp); return found; }