rendered paste body/**
* dvbcfg_sec (i.e. linuxtv sec format) configuration file support.
*
* Copyright (c) 2005 by Andrew de Quincey <adq_dvb@lidskialf.net>
*
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "dvbcfg_sec.h"
#include "dvbcfg_utils.h"
int dvbcfg_sec_load(FILE *f,
void *private,
dvbcfg_sec_callback cb)
{
struct dvbfe_sec_config tmpsec;
char *linebuf = NULL;
size_t line_size = 0;
int len;
int insection = 0;
char *value;
/* process each line */
while((len = getline(&linebuf, &line_size, f)) > 0) {
char *line = linebuf;
/* chop any comments */
char *hashpos = strchr(line, '#');
if (hashpos)
*hashpos = 0;
char *lineend = line + strlen(line);
/* trim the line */
while(*line && isspace(*line))
line++;
while((lineend != line) && isspace(*(lineend-1)))
lineend--;
*lineend = 0;
/* skip blank lines */
if (*line == 0)
continue;
if (dvbcfg_issection(line, "sec")) {
if (insection) {
if (cb(private, &tmpsec))
return 0;
}
insection = 1;
memset(&tmpsec, 0, sizeof(tmpsec));
} else if ((value = dvbcfg_iskey(line, "name")) != NULL) {
strncpy(tmpsec.id, value, sizeof(tmpsec.id));
} else if ((value = dvbcfg_iskey(line, "switch-frequency")) != NULL) {
tmpsec.switch_frequency = atoi(value);
} else if ((value = dvbcfg_iskey(line, "lof-lo")) != NULL) {
tmpsec.lof_lo = atoi(value);
} else if ((value = dvbcfg_iskey(line, "lof-hi")) != NULL) {
tmpsec.lof_hi = atoi(value);
} else if ((value = dvbcfg_iskey(line, "config-type")) != NULL) {
if (!strcasecmp(value, "none")) {
tmpsec.config_type = DVBFE_SEC_CONFIG_NONE;
} else if (!strcasecmp(value, "simple")) {
tmpsec.config_type = DVBFE_SEC_CONFIG_SIMPLE;
} else if (!strcasecmp(value, "advanced")) {
tmpsec.config_type = DVBFE_SEC_CONFIG_ADVANCED;
} else {
insection = 0;
}
} else if ((value = dvbcfg_iskey(line, "cmd-lo-v")) != NULL) {
strncpy(tmpsec.adv_cmd_lo_v, value, sizeof(tmpsec.adv_cmd_lo_v));
} else if ((value = dvbcfg_iskey(line, "cmd-lo-h")) != NULL) {
strncpy(tmpsec.adv_cmd_lo_h, value, sizeof(tmpsec.adv_cmd_lo_h));
} else if ((value = dvbcfg_iskey(line, "cmd-lo-r")) != NULL) {
strncpy(tmpsec.adv_cmd_lo_r, value, sizeof(tmpsec.adv_cmd_lo_r));
} else if ((value = dvbcfg_iskey(line, "cmd-lo-l")) != NULL) {
strncpy(tmpsec.adv_cmd_lo_l, value, sizeof(tmpsec.adv_cmd_lo_l));
} else if ((value = dvbcfg_iskey(line, "cmd-hi-v")) != NULL) {
strncpy(tmpsec.adv_cmd_hi_v, value, sizeof(tmpsec.adv_cmd_hi_v));
} else if ((value = dvbcfg_iskey(line, "cmd-hi-h")) != NULL) {
strncpy(tmpsec.adv_cmd_hi_h, value, sizeof(tmpsec.adv_cmd_hi_h));
} else if ((value = dvbcfg_iskey(line, "cmd-hi-r")) != NULL) {
strncpy(tmpsec.adv_cmd_hi_r, value, sizeof(tmpsec.adv_cmd_hi_r));
} else if ((value = dvbcfg_iskey(line, "cmd-hi-l")) != NULL) {
strncpy(tmpsec.adv_cmd_hi_l, value, sizeof(tmpsec.adv_cmd_hi_l));
} else {
insection = 0;
}
}
// output the final section if there is one
if (insection) {
if (cb(private, &tmpsec))
return 0;
}
if (linebuf)
free(linebuf);
return 0;
}
static int dvbcfg_sec_find_callback(void *private, struct dvbfe_sec_config *sec);
static int dvbcfg_sec_find_default(const char *sec_id, struct dvbfe_sec_config *sec);
struct findparams {
const char *sec_id;
struct dvbfe_sec_config *sec_dest;
};
int dvbcfg_sec_find(const char *config_file,
const char *sec_id,
struct dvbfe_sec_config *sec)
{
struct findparams findp;
// open the file
if (config_file != NULL) {
FILE *f = fopen(config_file, "r");
if (f == NULL)
return -EIO;
// parse each entry
memset(sec, 0, sizeof(struct dvbfe_sec_config));
findp.sec_id = sec_id;
findp.sec_dest = sec;
dvbcfg_sec_load(f, &findp, dvbcfg_sec_find_callback);
// done
fclose(f);
}
if (sec->id[0])
return 0;
return dvbcfg_sec_find_default(sec_id, sec);
}
static int dvbcfg_sec_find_callback(void *private, struct dvbfe_sec_config *sec)
{
struct findparams *findp = private;
if (strcmp(findp->sec_id, sec->id))
return 0;
memcpy(findp->sec_dest, sec, sizeof(struct dvbfe_sec_config));
return 1;
}
int dvbcfg_sec_save(FILE *f,
struct dvbfe_sec_config *secs,
int count)
{
int i;
for(i=0; i<count; i++) {
char *config_type = "";
switch(secs[i].config_type) {
case DVBFE_SEC_CONFIG_NONE:
config_type = "none";
break;
case DVBFE_SEC_CONFIG_SIMPLE:
config_type = "simple";
break;
case DVBFE_SEC_CONFIG_ADVANCED:
config_type = "advanced";
break;
}
fprintf(f, "[lnb]\n");
fprintf(f, "switch-frequency=%i\n", secs[i].switch_frequency);
fprintf(f, "lof-lo=%i\n", secs[i].lof_lo);
fprintf(f, "log-hi=%i\n", secs[i].lof_hi);
fprintf(f, "config-type=%s\n", config_type);
if (secs[i].config_type == DVBFE_SEC_CONFIG_ADVANCED) {
if (secs[i].adv_cmd_lo_h[0])
fprintf(f, "cmd-lo-h=%s\n", secs[i].adv_cmd_lo_h);
if (secs[i].adv_cmd_lo_v[0])
fprintf(f, "cmd-lo-v=%s\n", secs[i].adv_cmd_lo_v);
if (secs[i].adv_cmd_lo_r[0])
fprintf(f, "cmd-lo-r=%s\n", secs[i].adv_cmd_lo_r);
if (secs[i].adv_cmd_lo_l[0])
fprintf(f, "cmd-lo-l=%s\n", secs[i].adv_cmd_lo_l);
if (secs[i].adv_cmd_hi_h[0])
fprintf(f, "cmd-hi-h=%s\n", secs[i].adv_cmd_hi_h);
if (secs[i].adv_cmd_hi_v[0])
fprintf(f, "cmd-hi-v=%s\n", secs[i].adv_cmd_hi_v);
if (secs[i].adv_cmd_hi_r[0])
fprintf(f, "cmd-hi-r=%s\n", secs[i].adv_cmd_hi_r);
if (secs[i].adv_cmd_hi_l[0])
fprintf(f, "cmd-hi-l=%s\n", secs[i].adv_cmd_hi_l);
}
fprintf(f, "\n");
}
return 0;
}
static struct dvbfe_sec_config defaults[] = {
{
.id = "UNIVERSAL",
.switch_frequency = 11700000,
.lof_lo = 9750000,
.lof_hi = 10600000,
.config_type = DVBFE_SEC_CONFIG_SIMPLE,
},
{
.id = "DBS",
.switch_frequency = 0,
.lof_lo = 11250000,
.lof_hi = 0,
.config_type = DVBFE_SEC_CONFIG_SIMPLE,
},
{
.id = "STANDARD",
.switch_frequency = 0,
.lof_lo = 10000000,
.lof_hi = 0,
.config_type = DVBFE_SEC_CONFIG_SIMPLE,
},
{
.id = "ENHANCED",
.switch_frequency = 0,
.lof_lo = 9750000,
.lof_hi = 0,
.config_type = DVBFE_SEC_CONFIG_SIMPLE,
},
{
.id = "C-BAND",
.switch_frequency = 0,
.lof_lo = 5150000,
.lof_hi = 0,
.config_type = DVBFE_SEC_CONFIG_SIMPLE,
},
};
#define defaults_count (sizeof(defaults) / sizeof(struct dvbfe_sec_config))
static int dvbcfg_sec_find_default(const char *sec_id,
struct dvbfe_sec_config *sec)
{
unsigned int i;
for(i=0; i< defaults_count; i++) {
if (!strncmp(sec_id, defaults[i].id, sizeof(defaults[i].id))) {
memcpy(sec, &defaults[i], sizeof(struct dvbfe_sec_config));
return 0;
}
}
return -1;
}