/* 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 <conf.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ncurses.h>
#include <panel.h>
#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; i<ALIAS_MAX; i++)
settings->alias[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; i<ALIAS_MAX; i++) {
if (!settings->alias[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; i<ALIAS_MAX; i++) {
if (!settings->alias[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; i<ALIAS_MAX/2; i++)
mvwprintw(wMsg, lines++, 1, "F%-2d: %s",
i+1, settings->alias[i] ? settings->alias[i] : "");
lines-=ALIAS_MAX/2;
for( ; i<ALIAS_MAX; i++)
mvwprintw(wMsg, lines++, centre, " F%-2d: %s",
i+1, settings->alias[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;
}
syntax highlighted by Code2HTML, v. 0.9.1