config root man

Current Path : /usr/src/contrib/dialog/

FreeBSD hs32.drive.ne.jp 9.1-RELEASE FreeBSD 9.1-RELEASE #1: Wed Jan 14 12:18:08 JST 2015 root@hs32.drive.ne.jp:/sys/amd64/compile/hs32 amd64
Upload File :
Current File : //usr/src/contrib/dialog/rc.c

/*
 *  $Id: rc.c,v 1.47 2011/06/20 22:30:04 tom Exp $
 *
 *  rc.c -- routines for processing the configuration file
 *
 *  Copyright 2000-2010,2011	Thomas E. Dickey
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License, version 2.1
 *  as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to
 *	Free Software Foundation, Inc.
 *	51 Franklin St., Fifth Floor
 *	Boston, MA 02110, USA.
 *
 *  An earlier version of this program lists as authors
 *	Savio Lam (lam836@cs.cuhk.hk)
 */

#include <dialog.h>

#include <dlg_keys.h>

#ifdef HAVE_COLOR
#include <dlg_colors.h>

/*
 * For matching color names with color values
 */
static const color_names_st color_names[] =
{
#ifdef HAVE_USE_DEFAULT_COLORS
    {"DEFAULT", -1},
#endif
    {"BLACK", COLOR_BLACK},
    {"RED", COLOR_RED},
    {"GREEN", COLOR_GREEN},
    {"YELLOW", COLOR_YELLOW},
    {"BLUE", COLOR_BLUE},
    {"MAGENTA", COLOR_MAGENTA},
    {"CYAN", COLOR_CYAN},
    {"WHITE", COLOR_WHITE},
};				/* color names */
#define COLOR_COUNT	(sizeof(color_names) / sizeof(color_names[0]))
#endif /* HAVE_COLOR */

#define GLOBALRC "/etc/dialogrc"
#define DIALOGRC ".dialogrc"

/* Types of values */
#define VAL_INT  0
#define VAL_STR  1
#define VAL_BOOL 2

/* Type of line in configuration file */
typedef enum {
    LINE_ERROR = -1,
    LINE_EQUALS,
    LINE_EMPTY
} PARSE_LINE;

/* number of configuration variables */
#define VAR_COUNT        (sizeof(vars) / sizeof(vars_st))

/* check if character is white space */
#define whitespace(c)    (c == ' ' || c == TAB)

/* check if character is string quoting characters */
#define isquote(c)       (c == '"' || c == '\'')

/* get last character of string */
#define lastch(str)      str[strlen(str)-1]

/*
 * Configuration variables
 */
typedef struct {
    const char *name;		/* name of configuration variable as in DIALOGRC */
    void *var;			/* address of actual variable to change */
    int type;			/* type of value */
    const char *comment;	/* comment to put in "rc" file */
} vars_st;

/*
 * This table should contain only references to dialog_state, since dialog_vars
 * is reset specially in dialog.c before each widget.
 */
static const vars_st vars[] =
{
    {"aspect",
     &dialog_state.aspect_ratio,
     VAL_INT,
     "Set aspect-ration."},

    {"separate_widget",
     &dialog_state.separate_str,
     VAL_STR,
     "Set separator (for multiple widgets output)."},

    {"tab_len",
     &dialog_state.tab_len,
     VAL_INT,
     "Set tab-length (for textbox tab-conversion)."},

    {"visit_items",
     &dialog_state.visit_items,
     VAL_BOOL,
     "Make tab-traversal for checklist, etc., include the list."},

#ifdef HAVE_COLOR
    {"use_shadow",
     &dialog_state.use_shadow,
     VAL_BOOL,
     "Shadow dialog boxes? This also turns on color."},

    {"use_colors",
     &dialog_state.use_colors,
     VAL_BOOL,
     "Turn color support ON or OFF"},
#endif				/* HAVE_COLOR */
};				/* vars */

static int
skip_whitespace(char *str, int n)
{
    while (whitespace(str[n]) && str[n] != '\0')
	n++;
    return n;
}

static int
skip_keyword(char *str, int n)
{
    while (isalnum(UCH(str[n])) && str[n] != '\0')
	n++;
    return n;
}

static int
find_vars(char *name)
{
    int result = -1;
    unsigned i;

    for (i = 0; i < VAR_COUNT; i++) {
	if (dlg_strcmp(vars[i].name, name) == 0) {
	    result = (int) i;
	    break;
	}
    }
    return result;
}

