1116 lines
29 KiB
C
Executable File
1116 lines
29 KiB
C
Executable File
#define MODULE_LOG_PREFIX "config"
|
|
|
|
#include "globals.h"
|
|
#include "oscam-conf-mk.h"
|
|
#include "oscam-net.h"
|
|
#include "oscam-string.h"
|
|
|
|
const char *shortDay[8] = {"SUN","MON","TUE","WED","THU","FRI","SAT","ALL"};
|
|
const char *weekdstr = "SUNMONTUEWEDTHUFRISATALL";
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for CAIDs. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_caidtab(CAIDTAB *caidtab)
|
|
{
|
|
if (!caidtab || !caidtab->ctnum) return "";
|
|
|
|
// Max entry length is cs_strlen("1234&ffff:1234,") == 15
|
|
int32_t i, maxlen = 16 * caidtab->ctnum, pos = 0;
|
|
|
|
char *ret;
|
|
if (!cs_malloc(&ret, maxlen))
|
|
return "";
|
|
|
|
const char *comma = "";
|
|
|
|
for(i = 0; i < caidtab->ctnum; i++)
|
|
{
|
|
CAIDTAB_DATA *d = &caidtab->ctdata[i];
|
|
if (d->caid < 0x0100)
|
|
pos += snprintf(ret + pos, maxlen - pos, "%s%02X", comma, d->caid);
|
|
else
|
|
pos += snprintf(ret + pos, maxlen - pos, "%s%04X", comma, d->caid);
|
|
if (d->mask && d->mask != 0xffff)
|
|
pos += snprintf(ret + pos, maxlen - pos, "&%04X", d->mask);
|
|
if (d->cmap)
|
|
pos += snprintf(ret + pos, maxlen - pos, ":%04X", d->cmap);
|
|
comma = ",";
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for TunTabs. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_tuntab(TUNTAB *ttab)
|
|
{
|
|
if (!ttab || !ttab->ttnum) return "";
|
|
|
|
// Each entry max length is cs_strlen("aaaa.bbbb:cccc,") == 15
|
|
int32_t i, maxlen = 16 * ttab->ttnum, pos = 0;
|
|
|
|
char *ret;
|
|
if (!cs_malloc(&ret, maxlen))
|
|
return "";
|
|
|
|
const char *comma = "";
|
|
|
|
for(i = 0; i < ttab->ttnum; i++)
|
|
{
|
|
TUNTAB_DATA *d = &ttab->ttdata[i];
|
|
pos += snprintf(ret + pos, maxlen - pos, "%s%04X", comma, d->bt_caidfrom);
|
|
pos += snprintf(ret + pos, maxlen - pos, ".%04X", d->bt_srvid);
|
|
if (d->bt_caidto)
|
|
pos += snprintf(ret + pos, maxlen - pos, ":%04X", d->bt_caidto);
|
|
comma = ",";
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for groups. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_group(uint64_t grp)
|
|
{
|
|
int32_t i = 0, needed = 1, pos = 0, dot = 0;
|
|
|
|
for(i = 0; i < 64; i++)
|
|
{
|
|
if(grp & ((uint64_t)1 << i))
|
|
{
|
|
needed += 2;
|
|
if(i > 9) { needed += 1; }
|
|
}
|
|
}
|
|
|
|
char *value;
|
|
if(needed == 1 || !cs_malloc(&value, needed)) { return ""; }
|
|
char *saveptr = value;
|
|
|
|
for(i = 0; i < 64; i++)
|
|
{
|
|
if(grp & ((uint64_t)1 << i))
|
|
{
|
|
if(dot == 0)
|
|
{
|
|
snprintf(value + pos, needed - (value - saveptr), "%d", i + 1);
|
|
if(i > 8) { pos += 2; }
|
|
else { pos += 1; }
|
|
dot = 1;
|
|
}
|
|
else
|
|
{
|
|
snprintf(value + pos, needed - (value - saveptr), ",%d", i + 1);
|
|
if(i > 8) { pos += 3; }
|
|
else { pos += 2; }
|
|
}
|
|
}
|
|
}
|
|
value[pos] = '\0';
|
|
return value;
|
|
}
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for FTabs (CHID, Ident). You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_ftab(FTAB *ftab)
|
|
{
|
|
if (!ftab || !ftab->nfilts) return "";
|
|
|
|
// Worst case scenario where each entry have different
|
|
// caid, ident and only one length in it is cs_strlen("1234:123456,") == 12
|
|
int32_t i, j, maxlen = 13 * ftab->nfilts, pos = 0;
|
|
|
|
for(i = 0; i < ftab->nfilts; i++)
|
|
{
|
|
maxlen += ftab->filts[i].nprids * 7; /* cs_strlen("123456,") == 7 */
|
|
}
|
|
|
|
char *ret;
|
|
if (!cs_malloc(&ret, maxlen))
|
|
return "";
|
|
|
|
const char *semicolon = "", *comma = "";
|
|
|
|
for(i = 0; i < ftab->nfilts; i++)
|
|
{
|
|
FILTER *cur = &ftab->filts[i];
|
|
pos += snprintf(ret + pos, maxlen - pos, "%s%04X:", semicolon, cur->caid);
|
|
semicolon = ";";
|
|
comma = "";
|
|
|
|
for (j = 0; j < cur->nprids; j++)
|
|
{
|
|
pos += snprintf(ret + pos, maxlen - pos, "%s%06X", comma, cur->prids[j]);
|
|
comma = ",";
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for the camd35 tcp ports. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_camd35tcp_port(void)
|
|
{
|
|
#if defined(MODULE_CAMD35) || defined(MODULE_CAMD35_TCP)
|
|
int32_t i, j, pos = 0, needed = 1;
|
|
|
|
/* Precheck to determine how long the resulting string will maximally be (might be a little bit smaller but that shouldn't hurt) */
|
|
for(i = 0; i < cfg.c35_tcp_ptab.nports; ++i)
|
|
{
|
|
/* Port is maximally 5 chars long, plus comma, plus the @caid, plus the :provid plus the ";" between ports */
|
|
needed += 18;
|
|
if(cfg.c35_tcp_ptab.ports[i].ncd && cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids > 0)
|
|
{
|
|
needed += cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids * 7;
|
|
}
|
|
}
|
|
|
|
char *value;
|
|
if(needed == 1 || !cs_malloc(&value, needed)) { return ""; }
|
|
char *saveptr = value;
|
|
char *dot1 = "", *dot2;
|
|
|
|
for(i = 0; i < cfg.c35_tcp_ptab.nports; ++i)
|
|
{
|
|
if(cfg.c35_tcp_ptab.ports[i].ncd && cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].caid)
|
|
{
|
|
pos += snprintf(value + pos, needed - (value - saveptr), "%s%d@%04X", dot1,
|
|
cfg.c35_tcp_ptab.ports[i].s_port,
|
|
cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].caid);
|
|
|
|
if(cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids > 0)
|
|
{
|
|
dot2 = ":";
|
|
for(j = 0; j < cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids; ++j)
|
|
{
|
|
pos += snprintf(value + pos, needed - (value - saveptr), "%s%06X",
|
|
dot2, cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].prids[j]);
|
|
dot2 = ",";
|
|
}
|
|
}
|
|
dot1 = ";";
|
|
}
|
|
else
|
|
{
|
|
pos += snprintf(value + pos, needed - (value - saveptr), "%s%d",
|
|
dot1, cfg.c35_tcp_ptab.ports[i].s_port);
|
|
dot1 = ";";
|
|
}
|
|
}
|
|
return value;
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
#ifdef MODULE_CCCAM
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for the cccam tcp ports. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_cccam_port(void)
|
|
{
|
|
int32_t i, pos = 0, needed = CS_MAXPORTS * 6 + 8;
|
|
|
|
char *value;
|
|
if(!cs_malloc(&value, needed)) { return ""; }
|
|
char *dot = "";
|
|
|
|
for(i = 0; i < CS_MAXPORTS; i++)
|
|
{
|
|
if(!cfg.cc_port[i]) { break; }
|
|
|
|
pos += snprintf(value + pos, needed - pos, "%s%d", dot, cfg.cc_port[i]);
|
|
dot = ",";
|
|
}
|
|
return value;
|
|
}
|
|
#endif
|
|
|
|
#ifdef MODULE_GBOX
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for the gbox udp ports. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_gbox_port(void)
|
|
{
|
|
int32_t i, pos = 0, needed = CS_MAXPORTS * 6 + 8;
|
|
|
|
char *value;
|
|
if(!cs_malloc(&value, needed)) { return ""; }
|
|
char *dot = "";
|
|
|
|
for(i = 0; i < CS_MAXPORTS; i++)
|
|
{
|
|
if(!cfg.gbox_port[i]) { break; }
|
|
|
|
pos += snprintf(value + pos, needed - pos, "%s%d", dot, cfg.gbox_port[i]);
|
|
dot = ",";
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for the gbox proxy card. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_gbox_proxy_card(void)
|
|
{
|
|
int32_t i, pos = 0, needed = GBOX_MAX_PROXY_CARDS * 9 + 8;
|
|
|
|
char *value;
|
|
if(!cs_malloc(&value, needed)) { return ""; }
|
|
char *dot = "";
|
|
|
|
for(i = 0; i < GBOX_MAX_PROXY_CARDS; i++)
|
|
{
|
|
if(!cfg.gbox_proxy_card[i]) { break; }
|
|
|
|
pos += snprintf(value + pos, needed - pos, "%s%08lX", dot, cfg.gbox_proxy_card[i]);
|
|
dot = ",";
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for the gbox ignore peer. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_gbox_ignored_peer(void)
|
|
{
|
|
int32_t i, pos = 0, needed = GBOX_MAX_IGNORED_PEERS * 5 + 8;
|
|
|
|
char *value;
|
|
if(!cs_malloc(&value, needed)) { return ""; }
|
|
char *dot = "";
|
|
|
|
for(i = 0; i < GBOX_MAX_IGNORED_PEERS; i++)
|
|
{
|
|
if(!cfg.gbox_ignored_peer[i]) { break; }
|
|
|
|
pos += snprintf(value + pos, needed - pos, "%s%04hX", dot, cfg.gbox_ignored_peer[i]);
|
|
dot = ",";
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for the gbox accept_remm_peer. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_accept_remm_peer(void)
|
|
{
|
|
int32_t i, pos = 0, needed = GBOX_MAX_REMM_PEERS * 5 + 8;
|
|
|
|
char *value;
|
|
if(!cs_malloc(&value, needed)) { return ""; }
|
|
char *dot = "";
|
|
|
|
for(i = 0; i < GBOX_MAX_REMM_PEERS; i++)
|
|
{
|
|
if(!cfg.accept_remm_peer[i]) { break; }
|
|
|
|
pos += snprintf(value + pos, needed - pos, "%s%04hX", dot, cfg.accept_remm_peer[i]);
|
|
dot = ",";
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for the gbox block ecm. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_gbox_block_ecm(void)
|
|
{
|
|
int32_t i, pos = 0, needed = GBOX_MAX_BLOCKED_ECM * 5 + 8;
|
|
|
|
char *value;
|
|
if(!cs_malloc(&value, needed)) { return ""; }
|
|
char *dot = "";
|
|
|
|
for(i = 0; i < GBOX_MAX_BLOCKED_ECM; i++)
|
|
{
|
|
if(!cfg.gbox_block_ecm[i]) { break; }
|
|
|
|
pos += snprintf(value + pos, needed - pos, "%s%04hX", dot, cfg.gbox_block_ecm[i]);
|
|
dot = ",";
|
|
}
|
|
return value;
|
|
}
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for the gbox SMS dest peers. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_gbox_dest_peers(void)
|
|
{
|
|
int32_t i, pos = 0, needed = GBOX_MAX_DEST_PEERS * 5 + 8;
|
|
|
|
char *value;
|
|
if(!cs_malloc(&value, needed)) { return ""; }
|
|
char *dot = "";
|
|
|
|
for(i = 0; i < GBOX_MAX_DEST_PEERS; i++)
|
|
{
|
|
if(!cfg.gbox_dest_peers[i]) { break; }
|
|
pos += snprintf(value + pos, needed - pos, "%s%04hX", dot, cfg.gbox_dest_peers[i]);
|
|
dot = ",";
|
|
}
|
|
return value;
|
|
}
|
|
#endif
|
|
|
|
#ifdef READER_VIACCESS
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for AESKeys. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_aeskeys(struct s_reader *rdr)
|
|
{
|
|
AES_ENTRY *current = rdr->aes_list;
|
|
int32_t i, pos = 0, needed = 1, prevKeyid = 0, prevCaid = 0;
|
|
uint32_t prevIdent = 0;
|
|
|
|
/* Precheck for the approximate size that we will need; it's a bit overestimated but we correct that at the end of the function */
|
|
while(current)
|
|
{
|
|
/* The caid, ident, "@" and the trailing ";" need to be output when they are changing */
|
|
if(prevCaid != current->caid || prevIdent != current->ident) { needed += 12 + (current->keyid * 2); }
|
|
/* "0" keys are not saved so we need to check for gaps */
|
|
else if(prevKeyid != current->keyid + 1) { needed += (current->keyid - prevKeyid - 1) * 2; }
|
|
/* The 32 byte key plus either the (heading) ":" or "," */
|
|
needed += 33;
|
|
prevCaid = current->caid;
|
|
prevIdent = current->ident;
|
|
prevKeyid = current->keyid;
|
|
current = current->next;
|
|
}
|
|
|
|
/* Set everything back and now create the string */
|
|
current = rdr->aes_list;
|
|
prevCaid = 0;
|
|
prevIdent = 0;
|
|
prevKeyid = 0;
|
|
char tmp[needed];
|
|
char dot;
|
|
if(needed == 1) { tmp[0] = '\0'; }
|
|
char tmpkey[33];
|
|
|
|
while(current)
|
|
{
|
|
/* A change in the ident or caid means that we need to output caid and ident */
|
|
if(prevCaid != current->caid || prevIdent != current->ident)
|
|
{
|
|
if(pos > 0)
|
|
{
|
|
tmp[pos] = ';';
|
|
++pos;
|
|
}
|
|
pos += snprintf(tmp + pos, sizeof(tmp) - pos, "%04X@%06X", current->caid, current->ident);
|
|
prevKeyid = -1;
|
|
dot = ':';
|
|
}
|
|
else { dot = ','; }
|
|
|
|
/* "0" keys are not saved so we need to check for gaps and output them! */
|
|
for(i = prevKeyid + 1; i < current->keyid; ++i)
|
|
{
|
|
pos += snprintf(tmp + pos, sizeof(tmp) - pos, "%c0", dot);
|
|
dot = ',';
|
|
}
|
|
|
|
tmp[pos] = dot;
|
|
++pos;
|
|
|
|
for(i = 0; i < 16; ++i)
|
|
{
|
|
snprintf(tmpkey + (i * 2), sizeof(tmpkey) - (i * 2), "%02X", current->plainkey[i]);
|
|
}
|
|
|
|
/* A key consisting of only FFs has a special meaning (just return what the card outputted) and can be specified more compact */
|
|
if(strcmp(tmpkey, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF") == 0)
|
|
{
|
|
pos += snprintf(tmp + pos, sizeof(tmp) - pos, "FF");
|
|
}
|
|
else
|
|
{
|
|
pos += snprintf(tmp + pos, sizeof(tmp) - pos, "%s", tmpkey);
|
|
}
|
|
|
|
prevCaid = current->caid;
|
|
prevIdent = current->ident;
|
|
prevKeyid = current->keyid;
|
|
current = current->next;
|
|
}
|
|
|
|
/* copy to result array of correct size */
|
|
char *value;
|
|
if(pos == 0 || !cs_malloc(&value, pos + 1)) { return ""; }
|
|
memcpy(value, tmp, pos + 1);
|
|
return (value);
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for the Newcamd Port. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_newcamd_port(void)
|
|
{
|
|
#ifdef MODULE_NEWCAMD
|
|
int32_t i, j, k, pos = 0, needed = 1;
|
|
|
|
/* Precheck to determine how long the resulting string will maximally be (might be a little bit smaller but that shouldn't hurt) */
|
|
for(i = 0; i < cfg.ncd_ptab.nports; ++i)
|
|
{
|
|
/* Port is maximally 5 chars long, plus the @caid, plus the ";" between ports */
|
|
needed += 11;
|
|
if(cfg.ncd_ptab.ports[i].ncd)
|
|
{
|
|
if(cfg.ncd_ptab.ports[i].ncd->ncd_key_is_set) { needed += 30; }
|
|
|
|
if(cfg.ncd_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids > 0)
|
|
{
|
|
needed += cfg.ncd_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids * 7;
|
|
}
|
|
}
|
|
}
|
|
char *value;
|
|
if(needed == 1 || !cs_malloc(&value, needed)) { return ""; }
|
|
char *dot1 = "", *dot2;
|
|
|
|
for(i = 0; i < cfg.ncd_ptab.nports; ++i)
|
|
{
|
|
pos += snprintf(value + pos, needed - pos, "%s%d", dot1, cfg.ncd_ptab.ports[i].s_port);
|
|
|
|
// separate DES Key for this port
|
|
if(cfg.ncd_ptab.ports[i].ncd)
|
|
{
|
|
if(cfg.ncd_ptab.ports[i].ncd->ncd_key_is_set)
|
|
{
|
|
pos += snprintf(value + pos, needed - pos, "{");
|
|
for(k = 0; k < (int32_t)sizeof(cfg.ncd_ptab.ports[i].ncd->ncd_key); k++)
|
|
{
|
|
pos += snprintf(value + pos, needed - pos, "%02X", cfg.ncd_ptab.ports[i].ncd->ncd_key[k]);
|
|
}
|
|
pos += snprintf(value + pos, needed - pos, "}");
|
|
}
|
|
|
|
pos += snprintf(value + pos, needed - pos, "@%04X", cfg.ncd_ptab.ports[i].ncd->ncd_ftab.filts[0].caid);
|
|
|
|
if(cfg.ncd_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids > 0)
|
|
{
|
|
dot2 = ":";
|
|
for(j = 0; j < cfg.ncd_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids; ++j)
|
|
{
|
|
pos += snprintf(value + pos, needed - pos, "%s%06X", dot2, (int)cfg.ncd_ptab.ports[i].ncd->ncd_ftab.filts[0].prids[j]);
|
|
dot2 = ",";
|
|
}
|
|
}
|
|
}
|
|
dot1 = ";";
|
|
}
|
|
return value;
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for au readers. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_aureader(struct s_auth *account)
|
|
{
|
|
int32_t pos = 0;
|
|
char *dot = "";
|
|
|
|
char *value;
|
|
if(ll_count(account->aureader_list) == 0 || !cs_malloc(&value, 256)) { return ""; }
|
|
value[0] = '\0';
|
|
|
|
struct s_reader *rdr;
|
|
LL_ITER itr = ll_iter_create(account->aureader_list);
|
|
while((rdr = ll_iter_next(&itr)))
|
|
{
|
|
pos += snprintf(value + pos, 256 - pos, "%s%s", dot, rdr->label);
|
|
dot = ",";
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for blocknano and savenano. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_nano(uint16_t nano)
|
|
{
|
|
int32_t i, pos = 0, needed = 0;
|
|
|
|
for(i = 0; i < 16; i++)
|
|
{
|
|
if((1 << i) & nano)
|
|
{ needed++; }
|
|
}
|
|
|
|
char *value;
|
|
if(nano == 0xFFFF)
|
|
{
|
|
if(!cs_malloc(&value, 4)) { return ""; }
|
|
snprintf(value, 4, "all");
|
|
}
|
|
else
|
|
{
|
|
if(needed == 0 || !cs_malloc(&value, needed * 3 + 1)) { return ""; }
|
|
|
|
value[0] = '\0';
|
|
for(i = 0; i < 16; i++)
|
|
{
|
|
if((1 << i) & nano)
|
|
{ pos += snprintf(value + pos, (needed * 3) + 1 - pos, "%s%02x", pos ? "," : "", (i + 0x80)); }
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for the sidtab. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_service(SIDTABS *sidtabs)
|
|
{
|
|
int32_t i, pos;
|
|
char *dot;
|
|
char *value;
|
|
struct s_sidtab *sidtab = cfg.sidtab;
|
|
if(!sidtab || (!sidtabs->ok && !sidtabs->no) || !cs_malloc(&value, 1024)) { return ""; }
|
|
|
|
value[0] = '\0';
|
|
|
|
for(i = pos = 0, dot = ""; sidtab; sidtab = sidtab->next, i++)
|
|
{
|
|
if(sidtabs->ok & ((SIDTABBITS)1 << i))
|
|
{
|
|
pos += snprintf(value + pos, 1024 - pos, "%s%s", dot, sidtab->label);
|
|
dot = ",";
|
|
}
|
|
if(sidtabs->no & ((SIDTABBITS)1 << i))
|
|
{
|
|
pos += snprintf(value + pos, 1024 - pos, "%s!%s", dot, sidtab->label);
|
|
dot = ",";
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for the logfile parameter. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_logfile(void)
|
|
{
|
|
int32_t pos = 0, needed = 1;
|
|
char *value, *dot = "";
|
|
|
|
if(cfg.logtostdout == 1) { needed += 7; }
|
|
if(cfg.logtosyslog == 1) { needed += 7; }
|
|
if(cfg.logfile) { needed += cs_strlen(cfg.logfile); }
|
|
if(needed == 1 || !cs_malloc(&value, needed)) { return ""; }
|
|
|
|
if(cfg.logtostdout == 1)
|
|
{
|
|
pos += snprintf(value + pos, needed - pos, "stdout");
|
|
dot = ";";
|
|
}
|
|
|
|
if(cfg.logtosyslog == 1)
|
|
{
|
|
pos += snprintf(value + pos, needed - pos, "%ssyslog", dot);
|
|
dot = ";";
|
|
}
|
|
|
|
if(cfg.logfile)
|
|
{
|
|
snprintf(value + pos, needed - pos, "%s%s", dot, cfg.logfile);
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for the ecm whitelist. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_ecm_whitelist(struct s_ecm_whitelist *ecm_whitelist)
|
|
{
|
|
if (!ecm_whitelist || !ecm_whitelist->ewnum) return "";
|
|
|
|
// Worst case scenario where each entry have different
|
|
// caid, ident and only one length in it is cs_strlen("1234@123456:01;") == 15
|
|
int32_t i, maxlen = 16 * ecm_whitelist->ewnum, pos = 0;
|
|
char *ret;
|
|
if (!cs_malloc(&ret, maxlen))
|
|
return "";
|
|
|
|
const char *semicolon = "", *comma = "";
|
|
ECM_WHITELIST_DATA *last = NULL;
|
|
|
|
for(i = 0; i < ecm_whitelist->ewnum; i++)
|
|
{
|
|
ECM_WHITELIST_DATA *cur = &ecm_whitelist->ewdata[i];
|
|
bool change = !last || last->caid != cur->caid || last->ident != cur->ident;
|
|
|
|
if(change)
|
|
{
|
|
if(cur->caid && cur->ident)
|
|
pos += snprintf(ret + pos, maxlen - pos, "%s%04X@%06X:", semicolon, cur->caid, cur->ident);
|
|
else if(cur->caid)
|
|
pos += snprintf(ret + pos, maxlen - pos, "%s%04X:", semicolon, cur->caid);
|
|
else if(cur->ident)
|
|
pos += snprintf(ret + pos, maxlen - pos, "%s@%06X:", semicolon, cur->ident);
|
|
else
|
|
pos += snprintf(ret + pos, maxlen - pos, "%s", semicolon);
|
|
|
|
semicolon = ";";
|
|
comma = "";
|
|
}
|
|
pos += snprintf(ret + pos, maxlen - pos, "%s%02X", comma, cur->len);
|
|
comma = ",";
|
|
last = &ecm_whitelist->ewdata[i];
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for the ECM Headerwhitelist. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_ecm_hdr_whitelist(struct s_ecm_hdr_whitelist *ecm_hdr_whitelist)
|
|
{
|
|
if(!ecm_hdr_whitelist || !ecm_hdr_whitelist->ehnum) return "";
|
|
|
|
// Worst case scenario where each entry have different
|
|
// caid, provid and only one header in it is cs_strlen("1234@123456:0102030405060708091011121314151617181920;") == 52 ((sizeof(header) / 2) + 12)
|
|
int32_t i, r, maxlen = 53 * ecm_hdr_whitelist->ehnum, pos = 0;
|
|
char *ret;
|
|
if (!cs_malloc(&ret, maxlen))
|
|
return "";
|
|
|
|
const char *semicolon = "", *comma = "";
|
|
ECM_HDR_WHITELIST_DATA *last = NULL;
|
|
|
|
for(i = 0; i < ecm_hdr_whitelist->ehnum; i++)
|
|
{
|
|
ECM_HDR_WHITELIST_DATA *cur = &ecm_hdr_whitelist->ehdata[i];
|
|
bool change = !last || last->caid != cur->caid || last->provid != cur->provid;
|
|
if (change)
|
|
{
|
|
if (cur->caid && cur->provid)
|
|
pos += snprintf(ret + pos, maxlen - pos, "%s%04X@%06X:", semicolon, cur->caid, cur->provid);
|
|
else if (cur->caid)
|
|
pos += snprintf(ret + pos, maxlen - pos, "%s%04X:", semicolon, cur->caid);
|
|
else if (cur->provid)
|
|
pos += snprintf(ret + pos, maxlen - pos, "%s@%06X:", semicolon, cur->provid);
|
|
else
|
|
pos += snprintf(ret + pos, maxlen - pos, "%s", semicolon);
|
|
|
|
semicolon = ";";
|
|
comma = "";
|
|
}
|
|
pos += snprintf(ret + pos, maxlen - pos, "%s", comma);
|
|
for(r = 0; r < cur->len / 2; r++)
|
|
pos += snprintf(ret + pos, maxlen - pos, "%02X", cur->header[r]);
|
|
comma = ",";
|
|
last = &ecm_hdr_whitelist->ehdata[i];
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for an iprange. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_iprange(struct s_ip *range)
|
|
{
|
|
struct s_ip *cip;
|
|
char *value, *dot = "";
|
|
int32_t needed = 1, pos = 0;
|
|
for(cip = range; cip; cip = cip->next) { needed += 64; }
|
|
|
|
char tmp[needed];
|
|
|
|
for(cip = range; cip; cip = cip->next)
|
|
{
|
|
pos += snprintf(tmp + pos, needed - pos, "%s%s", dot, cs_inet_ntoa(cip->ip[0]));
|
|
if(!IP_EQUAL(cip->ip[0], cip->ip[1])) { pos += snprintf(tmp + pos, needed - pos, "-%s", cs_inet_ntoa(cip->ip[1])); }
|
|
dot = ",";
|
|
}
|
|
|
|
if(pos == 0 || !cs_malloc(&value, pos + 1)) { return ""; }
|
|
|
|
memcpy(value, tmp, pos + 1);
|
|
return value;
|
|
}
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf for the class attribute. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_cltab(CLASSTAB *clstab)
|
|
{
|
|
char *value, *dot = "";
|
|
int32_t i, needed = 1, pos = 0;
|
|
for(i = 0; i < clstab->an; ++i) { needed += 3; }
|
|
for(i = 0; i < clstab->bn; ++i) { needed += 4; }
|
|
|
|
char tmp[needed];
|
|
|
|
for(i = 0; i < clstab->an; ++i)
|
|
{
|
|
pos += snprintf(tmp + pos, needed - pos, "%s%02x", dot, (int32_t)clstab->aclass[i]);
|
|
dot = ",";
|
|
}
|
|
|
|
for(i = 0; i < clstab->bn; ++i)
|
|
{
|
|
pos += snprintf(tmp + pos, needed - pos, "%s!%02x", dot, (int32_t)clstab->bclass[i]);
|
|
dot = ",";
|
|
}
|
|
|
|
if(pos == 0 || !cs_malloc(&value, pos + 1)) { return ""; }
|
|
|
|
memcpy(value, tmp, pos + 1);
|
|
return value;
|
|
}
|
|
|
|
/*
|
|
* Creates a string ready to write as a token into config or WebIf. You must free the returned value through free_mk_t().
|
|
*/
|
|
char *mk_t_caidvaluetab(CAIDVALUETAB *caidvaluetab)
|
|
{
|
|
if (!caidvaluetab || !caidvaluetab->cvnum) return "";
|
|
|
|
// Max entry length is cs_strlen("1234@65535,") == 11
|
|
int32_t i, maxlen = 12 * caidvaluetab->cvnum, pos = 0;
|
|
char *ret;
|
|
if (!cs_malloc(&ret, maxlen))
|
|
return "";
|
|
const char *comma = "";
|
|
|
|
for(i = 0; i < caidvaluetab->cvnum; i++)
|
|
{
|
|
CAIDVALUETAB_DATA *d = &caidvaluetab->cvdata[i];
|
|
if (d->caid < 0x0100)
|
|
pos += snprintf(ret + pos, maxlen - pos, "%s%02X:%d", comma, d->caid, d->value);
|
|
else
|
|
pos += snprintf(ret + pos, maxlen - pos, "%s%04X:%d", comma, d->caid, d->value);
|
|
|
|
comma = ",";
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
char *mk_t_cacheex_valuetab(CECSPVALUETAB *tab)
|
|
{
|
|
if (!tab || !tab->cevnum) return "";
|
|
|
|
int32_t i, size = 2 + tab->cevnum * (4 + 1 + 4 + 1 + 6 + 1 + 4 + 1 + 5 + 1 + 5 + 1); // caid&mask@provid$servid:awtime:dwtime","
|
|
|
|
char *buf;
|
|
if(!cs_malloc(&buf, size))
|
|
{ return ""; }
|
|
|
|
char *ptr = buf;
|
|
|
|
for(i = 0; i < tab->cevnum; i++)
|
|
{
|
|
CECSPVALUETAB_DATA *d = &tab->cevdata[i];
|
|
|
|
if(i) { ptr += snprintf(ptr, size - (ptr - buf), ","); }
|
|
|
|
if(d->caid >= 0)
|
|
{
|
|
if(d->caid == 0)
|
|
{
|
|
if(d->awtime > 0)
|
|
{ ptr += snprintf(ptr, size - (ptr - buf), "%d", d->caid); }
|
|
}
|
|
else if(d->caid < 256) // Do not format 0D as 000D, its a shortcut for 0Dxx:
|
|
{
|
|
ptr += snprintf(ptr, size - (ptr - buf), "%02X", d->caid);
|
|
}
|
|
else
|
|
{
|
|
ptr += snprintf(ptr, size - (ptr - buf), "%04X", d->caid);
|
|
}
|
|
}
|
|
|
|
if(d->cmask >= 0)
|
|
{ ptr += snprintf(ptr, size - (ptr - buf), "&%04X", d->cmask); }
|
|
|
|
if(d->prid >= 0)
|
|
{ ptr += snprintf(ptr, size - (ptr - buf), "@%06X", d->prid); }
|
|
|
|
if(d->srvid >= 0)
|
|
{ ptr += snprintf(ptr, size - (ptr - buf), "$%04X", d->srvid); }
|
|
|
|
if(d->awtime > 0)
|
|
{ ptr += snprintf(ptr, size - (ptr - buf), ":%d", d->awtime); }
|
|
|
|
if(!(d->dwtime > 0))
|
|
{ ptr += snprintf(ptr, size - (ptr - buf), ":0"); }
|
|
|
|
if(d->dwtime > 0)
|
|
{
|
|
if((d->caid <= 0) && (d->prid == -1) && (d->srvid == -1) && (d->srvid == -1) && (d->awtime <= 0))
|
|
{
|
|
ptr += snprintf(ptr, size - (ptr - buf), "%d", d->dwtime);
|
|
}
|
|
else
|
|
{
|
|
ptr += snprintf(ptr, size - (ptr - buf), ":%d", d->dwtime);
|
|
}
|
|
}
|
|
}
|
|
*ptr = 0;
|
|
return buf;
|
|
}
|
|
|
|
|
|
char *mk_t_cacheex_cwcheck_valuetab(CWCHECKTAB *tab)
|
|
{
|
|
if(!tab || !tab->cwchecknum) { return ""; }
|
|
|
|
int32_t i, size = 2 + tab->cwchecknum * (4 + 1 + 4 + 1 + 6 + 1 + 4 + 1 + 5 + 1 + 5 + 1); // caid[&mask][@provid][$servid]:mode:counter","
|
|
char *buf;
|
|
if(!cs_malloc(&buf, size))
|
|
{ return ""; }
|
|
char *ptr = buf;
|
|
|
|
for(i = 0; i < tab->cwchecknum; i++)
|
|
{
|
|
CWCHECKTAB_DATA *d = &tab->cwcheckdata[i];
|
|
|
|
if(i) { ptr += snprintf(ptr, size - (ptr - buf), ","); }
|
|
|
|
if(d->caid >= 0)
|
|
{
|
|
if(d->caid == 0)
|
|
{
|
|
ptr += snprintf(ptr, size - (ptr - buf), "%d", d->caid);
|
|
}
|
|
else if(d->caid < 256) // Do not format 0D as 000D, its a shortcut for 0Dxx:
|
|
{
|
|
ptr += snprintf(ptr, size - (ptr - buf), "%02X", d->caid);
|
|
}
|
|
else
|
|
{
|
|
ptr += snprintf(ptr, size - (ptr - buf), "%04X", d->caid);
|
|
}
|
|
}
|
|
|
|
if(d->cmask >= 0)
|
|
{ ptr += snprintf(ptr, size - (ptr - buf), "&%04X", d->cmask); }
|
|
|
|
if(d->prid >= 0)
|
|
{ ptr += snprintf(ptr, size - (ptr - buf), "@%06X", d->prid); }
|
|
|
|
if(d->srvid >= 0)
|
|
{ ptr += snprintf(ptr, size - (ptr - buf), "$%04X", d->srvid); }
|
|
|
|
if(d->mode >= 0)
|
|
{ ptr += snprintf(ptr, size - (ptr - buf), ":%d", d->mode); }
|
|
|
|
if(d->counter > 0)
|
|
{ ptr += snprintf(ptr, size - (ptr - buf), ":%d", d->counter); }
|
|
}
|
|
*ptr = 0;
|
|
return buf;
|
|
}
|
|
|
|
char *mk_t_cacheex_hitvaluetab(CECSPVALUETAB *tab)
|
|
{
|
|
if (!tab || !tab->cevnum) return "";
|
|
|
|
int32_t i, size = 2 + tab->cevnum * (4 + 1 + 4 + 1 + 6 + 1 + 4 + 1); // caid&mask@provid$servid","
|
|
char *buf;
|
|
if(!cs_malloc(&buf, size))
|
|
{ return ""; }
|
|
char *ptr = buf;
|
|
|
|
for(i = 0; i < tab->cevnum; i++)
|
|
{
|
|
CECSPVALUETAB_DATA *d = &tab->cevdata[i];
|
|
|
|
if(i) { ptr += snprintf(ptr, size - (ptr - buf), ","); }
|
|
|
|
if(d->caid > 0)
|
|
{
|
|
if(d->caid < 256) // Do not format 0D as 000D, its a shortcut for 0Dxx:
|
|
{
|
|
ptr += snprintf(ptr, size - (ptr - buf), "%02X", d->caid);
|
|
}
|
|
else
|
|
{
|
|
ptr += snprintf(ptr, size - (ptr - buf), "%04X", d->caid);
|
|
}
|
|
|
|
if(d->cmask >= 0)
|
|
{ ptr += snprintf(ptr, size - (ptr - buf), "&%04X", d->cmask); }
|
|
|
|
if(d->prid >= 0)
|
|
{ ptr += snprintf(ptr, size - (ptr - buf), "@%06X", d->prid); }
|
|
|
|
if(d->srvid >= 0)
|
|
{ ptr += snprintf(ptr, size - (ptr - buf), "$%04X", d->srvid); }
|
|
}
|
|
}
|
|
*ptr = 0;
|
|
return buf;
|
|
}
|
|
|
|
/*
|
|
* returns string of comma separated values
|
|
*/
|
|
char *mk_t_emmbylen(struct s_reader *rdr)
|
|
{
|
|
char *value, *pos, *dot = "";
|
|
int32_t num, needed = 0;
|
|
struct s_emmlen_range *blocklen;
|
|
|
|
if(!rdr->blockemmbylen)
|
|
{ return ""; }
|
|
|
|
LL_ITER it = ll_iter_create(rdr->blockemmbylen);
|
|
while((blocklen = ll_iter_next(&it)))
|
|
{
|
|
needed += 5 + 1; // max digits of int16 + ","
|
|
if(blocklen->max == 0)
|
|
{ needed += 1 + 1; } // "-" + ","
|
|
else if(blocklen->min != blocklen->max)
|
|
{ needed += 1 + 5 + 1; } // "-" + max digits of int16 + ","
|
|
}
|
|
|
|
// the trailing zero is already included: it's the first ","
|
|
if(!cs_malloc(&value, needed))
|
|
{ return ""; }
|
|
|
|
pos = value;
|
|
ll_iter_reset(&it);
|
|
while((blocklen = ll_iter_next(&it)))
|
|
{
|
|
if(blocklen->min == blocklen->max)
|
|
{ num = snprintf(pos, needed, "%s%d", dot, blocklen->min); }
|
|
else if(blocklen->max == 0)
|
|
{ num = snprintf(pos, needed, "%s%d-", dot, blocklen->min); }
|
|
else
|
|
{ num = snprintf(pos, needed, "%s%d-%d", dot, blocklen->min, blocklen->max); }
|
|
|
|
pos += num;
|
|
needed -= num;
|
|
dot = ",";
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/*
|
|
* makes string from binary structure
|
|
*/
|
|
char *mk_t_allowedprotocols(struct s_auth *account)
|
|
{
|
|
if(!account->allowedprotocols)
|
|
{ return ""; }
|
|
|
|
int16_t i, tmp = 1, pos = 0, needed = 255, tagcnt;
|
|
char *tag[] = {"camd33", "cs357x", "cs378x", "newcamd", "cccam", "gbox", "radegast", "dvbapi", "constcw", "serial"};
|
|
char *value, *dot = "";
|
|
|
|
if(!cs_malloc(&value, needed))
|
|
{ return ""; }
|
|
|
|
tagcnt = sizeof(tag) / sizeof(char *);
|
|
for(i = 0; i < tagcnt; i++)
|
|
{
|
|
if((account->allowedprotocols & tmp) == tmp)
|
|
{
|
|
pos += snprintf(value + pos, needed, "%s%s", dot, tag[i]);
|
|
dot = ",";
|
|
}
|
|
tmp = tmp << 1;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/*
|
|
* return allowed time frame string from internal array content
|
|
*
|
|
*/
|
|
|
|
char *mk_t_allowedtimeframe(struct s_auth *account)
|
|
{
|
|
char *result;
|
|
if(!cs_malloc(&result, MAXALLOWEDTF))
|
|
{ return ""; }
|
|
|
|
if(account->allowedtimeframe_set)
|
|
{
|
|
char mytime[8];
|
|
uint8_t day;
|
|
uint8_t value_in_day = 0;
|
|
uint8_t intime = 0;
|
|
uint8_t minutes =0;
|
|
uint8_t hours;
|
|
char septime[2] = {'\0'};
|
|
char sepday[2] = {'\0'};
|
|
|
|
for(day = 0; day < SIZE_SHORTDAY; day++)
|
|
{
|
|
for(hours = 0; hours < 24; hours++)
|
|
{
|
|
for(minutes = 0; minutes < 60; minutes++)
|
|
{
|
|
if(CHECK_BIT(account->allowedtimeframe[day][hours][minutes / 30], (minutes % 30)))
|
|
{
|
|
if(value_in_day == 0)
|
|
{
|
|
cs_strncat(result, &sepday[0], MAXALLOWEDTF);
|
|
cs_strncat(result, (char *)shortDay[day], MAXALLOWEDTF);
|
|
cs_strncat(result, "@", MAXALLOWEDTF);
|
|
value_in_day = 1;
|
|
intime = 0;
|
|
sepday[0] = ';';
|
|
septime[0] = '\0';
|
|
}
|
|
|
|
if(!intime)
|
|
{
|
|
cs_strncat(result, &septime[0], MAXALLOWEDTF);
|
|
snprintf(mytime, sizeof(mytime), "%02d:%02d", hours, minutes);
|
|
cs_strncat(result, mytime, MAXALLOWEDTF);
|
|
cs_strncat(result, "-", MAXALLOWEDTF);
|
|
septime[0] = ',';
|
|
intime = 1;
|
|
}
|
|
|
|
// Special case 23H59 is enabled we close the day at 24H00
|
|
if(((hours * 60) + minutes) == 1439)
|
|
{
|
|
cs_strncat(result, "24:00", MAXALLOWEDTF);
|
|
intime = 0;
|
|
septime[0] = '\0';
|
|
value_in_day = 0;
|
|
}
|
|
}
|
|
else if(intime)
|
|
{
|
|
snprintf(mytime, sizeof(mytime), "%02d:%02d", hours, minutes);
|
|
cs_strncat(result, mytime, MAXALLOWEDTF);
|
|
septime[0] = ',';
|
|
intime = 0;
|
|
}
|
|
}
|
|
}
|
|
value_in_day = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result = "";
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
* mk_t-functions give back a constant empty string when allocation fails or when the result is an empty string.
|
|
* This function thus checks the stringlength and only frees if necessary.
|
|
*/
|
|
void free_mk_t(char *value)
|
|
{
|
|
if(cs_strlen(value) > 0) { NULLFREE(value); }
|
|
}
|