core: merge alias and column configuration into settings

This commit is contained in:
Kaian 2018-11-26 20:04:58 +01:00
parent 698cd705af
commit 611c19fafa
21 changed files with 696 additions and 653 deletions

View File

@ -49,7 +49,6 @@ set(SOURCES
src/filter.c
src/group.c
src/main.c
src/option.c
src/stream.c
src/setting.c
src/attribute.c

View File

@ -54,4 +54,3 @@ sngrep_SOURCES+=capture/capture.c
sngrep_SOURCES+=capture/capture_txt.c
sngrep_SOURCES+=capture/capture_pcap.c
sngrep_SOURCES+=filter.c
sngrep_SOURCES+=option.c

View File

@ -32,25 +32,25 @@
#include "ncurses/manager.h"
static AttributeHeader attrs[ATTR_COUNT] = {
{ ATTR_CALLINDEX, "index", "Idx", "Call Index", 4 , NULL },
{ ATTR_SIPFROM, "sipfrom", NULL, "SIP From", 25, NULL },
{ ATTR_SIPFROMUSER, "sipfromuser", NULL, "SIP From User", 20, NULL },
{ ATTR_SIPTO, "sipto", NULL, "SIP To", 25, NULL },
{ ATTR_SIPTOUSER, "siptouser", NULL, "SIP To User", 20, NULL },
{ ATTR_SRC, "src", NULL, "Source", 22, NULL },
{ ATTR_DST, "dst", NULL, "Destination", 22, NULL },
{ ATTR_CALLID, "callid", NULL, "Call-ID", 50, NULL },
{ ATTR_XCALLID, "xcallid", NULL, "X-Call-ID", 50, NULL },
{ ATTR_DATE, "date", NULL, "Date", 10, NULL },
{ ATTR_TIME, "time", NULL, "Time", 8, NULL },
{ ATTR_METHOD, "method", NULL, "Method", 10, attr_color_sip_method },
{ ATTR_TRANSPORT, "transport", "Trans", "Transport", 3, NULL },
{ ATTR_MSGCNT, "msgcnt", "Msgs", "Message Count", 5, NULL },
{ ATTR_CALLSTATE, "state", NULL, "Call State", 10, attr_color_call_state },
{ ATTR_CONVDUR, "convdur", "ConvDur", "Conversation Duration", 7, NULL },
{ ATTR_TOTALDUR, "totaldur", "TotalDur", "Total Duration", 8, NULL },
{ ATTR_REASON_TXT, "reason", "Reason Text", "Reason Text", 25, NULL },
{ ATTR_WARNING, "warning", "Warning", "Warning code", 4, NULL }
{ ATTR_CALLINDEX, "index", "Idx", "Call Index", NULL },
{ ATTR_SIPFROM, "sipfrom", NULL, "SIP From", NULL },
{ ATTR_SIPFROMUSER, "sipfromuser", NULL, "SIP From User", NULL },
{ ATTR_SIPTO, "sipto", NULL, "SIP To", NULL },
{ ATTR_SIPTOUSER, "siptouser", NULL, "SIP To User", NULL },
{ ATTR_SRC, "src", NULL, "Source", NULL },
{ ATTR_DST, "dst", NULL, "Destination", NULL },
{ ATTR_CALLID, "callid", NULL, "Call-ID", NULL },
{ ATTR_XCALLID, "xcallid", NULL, "X-Call-ID", NULL },
{ ATTR_DATE, "date", NULL, "Date", NULL },
{ ATTR_TIME, "time", NULL, "Time", NULL },
{ ATTR_METHOD, "method", NULL, "Method", attr_color_sip_method },
{ ATTR_TRANSPORT, "transport", "Trans", "Transport", NULL },
{ ATTR_MSGCNT, "msgcnt", "Msgs", "Message Count", NULL },
{ ATTR_CALLSTATE, "state", NULL, "Call State", attr_color_call_state },
{ ATTR_CONVDUR, "convdur", "ConvDur", "Conversation Duration", NULL },
{ ATTR_TOTALDUR, "totaldur", "TotalDur", "Total Duration", NULL },
{ ATTR_REASON_TXT, "reason", "Reason Text", "Reason Text", NULL },
{ ATTR_WARNING, "warning", "Warning", "Warning code", NULL }
};
AttributeHeader *
@ -91,16 +91,6 @@ attr_name(enum AttributeId id)
return NULL;
}
gint
attr_width(enum AttributeId id)
{
AttributeHeader *header;
if ((header = attr_header(id))) {
return header->dwidth;
}
return 0;
}
gint
attr_find_by_name(const gchar *name)
{

View File

@ -106,8 +106,6 @@ struct _AttributeHeader {
gchar *title;
//! Attribute description
gchar *desc;
//! Attribute default display width
guint dwidth;
//! This function determines the color of this attribute in CallList
int (*color)(const char *value);
};
@ -169,15 +167,6 @@ attr_title(enum AttributeId id);
const gchar *
attr_name(enum AttributeId id);
/**
* @brief Get Attribute prefered display width
*
* @param id Attribute id
* @return prefered attribute width
*/
int
attr_width(enum AttributeId id);
/**
* @brief Get Attribute id from its name
*

View File

@ -28,7 +28,7 @@
#include "config.h"
#include <glib.h>
#include "option.h"
#include "setting.h"
#include "capture/capture.h"
#include "ncurses/manager.h"
#ifdef USE_HEP
@ -147,23 +147,13 @@ main(int argc, char* argv[])
return 1;
}
// Parse command line arguments that have high priority
if (version) {
print_version_info();
return 0;
} else if (config_dump) {
key_bindings_dump();
settings_dump();
return 0;
}
/***************************** Configuration *****************************/
// Initialize configuration options
init_options(no_config);
settings_init(no_config);
// Override default configuration options if requested
if (config_file)
read_options(config_file);
setting_read_file(config_file);
// Get initial values for configurable arguments
if (!storage_mopts.invite)
@ -183,6 +173,16 @@ main(int argc, char* argv[])
if (!keyfile) keyfile = g_strdup(setting_get_value(SETTING_CAPTURE_KEYFILE));
#endif
// Parse command line arguments that have high priority
if (version) {
print_version_info();
return 0;
} else if (config_dump) {
key_bindings_dump();
settings_dump();
return 0;
}
/***************************** Capture Inputs *****************************/
// Main packet capture manager
manager = capture_manager_new();
@ -348,7 +348,7 @@ main(int argc, char* argv[])
ncurses_deinit();
// Deinitialize configuration options
deinit_options();
settings_deinit();
// Deallocate sip stored messages
storage_deinit();

View File

@ -231,8 +231,10 @@ ncurses_find_by_type(enum WindowTypes type)
break;
case WINDOW_SETTINGS:
window = settings_win_new();
break;
case WINDOW_AUTH_VALIDATE:
window = auth_validate_win_new();
break;
default: break;
}

View File

@ -368,7 +368,7 @@ auth_validate_win_new()
form_opts_off(info->form, O_BS_OVERLOAD);
// Set Default field values
char savepath[MAX_SETTING_LEN];
char savepath[SETTING_MAX_LEN];
sprintf(savepath, "%s", setting_get_value(SETTING_SAVEPATH));
set_field_buffer(info->fields[FLD_AUTH_CLOSE], 0, "[ Close ]");

View File

