isdn4k-utils/ant-phone/src/settings.c

602 lines
18 KiB
C

/*
* functions for dotfile handling (options, history, ...)
*
* This file is part of ANT (Ant is Not a Telephone)
*
* Copyright 2002, 2003 Roland Stigge
*
* ANT 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 2 of the License, or
* (at your option) any later version.
*
* ANT 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 ANT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*
* To add a new option, do the following:
* -> set default in session_init()
* -> add entry in settings_option_set()
* -> add entry in settings_options_write()
* -> of course, set it in gtksettings (also set_data()!) / whatever
* -> get it back in gtksettings_try()
*/
/* regular GNU system includes */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <limits.h>
/* own header files */
#include "globals.h"
#include "session.h"
#include "settings.h"
#include "calleridparser.h"
#include "util.h"
#include "callerid.h"
#include "isdn.h"
#include "isdnlexer.h"
#include "isdnparser.h"
#include "isdntree.h"
extern FILE *callerid_in;
int callerid_parse(void *session);
extern FILE *isdn_in;
int isdn_parse();
/*
* sets an option for the specified session
*
* used as callback from yyparse()
*/
void settings_option_set(session_t *session, char *option, char *value) {
int i_value = INT_MIN; /* set value to 0 or 1 if appropriate */
if (!strcmp(value, "0") || !strcasecmp(value, "false") ||
!strcasecmp(value, "off")) {
i_value = 0;
} else
if (!strcmp(value, "1") || !strcasecmp(value, "true") ||
!strcasecmp(value, "on")) {
i_value = 1;
} else
i_value = strtol(value, NULL, 0);
/* Settings */
if (i_value != INT_MIN) {
if (!strcmp(option, "HistorySize")) {
session->dial_number_history_maxlen = i_value;
}
if (!strcmp(option, "CallerIDSize")) {
session->cid_num_max = i_value;
}
if (!strcmp(option, "SaveOptions")) {
session->option_save_options = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "ExecOnIncoming")) {
free(session->exec_on_incoming);
session->exec_on_incoming = strdup(value);
}
if (!strcmp(option, "PopupOnIncoming")) {
session->option_popup = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "RecordingFormat")) {
if (!strcasecmp(value, "aiff")) {
session->option_recording_format =
(session->option_recording_format & ~RECORDING_FORMAT_MAJOR)
| RECORDING_FORMAT_AIFF;
} else { /* wav */
session->option_recording_format =
(session->option_recording_format & ~RECORDING_FORMAT_MAJOR)
| RECORDING_FORMAT_WAV;
}
}
if (!strcmp(option, "RecordingEncoding")) {
if (!strcasecmp(value, "s16")) {
session->option_recording_format =
(session->option_recording_format & ~RECORDING_FORMAT_MINOR)
| RECORDING_FORMAT_S16;
} else { /* ulaw */
session->option_recording_format =
(session->option_recording_format & ~RECORDING_FORMAT_MINOR)
| RECORDING_FORMAT_ULAW;
}
}
if (!strncmp(option, "PresetName", 10)) {
int num = strtol(&option[10], NULL, 0);
if (0 <= num && num < SESSION_PRESET_SIZE) {
free(session->preset_names[num]);
session->preset_names[num] = strdup(value);
}
}
if (!strncmp(option, "PresetNumber", 12)) {
int num = strtol(&option[12], NULL, 0);
if (0 <= num && num < SESSION_PRESET_SIZE) {
free(session->preset_numbers[num]);
session->preset_numbers[num] = strdup(value);
}
}
if (!strcmp(option, "MergeIsdnlog")) {
session->option_calls_merge = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "MergeIsdnlogDays")) {
session->option_calls_merge_max_days = i_value;
}
if (!strcmp(option, "AudioDeviceIn") &&
!strcmp(session->audio_device_name_in, "")) { /* may be overridden */
free(session->audio_device_name_in);
session->audio_device_name_in = strdup(value);
}
if (!strcmp(option, "AudioDeviceOut") &&
!strcmp(session->audio_device_name_out, "")) { /* may be overridden */
free(session->audio_device_name_out);
session->audio_device_name_out = strdup(value);
}
if (!strcmp(option, "ReleaseAudioDevices")) {
session->option_release_devices = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "IdentifyingMSN") &&
!strcmp(session->msn, "")) { /* may be overridden */
free(session->msn);
session->msn = strdup(value);
}
if (!strcmp(option, "ListenOnMSNs") &&
!strcmp(session->msns, "")) { /* may be overridden */
free(session->msns);
session->msns = strdup(value);
}
/* GUI state */
if (!strcmp(option, "ShowCallerID")) {
session->option_show_callerid = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "ShowLLCheckers")) {
session->option_show_llcheck = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "ShowControlPad")) {
session->option_show_controlpad = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "Muted")) {
session->option_muted = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "RecordToFile")) {
session->option_record = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "RecordLocalChannel")) {
session->option_record_local = (i_value == 0 ? 0 : 1);
}
if (!strcmp(option, "RecordRemoteChannel")) {
session->option_record_remote = (i_value == 0 ? 0 : 1);
}
}
}
/*
* Read options from options file and isdn4linux config
*
* Here, we parse the config file and _change_ options. The defaults
* will be all set at init time
*/
void settings_options_read(session_t *session) {
char *homedir;
char *filename;
/* read isdn4linux config */
isdn_lexer_init(ISDN_CONFIG_FILENAME);
if (!isdn_in) {
fprintf(stderr, "Warning: Couldn't read ISDN config file.\n");
} else {
isdn_tree_node_t* node;
isdn_parse();
isdn_lexer_deinit();
if (debug > 1) {
printf("ISDN config file (%s) contents:\n", ISDN_CONFIG_FILENAME);
isdn_tree_dump();
}
/* get calls file name if possible */
node = isdn_tree;
while (node != NULL) {
if (node->type == ISDN_NODE_TYPE_SECTION &&
!strcmp(node->name, "ISDNLOG"))
{
isdn_tree_node_t* entry = node->content.section;
while (entry != NULL ) {
if (entry->type == ISDN_NODE_TYPE_ENTRY &&
!strcmp(entry->name, "LOGFILE"))
{
if (isdn_calls_filename_from_config)
free(isdn_calls_filename_from_config);
isdn_calls_filename_from_config = strdup(entry->content.value);
}
entry = entry->next;
}
}
node = node->next;
}
isdn_tree_free();
}
if (!(homedir = get_homedir())) {
fprintf(stderr, "Warning: Couldn't get home dir.\n");
return;
}
/* dotfile */
if (asprintf(&filename, "%s/." PACKAGE "/%s",
homedir, SETTINGS_OPTIONS_FILENAME) < 0)
{
fprintf(stderr,
"Warning: Couldn't allocate memory for options filename.\n");
return;
}
isdn_lexer_init(filename);
if (!isdn_in) {
fprintf(stderr, "Warning: No options file available.\n");
} else {
isdn_tree_node_t* node;
isdn_parse();
isdn_lexer_deinit();
node = isdn_tree;
if (debug > 1) {
printf("Options file (%s) contents:\n", filename);
isdn_tree_dump();
}
/* actually set options */
while (node != NULL) {
switch (node->type) {
case ISDN_NODE_TYPE_ENTRY:
if (debug)
printf("Setting \"%s\" to \"%s\"...\n",
node->name, node->content.value);
settings_option_set(session, node->name, node->content.value);
break;
case ISDN_NODE_TYPE_SECTION:
fprintf(stderr, "Warning: Unexpected section \"%s\".\n", node->name);
break;
case ISDN_NODE_TYPE_SUBSECTION:
fprintf(stderr,
"Warning: Unexpected subsection \"%s\".\n", node->name);
break;
default:
fprintf(stderr, "Unknown ISDN_NODE_TYPE\n");
}
node = node->next;
}
isdn_tree_free();
}
free(filename);
}
/*
* write options to options file (in dotfile directory)
*/
void settings_options_write(session_t *session) {
int i;
char *homedir;
char *filename;
FILE *f;
if (!(homedir = get_homedir())) {
fprintf(stderr, "Warning: Couldn't get home dir.\n");
return;
}
if (touch_dotdir())
return;
if (asprintf(&filename, "%s/." PACKAGE "/%s",
homedir, SETTINGS_OPTIONS_FILENAME) < 0) {
fprintf(stderr,
"Warning: Couldn't allocate memory for options filename.\n");
return;
}
if ((f = fopen(filename, "w"))) {
fprintf(f, "# " PACKAGE " options file \n\n");
fprintf(f, "#\n# Number of dialed numbers to remember\n#\n");
fprintf(f, "HistorySize = %u\n\n", session->dial_number_history_maxlen);
fprintf(f, "#\n# Maximum number of rows Caller ID window\n#\n");
fprintf(f, "CallerIDSize = %u\n\n", session->cid_num_max);
fprintf(f, "#\n# Automatically save options on exit?\n#\n");
fprintf(f, "SaveOptions = %d\n\n", session->option_save_options);
fprintf(f, "#\n# Execute an arbitrary command on incoming call\n#\n");
fprintf(f, "ExecOnIncoming = \"%s\"\n\n", session->exec_on_incoming);
fprintf(f, "#\n# When activated, the main window will be pushed to "
"foreground\n# on incoming call\n#\n");
fprintf(f, "PopupOnIncoming = \"%d\"\n\n", session->option_popup);
fprintf(f, "#\n# Audio recording device\n#\n");
fprintf(f, "AudioDeviceIn = %s\n\n", session->audio_device_name_in);
fprintf(f, "#\n# Audio playback device, "
"may be the same as AudioDeviceIn\n#\n");
fprintf(f, "AudioDeviceOut = %s\n\n", session->audio_device_name_out);
fprintf(f, "#\n# Release audio devices in idle (\"Ready\") mode "
"(when not needed)\n#\n");
fprintf(f, "ReleaseAudioDevices = %d\n\n",session->option_release_devices);
fprintf(f, "#\n# MSN (Multiple Subscriber Number) to send to identify\n"
"# ourselves at called party\n#\n");
fprintf(f, "IdentifyingMSN = %s\n\n", session->msn);
fprintf(f, "#\n# These are the MSNs we want to listen on "
"(and accept calls)\n#\n");
fprintf(f, "ListenOnMSNs = %s\n\n", session->msns);
fprintf(f, "#\n# Show Caller ID frame in main window?\n#\n");
fprintf(f, "ShowCallerID = %d\n\n", session->option_show_callerid);
fprintf(f, "#\n# Show Line Level Checkers in main window?\n#\n");
fprintf(f, "ShowLLCheckers = %d\n\n", session->option_show_llcheck);
fprintf(f, "#\n# Show control pad (key pad etc.) in main window?\n#\n");
fprintf(f, "ShowControlPad = %d\n\n", session->option_show_controlpad);
fprintf(f, "#\n# Turn on to make the other party receive silence\n#\n");
fprintf(f, "Muted = %d\n\n", session->option_muted);
fprintf(f, "#\n# Record Audio stream to file?\n#\n");
fprintf(f, "RecordToFile = %d\n\n", session->option_record);
fprintf(f, "#\n# When RecordToFile is set, record local channel?\n#\n");
fprintf(f, "RecordLocalChannel = %d\n\n", session->option_record_local);
fprintf(f, "#\n# When RecordToFile is set, record remote channel?\n#\n");
fprintf(f, "RecordRemoteChannel = %d\n\n", session->option_record_remote);
fprintf(f, "#\n# Recording file format\n"
"# (\"wav\" for Microsoft WAV / "
"\"aiff\" for Apple/SGI AIFF)\n#\n");
fprintf(f, "RecordingFormat = \"%s\"\n\n",
(session->option_recording_format & RECORDING_FORMAT_MAJOR) ==
RECORDING_FORMAT_WAV ? "wav" : "aiff");
fprintf(f, "#\n# Recording file encoding\n"
"# (\"ulaw\" for uLaw / \"s16\" for 16-bit signed)\n#\n");
fprintf(f, "RecordingEncoding = \"%s\"\n\n",
(session->option_recording_format & RECORDING_FORMAT_MINOR) ==
RECORDING_FORMAT_S16 ? "s16" : "ulaw");
fprintf(f, "#\n# Preset Names and Numbers\n#\n");
for (i = 0; i < SESSION_PRESET_SIZE; i++) {
fprintf(f, "PresetName%d = \"%s\"\n", i, session->preset_names[i]);
fprintf(f, "PresetNumber%d = \"%s\"\n", i, session->preset_numbers[i]);
}
fprintf(f, "\n");
fprintf(f,
"#\n# Merge isdnlog callerid history to local history at startup?\n#\n");
fprintf(f, "MergeIsdnlog = %d\n\n", session->option_calls_merge);
fprintf(f, "#\n# Get data from this number of last days when retrieving "
"data from\n"
"# isdnlog at startup\n"
"# (set to 0 if you prefer an unlimited number of days)\n#\n");
fprintf(f, "MergeIsdnlogDays = %d\n\n",
session->option_calls_merge_max_days);
if (fclose(f) == EOF) {
fprintf(stderr, "Warning: Couldn't close options file.\n");
}
} else if (debug) {
fprintf(stderr, "Warning: Can't write to options file.\n");
}
free(filename);
}
/* Read history file and set dial combo box */
void settings_history_read(session_t *session) {
char *homedir;
char *filename;
FILE *f;
char *lineptr = NULL;
size_t linesize = 0;
ssize_t got;
if (!(homedir = get_homedir())) {
fprintf(stderr, "Warning: Couldn't get home dir.\n");
return;
}
if (asprintf(&filename, "%s/." PACKAGE "/%s",
homedir, SETTINGS_HISTORY_FILENAME) < 0) {
fprintf(stderr,
"Warning: Couldn't allocate memory for history filename.\n");
return;
}
if (debug)
fprintf(stdout, "Info: History Filename: %s.\n", filename);
if ((f = fopen(filename, "r"))) {
do {
got = getline(&lineptr, &linesize, f);
if (lineptr[got - 1] == '\n') {
lineptr[got - 1] = '\0';
}
if (got > 0 && strlen(lineptr) > 0) {
session_history_append(session, lineptr);
if (debug)
fprintf(stdout, "Info: History Number: %s.\n", lineptr);
}
} while (got > 0);
if (fclose(f) == EOF) {
fprintf(stderr, "Warning: Couldn't close history file.\n");
}
} else if (debug) {
fprintf(stderr, "Warning: No history file available.\n");
}
free(filename);
if (lineptr) free(lineptr);
}
/*
* helper function writing the specified line s to stream f
* used as callback by settings_history_write
*/
static void settings_history_write_line(gpointer s, gpointer f) {
if (strcmp(s, "")) {
fprintf(f, "%s\n", (char*)s);
}
}
/*
* write out dial history file
*/
void settings_history_write(session_t *session) {
char *homedir;
char *filename;
FILE *f;
if (!(homedir = get_homedir())) {
fprintf(stderr, "Warning: Couldn't get home dir.\n");
return;
}
if (touch_dotdir())
return;
if (asprintf(&filename, "%s/." PACKAGE "/%s",
homedir, SETTINGS_HISTORY_FILENAME) < 0) {
fprintf(stderr,
"Warning: Couldn't allocate memory for history filename.\n");
return;
}
if ((f = fopen(filename, "w"))) {
g_list_foreach(session->dial_number_history,
settings_history_write_line, f);
if (fclose(f) == EOF) {
fprintf(stderr, "Warning: Couldn't close history file.\n");
}
} else if (debug) {
fprintf(stderr, "Warning: Can't write to history file.\n");
}
free(filename);
}
/* Read callerid history file */
void settings_callerid_read(session_t *session) {
char *homedir;
char *filename;
if (!(homedir = get_homedir())) {
fprintf(stderr, "Warning: Couldn't get home dir.\n");
return;
}
if (asprintf(&filename, "%s/." PACKAGE "/%s",
homedir, SETTINGS_CALLERID_HISTORY_FILENAME) < 0) {
fprintf(stderr, "Warning: "
"Couldn't allocate memory for caller id history filename.\n");
return;
}
if ((callerid_in = fopen(filename, "r"))) {
callerid_parse(session);
if (fclose(callerid_in) == EOF) {
fprintf(stderr, "Warning: Couldn't close callerid history file.\n");
}
} else if (debug) {
fprintf(stderr, "Warning: No caller id history file available.\n");
}
free(filename);
}
/*
* write out callerid history file
*/
void settings_callerid_write(session_t *session) {
char *homedir;
char *filename;
FILE *f;
int akt_line;
gchar *date;
gchar *type;
gchar *from;
gchar *to;
gchar *duration;
if (!(homedir = get_homedir())) {
fprintf(stderr, "Warning: Couldn't get home dir.\n");
return;
}
if (touch_dotdir())
return;
if (asprintf(&filename, "%s/." PACKAGE "/%s",
homedir, SETTINGS_CALLERID_HISTORY_FILENAME) < 0) {
fprintf(stderr, "Warning: "
"Couldn't allocate memory for callerid history filename.\n");
return;
}
if ((f = fopen(filename, "w"))) {
for (akt_line = 0; akt_line < session->cid_num; akt_line++)
{
gtk_clist_get_text(GTK_CLIST(session->cid_list), akt_line,
CID_COL_TIME, &date);
gtk_clist_get_pixtext(GTK_CLIST(session->cid_list), akt_line,
CID_COL_TYPE, &type, NULL, NULL, NULL);
gtk_clist_get_text(GTK_CLIST(session->cid_list), akt_line,
CID_COL_FROM, &from);
gtk_clist_get_text(GTK_CLIST(session->cid_list), akt_line,
CID_COL_TO, &to);
gtk_clist_get_text(GTK_CLIST(session->cid_list), akt_line,
CID_COL_DURATION, &duration);
fprintf (f, "%-19s|%-3s|%-20s|%-20s|%-10s\n",
date, type, from, to, duration);
if (debug > 1)
fprintf(stderr, "%-19s|%-3s|%-20s|%-20s|%-10s\n",
date, type, from, to, duration);
}
if (fclose(f) == EOF) {
fprintf(stderr, "Warning: Couldn't close callerid history file.\n");
}
} else if (debug) {
fprintf(stderr, "Warning: Can't write to callerid history file.\n");
}
free(filename);
}