#ifdef HAVE_COLOR
static int
find_color(char *name)
{
    int result = -1;
    int i;
    int limit = dlg_color_count();

    for (i = 0; i < limit; i++) {
	if (dlg_strcmp(dlg_color_table[i].name, name) == 0) {
	    result = i;
	    break;
	}
    }
    return result;
}

/*
 * Convert an attribute to a string representation like this:
 *
 * "(foreground,background,highlight)"
 */
static char *
attr_to_str(char *str, int fg, int bg, int hl)
{
    int i;

    strcpy(str, "(");
    /* foreground */
    for (i = 0; fg != color_names[i].value; i++) ;
    strcat(str, color_names[i].name);
    strcat(str, ",");

    /* background */
    for (i = 0; bg != color_names[i].value; i++) ;
    strcat(str, color_names[i].name);

    /* highlight */
    strcat(str, hl ? ",ON)" : ",OFF)");

    return str;
}

/*
 * Extract the foreground, background and highlight values from an attribute
 * represented as a string in this form:
 *
 * "(foreground,background,highlight)"
 */
static int
str_to_attr(char *str, int *fg, int *bg, int *hl)
{
    int i = 0, get_fg = 1;
    unsigned j;
    char tempstr[MAX_LEN + 1], *part;

    if (str[0] != '(' || lastch(str) != ')')
	return -1;		/* invalid representation */

    /* remove the parenthesis */
    strcpy(tempstr, str + 1);
    lastch(tempstr) = '\0';

    /* get foreground and background */

    while (1) {
	/* skip white space before fg/bg string */
	i = skip_whitespace(tempstr, i);
	if (tempstr[i] == '\0')
	    return -1;		/* invalid representation */
	part = tempstr + i;	/* set 'part' to start of fg/bg string */

	/* find end of fg/bg string */
	while (!whitespace(tempstr[i]) && tempstr[i] != ','
	       && tempstr[i] != '\0')
	    i++;

	if (tempstr[i] == '\0')
	    return -1;		/* invalid representation */
	else if (whitespace(tempstr[i])) {	/* not yet ',' */
	    tempstr[i++] = '\0';

	    /* skip white space before ',' */
	    i = skip_whitespace(tempstr, i);
	    if (tempstr[i] != ',')
		return -1;	/* invalid representation */
	}
	tempstr[i++] = '\0';	/* skip the ',' */
	for (j = 0; j < COLOR_COUNT && dlg_strcmp(part, color_names[j].name);
	     j++) ;
	if (j == COLOR_COUNT)	/* invalid color name */
	    return -1;
	if (get_fg) {
	    *fg = color_names[j].value;
	    get_fg = 0;		/* next we have to get the background */
	} else {
	    *bg = color_names[j].value;
	    break;
	}
    }				/* got foreground and background */

    /* get highlight */

    /* skip white space before highlight string */
    i = skip_whitespace(tempstr, i);
    if (tempstr[i] == '\0')
	return -1;		/* invalid representation */
    part = tempstr + i;		/* set 'part' to start of highlight string */

    /* trim trailing white space from highlight string */
    i = (int) strlen(part) - 1;
    while (whitespace(part[i]) && i > 0)
	i--;
    part[i + 1] = '\0';

    if (!dlg_strcmp(part, "ON"))
	*hl = TRUE;
    else if (!dlg_strcmp(part, "OFF"))
	*hl = FALSE;
    else
	return -1;		/* invalid highlight value */

    return 0;
}
#endif /* HAVE_COLOR */

/*
 * Check if the line begins with a special keyword; if so, return true while
 * pointing params to its parameters.
 */
static int
begins_with(char *line, const char *keyword, char **params)
{
    int i = skip_whitespace(line, 0);
    int j = skip_keyword(line, i);

    if ((j - i) == (int) strlen(keyword)) {
	char save = line[j];
	line[j] = 0;
	if (!dlg_strcmp(keyword, line + i)) {
	    *params = line + skip_whitespace(line, j + 1);
	    return 1;
	}
	line[j] = save;
    }

    return 0;
}

/*
 * Parse a line in the configuration file
 *
 * Each line is of the form:  "variable = value". On exit, 'var' will contain
 * the variable name, and 'value' will contain the value string.
 *
 * Return values:
 *
 * LINE_EMPTY   - line is blank or comment
 * LINE_EQUALS  - line contains "variable = value"
 * LINE_ERROR   - syntax error in line
 */