@ -40,7 +40,7 @@
#include "save_win.h"
#include "timeval.h"
#include "glib-utils.h"
#include "option.h"
#include "setting.h"
/***
*
@ -170,7 +170,7 @@ call_flow_arrow_filter(void *item)
if (setting_enabled(SETTING_CF_MEDIA))
return 1;
// Otherwise only show active streams
if (setting_has_value(SETTING_CF_MEDIA, SETTING_ACTIVE))
if (setting_has_value(SETTING_CF_MEDIA, "active"))
return stream_is_active(arrow->item);
}
@ -361,7 +361,7 @@ call_flow_column_get_starting(Window *window, G_GNUC_UNUSED const char *callid,
gboolean match_port = addr.port != 0;
// Get alias value for given address
const gchar *alias = get_alias_value(addr.ip);
const gchar *alias = setting_get_alias(addr.ip);
for (guint i = start; i < g_ptr_array_len(info->columns); i++) {
CallFlowColumn *column = g_ptr_array_index(info->columns, i);
@ -427,7 +427,7 @@ call_flow_column_new(Address addr)
// Create a new column
CallFlowColumn * column = g_malloc0(sizeof(CallFlowColumn));
column->addr = addr;
column->alias = g_strdup(get_alias_value(addr.ip));
column->alias = setting_get_alias(addr.ip);
return column;
}
@ -546,7 +546,7 @@ call_flow_draw_columns(Window *window)
{
Call *call = NULL;
RtpStream *stream;
char coltext[MAX_SETTING_LEN];
char coltext[SETTING_MAX_LEN];
Address addr;
// Get panel information
@ -592,22 +592,22 @@ call_flow_draw_columns(Window *window)
}
if (setting_enabled(SETTING_CF_SPLITCALLID) || !column->addr.port) {
snprintf(coltext, MAX_SETTING_LEN, "%s", column->alias);
snprintf(coltext, SETTING_MAX_LEN, "%s", column->alias);
} else if (setting_enabled(SETTING_DISPLAY_ALIAS)) {
if (strlen(column->addr.ip) > 15) {
snprintf(coltext, MAX_SETTING_LEN, "..%.*s:%hu",
MAX_SETTING_LEN - 7, column->alias + strlen(column->alias) - 13, column->addr.port);
snprintf(coltext, SETTING_MAX_LEN, "..%.*s:%hu",
SETTING_MAX_LEN - 7, column->alias + strlen(column->alias) - 13, column->addr.port);
} else {
snprintf(coltext, MAX_SETTING_LEN, "%.*s:%hu",
MAX_SETTING_LEN - 7, column->alias, column->addr.port);
snprintf(coltext, SETTING_MAX_LEN, "%.*s:%hu",
SETTING_MAX_LEN - 7, column->alias, column->addr.port);
}
} else {
if (strlen(column->addr.ip) > 15) {
snprintf(coltext, MAX_SETTING_LEN, "..%.*s:%hu",
MAX_SETTING_LEN - 7, column->addr.ip + strlen(column->addr.ip) - 13, column->addr.port);
snprintf(coltext, SETTING_MAX_LEN, "..%.*s:%hu",
SETTING_MAX_LEN - 7, column->addr.ip + strlen(column->addr.ip) - 13, column->addr.port);
} else {
snprintf(coltext, MAX_SETTING_LEN, "%.*s:%hu",
MAX_SETTING_LEN - 7, column->addr.ip, column->addr.port);
snprintf(coltext, SETTING_MAX_LEN, "%.*s:%hu",
SETTING_MAX_LEN - 7, column->addr.ip, column->addr.port);
}
}

View File

@ -123,7 +123,7 @@ struct _CallFlowColumn {
//! Address header for this column
Address addr;
//! Alias for the given address
gchar *alias;
const gchar *alias;
//! Call Ids
GList *callids;
};

View File

@ -34,7 +34,7 @@
#include <stdio.h>
#include <ctype.h>
#include "glib-utils.h"
#include "option.h"
#include "setting.h"
#include "filter.h"
#include "capture/capture_pcap.h"
#ifdef USE_HEP
@ -1082,6 +1082,14 @@ call_list_help(G_GNUC_UNUSED Window *window)
return 0;
}
static gint
call_list_column_sorter(const CallListColumn **a, const CallListColumn **b)
{
if ((*a)->position > (*b)->position) return 1;
if ((*a)->position < (*b)->position) return -1;
return 0;
}
/**
* @brief Add a column the Call List
*
@ -1096,7 +1104,7 @@ call_list_help(G_GNUC_UNUSED Window *window)
*/
static void
call_list_add_column(Window *window, enum AttributeId id, const char* attr,
const char *title, int width)
const char *title, gint position, int width)
{
CallListWinInfo *info = call_list_info(window);
g_return_if_fail(info != NULL);
@ -1105,7 +1113,8 @@ call_list_add_column(Window *window, enum AttributeId id, const char* attr,
column->id = id;
column->attr = attr;
column->title = title;
column->width = (guint) width;
column->position = position;
column->width = width;
g_ptr_array_add(info->columns, column);
}
@ -1177,27 +1186,21 @@ call_list_win_new()
// Add configured columns
info->columns = g_ptr_array_new_with_free_func(g_free);
for (guint i = 0; i < ATTR_COUNT; i++) {
for (guint attr_id = 0; attr_id < ATTR_COUNT; attr_id++) {
// Get column attribute name from options
gchar *option = g_strdup_printf("cl.column%d", i);
const gchar *field = NULL;
if ((field = get_option_value(option)) != NULL) {
gint attrid, collen;
if ((attrid = attr_find_by_name(field)) == -1)
continue;
gint position = setting_column_pos(attr_id);
// Check column is visible
if (position == -1) continue;
// Get column width from options
sprintf(option, "cl.column%d.width", i);
if ((collen = get_option_int_value(option)) == -1)
collen = attr_width(attrid);
// Get column information
gint collen = setting_column_width(attr_id);
const gchar *title = attr_title(attr_id);
const gchar *field = attr_name(attr_id);
// Get column title
const gchar *title = attr_title(attrid);
// Add column to the list
call_list_add_column(window, attrid, field, title, collen);
}
g_free(option);
// Add column to the list
call_list_add_column(window, attr_id, field, title, position, collen);
}
g_ptr_array_sort(info->columns, (GCompareFunc) call_list_column_sorter);
// Initialize the fields
info->fields[FLD_LIST_FILTER] = new_field(1, window->width - 19, 3, 18, 0, 0);

View File

@ -66,8 +66,10 @@ struct _CallListColumn {
const char *attr;
//! Column title
const char *title;
//! Current column position
gint position;
//! Current width
guint width;
gint width;
};
/**

View File

@ -177,7 +177,7 @@ column_select_update_columns(Window *ui)
column->id = attr_id;
column->attr = attr_name(attr_id);
column->title = attr_title(attr_id);
column->width = (guint) attr_width(attr_id);
column->width = setting_column_width(attr_id);
g_ptr_array_add(info->selected, column);
}
}
@ -257,11 +257,12 @@ column_select_save_columns(Window *ui)
// Add all selected columns
for (gint i = 0; i < item_count(info->menu); i++) {
// If column is active
if (!strncmp(item_name(info->items[i]), "[ ]", 3))
continue;
// Add the columns settings
g_fprintf(fo, "set cl.column%d %s\n", i, (const char*) item_userptr(info->items[i]));
if (!strncmp(item_name(info->items[i]), "[ ]", 3)) {
g_fprintf(fo, "set cl.column.%s.pos -1\n", (const char*) item_userptr(info->items[i]));
} else {
// Add the columns settings
g_fprintf(fo, "set cl.column.%s.pos %d\n", (const char *) item_userptr(info->items[i]), i);
}
}
fclose(fo);

View File

@ -113,7 +113,7 @@ filter_field_method(int field_id)
static void
filter_save_options(Window *ui)
{
char field_value[MAX_SETTING_LEN];
char field_value[SETTING_MAX_LEN];
char *expr;
int field_id;
char method_expr[256];
@ -201,7 +201,7 @@ static int
filter_handle_key(Window *ui, int key)
{
int field_idx;
char field_value[MAX_SETTING_LEN];
char field_value[SETTING_MAX_LEN];
// Get panel information
FilterWinInfo *info = filter_info(ui);

View File

@ -29,7 +29,7 @@
#include <stdlib.h>
#include <string.h>
#include "msg_diff_win.h"
#include "option.h"
#include "setting.h"
/***
*

View File

@ -68,7 +68,7 @@ save_info(Window *window)
static int
save_draw(Window *window)
{
char field_value[MAX_SETTING_LEN];
char field_value[SETTING_MAX_LEN];
// Get panel information
SaveWinInfo *info = save_info(window);
@ -148,9 +148,9 @@ save_packet_cb(Packet *packet, CaptureOutput *output)
static int
save_to_file(Window *window)
{
char savepath[MAX_SETTING_LEN];
char savefile[MAX_SETTING_LEN];
char fullfile[MAX_SETTING_LEN*2];
char savepath[SETTING_MAX_LEN];
char savefile[SETTING_MAX_LEN];
char fullfile[SETTING_MAX_LEN*2];
CaptureOutput *output = NULL;
int cur = 0, total = 0;
WINDOW *progress;
@ -530,8 +530,8 @@ save_win_new()
field_opts_off(info->fields[FLD_SAVE_MESSAGE], O_VISIBLE);
// Limit max save path and file length
set_max_field(info->fields[FLD_SAVE_PATH], MAX_SETTING_LEN);
set_max_field(info->fields[FLD_SAVE_FILE], MAX_SETTING_LEN);
set_max_field(info->fields[FLD_SAVE_PATH], SETTING_MAX_LEN);
set_max_field(info->fields[FLD_SAVE_FILE], SETTING_MAX_LEN);
// Change background of input fields
set_field_back(info->fields[FLD_SAVE_PATH], A_UNDERLINE);
@ -548,7 +548,7 @@ save_win_new()
form_opts_off(info->form, O_BS_OVERLOAD);
// Set Default field values
char savepath[MAX_SETTING_LEN];
char savepath[SETTING_MAX_LEN];
sprintf(savepath, "%s", setting_get_value(SETTING_SAVEPATH));
set_field_buffer(info->fields[FLD_SAVE_PATH], 0, savepath);

View File

@ -324,7 +324,7 @@ settings_handle_key(Window *ui, int key)
{
int field_idx;
SettingsWinEntry *entry;
enum setting_fmt sett_fmt = -1;
enum SettingFormat sett_fmt = -1;
// Get panel information
SettingsWinInfo *info = settings_info(ui);
@ -536,6 +536,11 @@ settings_win_new()
field_opts_off(entry, O_STATIC);
set_field_back(entry, A_UNDERLINE);
break;
case SETTING_FMT_BOOLEAN:
entry = new_field(1, 12, line, 48, 0, 0);
field_opts_off(entry, O_EDIT);
set_field_type(entry, TYPE_ENUM, setting_valid_values(entries[j].setting_id), 0, 0);
break;
case SETTING_FMT_ENUM:
entry = new_field(1, 12, line, 48, 0, 0);
field_opts_off(entry, O_EDIT);

View File

@ -149,7 +149,7 @@ struct _SettingsWinEntry {
//! Field id in settings_info array
enum SettingWinField field_id;
//! Setting id of current entry
enum setting_id setting_id;
enum SettingId setting_id;
//! Entry text
const char *label;
};

View File

@ -1,214 +0,0 @@
/**************************************************************************
**
** sngrep - SIP Messages flow viewer
**
** Copyright (C) 2013-2018 Ivan Alonso (Kaian)
** Copyright (C) 2013-2018 Irontec SL. All rights reserved.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** 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 General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**
****************************************************************************/
/**
* @file option.c
* @author Ivan Alonso [aka Kaian] <kaian@irontec.com>
*
* @brief Source code of functions defined in option.h
*
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include "ncurses/keybinding.h"
#include "option.h"
#include "setting.h"
#include "timeval.h"
/**
* @brief Configuration options array
*
* Contains all availabe options that can be optionured
* @todo make this dynamic
*/
option_opt_t options[1024];
int optscnt = 0;
int
init_options(int no_config)
{
// Custom user conf file
GString *userconf = NULL;
char *rcfile;
char pwd[MAX_SETTING_LEN];
// Defualt savepath is current directory
if (getcwd(pwd, MAX_SETTING_LEN)) {
setting_set_value(SETTING_SAVEPATH, pwd);
}
// Initialize settings
setting_set_value(SETTING_FILTER_METHODS, "REGISTER,INVITE,SUBSCRIBE,NOTIFY,OPTIONS,PUBLISH,MESSAGE,INFO,REFER,UPDATE");
// Add Call list column options
set_option_value("cl.column0", "index");
set_option_value("cl.column1", "method");
set_option_value("cl.column2", "sipfrom");
set_option_value("cl.column3", "sipto");
set_option_value("cl.column4", "msgcnt");
set_option_value("cl.column5", "src");
set_option_value("cl.column6", "dst");
set_option_value("cl.column7", "state");
// Done if config file should not be read
if(no_config) {
return 0;
}
// Read options from configuration files
read_options("/etc/sngreprc");
read_options("/usr/local/etc/sngreprc");
// Get user configuration
if ((rcfile = getenv("SNGREPRC"))) {
read_options(rcfile);
} else if ((rcfile = getenv("HOME"))) {
userconf = g_string_new(rcfile);
g_string_append(userconf, "/.sngreprc");
read_options(userconf->str);
g_string_free(userconf, TRUE);
}
return 0;
}
void
deinit_options()
{
int i;
// Deallocate options memory
for (i = 0; i < optscnt; i++) {
g_free(options[i].opt);
g_free(options[i].value);
}
}
int
read_options(const char *fname)
{
FILE *fh;
char line[1024], type[20], option[50], value[50];
int id;
if (!(fh = fopen(fname, "rt")))
return -1;
while (fgets(line, 1024, fh) != NULL) {
// Check if this line is a commentary or empty line
if (!strlen(line) || *line == '#')
continue;
// Get configuration option from setting line
if (sscanf(line, "%s %s %[^\t\n]", type, option, value) == 3) {
if (!strcasecmp(type, "set")) {
if ((id = setting_id(option)) >= 0) {
setting_set_value(id, value);
} else {
set_option_value(option, value);
}
} else if (!strcasecmp(type, "alias")) {
set_alias_value(option, value);
} else if (!strcasecmp(type, "bind")) {
key_bind_action(key_action_id(option), key_from_str(value));
} else if (!strcasecmp(type, "unbind")) {
key_unbind_action(key_action_id(option), key_from_str(value));
}
}
}
fclose(fh);
return 0;
}
const char*
get_option_value(const char *opt)
{
int i;
for (i = 0; i < optscnt; i++) {
if (!strcasecmp(opt, options[i].opt)) {
return options[i].value;
}
}
return NULL;
}
int
get_option_int_value(const char *opt)
{
const char *value;
if ((value = get_option_value(opt))) {
return atoi(value);
}
return -1;
}
void
set_option_value(const char *opt, const char *value)
{
if (!opt || !value)
return;
int i;
if (!get_option_value(opt)) {
options[optscnt].type = COLUMN;
options[optscnt].opt = strdup(opt);
options[optscnt].value = strdup(value);
optscnt++;
} else {
for (i = 0; i < optscnt; i++) {
if (!strcasecmp(opt, options[i].opt)) {
g_free(options[i].value);
options[i].value = strdup(value);
}
}
}
}
void
set_alias_value(const char *address, const char *alias)
{
options[optscnt].type = ALIAS;
options[optscnt].opt = strdup(address);
options[optscnt].value = strdup(alias);
optscnt++;
}
const char *
get_alias_value(const char *address)
{
int i;
if (!address)
return NULL;
for (i = 0; i < optscnt; i++) {
if (options[i].type != ALIAS)
continue;
if (!strcmp(options[i].opt, address))
return options[i].value;
}
return address;
}

View File

@ -1,161 +0,0 @@
/**************************************************************************
**
** sngrep - SIP Messages flow viewer
**
** Copyright (C) 2013-2018 Ivan Alonso (Kaian)
** Copyright (C) 2013-2018 Irontec SL. All rights reserved.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** 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 General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**
****************************************************************************/
/**
* @file option.h
* @author Ivan Alonso [aka Kaian] <kaian@irontec.com>
*
* @brief Functions to manage application settings
*
* This file contains the functions to manage application settings and
* optionuration resource files. Configuration will be parsed in this order,
* from less to more priority, so the later will overwrite the previous.
*
* - Initialization
* - \@sysdir\@/sngreprc
* - $HOME/.sngreprc
* - $SNGREPRC
*
* This is a basic approach to configuration, but at least a minimun is required
* for those who can not see all the list columns or want to disable colours in
* every sngrep execution.
*
*/
#ifndef __SNGREP_CONFIG_H
#define __SNGREP_CONFIG_H
//! Shorter declarartion of config_option struct
typedef struct config_option option_opt_t;
//! Option types
enum option_type {
COLUMN = 0,
ALIAS
};
/**
* @brief Configurable option structure
*
* sngrep is optionured by a group of attributes that can be
* modified using resource files.
*/
struct config_option {
//! Setting type
enum option_type type;
//! Name of attribute
char *opt;
//! Value of attribute
char *value;
};
/**
* @brief Initialize all program options
*
* This function will give all available settings an initial value.
* This values can be overriden using resources files, either from system dir
* or user home dir.
*
* @param no_config Do not load config file if set to 1
* @return 0 in all cases
*/
int
init_options(int no_config);
/**
* @brief Deallocate options memory
*
* Deallocate memory used for program configurations
*/
void
deinit_options();
/**
* @brief Read optionuration directives from file
*
* This funtion will parse passed filenames searching for configuration
* directives of sngrep. See documentation for a list of available
* directives and attributes
*
* @param fname Full path configuration file name
* @return 0 in case of parse success, -1 otherwise
*/
int
read_options(const char *fname);
/**
* @brief Get settings option value (string)
*
* Used in all the program to access the optionurable options of sngrep
* Use this function instead of accessing optionuration array.
*
* @param opt Name of optionurable option
* @return configuration option value or NULL if not found
*/
const char*
get_option_value(const char *opt);
/**
* @brief Get settings option value (int)
*
* Basically the same as get_option_value converting the result to
* integer.
* Use this function instead of accessing configuration array.
*
* @todo -1 is an error!
*
* @param opt Name of optionurable option
* @return option numeric value or -1 in case of error
*/
int
get_option_int_value(const char *opt);
/**
* @brief Sets a settings option value
*
* Basic setter for 'set' directive attributes
*
* @param opt Name of configuration option
* @param value Value of configuration option
*/
void
set_option_value(const char *opt, const char *value);
/**
* @brief Sets an alias for a given address
*
* @param address IP Address
* @param string representing the alias
*/
void
set_alias_value(const char *address, const char *alias);
/**
* @brief Get alias for a given address (string)
*
* @param address IP Address
* @return configured alias or address if not alias found
*/
const char *
get_alias_value(const char *address);
#endif

View File

@ -28,155 +28,159 @@
*/
#include "config.h"
#include <string.h>
#include <glib.h>
#include <stdlib.h>
#include <stdio.h>
#include "ncurses/keybinding.h"
#include "glib-utils.h"
#include "setting.h"
#include "timeval.h"
/**
* @brief Storage settings
*
* This struct contains all the configurable options and can be updated
* from resource files.
*
* - Settings
* - Alias
* - Call List columns
*/
static SettingStorage *storage = NULL;
//! Available configurable settings
setting_t settings[SETTING_COUNT] = {
{ SETTING_BACKGROUND, "background", SETTING_FMT_ENUM, "dark", SETTING_ENUM_BACKGROUND },
{ SETTING_COLORMODE, "colormode", SETTING_FMT_ENUM, "request", SETTING_ENUM_COLORMODE },
{ SETTING_SYNTAX, "syntax", SETTING_FMT_ENUM, SETTING_ON, SETTING_ENUM_ONOFF },
{ SETTING_SYNTAX_TAG, "syntax.tag", SETTING_FMT_ENUM, SETTING_OFF, SETTING_ENUM_ONOFF },
{ SETTING_SYNTAX_BRANCH, "syntax.branch", SETTING_FMT_ENUM, SETTING_OFF, SETTING_ENUM_ONOFF },
{ SETTING_ALTKEY_HINT, "hintkeyalt", SETTING_FMT_ENUM, SETTING_OFF, SETTING_ENUM_ONOFF },
{ SETTING_EXITPROMPT, "exitprompt", SETTING_FMT_ENUM, SETTING_ON, SETTING_ENUM_ONOFF },
{ SETTING_CAPTURE_LIMIT, "capture.limit", SETTING_FMT_NUMBER, "20000", NULL },
{ SETTING_CAPTURE_DEVICE, "capture.device", SETTING_FMT_STRING, "any", NULL },
{ SETTING_CAPTURE_OUTFILE, "capture.outfile", SETTING_FMT_STRING, "", NULL },
#ifdef WITH_SSL
{ SETTING_CAPTURE_KEYFILE, "capture.keyfile", SETTING_FMT_STRING, "", NULL },
{ SETTING_CAPTURE_TLSSERVER, "capture.tlsserver", SETTING_FMT_STRING, "", NULL },
#endif
{ SETTING_CAPTURE_RTP, "capture.rtp", SETTING_FMT_ENUM, SETTING_OFF, SETTING_ENUM_ONOFF },
{ SETTING_CAPTURE_STORAGE, "capture.storage", SETTING_FMT_ENUM, "memory", SETTING_ENUM_STORAGE },
{ SETTING_CAPTURE_ROTATE, "capture.rotate", SETTING_FMT_ENUM, SETTING_OFF, SETTING_ENUM_ONOFF },
{ SETTING_SIP_NOINCOMPLETE, "sip.noincomplete", SETTING_FMT_ENUM, SETTING_ON, SETTING_ENUM_ONOFF },
{ SETTING_SIP_HEADER_X_CID, "sip.xcid", SETTING_FMT_STRING, "X-Call-ID|X-CID", NULL },
{ SETTING_SIP_CALLS, "sip.calls", SETTING_FMT_ENUM, SETTING_OFF, SETTING_ENUM_ONOFF },
{ SETTING_SAVEPATH, "savepath", SETTING_FMT_STRING, "", NULL },
{ SETTING_DISPLAY_ALIAS, "displayalias", SETTING_FMT_ENUM, SETTING_OFF, SETTING_ENUM_ONOFF },
{ SETTING_CL_SCROLLSTEP, "cl.scrollstep", SETTING_FMT_NUMBER, "4", NULL },
{ SETTING_CL_COLORATTR, "cl.colorattr", SETTING_FMT_ENUM, SETTING_ON, SETTING_ENUM_ONOFF },
{ SETTING_CL_AUTOSCROLL, "cl.autoscroll", SETTING_FMT_ENUM, SETTING_OFF, SETTING_ENUM_ONOFF },
{ SETTING_CL_SORTFIELD, "cl.sortfield", SETTING_FMT_STRING, "index", NULL },
{ SETTING_CL_SORTORDER, "cl.sortorder", SETTING_FMT_STRING, "asc", NULL },
{ SETTING_CF_FORCERAW, "cf.forceraw", SETTING_FMT_ENUM, SETTING_ON, SETTING_ENUM_ONOFF },
{ SETTING_CF_RAWMINWIDTH, "cf.rawminwidth", SETTING_FMT_NUMBER, "40", NULL },
{ SETTING_CF_RAWFIXEDWIDTH, "cf.rawfixedwidth", SETTING_FMT_NUMBER, "", NULL },
{ SETTING_CF_SPLITCALLID, "cf.splitcallid", SETTING_FMT_ENUM, SETTING_OFF, SETTING_ENUM_ONOFF },
{ SETTING_CF_HIGHTLIGHT, "cf.highlight", SETTING_FMT_ENUM, "bold", SETTING_ENUM_HIGHLIGHT },
{ SETTING_CF_SCROLLSTEP, "cf.scrollstep", SETTING_FMT_NUMBER, "4", NULL },
{ SETTING_CF_LOCALHIGHLIGHT, "cf.localhighlight", SETTING_FMT_ENUM, SETTING_ON, SETTING_ENUM_ONOFF },
{ SETTING_CF_SDP_INFO, "cf.sdpinfo", SETTING_FMT_ENUM, SETTING_OFF, SETTING_ENUM_SDP_INFO },
{ SETTING_CF_MEDIA, "cf.media", SETTING_FMT_ENUM, SETTING_OFF, SETTING_ENUM_MEDIA },
{ SETTING_CF_ONLYMEDIA, "cf.onlymedia", SETTING_FMT_ENUM, SETTING_OFF, SETTING_ENUM_ONOFF },
{ SETTING_CF_DELTA, "cf.deltatime", SETTING_FMT_ENUM, SETTING_ON, SETTING_ENUM_ONOFF },
{ SETTING_CR_SCROLLSTEP, "cr.scrollstep", SETTING_FMT_NUMBER, "10", NULL },
{ SETTING_CR_NON_ASCII, "cr.nonascii", SETTING_FMT_STRING, ".", NULL },
{ SETTING_FILTER_PAYLOAD, "filter.payload", SETTING_FMT_STRING, "", NULL },
{ SETTING_FILTER_METHODS, "filter.methods", SETTING_FMT_STRING, "", NULL },
#ifdef USE_HEP
{ SETTING_HEP_SEND, "eep.send", SETTING_FMT_ENUM, SETTING_OFF, SETTING_ENUM_ONOFF },
{ SETTING_HEP_SEND_VER, "eep.send.version", SETTING_FMT_ENUM, "3", SETTING_ENUM_HEPVERSION },
{ SETTING_HEP_SEND_ADDR, "eep.send.address", SETTING_FMT_STRING, "127.0.0.1", NULL },
{ SETTING_HEP_SEND_PORT, "eep.send.port", SETTING_FMT_NUMBER, "9060", NULL },
{ SETTING_HEP_SEND_PASS, "eep.send.pass", SETTING_FMT_STRING, "", NULL },
{ SETTING_HEP_SEND_ID, "eep.send.id", SETTING_FMT_NUMBER, "2002", NULL },
{ SETTING_HEP_LISTEN, "eep.listen", SETTING_FMT_ENUM, SETTING_OFF, SETTING_ENUM_ONOFF },
{ SETTING_HEP_LISTEN_VER, "eep.listen.version", SETTING_FMT_ENUM, "3", SETTING_ENUM_HEPVERSION },
{ SETTING_HEP_LISTEN_ADDR, "eep.listen.address", SETTING_FMT_STRING, "0.0.0.0", NULL },
{ SETTING_HEP_LISTEN_PORT, "eep.listen.port", SETTING_FMT_NUMBER, "9060", NULL },
{ SETTING_HEP_LISTEN_PASS, "eep.listen.pass", SETTING_FMT_STRING, "", NULL },
{ SETTING_HEP_LISTEN_UUID, "eep.listen.uuid", SETTING_FMT_ENUM, SETTING_OFF, SETTING_ENUM_ONOFF },
#endif
};
setting_t *
setting_by_id(int id)
/**
* @brief Create a new number type setting
*/
static Setting *
setting_number_new(const gchar *name, const gchar *value)
{
int i;
for (i = 0; i < SETTING_COUNT; i++) {
if ((guint) id == settings[i].id)
return &settings[i];
Setting *setting = g_malloc0(sizeof(Setting));
setting->name = name;
setting->fmt = SETTING_FMT_NUMBER;
strncpy(setting->value, value, SETTING_MAX_LEN);
return setting;
}
/**
* @brief Create a new string type setting
*/
static Setting *
setting_string_new(const gchar *name, const gchar *value)
{
Setting *setting = g_malloc0(sizeof(Setting));
setting->name = name;
setting->fmt = SETTING_FMT_STRING;
strncpy(setting->value, value, SETTING_MAX_LEN);
return setting;
}
/**
* @brief Create a new boolean type setting
*/
static Setting *
setting_bool_new(const gchar *name, const gchar *value)
{
Setting *setting = g_malloc0(sizeof(Setting));
setting->name = name;
setting->fmt = SETTING_FMT_BOOLEAN;
strncpy(setting->value, value, SETTING_MAX_LEN);
setting->valuelist = g_strsplit("on,off", ",", -1);
return setting;
}
/**
* @brief Create a new enum type setting
*/
static Setting *
setting_enum_new(const gchar *name, const gchar *value, const gchar *valuelist)
{
Setting *setting = g_malloc0(sizeof(Setting));
setting->name = name;
setting->fmt = SETTING_FMT_ENUM;
strncpy(setting->value, value, SETTING_MAX_LEN);
setting->valuelist = g_strsplit(valuelist, ",", -1);
return setting;
}
Setting *
setting_by_id(enum SettingId id)
{
return g_ptr_array_index(storage->settings, id);
}
Setting *
setting_by_name(const gchar *name)
{
for (guint i = 0; i < g_ptr_array_len(storage->settings); i++) {
Setting *setting = g_ptr_array_index(storage->settings, i);
if (g_strcmp0(setting->name, name) == 0) {
return setting;
}
}
return NULL;
}
setting_t *
setting_by_name(const char *name)
enum SettingId
setting_id(const gchar *name)
{
int i;
for (i = 0; i < SETTING_COUNT; i++) {
if (!strcmp(name, settings[i].name))
return &settings[i];
}
return NULL;
const Setting *sett = setting_by_name(name);
return (sett) ? g_ptr_array_data_index(storage->settings, sett): SETTING_UNKNOWN;
}
int
setting_id(const char *name)
const gchar *
setting_name(enum SettingId id)
{
const setting_t *sett = setting_by_name(name);
return (sett) ? (int) sett->id : -1;
}
const char *
setting_name(int id)
{
const setting_t *sett = setting_by_id(id);
const Setting *sett = setting_by_id(id);
return (sett) ? sett->name : NULL;
}
int
setting_format(int id)
setting_format(enum SettingId id)
{
const setting_t *sett = setting_by_id(id);
const Setting *sett = setting_by_id(id);
return (sett) ? (int) sett->fmt : -1;
}
const char **
setting_valid_values(int id)
setting_valid_values(enum SettingId id)
{
const setting_t *sett = setting_by_id(id);
const Setting *sett = setting_by_id(id);
return (sett) ? sett->valuelist : NULL;
}
const char *
setting_get_value(int id)
setting_get_value(enum SettingId id)
{
const setting_t *sett = setting_by_id(id);
const Setting *sett = setting_by_id(id);
return (sett && strlen(sett->value)) ? sett->value : NULL;
}
int
setting_get_intvalue(int id)
setting_get_intvalue(enum SettingId id)
{
const setting_t *sett = setting_by_id(id);
const Setting *sett = setting_by_id(id);
return (sett && strlen(sett->value)) ? atoi(sett->value) : -1;
}
void
setting_set_value(int id, const char *value)
setting_set_value(enum SettingId id, const char *value)
{
setting_t *sett = setting_by_id(id);
if (sett) {
memset(sett->value, 0, sizeof(sett->value));
if (value) {
if (strlen(value) < MAX_SETTING_LEN) {
strcpy(sett->value, value);
} else {
fprintf(stderr, "Setting value %s for %s is too long\n", sett->value, sett->name);
exit(1);
}
Setting *sett = setting_by_id(id);
g_return_if_fail(sett != NULL);
memset(sett->value, 0, sizeof(sett->value));
if (value) {
if (strlen(value) < SETTING_MAX_LEN) {
strcpy(sett->value, value);
} else {
fprintf(stderr, "Setting value %s for %s is too long\n", sett->value, sett->name);
exit(1);
}
}
}
void
setting_set_intvalue(int id, int value)
setting_set_intvalue(enum SettingId id, int value)
{
char strvalue[80];
sprintf(strvalue, "%d", value);
@ -184,23 +188,23 @@ setting_set_intvalue(int id, int value)
}
int
setting_enabled(int id)
setting_enabled(enum SettingId id)
{
return setting_has_value(id, "on") ||
setting_has_value(id, "yes");
}
int
setting_disabled(int id)
setting_disabled(enum SettingId id)
{
return setting_has_value(id, "off") ||
setting_has_value(id, "no");
}
int
setting_has_value(int id, const char *value)
setting_has_value(enum SettingId id, const char *value)
{
setting_t *sett = setting_by_id(id);
Setting *sett = setting_by_id(id);
if (sett) {
return !strcmp(sett->value, value);
}
@ -209,27 +213,30 @@ setting_has_value(int id, const char *value)
}
void
setting_toggle(int id)
setting_toggle(enum SettingId id)
{
setting_t *sett = setting_by_id(id);
Setting *sett = setting_by_id(id);
if (sett) {
if (sett->fmt == SETTING_FMT_STRING)
return;
if (sett->fmt == SETTING_FMT_NUMBER)
return;
if (sett->fmt == SETTING_FMT_ENUM) {
setting_set_value(id, setting_enum_next(id, sett->value));
switch(sett->fmt) {
case SETTING_FMT_BOOLEAN:
(setting_enabled(id)) ? setting_set_value(id, SETTING_OFF) : setting_set_value(id, SETTING_ON);
break;
case SETTING_FMT_ENUM:
setting_set_value(id, setting_enum_next(id, sett->value));
case SETTING_FMT_STRING: break;
case SETTING_FMT_NUMBER: break;
default: break;
}
}
}
const char *
setting_enum_next(int id, const char *value)
setting_enum_next(enum SettingId id, const char *value)
{
int i;
const char *vnext;
setting_t *sett;
Setting *sett;
if (!(sett = setting_by_id(id)))
return NULL;
@ -256,12 +263,335 @@ setting_enum_next(int id, const char *value)
return NULL;
}
gint
setting_column_pos(enum AttributeId id)
{
const gchar *sett_name = attr_name(id);
g_return_val_if_fail(sett_name != NULL, -1);
gchar *sett_text = g_strdup_printf("cl.column.%s.pos", sett_name);
g_return_val_if_fail(sett_text != NULL, -1);
gint sett_id = setting_id(sett_text);
g_free(sett_text);
g_return_val_if_fail(sett_id != SETTING_UNKNOWN, -1);
return setting_get_intvalue(sett_id);
}
gint
setting_column_width(enum AttributeId id)
{
const gchar *sett_name = attr_name(id);
g_return_val_if_fail(sett_name != NULL, -1);
gchar *sett_text = g_strdup_printf("cl.column.%s.width", sett_name);
g_return_val_if_fail(sett_text != NULL, -1);
gint sett_id = setting_id(sett_text);
g_free(sett_text);
g_return_val_if_fail(setting_name != NULL, -1);
return setting_get_intvalue(sett_id);
}
/**
* @brief Sets an alias for a given address
*
* @param address IP Address
* @param string representing the alias
*/
static void
setting_add_alias(const gchar *address, const gchar *alias)
{
SettingAlias *setting = g_malloc0(sizeof(SettingAlias));
setting->address = address;
setting->alias = alias;
storage->alias = g_list_append(storage->alias, setting);
}
const gchar *
setting_get_alias(const gchar *address)
{
g_return_val_if_fail(address != NULL, NULL);
for (GList *l = storage->alias; l != NULL; l = l->next) {
SettingAlias *alias = l->data;
if (g_strcmp0(alias->address, address) == 0) {
return alias->alias;
}
}
return NULL;
}
int
setting_read_file(const gchar *fname)
{
FILE *fh;
char line[1024], type[20], option[50], value[50];
if (!(fh = fopen(fname, "rt")))
return -1;
while (fgets(line, 1024, fh) != NULL) {
// Check if this line is a commentary or empty line
if (!strlen(line) || *line == '#')
continue;
// Get configuration option from setting line
if (sscanf(line, "%s %s %[^\t\n]", type, option, value) == 3) {
if (!strcasecmp(type, "set")) {
setting_set_value(setting_id(option), value);
} else if (!strcasecmp(type, "alias")) {
setting_add_alias(option, value);
} else if (!strcasecmp(type, "bind")) {
key_bind_action(key_action_id(option), key_from_str(value));
} else if (!strcasecmp(type, "unbind")) {
key_unbind_action(key_action_id(option), key_from_str(value));
}
}
}
fclose(fh);
return 0;
}
int
settings_init(int no_config)
{
// Custom user conf file
GString *userconf = NULL;
char *rcfile;
// Allocate memory for settings storage
storage = g_malloc0(sizeof(SettingStorage));
storage->settings = g_ptr_array_new_with_free_func(g_free);
g_ptr_array_set_size(storage->settings, SETTING_COUNT);
// Default settings values
g_ptr_array_set(storage->settings, SETTING_BACKGROUND,
setting_enum_new("background", "dark", "dark,default"));
g_ptr_array_set(storage->settings, SETTING_COLORMODE,
setting_enum_new("colormode", "request", "request,cseq,callid"));
g_ptr_array_set(storage->settings, SETTING_SYNTAX,
setting_bool_new("syntax", SETTING_ON));
g_ptr_array_set(storage->settings, SETTING_SYNTAX_TAG,
setting_bool_new("syntax.tag", SETTING_OFF));
g_ptr_array_set(storage->settings, SETTING_SYNTAX_BRANCH,
setting_bool_new("syntax.tag", SETTING_OFF));
g_ptr_array_set(storage->settings, SETTING_ALTKEY_HINT,
setting_bool_new("syntax.branch", SETTING_OFF));
g_ptr_array_set(storage->settings, SETTING_SYNTAX_TAG,
setting_bool_new("hintkeyalt", SETTING_OFF));
g_ptr_array_set(storage->settings, SETTING_EXITPROMPT,
setting_bool_new("exitprompt", SETTING_OFF));
g_ptr_array_set(storage->settings, SETTING_CAPTURE_LIMIT,
setting_number_new("capture.limit", "20000"));
g_ptr_array_set(storage->settings, SETTING_CAPTURE_DEVICE,
setting_string_new("capture.device", "any"));
g_ptr_array_set(storage->settings, SETTING_CAPTURE_OUTFILE,
setting_string_new("capture.outfile", ""));
#ifdef WITH_SSL
g_ptr_array_set(storage->settings, SETTING_CAPTURE_KEYFILE,
setting_string_new("capture.keyfile", ""));
g_ptr_array_set(storage->settings, SETTING_CAPTURE_TLSSERVER,
setting_string_new("capture.tlsserver", ""));
#endif
g_ptr_array_set(storage->settings, SETTING_CAPTURE_RTP,
setting_bool_new("capture.rtp", SETTING_OFF));
g_ptr_array_set(storage->settings, SETTING_CAPTURE_STORAGE,
setting_enum_new("capture.storage", "memory", "none,memory"));
g_ptr_array_set(storage->settings, SETTING_CAPTURE_ROTATE,
setting_bool_new("capture.rotate", SETTING_OFF));
g_ptr_array_set(storage->settings, SETTING_SIP_NOINCOMPLETE,
setting_bool_new("sip.noincomplete", SETTING_ON));
g_ptr_array_set(storage->settings, SETTING_SIP_HEADER_X_CID,
setting_string_new("sip.xcid", "X-Call-ID|X-CID"));
g_ptr_array_set(storage->settings, SETTING_SIP_CALLS,
setting_bool_new("sip.calls", SETTING_OFF));
g_ptr_array_set(storage->settings, SETTING_SAVEPATH,
setting_string_new("savepath", g_get_current_dir()));
g_ptr_array_set(storage->settings, SETTING_DISPLAY_ALIAS,
setting_bool_new("displayalias", SETTING_OFF));
g_ptr_array_set(storage->settings, SETTING_CL_SCROLLSTEP,
setting_number_new("cl.scrollstep", "4"));
g_ptr_array_set(storage->settings, SETTING_CL_COLORATTR,
setting_bool_new("cl.colorattr", SETTING_ON));
g_ptr_array_set(storage->settings, SETTING_CL_AUTOSCROLL,
setting_bool_new("cl.autoscroll", SETTING_OFF));
g_ptr_array_set(storage->settings, SETTING_CL_SORTFIELD,
setting_string_new("cl.sortfield", attr_name(ATTR_CALLINDEX)));
g_ptr_array_set(storage->settings, SETTING_CL_SORTORDER,
setting_string_new("cl.sortorder", "asc"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_INDEX_POS,
setting_number_new("cl.column.index.pos", "0"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_INDEX_WIDTH,
setting_number_new("cl.column.index.width", "4"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_SIPFROM_POS,
setting_number_new("cl.column.sipfrom.pos", "2"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_SIPFROM_WIDTH,
setting_number_new("cl.column.sipfrom.width", "25"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_SIPFROMUSER_POS,
setting_number_new("cl.column.sipfromuser.pos", "-1"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_SIPFROMUSER_WIDTH,
setting_number_new("cl.column.sipfromuser.width", "20"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_SIPTO_POS,
setting_number_new("cl.column.sipto.pos", "3"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_SIPTO_WIDTH,
setting_number_new("cl.column.sipto.width", "25"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_SIPTOUSER_POS,
setting_number_new("cl.column.siptouser.pos", "-1"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_SIPTOUSER_WIDTH,
setting_number_new("cl.column.siptouser.width", "20"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_SRC_POS,
setting_number_new("cl.column.src.pos", "5"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_SRC_WIDTH,
setting_number_new("cl.column.src.width", "22"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_DST_POS,
setting_number_new("cl.column.dst.pos", "6"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_DST_WIDTH,
setting_number_new("cl.column.dst.width", "22"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_CALLID_POS,
setting_number_new("cl.column.callid.pos", "-1"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_CALLID_WIDTH,
setting_number_new("cl.column.callid.width", "50"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_XCALLID_POS,
setting_number_new("cl.column.xcallid.pos", "-1"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_XCALLID_WIDTH,
setting_number_new("cl.column.xcallid.width", "50"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_DATE_POS,
setting_number_new("cl.column.date.pos", "-1"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_DATE_WIDTH,
setting_number_new("cl.column.date.width", "10"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_TIME_POS,
setting_number_new("cl.column.time.pos", "-1"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_TIME_WIDTH,
setting_number_new("cl.column.time.width", "8"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_METHOD_POS,
setting_number_new("cl.column.method.pos", "1"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_METHOD_WIDTH,
setting_number_new("cl.column.method.width", "10"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_TRANSPORT_POS,
setting_number_new("cl.column.transport.pos", "-1"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_TRANSPORT_WIDTH,
setting_number_new("cl.column.transport.width", "3"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_MSGCNT_POS,
setting_number_new("cl.column.msgcnt.pos", "4"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_MSGCNT_WIDTH,
setting_number_new("cl.column.msgcnt.width", "5"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_CALLSTATE_POS,
setting_number_new("cl.column.state.pos", "7"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_CALLSTATE_WIDTH,
setting_number_new("cl.column.state.width", "10"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_CONVDUR_POS,
setting_number_new("cl.column.convdur.pos", "-1"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_CONVDUR_WIDTH,
setting_number_new("cl.column.convdur.width", "7"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_TOTALDUR_POS,
setting_number_new("cl.column.totaldur.pos", "-1"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_TOTALDUR_WIDTH,
setting_number_new("cl.column.totaldur.width", "8"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_REASON_TXT_POS,
setting_number_new("cl.column.reason.pos", "-1"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_REASON_TXT_WIDTH,
setting_number_new("cl.column.reason.width", "25"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_WARNING_POS,
setting_number_new("cl.column.warning.pos", "-1"));
g_ptr_array_set(storage->settings, SETTING_CL_COL_WARNING_WIDTH,
setting_number_new("cl.column.warning.width", "4"));
g_ptr_array_set(storage->settings, SETTING_CF_FORCERAW,
setting_bool_new("cf.forceraw", SETTING_ON));
g_ptr_array_set(storage->settings, SETTING_CF_RAWMINWIDTH,
setting_number_new("cf.rawminwidth", "40"));
g_ptr_array_set(storage->settings, SETTING_CF_RAWFIXEDWIDTH,
setting_number_new("cf.rawfixedwidth", ""));
g_ptr_array_set(storage->settings, SETTING_CF_SPLITCALLID,
setting_bool_new("cf.splitcallid", SETTING_OFF));
g_ptr_array_set(storage->settings, SETTING_CF_HIGHTLIGHT,
setting_enum_new("cf.highlight", "bold", "bold,reverse,reversebold"));
g_ptr_array_set(storage->settings, SETTING_CF_SCROLLSTEP,
setting_number_new("cf.scrollstep", "4"));
g_ptr_array_set(storage->settings, SETTING_CF_LOCALHIGHLIGHT,
setting_bool_new("cf.localhighlight", SETTING_ON));
g_ptr_array_set(storage->settings, SETTING_CF_SDP_INFO,
setting_enum_new("cf.sdpinfo", SETTING_OFF, "off,first,full,compressed"));
g_ptr_array_set(storage->settings, SETTING_CF_MEDIA,
setting_bool_new("cf.media", SETTING_OFF));
g_ptr_array_set(storage->settings, SETTING_CF_ONLYMEDIA,
setting_bool_new("cf.onlymedia", SETTING_OFF));
g_ptr_array_set(storage->settings, SETTING_CF_DELTA,
setting_bool_new("cf.deltatime", SETTING_ON));
g_ptr_array_set(storage->settings, SETTING_CR_SCROLLSTEP,
setting_number_new("cr.scrollstep", "10"));
g_ptr_array_set(storage->settings, SETTING_CR_NON_ASCII,
setting_string_new("cr.nonascii", "."));
g_ptr_array_set(storage->settings, SETTING_FILTER_PAYLOAD,
setting_string_new("filter.payload", ""));
g_ptr_array_set(storage->settings, SETTING_FILTER_METHODS,
setting_string_new("filter.methods",
"REGISTER,INVITE,SUBSCRIBE,NOTIFY,OPTIONS,PUBLISH,MESSAGE,INFO,REFER,UPDATE"));
#ifdef USE_HEP
g_ptr_array_set(storage->settings, SETTING_HEP_SEND,
setting_bool_new("eep.send", SETTING_OFF));
g_ptr_array_set(storage->settings, SETTING_HEP_SEND_VER,
setting_number_new("eep.send.version", "3"));
g_ptr_array_set(storage->settings, SETTING_HEP_SEND_ADDR,
setting_string_new("eep.send.address", "127.0.0.1"));
g_ptr_array_set(storage->settings, SETTING_HEP_SEND_PORT,
setting_number_new("eep.send.port", "9060"));
g_ptr_array_set(storage->settings, SETTING_HEP_SEND_PASS,
setting_string_new("eep.send.pass", ""));
g_ptr_array_set(storage->settings, SETTING_HEP_SEND_ID,
setting_number_new("eep.send.id", "2000"));
g_ptr_array_set(storage->settings, SETTING_HEP_LISTEN,
setting_bool_new("eep.listen", SETTING_OFF));
g_ptr_array_set(storage->settings, SETTING_HEP_LISTEN_VER,
setting_string_new("eep.listen.version", "3"));
g_ptr_array_set(storage->settings, SETTING_HEP_LISTEN_ADDR,
setting_string_new("eep.listen.address", "0.0.0.0"));
g_ptr_array_set(storage->settings, SETTING_HEP_LISTEN_PORT,
setting_number_new("eep.listen.port", "9060"));
g_ptr_array_set(storage->settings, SETTING_HEP_LISTEN_PASS,
setting_string_new("eep.listen.pass", ""));
g_ptr_array_set(storage->settings, SETTING_HEP_LISTEN_UUID,
setting_bool_new("eep.listen.uuid", SETTING_OFF));
#endif
// Done if config file should not be read
if(no_config) {
return 0;
}
// Read options from configuration files
setting_read_file("/etc/sngreprc");
setting_read_file("/usr/local/etc/sngreprc");
// Get user configuration
if ((rcfile = getenv("SNGREPRC"))) {
setting_read_file(rcfile);
} else if ((rcfile = getenv("HOME"))) {
userconf = g_string_new(rcfile);
g_string_append(userconf, "/.sngreprc");
setting_read_file(userconf->str);
g_string_free(userconf, TRUE);
}
return 0;
}
void
settings_deinit()
{
g_ptr_array_free(storage->settings, TRUE);
g_list_free(storage->alias);
g_free(storage);
}
void
settings_dump()
{
int i;
for (i = 1; i < SETTING_COUNT; i++) {
printf("SettingId: %d\t SettingName: %-20s Value: %s\n", i,
for (guint i = 1; i < SETTING_COUNT; i++) {
printf("SettingId: %d\t SettingName: %-30s Value: %s\n", i,
setting_name(i),
setting_get_value(i));
}

View File

@ -42,36 +42,24 @@
#ifndef __SNGREP_SETTING_H
#define __SNGREP_SETTING_H
//! Max setting value
#define MAX_SETTING_LEN 1024
#include <glib.h>
#include "attribute.h"
//! Max extra length needed for "/.sngreprc.old"
#define RCFILE_EXTRA_LEN 16
//! Max setting value
#define SETTING_MAX_LEN 1024
//! Shorter declarartion of setting_option struct
typedef struct setting_option setting_t;
//! Generic setting formats
#define SETTING_ENUM_ONOFF (const char *[]){ "on", "off", NULL }
#define SETTING_ENUM_YESNO (const char *[]){ "yes", "no", NULL }
#define SETTING_ENUM_BACKGROUND (const char *[]){ "dark" , "default", NULL }
#define SETTING_ENUM_COLORMODE (const char *[]){ "request", "cseq", "callid", NULL }
#define SETTING_ENUM_HIGHLIGHT (const char *[]){ "bold", "reverse", "reversebold", NULL }
#define SETTING_ENUM_SDP_INFO (const char *[]){ "off", "first", "full", "compressed", NULL}
#define SETTING_ENUM_STORAGE (const char *[]){ "none", "memory", NULL }
#define SETTING_ENUM_HEPVERSION (const char *[]){ "2", "3", NULL }
#define SETTING_ENUM_MEDIA (const char *[]){ "off", "on", "active", NULL }
typedef struct _Setting Setting;
typedef struct _SettingStorage SettingStorage;
typedef struct _SettingAlias SettingAlias;
//! Other useful defines
#define SETTING_ON "on"
#define SETTING_OFF "off"
#define SETTING_YES "yes"
#define SETTING_NO "no"
#define SETTING_ACTIVE "active"
//! Available setting Options
enum setting_id {
enum SettingId {
SETTING_UNKNOWN = -1,
SETTING_BACKGROUND = 0,
SETTING_COLORMODE,
SETTING_SYNTAX,
@ -99,6 +87,44 @@ enum setting_id {
SETTING_CL_AUTOSCROLL,
SETTING_CL_SORTFIELD,
SETTING_CL_SORTORDER,
SETTING_CL_COL_INDEX_POS,
SETTING_CL_COL_INDEX_WIDTH,
SETTING_CL_COL_SIPFROM_POS,
SETTING_CL_COL_SIPFROM_WIDTH,
SETTING_CL_COL_SIPFROMUSER_POS,
SETTING_CL_COL_SIPFROMUSER_WIDTH,
SETTING_CL_COL_SIPTO_POS,
SETTING_CL_COL_SIPTO_WIDTH,
SETTING_CL_COL_SIPTOUSER_POS,
SETTING_CL_COL_SIPTOUSER_WIDTH,
SETTING_CL_COL_SRC_POS,
SETTING_CL_COL_SRC_WIDTH,
SETTING_CL_COL_DST_POS,
SETTING_CL_COL_DST_WIDTH,
SETTING_CL_COL_CALLID_POS,
SETTING_CL_COL_CALLID_WIDTH,
SETTING_CL_COL_XCALLID_POS,
SETTING_CL_COL_XCALLID_WIDTH,
SETTING_CL_COL_DATE_POS,
SETTING_CL_COL_DATE_WIDTH,
SETTING_CL_COL_TIME_POS,
SETTING_CL_COL_TIME_WIDTH,
SETTING_CL_COL_METHOD_POS,
SETTING_CL_COL_METHOD_WIDTH,
SETTING_CL_COL_TRANSPORT_POS,
SETTING_CL_COL_TRANSPORT_WIDTH,
SETTING_CL_COL_MSGCNT_POS,
SETTING_CL_COL_MSGCNT_WIDTH,
SETTING_CL_COL_CALLSTATE_POS,
SETTING_CL_COL_CALLSTATE_WIDTH,
SETTING_CL_COL_CONVDUR_POS,
SETTING_CL_COL_CONVDUR_WIDTH,
SETTING_CL_COL_TOTALDUR_POS,
SETTING_CL_COL_TOTALDUR_WIDTH,
SETTING_CL_COL_REASON_TXT_POS,
SETTING_CL_COL_REASON_TXT_WIDTH,
SETTING_CL_COL_WARNING_POS,
SETTING_CL_COL_WARNING_WIDTH,
SETTING_CF_FORCERAW,
SETTING_CF_RAWMINWIDTH,
SETTING_CF_RAWFIXEDWIDTH,
@ -132,8 +158,9 @@ enum setting_id {
};
//! Available setting formats
enum setting_fmt {
enum SettingFormat {
SETTING_FMT_STRING = 0,
SETTING_FMT_BOOLEAN,
SETTING_FMT_NUMBER,
SETTING_FMT_ENUM,
};
@ -141,23 +168,39 @@ enum setting_fmt {
/**
* @brief Configurable Setting structure
*/
struct setting_option {
//! Setting id
enum setting_id id;
struct _Setting {
//! Setting name
const char *name;
const gchar *name;
//! Setting format
enum setting_fmt fmt;
enum SettingFormat fmt;
//! Value of the setting
char value[MAX_SETTING_LEN];
//! Compa separated valid values
const char **valuelist;
char value[SETTING_MAX_LEN];
//! Comma separated valid values
gchar **valuelist;
};
setting_t *
setting_by_id(int id);
/**
* @brief Alias setting structure
*/
struct _SettingAlias {
//! Original address value
const gchar *address;
//! Alias name
const gchar *alias;
setting_t *
};
struct _SettingStorage {
//! Array of settings
GPtrArray *settings;
//! List of configured IP address aliases
GList *alias;
};
Setting *
setting_by_id(enum SettingId id);
Setting *
setting_by_name(const char *name);
/**
@ -166,7 +209,7 @@ setting_by_name(const char *name);
* @param name String representing configurable setting
* @return setting id or -1 if setting is not found
*/
int
enum SettingId
setting_id(const char *name);
/**
@ -176,40 +219,95 @@ setting_id(const char *name);
* @return string representation of setting or NULL
*/
const char *
setting_name(int id);
setting_name(enum SettingId id);
int
setting_format(int id);
setting_format(enum SettingId id);
const char **
setting_valid_values(int id);
setting_valid_values(enum SettingId id);
const char*
setting_get_value(int id);
setting_get_value(enum SettingId id);
int
setting_get_intvalue(int id);
setting_get_intvalue(enum SettingId id);
void
setting_set_value(int id, const char *value);
setting_set_value(enum SettingId id, const char *value);
void
setting_set_intvalue(int id, int value);
setting_set_intvalue(enum SettingId id, int value);
int
setting_enabled(int id);
setting_enabled(enum SettingId id);
int
setting_disabled(int id);
setting_disabled(enum SettingId id);
int
setting_has_value(int id, const char *value);
setting_has_value(enum SettingId id, const char *value);
void
setting_toggle(int id);
setting_toggle(enum SettingId id);
const char *
setting_enum_next(int id, const char *value);
setting_enum_next(enum SettingId id, const char *value);
gint
setting_column_pos(enum AttributeId id);
/**
* @brief Get Attribute column display width
*
* @param id Attribute id
* @return configured column width
*/
gint
setting_column_width(enum AttributeId id);
/**
* @brief Get alias for a given address (string)
*
* @param address IP Address
* @return configured alias or address if not alias found
*/
const gchar *
setting_get_alias(const gchar *address);
/**
* @brief Read optionuration directives from file
*
* This funtion will parse passed filenames searching for configuration
* directives of sngrep. See documentation for a list of available
* directives and attributes
*
* @param fname Full path configuration file name
* @return 0 in case of parse success, -1 otherwise
*/
int
setting_read_file(const gchar *fname);
/**
* @brief Initialize all program options
*
* This function will give all available settings an initial value.
* This values can be overriden using resources files, either from system dir
* or user home dir.
*
* @param no_config Do not load config file if set to 1
* @return 0 in all cases
*/
int
settings_init(int no_config);
/**
* @brief Deallocate options memory
*
* Deallocate memory used for program configurations
*/
void
settings_deinit();
/**
* @brief Dump configuration settings