#define _LARGEFILE64_SOURCE /* required for GLIBC to enable stat64 and friends */ #include "doassert.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "mt.h" #include "mem.h" #include "error.h" #include "utils.h" #include "color.h" #include "term.h" #include "exec.h" #include "globals.h" #include "config.h" /* "local global" */ int cur_colorscheme_nr = -1; int cur_filterscheme_nr = -1; int cur_editscheme_nr = -1; mybool_t config_yes_no(char *what) { if (what[0] == '1' || strcasecmp(what, "yes") == 0 || strcasecmp(what, "on") == 0) { return MY_TRUE; } return MY_FALSE; } long long int kb_str_to_value(char *field, char *str) { char *mult; long long int bytes = atoll(str); if (bytes < -1) error_exit(__FILE__, __PRETTY_FUNCTION__, __LINE__, "%s: value cannot be < -1\n", field); mult = &str[strlen(str) - 2]; if (strcasecmp(mult, "kb") == 0) bytes *= 1024; else if (strcasecmp(mult, "mb") == 0) bytes *= 1024 * 1024; else if (strcasecmp(mult, "gb") == 0) bytes *= 1024 * 1024 * 1024; return bytes; } void config_error_exit(int linenr, char *format, ...) { va_list ap; fprintf(stderr, version_str, VERSION); fprintf(stderr, "\n\n"); if (linenr != -1) fprintf(stderr, "Error while processing configuration file at line %d:\n", linenr); va_start(ap, format); (void)vfprintf(stderr, format, ap); va_end(ap); exit(EXIT_FAILURE); } void add_cs_re(int linenr, char *incmd, char *par) { if (use_colors) { char *re = NULL, *val = NULL; char *cmd = &incmd[5]; char *colon; if (strncmp(cmd, "_val", 4) == 0) { val = find_next_par(par); if (!val) config_error_exit(linenr, "cs_re_val...-entry malformed: value missing.\n"); re = find_next_par(val); } else re = find_next_par(par); if (re == NULL) config_error_exit(linenr, "cs_re-entry malformed: color or regular expression missing.\n"); if (cur_colorscheme_nr == -1) config_error_exit(linenr, "For cs_re one needs to define a color scheme name first.\n"); /* find colorscheme */ if (cschemes[cur_colorscheme_nr].color_script.script) config_error_exit(linenr, "One cannot let a color script have the same name has a color scheme."); /* grow/create list */ cschemes[cur_colorscheme_nr].pentries = (color_scheme_entry *)myrealloc(cschemes[cur_colorscheme_nr].pentries, (cschemes[cur_colorscheme_nr].n + 1) * sizeof(color_scheme_entry), __FILE__, __PRETTY_FUNCTION__, __LINE__); /* add to list */ if (cmd[0] == 0x00) cschemes[cur_colorscheme_nr].pentries[cschemes[cur_colorscheme_nr].n].flags = 0; else if (strcmp(cmd, "_s") == 0) cschemes[cur_colorscheme_nr].pentries[cschemes[cur_colorscheme_nr].n].flags = CSREFLAG_SUB; else if (strcmp(cmd, "_val_less") == 0) cschemes[cur_colorscheme_nr].pentries[cschemes[cur_colorscheme_nr].n].flags = CSREFLAG_CMP_VAL_LESS; else if (strcmp(cmd, "_val_bigger") == 0) cschemes[cur_colorscheme_nr].pentries[cschemes[cur_colorscheme_nr].n].flags = CSREFLAG_CMP_VAL_BIGGER; else if (strcmp(cmd, "_val_equal") == 0) cschemes[cur_colorscheme_nr].pentries[cschemes[cur_colorscheme_nr].n].flags = CSREFLAG_CMP_VAL_EQUAL; /* sanity check */ if (cmd[0] != 0x00 && strchr(re, '(') == NULL) config_error_exit(linenr, "%s is missing substring selections! ('(' and ')')\n", cmd); if (val) cschemes[cur_colorscheme_nr].pentries[cschemes[cur_colorscheme_nr].n].cmp_value = atof(val); cschemes[cur_colorscheme_nr].pentries[cschemes[cur_colorscheme_nr].n].merge_color = incmd[0] == 'm' ? MY_TRUE : MY_FALSE; cschemes[cur_colorscheme_nr].pentries[cschemes[cur_colorscheme_nr].n].cdef.ac_index = 0; colon = strchr(par, '|'); if (colon) { *colon = 0x00; cschemes[cur_colorscheme_nr].pentries[cschemes[cur_colorscheme_nr].n].cdef.use_alternating_colors = MY_TRUE; cschemes[cur_colorscheme_nr].pentries[cschemes[cur_colorscheme_nr].n].cdef.attrs2 = parse_attributes(colon + 1); } else { cschemes[cur_colorscheme_nr].pentries[cschemes[cur_colorscheme_nr].n].cdef.use_alternating_colors = MY_FALSE; } cschemes[cur_colorscheme_nr].pentries[cschemes[cur_colorscheme_nr].n].cdef.attrs1 = parse_attributes(par); /* compile regular expression */ compile_re(&cschemes[cur_colorscheme_nr].pentries[cschemes[cur_colorscheme_nr].n].regex, re); cschemes[cur_colorscheme_nr].n++; } } void add_colorscheme(int linenr, char *cmd, char *par) { if (use_colors) { char *descr = find_next_par(par); cur_colorscheme_nr = n_cschemes++; cschemes = (color_scheme *)myrealloc(cschemes, n_cschemes * sizeof(color_scheme), __FILE__, __PRETTY_FUNCTION__, __LINE__); memset(&cschemes[cur_colorscheme_nr], 0x00, sizeof(color_scheme)); cschemes[cur_colorscheme_nr].descr = mystrdup(USE_IF_SET(descr, ""), __FILE__, __PRETTY_FUNCTION__, __LINE__); cschemes[cur_colorscheme_nr].name = mystrdup(par, __FILE__, __PRETTY_FUNCTION__, __LINE__); } } void add_colorscript(int linenr, char *cmd, char *par) { char *dummy1, *dummy2; dummy1 = find_next_par(par); /* find script */ dummy2 = find_next_par(dummy1); /* find description */ cur_colorscheme_nr = n_cschemes++; cschemes = (color_scheme *)myrealloc(cschemes, n_cschemes * sizeof(color_scheme), __FILE__, __PRETTY_FUNCTION__, __LINE__); memset(&cschemes[cur_colorscheme_nr], 0x00, sizeof(color_scheme)); cschemes[cur_colorscheme_nr].name = mystrdup(par, __FILE__, __PRETTY_FUNCTION__, __LINE__); cschemes[cur_colorscheme_nr].descr = mystrdup(dummy2, __FILE__, __PRETTY_FUNCTION__, __LINE__); cschemes[cur_colorscheme_nr].color_script.script = mystrdup(dummy1, __FILE__, __PRETTY_FUNCTION__, __LINE__); cur_colorscheme_nr = -1; } void add_editscheme(int linenr, char *cmd, char *par) { char *descr = find_next_par(par); pes = (editscheme *)myrealloc(pes, sizeof(editscheme) * (n_es + 1), __FILE__, __PRETTY_FUNCTION__, __LINE__); memset(&pes[n_es], 0x00, sizeof(editscheme)); pes[n_es].es_name = mystrdup(par, __FILE__, __PRETTY_FUNCTION__, __LINE__); pes[n_es].es_desc = mystrdup(USE_IF_SET(descr, ""), __FILE__, __PRETTY_FUNCTION__, __LINE__); cur_editscheme_nr = n_es++; } void add_editrule(int linenr, char *cmd, char *par) { char *type_str = par; char *par1 = find_next_par(type_str); char *par2 = NULL; striptype_t type = STRIP_TYPE_REGEXP; int rule_index = -1; if (!par1) config_error_exit(linenr, "editrule:%s requires a parameter.\n", type_str); if (strcmp(type_str, "kr") == 0) type = STRIP_TYPE_RANGE; else if (strcmp(type_str, "ke") == 0) type = STRIP_TYPE_REGEXP; else if (strcmp(type_str, "kc") == 0) type = STRIP_TYPE_COLUMN; else if (strcmp(type_str, "kS") == 0) type = STRIP_KEEP_SUBSTR; else config_error_exit(linenr, "editrule requirs either ke, kr, kS or kc.\n"); if (type == STRIP_TYPE_RANGE || type == STRIP_TYPE_COLUMN) { par2 = find_next_par(par1); if (!par2) config_error_exit(linenr, "editrule:%s requires another parameter.\n", type_str); } rule_index = pes[cur_editscheme_nr].n_strips; pes[cur_editscheme_nr].strips = (strip_t *)myrealloc(pes[cur_editscheme_nr].strips, (pes[cur_editscheme_nr].n_strips + 1) * sizeof(strip_t), __FILE__, __PRETTY_FUNCTION__, __LINE__); memset(&pes[cur_editscheme_nr].strips[pes[cur_editscheme_nr].n_strips], 0x00, sizeof(strip_t)); pes[cur_editscheme_nr].n_strips++; pes[cur_editscheme_nr].strips[rule_index].type = type; if (type == STRIP_TYPE_RANGE) { pes[cur_editscheme_nr].strips[rule_index].start = atoi(par1); pes[cur_editscheme_nr].strips[rule_index].end = atoi(par2); } else if (type == STRIP_TYPE_REGEXP || type == STRIP_KEEP_SUBSTR) { pes[cur_editscheme_nr].strips[rule_index].regex_str = mystrdup(par1, __FILE__, __PRETTY_FUNCTION__, __LINE__); compile_re(&pes[cur_editscheme_nr].strips[rule_index].regex, par1); } else if (type == STRIP_TYPE_COLUMN) { pes[cur_editscheme_nr].strips[rule_index].del = mystrdup(par1, __FILE__, __PRETTY_FUNCTION__, __LINE__); pes[cur_editscheme_nr].strips[rule_index].col_nr = atoi(par2); } } void add_filterscheme(int linenr, char *cmd, char *par) { char *descr = find_next_par(par); pfs = (filterscheme *)myrealloc(pfs, sizeof(filterscheme) * (n_fs + 1), __FILE__, __PRETTY_FUNCTION__, __LINE__); memset(&pfs[n_fs], 0x00, sizeof(filterscheme)); pfs[n_fs].fs_name = mystrdup(par, __FILE__, __PRETTY_FUNCTION__, __LINE__); pfs[n_fs].fs_desc = mystrdup(USE_IF_SET(descr, ""), __FILE__, __PRETTY_FUNCTION__, __LINE__); cur_filterscheme_nr = n_fs++; } void add_filterscheme_rule(int linenr, char *cmd, char *par) { char *type = par; int use_regex = 0x00; char *re_cmd = NULL; char *re_str = find_next_par(par); if (!re_str) config_error_exit(linenr, "Missing regular expression in rule-line for scheme %s.\n", pfs[cur_filterscheme_nr].fs_name); if (type[0] != 'e') config_error_exit(linenr, "Regular expression type '%s' is not recognized.\n", type); if (type[1] == 0x00 || type[1] == 'm') use_regex = 'm'; else if (type[1] == 'v') use_regex = 'v'; else if (type[1] == 'c') use_regex = 'c'; else if (type[1] == 'C') use_regex = 'C'; else if (toupper(type[1]) == 'X') { char *dummy = find_next_par(re_str); if (!dummy) config_error_exit(linenr, "Missing command for rule of type 'e%c' for scheme %s.\n", type[1], pfs[cur_filterscheme_nr].fs_name); re_cmd = mystrdup(dummy, __FILE__, __PRETTY_FUNCTION__, __LINE__); use_regex = type[1]; if (use_regex == 'X' && (strchr(re_str, '(') == NULL || strchr(re_str, ')') == NULL)) config_error_exit(linenr, "Filter scheme rule: -eX requires a regular expression which selects a substring using '(' and ')'.\n"); } pfs[cur_filterscheme_nr].pre = (re *)myrealloc(pfs[cur_filterscheme_nr].pre, (pfs[cur_filterscheme_nr].n_re + 1) * sizeof(re), __FILE__, __PRETTY_FUNCTION__, __LINE__); memset(&pfs[cur_filterscheme_nr].pre[pfs[cur_filterscheme_nr].n_re], 0x00, sizeof(re)); pfs[cur_filterscheme_nr].pre[pfs[cur_filterscheme_nr].n_re].use_regex = use_regex; pfs[cur_filterscheme_nr].pre[pfs[cur_filterscheme_nr].n_re].regex_str = mystrdup(re_str, __FILE__, __PRETTY_FUNCTION__, __LINE__); compile_re(&pfs[cur_filterscheme_nr].pre[pfs[cur_filterscheme_nr].n_re].regex, re_str); pfs[cur_filterscheme_nr].pre[pfs[cur_filterscheme_nr].n_re].cmd = re_cmd; pfs[cur_filterscheme_nr].n_re++; } void add_convert(int linenr, char *cmd, char *par) { char *conv_name = par; char *conv_type = NULL; conversion_t type = 0; char *conv_script = NULL; char *conv_re = NULL; int loop; /* parse type */ conv_type = find_next_par(conv_name); if (!conv_type) config_error_exit(linenr, "'convert'-entry malformed: conversion type missing.\n"); if (strncmp(conv_type, "script:", 7) == 0) { conv_script = find_next_par(conv_type); if (conv_script) conv_re = find_next_par(conv_script); else config_error_exit(linenr, "Convert: script filename missing.\n"); } else conv_re = find_next_par(conv_type); if (!conv_re) config_error_exit(linenr, "'convert'-entry malformed: type or regular expression missing.\n"); /* find this conversion: is it from an already known group? */ for(loop=0; loop 2) config_error_exit(linenr, "bind parameter malformed: unknown keyselection.\n"); keybindings = (keybinding *)myrealloc(keybindings, sizeof(keybinding) * (n_keybindings + 1), __FILE__, __PRETTY_FUNCTION__, __LINE__); if (par[0] == '^') keybindings[n_keybindings].key = toupper(par[1]) - 'A' + 1; else keybindings[n_keybindings].key = par[0]; keybindings[n_keybindings].command = mystrdup(proc, __FILE__, __PRETTY_FUNCTION__, __LINE__); n_keybindings++; } void set_suppress_empty_lines(int linenr, char *cmd, char *par) { suppress_empty_lines = config_yes_no(par); } void set_close_closed_windows(int linenr, char *cmd, char *par) { do_not_close_closed_windows = !config_yes_no(par); } void set_follow_filename(int linenr, char *cmd, char *par) { default_follow_filename = config_yes_no(par); } void set_default_linewrap(int linenr, char *cmd, char *par) { default_linewrap = par[0]; if (default_linewrap == 'o') { char *dummy = find_next_par(par); if (!dummy) config_error_exit(linenr, "default_linewrap: 'o' needs a wrap offset parameter.\n"); default_line_wrap_offset = atoi(dummy); } } void set_umask(int linenr, char *cmd, char *par) { def_umask = strtol(par, NULL, 0); } void set_shell(int linenr, char *cmd, char *par) { myfree(shell); shell = mystrdup(par, __FILE__, __PRETTY_FUNCTION__, __LINE__); } void set_statusline_above_data(int linenr, char *cmd, char *par) { statusline_above_data = config_yes_no(par); } void set_caret_notation(int linenr, char *cmd, char *par) { caret_notation = config_yes_no(par); } void set_searches_case_insensitive(int linenr, char *cmd, char *par) { re_case_insensitive = MY_TRUE; } void set_beep_method(int linenr, char *cmd, char *par) { if (strcmp(par, "beep") == 0) beep_method = BEEP_BEEP; else if (strcmp(par, "flash") == 0) beep_method = BEEP_FLASH; else if (strcmp(par, "popup") == 0) beep_method = BEEP_POPUP; else if (strcmp(par, "none") == 0) beep_method = BEEP_NONE; else config_error_exit(linenr, "'%s' is an unknown beep method.\n"); } void set_beep_popup_length(int linenr, char *cmd, char *par) { beep_popup_length = atof(par); if (beep_popup_length < 0.0) config_error_exit(linenr, "beep_popup_length must be >= 0.0\n"); } void set_allow_8bit(int linenr, char *cmd, char *par) { allow_8bit = config_yes_no(par); } void set_dsblwm(int linenr, char *cmd, char *par) { no_linewrap = 1 - config_yes_no(par); } void set_warn_closed(int linenr, char *cmd, char *par) { warn_closed = config_yes_no(par); } void set_basename(int linenr, char *cmd, char *par) { filename_only = config_yes_no(par); } void set_bright(int linenr, char *cmd, char *par) { bright_colors = config_yes_no(par); } void set_ts_format(int linenr, char *cmd, char *par) { myfree(ts_format); ts_format = mystrdup(par, __FILE__, __PRETTY_FUNCTION__, __LINE__); } void set_cnv_ts_format(int linenr, char *cmd, char *par) { myfree(cnv_ts_format); cnv_ts_format = mystrdup(par, __FILE__, __PRETTY_FUNCTION__, __LINE__); } void set_statusline_ts_format(int linenr, char *cmd, char *par) { myfree(statusline_ts_format); statusline_ts_format = mystrdup(par, __FILE__, __PRETTY_FUNCTION__, __LINE__); } void set_markerline_attrs(int linenr, char *cmd, char *par) { markerline_attrs = parse_attributes(par); } void set_idleline_color(int linenr, char *cmd, char *par) { idleline_attrs = parse_attributes(par); } void set_msgline_color(int linenr, char *cmd, char *par) { msgline_attrs = parse_attributes(par); } void set_changeline_color(int linenr, char *cmd, char *par) { changeline_attrs = parse_attributes(par); } void set_statusline_attrs(int linenr, char *cmd, char *par) { statusline_attrs = parse_attributes(par); } void set_splitline_attrs(int linenr, char *cmd, char *par) { splitline_attrs = parse_attributes(par); } void set_inverse_attrs(int linenr, char *cmd, char *par) { inverse_attrs = attrstr_to_nr(par); } void set_splitline(int linenr, char *cmd, char *par) { if (strcmp(par, "none") == 0) splitline_mode = SL_NONE; else if (strcmp(par, "regular") == 0) splitline_mode = SL_REGULAR; else if (strcmp(par, "attributes") == 0) splitline_mode = SL_ATTR; else config_error_exit(linenr, "Parameter '%s' for 'splitline' not recognized.\n", par); } void set_show_subwindow_id(int linenr, char *cmd, char *par) { show_subwindow_id = config_yes_no(par); } void set_markerline_timestamp(int linenr, char *cmd, char *par) { timestamp_in_markerline = config_yes_no(par); } void set_global_default_nlines(int linenr, char *cmd, char *par) { default_maxnlines = atoi(par); } void set_global_default_nkb(int linenr, char *cmd, char *par) { default_maxbytes = kb_str_to_value(cmd, par); } void set_default_nlines(int linenr, char *cmd, char *par) { char *re; int n_lines; if ((re = find_next_par(par)) == NULL) /* format: cs_re:color:regular expression */ config_error_exit(linenr, "Scheme entry malformed: scheme name or regular expression missing.\n"); /* find colorscheme */ n_lines = atoi(par); if (n_lines < -1) config_error_exit(linenr, "default_nlines: value cannot be lower then -1.\n"); add_pars_per_file(re, NULL, n_lines, -1, -1, -1, -1, NULL); } void set_default_mark_change(int linenr, char *cmd, char *par) { char *re; if ((re = find_next_par(par)) == NULL) /* format: cs_re:color:regular expression */ config_error_exit(linenr, "Scheme entry malformed: scheme name or regular expression missing.\n"); add_pars_per_file(re, NULL, -1, -1, config_yes_no(par), -1, -1, NULL); } void set_default_bytes(int linenr, char *cmd, char *par) { int bytes; char *re; if ((re = find_next_par(par)) == NULL) /* format: cs_re:color:regular expression */ config_error_exit(linenr, "Scheme entry malformed: scheme name or regular expression missing.\n"); bytes = kb_str_to_value(cmd, par); add_pars_per_file(re, NULL, -1, bytes, -1, -1, -1, NULL); } void set_check_mail(int linenr, char *cmd, char *par) { check_for_mail = get_value_arg("check_mail", par, VAL_ZERO_POSITIVE); } void set_tab_stop(int linenr, char *cmd, char *par) { tab_width = atoi(par); } void set_tail(int linenr, char *cmd, char *par) { myfree(tail); tail = mystrdup(par, __FILE__, __PRETTY_FUNCTION__, __LINE__); } void set_titlebar(int linenr, char *cmd, char *par) { myfree(set_title); set_title = mystrdup(par, __FILE__, __PRETTY_FUNCTION__, __LINE__); } void set_abbreviate_filesize(int linenr, char *cmd, char *par) { afs = config_yes_no(par); } void set_replace_by_markerline(int linenr, char *cmd, char *par) { myfree(replace_by_markerline); replace_by_markerline = mystrdup(par, __FILE__, __PRETTY_FUNCTION__, __LINE__); } void set_popup_refresh_interval(int linenr, char *cmd, char *par) { popup_refresh_interval = get_value_arg("popup_refresh_interval", par, VAL_POSITIVE); } void set_msgline_char(int linenr, char *cmd, char *par) { msgline_char = par[0]; } void set_idleline_char(int linenr, char *cmd, char *par) { idleline_char = par[0]; } void set_changeline_char(int linenr, char *cmd, char *par) { changeline_char = par[0]; } void set_markerline_char(int linenr, char *cmd, char *par) { markerline_char = par[0]; } void set_global_mark_change(int linenr, char *cmd, char *par) { global_marker_of_other_window = config_yes_no(par); } void set_default_bufferwhat(int linenr, char *cmd, char *par) { char what = par[0]; if (what != 'a' && what != 'f') config_error_exit(linenr, "default_bufferwhat expects either 'a' or 'f'. Got: '%c'.\n", what); default_bufferwhat = what; } void set_abort_key(int linenr, char *cmd, char *par) { int dummy = atoi(par); if (dummy < 0 || dummy > 255) config_error_exit(linenr, "abort_key expects an ascii value which is >= 0 && <= 255.\n"); abort_key = dummy; } void set_exit_key(int linenr, char *cmd, char *par) { int dummy = atoi(par); if (dummy < 0 || dummy > 255) config_error_exit(linenr, "exit_key expects an ascii value which is >= 0 && <= 255.\n"); exit_key = dummy; } void set_line_ts_format(int linenr, char *cmd, char *par) { myfree(line_ts_format); line_ts_format = mystrdup(par, __FILE__, __PRETTY_FUNCTION__, __LINE__); } void set_default_min_shrink(int linenr, char *cmd, char *par) { default_min_shrink = get_value_arg("min_shrink", par, VAL_POSITIVE); } void set_scrollback_show_winnrs(int linenr, char *cmd, char *par) { default_sb_showwinnr = config_yes_no(par); } void set_wordwrapmaxlength(int linenr, char *cmd, char *par) { wordwrapmaxlength = get_value_arg("wordwrapmaxlength", par, VAL_POSITIVE); } void set_searchhistory_file(int linenr, char *cmd, char *par) { if (par[0] == 0x00) { search_h.history_file = NULL; search_h.history_size = 0; } else { search_h.history_file = myrealpath(par); } } void set_searchhistory_size(int linenr, char *cmd, char *par) { int hs = atoi(par); if (hs <= 0) { search_h.history_file = NULL; search_h.history_size = 0; } else { search_h.history_size = hs; } } void set_cmdfile_history_file(int linenr, char *cmd, char *par) { if (par[0] == 0x00) { cmdfile_h.history_file = NULL; cmdfile_h.history_size = 0; } else { cmdfile_h.history_file = myrealpath(par); } } void set_cmdfile_history_size(int linenr, char *cmd, char *par) { int hs = atoi(par); if (hs <= 0) { cmdfile_h.history_file = NULL; cmdfile_h.history_size = 0; } else { cmdfile_h.history_size = hs; } } void set_default_background_color(int linenr, char *cmd, char *par) { if (use_colors) { default_bg_color = colorstr_to_nr(par); if (default_bg_color == -1) config_error_exit(linenr, "default_background_color: '%s' is not a recognized color.", par); } } void set_reuse_searchstring(int linenr, char *cmd, char *par) { reuse_searchstring = config_yes_no(par); } void set_min_n_bufferlines(int linenr, char *cmd, char *par) { min_n_bufferlines = atoi(par); if (min_n_bufferlines < 0) config_error_exit(linenr, "min_n_bufferlines must have a value >= 0."); } void set_box_bottom_left_hand_corner(int linenr, char *cmd, char *par) { box_bottom_left_hand_corner = par[0]; } void set_box_bottom_right_hand_corner(int linenr, char *cmd, char *par) { box_bottom_right_hand_corner = par[0]; } void set_box_bottom_side(int linenr, char *cmd, char *par) { box_bottom_side = par[0]; } void set_box_left_side(int linenr, char *cmd, char *par) { box_left_side = par[0]; } void set_box_right_side(int linenr, char *cmd, char *par) { box_right_side = par[0]; } void set_box_top_left_hand_corner(int linenr, char *cmd, char *par) { box_top_left_hand_corner = par[0]; } void set_box_top_right_hand_corner(int linenr, char *cmd, char *par) { box_top_right_hand_corner = par[0]; } void set_box_top_side(int linenr, char *cmd, char *par) { box_top_side = par[0]; } void set_window_number(int linenr, char *cmd, char *par) { myfree(window_number); window_number = mystrdup(par, __FILE__, __PRETTY_FUNCTION__, __LINE__); } void set_subwindow_number(int linenr, char *cmd, char *par) { myfree(subwindow_number); subwindow_number = mystrdup(par, __FILE__, __PRETTY_FUNCTION__, __LINE__); } void set_posix_tail(int linenr, char *cmd, char *par) { posix_tail = config_yes_no(par); } void set_syslog_ts_format(int linenr, char *cmd, char *par) { myfree(syslog_ts_format); syslog_ts_format = mystrdup(par, __FILE__, __PRETTY_FUNCTION__, __LINE__); } void set_resolv_ip_addresses(int linenr, char *cmd, char *par) { resolv_ip_addresses = config_yes_no(par); } void set_show_severity_facility(int linenr, char *cmd, char *par) { show_severity_facility = config_yes_no(par); } void set_scrollback_no_colors(int linenr, char *cmd, char *par) { scrollback_no_colors = config_yes_no(par); } void set_scrollback_search_new_window(int linenr, char *cmd, char *par) { scrollback_search_new_window = config_yes_no(par); } config_file_keyword cf_entries[] = { { "abbreviate_filesize", set_abbreviate_filesize }, { "abort_key", set_abort_key }, { "allow_8bit", set_allow_8bit }, { "basename", set_basename }, { "beep_method", set_beep_method }, { "beep_popup_length", set_beep_popup_length }, { "bind", bind_char }, { "box_bottom_left_hand_corner", set_box_bottom_left_hand_corner }, { "box_bottom_right_hand_corner", set_box_bottom_right_hand_corner }, { "box_bottom_side", set_box_bottom_side }, { "box_left_side", set_box_left_side }, { "box_right_side", set_box_right_side }, { "box_top_left_hand_corner", set_box_top_left_hand_corner }, { "box_top_right_hand_corner", set_box_top_right_hand_corner }, { "box_top_side", set_box_top_side }, { "bright", set_bright }, { "caret_notation", set_caret_notation }, { "changeline_char", set_changeline_char }, { "changeline_color", set_changeline_color }, { "check_mail", set_check_mail }, { "close_closed_windows", set_close_closed_windows }, { "cmdfile_history_file", set_cmdfile_history_file }, { "cmdfile_history_size", set_cmdfile_history_size }, { "cnv_ts_format", set_cnv_ts_format }, { "colorscheme", add_colorscheme }, { "colorscript", add_colorscript }, { "convert", add_convert }, { "cs_re", add_cs_re }, { "cs_re_s", add_cs_re }, { "cs_re_val_bigger", add_cs_re }, { "cs_re_val_equal", add_cs_re }, { "cs_re_val_less", add_cs_re }, { "default_background_color", set_default_background_color }, { "default_bufferwhat", set_default_bufferwhat }, { "default_bytes", set_default_bytes }, { "default_convert", set_default_convert }, { "default_linewrap", set_default_linewrap }, { "default_mark_change", set_default_mark_change }, { "default_nlines", set_default_nlines }, { "defaultcscheme", set_defaultcscheme }, { "dsblwm", set_dsblwm }, { "editrule", add_editrule }, { "editscheme", add_editscheme }, { "exit_key", set_exit_key }, { "filterscheme", add_filterscheme }, { "follow_filename", set_follow_filename }, { "global_default_nkb", set_global_default_nkb }, { "global_default_nlines", set_global_default_nlines }, { "global_mark_change", set_global_mark_change }, { "idleline_char", set_idleline_char }, { "idleline_color", set_idleline_color }, { "include", do_load_config }, { "inverse", set_inverse_attrs }, { "line_ts_format", set_line_ts_format }, { "markerline_char", set_markerline_char }, { "markerline_color", set_markerline_attrs }, { "markerline_timestamp", set_markerline_timestamp }, { "mcsre", add_cs_re }, { "mcsre_s", add_cs_re }, { "mcsre_val_bigger", add_cs_re }, { "mcsre_val_equal", add_cs_re }, { "mcsre_val_less", add_cs_re }, { "min_n_bufferlines", set_min_n_bufferlines }, { "min_shrink", set_default_min_shrink }, { "msgline_char", set_msgline_char }, { "msgline_color", set_msgline_color }, { "popup_refresh_interval", set_popup_refresh_interval }, { "posix_tail", set_posix_tail }, { "replace_by_markerline", set_replace_by_markerline }, { "resolv_ip_addresses", set_resolv_ip_addresses }, { "reuse_searchstring", set_reuse_searchstring }, { "rule", add_filterscheme_rule }, { "scheme", scheme }, { "scrollback_no_colors", set_scrollback_no_colors }, { "scrollback_search_new_window", set_scrollback_search_new_window }, { "scrollback_show_winnrs", set_scrollback_show_winnrs }, { "searches_case_insensitive", set_searches_case_insensitive }, { "searchhistory_file", set_searchhistory_file }, { "searchhistory_size", set_searchhistory_size }, { "shell", set_shell }, { "show_severity_facility", set_show_severity_facility }, { "show_subwindow_id", set_show_subwindow_id }, { "splitline", set_splitline }, { "splitline_attrs", set_splitline_attrs }, { "statusline_above_data", set_statusline_above_data }, { "statusline_attrs", set_statusline_attrs }, { "statusline_ts_format", set_statusline_ts_format }, { "subwindow_number", set_subwindow_number }, { "suppress_empty_lines", set_suppress_empty_lines }, { "syslog_ts_format", set_syslog_ts_format }, { "tab_stop", set_tab_stop }, { "tail", set_tail }, { "titlebar", set_titlebar }, { "ts_format", set_ts_format }, { "umask", set_umask }, { "useeditscheme", use_editscheme }, { "usefilterscheme", use_filterscheme }, { "warn_closed", set_warn_closed }, { "window_number", set_window_number }, { "wordwrapmaxlength", set_wordwrapmaxlength } }; int find_config_entry_in_dispatch_table(char *cmd_name) { int left = 0; int right = (sizeof(cf_entries) / sizeof(config_file_keyword)) - 1; while(left <= right) { int mid = (left + right) / 2; int compare = strcmp(cmd_name, cf_entries[mid].config_keyword); if (compare > 0) left = mid + 1; else if (compare < 0) right = mid - 1; else return mid; } return -1; } int config_file_entry(int linenr, char *cmd) { int function_nr; char *par = NULL; /* remove spaces at the beginning of the line */ while (isspace(*cmd)) cmd++; /* skip empty lines and comments */ if (cmd[0] == 0x00 || cmd[0] == '#' || cmd[0] == ';') return 0; /* lines are in the format of command:parameter */ if ((par = find_next_par(cmd)) == NULL) config_error_exit(linenr, "Malformed configuration line found: %s (command delimiter (':') missing).\n", cmd); function_nr = find_config_entry_in_dispatch_table(cmd); if (function_nr == -1) return -1; cf_entries[function_nr].function(linenr, cmd, par); return 0; } int sort_colorschemes_compare(const void *a, const void *b) { color_scheme *pa = (color_scheme *)a; color_scheme *pb = (color_scheme *)b; return strcmp(pa -> name, pb -> name); } /* returns the default color scheme or -1 if none */ void do_load_config(int dummynr, char *dummy, char *file) { static char sorted = 0; FILE *fh; int linenr = 0; /* given file */ fh = fopen(file, "r"); if (fh == NULL) { if (errno == ENOENT) /* file does not exist, not an error */ return; error_exit(__FILE__, __PRETTY_FUNCTION__, __LINE__, "do_load_config: error loading configfile '%s'\n", file); } for(;;) { char read_buffer[CONFIG_READ_BUFFER]; char *dummy; char *cmd = fgets(read_buffer, sizeof(read_buffer) - 1, fh); if (!cmd) break; linenr++; /* strip LF */ dummy = strchr(cmd, '\n'); if (dummy) *dummy = 0x00; else error_exit(__FILE__, __PRETTY_FUNCTION__, __LINE__, "line %d of file '%s' is too long!\n", linenr, file); /* LOG("%d: %s\n", linenr, cmdin); */ if (config_file_entry(linenr, cmd) == -1) error_exit(__FILE__, __PRETTY_FUNCTION__, __LINE__, "Configuration parameter '%s' is unknown (file: %s, line: %d).\n", read_buffer, file, linenr); } fclose(fh); if (!sorted) { sorted = 1; qsort(cschemes, n_cschemes, sizeof(color_scheme), sort_colorschemes_compare); } } void load_configfile_wrapper(char *config_file) { /* load configurationfile (if any) */ if (load_global_config) do_load_config(-1, NULL, CONFIG_FILE); if (config_file) { do_load_config(-1, NULL, config_file); } else { int path_max = find_path_max(); char *path = mymalloc(path_max + 1, __FILE__, __PRETTY_FUNCTION__, __LINE__); char *home = getenv("HOME"); struct passwd *pp = getuserinfo(); if (home) snprintf(path, path_max, "%s/.multitailrc", home); else snprintf(path, path_max, "%s/.multitailrc", pp -> pw_dir); do_load_config(-1, NULL, path); myfree(path); } } char load_configfile(char *config_file) { static char config_loaded = 0; if (config_loaded == 0) { /* load configurationfile (if any) */ load_configfile_wrapper(config_file); config_loaded = 1; return 1; } return 0; }