static PARSE_LINE
parse_line(char *line, char **var, char **value)
{
    int i = 0;

    /* ignore white space at beginning of line */
    i = skip_whitespace(line, i);

    if (line[i] == '\0')	/* line is blank */
	return LINE_EMPTY;
    else if (line[i] == '#')	/* line is comment */
	return LINE_EMPTY;
    else if (line[i] == '=')	/* variable names cannot start with a '=' */
	return LINE_ERROR;

    /* set 'var' to variable name */
    *var = line + i++;		/* skip to next character */

    /* find end of variable name */
    while (!whitespace(line[i]) && line[i] != '=' && line[i] != '\0')
	i++;

    if (line[i] == '\0')	/* syntax error */
	return LINE_ERROR;
    else if (line[i] == '=')
	line[i++] = '\0';
    else {
	line[i++] = '\0';

	/* skip white space before '=' */
	i = skip_whitespace(line, i);

	if (line[i] != '=')	/* syntax error */
	    return LINE_ERROR;
	else
	    i++;		/* skip the '=' */
    }

    /* skip white space after '=' */
    i = skip_whitespace(line, i);

    if (line[i] == '\0')
	return LINE_ERROR;
    else
	*value = line + i;	/* set 'value' to value string */

    /* trim trailing white space from 'value' */
    i = (int) strlen(*value) - 1;
    while (whitespace((*value)[i]) && i > 0)
	i--;
    (*value)[i + 1] = '\0';

    return LINE_EQUALS;		/* no syntax error in line */
}

/*
 * Create the configuration file
 */
void
dlg_create_rc(const char *filename)
{
    unsigned i;
    FILE *rc_file;

    if ((rc_file = fopen(filename, "wt")) == NULL)
	dlg_exiterr("Error opening file for writing in dlg_create_rc().");

    fprintf(rc_file, "#\n\
# Run-time configuration file for dialog\n\
#\n\
# Automatically generated by \"dialog --create-rc <file>\"\n\
#\n\
#\n\
# Types of values:\n\
#\n\
# Number     -  <number>\n\
# String     -  \"string\"\n\
# Boolean    -  <ON|OFF>\n"
#ifdef HAVE_COLOR
	    "\
# Attribute  -  (foreground,background,highlight?)\n"
#endif
	);

    /* Print an entry for each configuration variable */
    for (i = 0; i < VAR_COUNT; i++) {
	fprintf(rc_file, "\n# %s\n", vars[i].comment);
	switch (vars[i].type) {
	case VAL_INT:
	    fprintf(rc_file, "%s = %d\n", vars[i].name,
		    *((int *) vars[i].var));
	    break;
	case VAL_STR:
	    fprintf(rc_file, "%s = \"%s\"\n", vars[i].name,
		    (char *) vars[i].var);
	    break;
	case VAL_BOOL:
	    fprintf(rc_file, "%s = %s\n", vars[i].name,
		    *((bool *) vars[i].var) ? "ON" : "OFF");
	    break;
	}
    }
#ifdef HAVE_COLOR
    for (i = 0; i < (unsigned) dlg_color_count(); ++i) {
	char buffer[MAX_LEN + 1];

	fprintf(rc_file, "\n# %s\n", dlg_color_table[i].comment);
	fprintf(rc_file, "%s = %s\n", dlg_color_table[i].name,
		attr_to_str(buffer,
			    dlg_color_table[i].fg,
			    dlg_color_table[i].bg,
			    dlg_color_table[i].hilite));
    }
#endif /* HAVE_COLOR */
    dlg_dump_keys(rc_file);

    (void) fclose(rc_file);
}

/*
 * Parse the configuration file and set up variables
 */
int
dlg_parse_rc(void)
{
    int i;
    int l = 1;
    PARSE_LINE parse;
    char str[MAX_LEN + 1];
    char *var;
    char *value;
    char *tempptr;
    int result = 0;
    FILE *rc_file = 0;
    char *params;

    /*
     *  At startup, dialog determines the settings to use as follows:
     *
     *  a) if the environment variable $DIALOGRC is set, its value determines
     *     the name of the configuration file.
     *
     *  b) if the file in (a) can't be found, use the file $HOME/.dialogrc
     *     as the configuration file.
     *
     *  c) if the file in (b) can't be found, try using the GLOBALRC file.
     *     Usually this will be /etc/dialogrc.
     *
     *  d) if the file in (c) cannot be found, use the compiled-in defaults.
     */

    /* try step (a) */
    if ((tempptr = getenv("DIALOGRC")) != NULL)
	rc_file = fopen(tempptr, "rt");

    if (rc_file == NULL) {	/* step (a) failed? */
	/* try step (b) */
	if ((tempptr = getenv("HOME")) != NULL
	    && strlen(tempptr) < MAX_LEN - (sizeof(DIALOGRC) + 3)) {
	    if (tempptr[0] == '\0' || lastch(tempptr) == '/')
		sprintf(str, "%s%s", tempptr, DIALOGRC);
	    else
		sprintf(str, "%s/%s", tempptr, DIALOGRC);
	    rc_file = fopen(tempptr = str, "rt");
	}
    }

    if (rc_file == NULL) {	/* step (b) failed? */
	/* try step (c) */
	strcpy(str, GLOBALRC);
	if ((rc_file = fopen(tempptr = str, "rt")) == NULL)
	    return 0;		/* step (c) failed, use default values */
    }

    DLG_TRACE(("opened rc file \"%s\"\n", tempptr));
    /* Scan each line and set variables */
    while ((result == 0) && (fgets(str, MAX_LEN, rc_file) != NULL)) {
	DLG_TRACE(("rc:%s", str));
	if (*str == '\0' || lastch(str) != '\n') {
	    /* ignore rest of file if line too long */
	    fprintf(stderr, "\nParse error: line %d of configuration"
		    " file too long.\n", l);
	    result = -1;	/* parse aborted */
	    break;
	}

	lastch(str) = '\0';
	if (begins_with(str, "bindkey", &params)) {
	    dlg_parse_bindkey(params);
	    continue;
	}
	parse = parse_line(str, &var, &value);	/* parse current line */

	switch (parse) {
	case LINE_EMPTY:	/* ignore blank lines and comments */
	    break;
	case LINE_EQUALS:
	    /* search table for matching config variable name */
	    if ((i = find_vars(var)) >= 0) {
		switch (vars[i].type) {
		case VAL_INT:
		    *((int *) vars[i].var) = atoi(value);
		    break;
		case VAL_STR:
		    if (!isquote(value[0]) || !isquote(lastch(value))
			|| strlen(value) < 2) {
			fprintf(stderr, "\nParse error: string value "
				"expected at line %d of configuration "
				"file.\n", l);
			result = -1;	/* parse aborted */
		    } else {
			/* remove the (") quotes */
			value++;
			lastch(value) = '\0';
			strcpy((char *) vars[i].var, value);
		    }
		    break;
		case VAL_BOOL:
		    if (!dlg_strcmp(value, "ON"))
			*((bool *) vars[i].var) = TRUE;
		    else if (!dlg_strcmp(value, "OFF"))
			*((bool *) vars[i].var) = FALSE;
		    else {
			fprintf(stderr, "\nParse error: boolean value "
				"expected at line %d of configuration "
				"file (found %s).\n", l, value);
			result = -1;	/* parse aborted */
		    }
		    break;
		}
#ifdef HAVE_COLOR
	    } else if ((i = find_color(var)) >= 0) {
		int fg = 0;
		int bg = 0;
		int hl = 0;
		if (str_to_attr(value, &fg, &bg, &hl) == -1) {
		    fprintf(stderr, "\nParse error: attribute "
			    "value expected at line %d of configuration "
			    "file.\n", l);
		    result = -1;	/* parse aborted */
		} else {
		    dlg_color_table[i].fg = fg;
		    dlg_color_table[i].bg = bg;
		    dlg_color_table[i].hilite = hl;
		}
	    } else {
#endif /* HAVE_COLOR */
		fprintf(stderr, "\nParse error: unknown variable "
			"at line %d of configuration file:\n\t%s\n", l, var);
		result = -1;	/* parse aborted */
	    }
	    break;
	case LINE_ERROR:
	    fprintf(stderr, "\nParse error: syntax error at line %d of "
		    "configuration file.\n", l);
	    result = -1;	/* parse aborted */
	    break;
	}
	l++;			/* next line */
    }

    (void) fclose(rc_file);
    return result;
}

Man Man