#define MODULE_LOG_PREFIX "config" #include "globals.h" #include "module-dvbapi.h" #include "module-gbox.h" #include "oscam-array.h" #include "oscam-conf.h" #include "oscam-conf-chk.h" #include "oscam-conf-mk.h" #include "oscam-config.h" #include "oscam-net.h" #include "oscam-string.h" #ifdef CS_CACHEEX_AIO #include "module-cacheex.h" #endif #define cs_conf "oscam.conf" #define DEFAULT_HTTP_PORT 8888 #define DEFAULT_HTTP_ALLOW "127.0.0.1,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255,172.16.0.0-172.31.255.255,::1" static void disablelog_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { if(value) { cs_disable_log(strToIntVal(value, 0)); return; } if(cfg.disablelog || cfg.http_full_cfg) { fprintf_conf(f, token, "%d\n", cfg.disablelog); } } #if defined(WEBIF) || defined(MODULE_MONITOR) static void loghistorylines_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { if(value) { uint32_t newsize = strToUIntVal(value, 256); if(newsize < 64 && newsize != 0) { fprintf(stderr, "WARNING: loghistorylines is too small, adjusted to 64\n"); newsize = 64; } cs_reinit_loghist(newsize); return; } if(cfg.loghistorylines != 256 || cfg.http_full_cfg) { fprintf_conf(f, token, "%u\n", cfg.loghistorylines); } } #endif static void serverip_fn(const char *token, char *value, void *setting, FILE *f) { IN_ADDR_T srvip = *(IN_ADDR_T *)setting; if(value) { if(cs_strlen(value) == 0) { set_null_ip((IN_ADDR_T *)setting); } else { cs_inet_addr(value, (IN_ADDR_T *)setting); } return; } if(IP_ISSET(srvip) || cfg.http_full_cfg) { fprintf_conf(f, token, "%s\n", cs_inet_ntoa(srvip)); } } void iprange_fn(const char *token, char *value, void *setting, FILE *f) { struct s_ip **ip = setting; if(value) { if(cs_strlen(value) == 0) { clear_sip(ip); } else { chk_iprange(value, ip); } return; } value = mk_t_iprange(*ip); if(cs_strlen(value) > 0 || cfg.http_full_cfg) { fprintf_conf(f, token, "%s\n", value); } free_mk_t(value); } void iprange_free_fn(void *setting) { clear_sip(setting); } static void logfile_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { if(value) { char *saveptr1 = NULL; cfg.logtostdout = 0; cfg.logtosyslog = 0; NULLFREE(cfg.logfile); if(cs_strlen(value) > 0) { char *pch; for(pch = strtok_r(value, ";", &saveptr1); pch != NULL; pch = strtok_r(NULL, ";", &saveptr1)) { pch = trim(pch); if(!strcmp(pch, "stdout")) { cfg.logtostdout = 1; } else if(!strcmp(pch, "syslog")) { cfg.logtosyslog = 1; } else { NULLFREE(cfg.logfile); if(!(cfg.logfile = cs_strdup(pch))) { continue; } } } } else { if(!(cfg.logfile = cs_strdup(CS_LOGFILE))) { cfg.logtostdout = 1; } } return; } if(cfg.logfile || cfg.logtostdout == 1 || cfg.logtosyslog == 1 || cfg.http_full_cfg) { value = mk_t_logfile(); fprintf_conf(f, token, "%s\n", value); free_mk_t(value); } } void check_caidtab_fn(const char *token, char *value, void *setting, FILE *f) { CAIDTAB *caid_table = setting; if(value) { if(cs_strlen(value)) { chk_caidtab(value, caid_table); } else { caidtab_clear(caid_table); } return; } if(caid_table->ctnum || cfg.http_full_cfg) { value = mk_t_caidtab(caid_table); fprintf_conf(f, token, "%s\n", value); free_mk_t(value); } } void chk_ftab_fn(const char *token, char *value, void *setting, FILE *f) { FTAB *ftab = setting; if(value) { if(cs_strlen(value)) chk_ftab(value, ftab); else ftab_clear(ftab); return; } value = mk_t_ftab(ftab); if(cs_strlen(value) > 0 || cfg.http_full_cfg) { fprintf_conf(f, token, "%s\n", value); } free_mk_t(value); } void caidvaluetab_fn(const char *token, char *value, void *setting, FILE *f) { CAIDVALUETAB *caid_value_table = setting; if(value) { if (cs_strlen(value)) { chk_caidvaluetab(value, caid_value_table); if (streq(token, "lb_retrylimits")) { int32_t i; for (i = 0; i < caid_value_table->cvnum; i++) { if (caid_value_table->cvdata[i].value < 50) caid_value_table->cvdata[i].value = 50; } } } else { caidvaluetab_clear(caid_value_table); } return; } if(caid_value_table->cvnum || cfg.http_full_cfg) { value = mk_t_caidvaluetab(caid_value_table); fprintf_conf(f, token, "%s\n", value); free_mk_t(value); } } #ifdef CS_CACHEEX void cacheex_valuetab_fn(const char *token, char *value, void *setting, FILE *f) { CECSPVALUETAB *cacheex_value_table = setting; if(value) { if(cs_strlen(value) == 0) { clear_cacheextab(cacheex_value_table); } else { chk_cacheex_valuetab(value, cacheex_value_table); } return; } if(cacheex_value_table->cevnum || cfg.http_full_cfg) { value = mk_t_cacheex_valuetab(cacheex_value_table); fprintf_conf(f, token, "%s\n", value); free_mk_t(value); } } void cacheex_cwcheck_tab_fn(const char *token, char *value, void *setting, FILE *f) { CWCHECKTAB *cacheex_value_table = setting; if(value) { if(cs_strlen(value) == 0) { cacheex_value_table->cwchecknum = 0; NULLFREE(cacheex_value_table->cwcheckdata); } else { chk_cacheex_cwcheck_valuetab(value, cacheex_value_table); } return; } if(cacheex_value_table->cwchecknum || cfg.http_full_cfg) { value = mk_t_cacheex_cwcheck_valuetab(cacheex_value_table); fprintf_conf(f, token, "%s\n", value); free_mk_t(value); } } void cacheex_hitvaluetab_fn(const char *token, char *value, void *setting, FILE *f) { CECSPVALUETAB *cacheex_value_table = setting; if(value) { if(cs_strlen(value) == 0) { clear_cacheextab(cacheex_value_table); } else { chk_cacheex_hitvaluetab(value, cacheex_value_table); } return; } if(cacheex_value_table->cevnum || cfg.http_full_cfg) { value = mk_t_cacheex_hitvaluetab(cacheex_value_table); fprintf_conf(f, token, "%s\n", value); free_mk_t(value); } } #endif #ifdef __CYGWIN__ #include #else #include // for setpriority #endif void global_fixups_fn(void *UNUSED(var)) { if(!cfg.usrfile) { cfg.disableuserfile = 1; } if(!cfg.mailfile) { cfg.disablemail = 1; } if(cfg.ctimeout < 10) { cfg.ctimeout = cfg.ctimeout * 1000; } // save always in ms if(cfg.nice < -20 || cfg.nice > 20) { cfg.nice = 99; } if(cfg.nice != 99) { #ifndef __CYGWIN__ setpriority(PRIO_PROCESS, 0, cfg.nice); #else HANDLE WinId; uint32_t wprio; switch((cfg.nice + 20) / 10) { case 0: wprio = REALTIME_PRIORITY_CLASS; break; case 1: wprio = HIGH_PRIORITY_CLASS; break; case 2: wprio = NORMAL_PRIORITY_CLASS; break; default: wprio = IDLE_PRIORITY_CLASS; break; } WinId = GetCurrentProcess(); SetPriorityClass(WinId, wprio); #endif } if(cfg.netprio <= 0 || cfg.netprio > 20) { cfg.netprio = 0; } if(cfg.max_log_size != 0 && cfg.max_log_size <= 10) { cfg.max_log_size = 10; } #ifdef WITH_LB if(cfg.lb_save > 0 && cfg.lb_save < 100) { cfg.lb_save = 100; } if(cfg.lb_nbest_readers < 2) { cfg.lb_nbest_readers = DEFAULT_NBEST; } #endif } #define OFS(X) offsetof(struct s_config, X) #define SIZEOF(X) sizeof(((struct s_config *)0)->X) static const struct config_list global_opts[] = { DEF_OPT_FIXUP_FUNC(global_fixups_fn), #ifdef LEDSUPPORT DEF_OPT_INT8("enableled" , OFS(enableled) , 0), #endif DEF_OPT_FUNC("disablelog" , OFS(disablelog) , disablelog_fn), #if defined(WEBIF) || defined(MODULE_MONITOR) DEF_OPT_FUNC("loghistorylines" , OFS(loghistorylines) , loghistorylines_fn), #endif DEF_OPT_FUNC("serverip" , OFS(srvip) , serverip_fn), DEF_OPT_FUNC("logfile" , OFS(logfile) , logfile_fn), DEF_OPT_INT32("initial_debuglevel" , OFS(initial_debuglevel) , 0), DEF_OPT_STR("sysloghost" , OFS(sysloghost) , NULL), DEF_OPT_INT32("syslogport" , OFS(syslogport) , 514), DEF_OPT_INT8("logduplicatelines" , OFS(logduplicatelines) , 0), DEF_OPT_STR("pidfile" , OFS(pidfile) , NULL), DEF_OPT_INT8("disableuserfile" , OFS(disableuserfile) , 1), DEF_OPT_INT8("disablemail" , OFS(disablemail) , 1), DEF_OPT_INT8("usrfileflag" , OFS(usrfileflag) , 0), DEF_OPT_UINT32("clienttimeout" , OFS(ctimeout) , CS_CLIENT_TIMEOUT), DEF_OPT_UINT32("fallbacktimeout" , OFS(ftimeout) , CS_CLIENT_TIMEOUT / 2), DEF_OPT_FUNC("fallbacktimeout_percaid" , OFS(ftimeouttab) , caidvaluetab_fn), DEF_OPT_UINT32("clientmaxidle" , OFS(cmaxidle) , CS_CLIENT_MAXIDLE), DEF_OPT_INT32("bindwait" , OFS(bindwait) , CS_BIND_TIMEOUT), DEF_OPT_UINT32("netprio" , OFS(netprio) , 0), DEF_OPT_INT32("sleep" , OFS(tosleep) , 0), DEF_OPT_INT32("unlockparental" , OFS(ulparent) , 0), DEF_OPT_INT32("nice" , OFS(nice) , 99), DEF_OPT_INT32("maxlogsize" , OFS(max_log_size) , 10), DEF_OPT_INT8("waitforcards" , OFS(waitforcards) , 1), DEF_OPT_INT32("waitforcards_extra_delay" , OFS(waitforcards_extra_delay) , 500), DEF_OPT_INT8("preferlocalcards" , OFS(preferlocalcards) , 0), DEF_OPT_INT32("readerrestartseconds" , OFS(reader_restart_seconds) , 5), DEF_OPT_INT8("dropdups" , OFS(dropdups) , 0), DEF_OPT_INT8("reload_useraccounts" , OFS(reload_useraccounts) , 0), DEF_OPT_INT8("reload_readers" , OFS(reload_readers) , 0), DEF_OPT_INT8("reload_provid" , OFS(reload_provid) , 0), DEF_OPT_INT8("reload_services_ids" , OFS(reload_services_ids) , 0), DEF_OPT_INT8("reload_tier_ids" , OFS(reload_tier_ids) , 0), DEF_OPT_INT8("reload_fakecws" , OFS(reload_fakecws) , 0), DEF_OPT_INT8("reload_ac_stat" , OFS(reload_ac_stat) , 0), DEF_OPT_INT8("reload_log" , OFS(reload_log) , 0), DEF_OPT_INT8("block_same_ip" , OFS(block_same_ip) , 1), DEF_OPT_INT8("block_same_name" , OFS(block_same_name) , 1), DEF_OPT_STR("usrfile" , OFS(usrfile) , NULL), DEF_OPT_STR("mailfile" , OFS(mailfile) , NULL), DEF_OPT_STR("cwlogdir" , OFS(cwlogdir) , NULL), DEF_OPT_STR("emmlogdir" , OFS(emmlogdir) , NULL), #ifdef WITH_LB DEF_OPT_INT32("lb_mode" , OFS(lb_mode) , DEFAULT_LB_MODE), DEF_OPT_INT32("lb_save" , OFS(lb_save) , 0), DEF_OPT_INT32("lb_nbest_readers" , OFS(lb_nbest_readers) , DEFAULT_NBEST), DEF_OPT_INT32("lb_nfb_readers" , OFS(lb_nfb_readers) , DEFAULT_NFB), DEF_OPT_INT32("lb_min_ecmcount" , OFS(lb_min_ecmcount) , DEFAULT_MIN_ECM_COUNT), DEF_OPT_INT32("lb_max_ecmcount" , OFS(lb_max_ecmcount) , DEFAULT_MAX_ECM_COUNT), DEF_OPT_INT32("lb_reopen_seconds" , OFS(lb_reopen_seconds) , DEFAULT_REOPEN_SECONDS), DEF_OPT_INT8("lb_reopen_invalid" , OFS(lb_reopen_invalid) , 1), DEF_OPT_INT8("lb_force_reopen_always" , OFS(lb_force_reopen_always) , 0), DEF_OPT_INT32("lb_retrylimit" , OFS(lb_retrylimit) , DEFAULT_RETRYLIMIT), DEF_OPT_INT32("lb_stat_cleanup" , OFS(lb_stat_cleanup) , DEFAULT_LB_STAT_CLEANUP), DEF_OPT_INT32("lb_max_readers" , OFS(lb_max_readers) , 0), DEF_OPT_INT32("lb_auto_betatunnel" , OFS(lb_auto_betatunnel) , DEFAULT_LB_AUTO_BETATUNNEL), DEF_OPT_INT32("lb_auto_betatunnel_mode" , OFS(lb_auto_betatunnel_mode) , DEFAULT_LB_AUTO_BETATUNNEL_MODE), DEF_OPT_INT32("lb_auto_betatunnel_prefer_beta" , OFS(lb_auto_betatunnel_prefer_beta), DEFAULT_LB_AUTO_BETATUNNEL_PREFER_BETA), DEF_OPT_STR("lb_savepath" , OFS(lb_savepath) , NULL), DEF_OPT_FUNC("lb_retrylimits" , OFS(lb_retrylimittab) , caidvaluetab_fn), DEF_OPT_FUNC("lb_nbest_percaid" , OFS(lb_nbest_readers_tab) , caidvaluetab_fn), DEF_OPT_FUNC("lb_noproviderforcaid" , OFS(lb_noproviderforcaid) , check_caidtab_fn), DEF_OPT_INT32("lb_auto_timeout" , OFS(lb_auto_timeout) , DEFAULT_LB_AUTO_TIMEOUT), DEF_OPT_INT32("lb_auto_timeout_p" , OFS(lb_auto_timeout_p) , DEFAULT_LB_AUTO_TIMEOUT_P), DEF_OPT_INT32("lb_auto_timeout_t" , OFS(lb_auto_timeout_t) , DEFAULT_LB_AUTO_TIMEOUT_T), #endif DEF_OPT_FUNC("double_check_caid" , OFS(double_check_caid) , chk_ftab_fn), DEF_OPT_STR("ecmfmt" , OFS(ecmfmt) , NULL), DEF_OPT_INT32("resolvegethostbyname" , OFS(resolve_gethostbyname) , 0), DEF_OPT_INT32("failbantime" , OFS(failbantime) , 0), DEF_OPT_INT32("failbancount" , OFS(failbancount) , 0), DEF_OPT_INT8("suppresscmd08" , OFS(c35_suppresscmd08) , 0), DEF_OPT_INT8("getblockemmauprovid" , OFS(getblockemmauprovid) , 0), DEF_OPT_INT8("double_check" , OFS(double_check) , 0), DEF_OPT_INT8("disablecrccws" , OFS(disablecrccws) , 0), DEF_OPT_FUNC("disablecrccws_only_for" , OFS(disablecrccws_only_for) , chk_ftab_fn), #ifdef CS_CACHEEX_AIO DEF_OPT_INT8("cacheex_srcname_webif" , OFS(cacheex_srcname_webif) , 0), #endif DEF_LAST_OPT }; #ifdef CS_ANTICASC static void anticasc_fixups_fn(void *UNUSED(var)) { if(cfg.ac_users < 0) { cfg.ac_users = 0; } if(cfg.ac_stime < 0) { cfg.ac_stime = 2; } if(cfg.ac_samples < 2 || cfg.ac_samples > 10) { cfg.ac_samples = 10; } if(cfg.ac_penalty < 0 || cfg.ac_penalty > 3) { cfg.ac_penalty = 0; } if(cfg.ac_fakedelay < 100 || cfg.ac_fakedelay > 3000) { cfg.ac_fakedelay = 1000; } if(cfg.ac_denysamples < 2 || cfg.ac_denysamples > cfg.ac_samples - 1) { cfg.ac_denysamples = cfg.ac_samples - 1; } if(cfg.ac_denysamples + 1 > cfg.ac_samples) { cfg.ac_denysamples = cfg.ac_samples - 1; } if(cfg.acosc_max_ecms_per_minute < 0) { cfg.acosc_max_ecms_per_minute = 0; } if(cfg.acosc_penalty == 4) { cfg.acosc_max_active_sids = 0; // set default cfg.acosc_zap_limit = 0; // set default //cfg.acosc_penalty_duration = 0; // set default if(cfg.acosc_max_ecms_per_minute != 0) { if(cfg.acosc_max_ecms_per_minute < 6) { cfg.acosc_max_ecms_per_minute = 6; } if(cfg.acosc_max_ecms_per_minute > 20) { cfg.acosc_max_ecms_per_minute = 20; } cfg.acosc_penalty_duration = (60 / cfg.acosc_max_ecms_per_minute); } } if(cfg.acosc_max_active_sids < 0) { cfg.acosc_max_active_sids = 0; } if(cfg.acosc_zap_limit < 0) { cfg.acosc_zap_limit = 0; } if(cfg.acosc_penalty < 0 || cfg.acosc_penalty > 4) { cfg.acosc_penalty = 0; } if(cfg.acosc_penalty_duration < 0) { cfg.acosc_penalty_duration = 0; } if(cfg.acosc_delay < 0 || cfg.acosc_delay > 4000) { cfg.acosc_delay = 0; } } static bool anticasc_should_save_fn(void *UNUSED(var)) { return cfg.ac_enabled || cfg.acosc_enabled; } static const struct config_list anticasc_opts[] = { DEF_OPT_SAVE_FUNC(anticasc_should_save_fn), DEF_OPT_FIXUP_FUNC(anticasc_fixups_fn), DEF_OPT_INT8("enabled" , OFS(ac_enabled) , 0), DEF_OPT_INT32("numusers" , OFS(ac_users) , 0), DEF_OPT_INT32("sampletime" , OFS(ac_stime) , 2), DEF_OPT_INT32("samples" , OFS(ac_samples) , 10), DEF_OPT_INT8("penalty" , OFS(ac_penalty) , 0), DEF_OPT_STR("aclogfile" , OFS(ac_logfile) , NULL), DEF_OPT_INT32("fakedelay" , OFS(ac_fakedelay) , 3000), DEF_OPT_INT32("denysamples" , OFS(ac_denysamples) , 8), DEF_OPT_INT8("acosc_enabled" , OFS(acosc_enabled) , 0 ), DEF_OPT_INT8("acosc_max_ecms_per_minute" , OFS(acosc_max_ecms_per_minute), 0 ), DEF_OPT_INT8("acosc_max_active_sids" , OFS(acosc_max_active_sids) , 0 ), DEF_OPT_INT8("acosc_zap_limit" , OFS(acosc_zap_limit) , 0 ), DEF_OPT_INT8("acosc_penalty" , OFS(acosc_penalty) , 0 ), DEF_OPT_INT32("acosc_penalty_duration" , OFS(acosc_penalty_duration), 0 ), DEF_OPT_INT32("acosc_delay" , OFS(acosc_delay) , 0 ), DEF_LAST_OPT }; #else static const struct config_list anticasc_opts[] = { DEF_LAST_OPT }; #endif #ifdef MODULE_MONITOR static bool monitor_should_save_fn(void *UNUSED(var)) { return cfg.mon_port; } static const struct config_list monitor_opts[] = { DEF_OPT_SAVE_FUNC(monitor_should_save_fn), DEF_OPT_INT32("port" , OFS(mon_port) , 0), DEF_OPT_FUNC("serverip" , OFS(mon_srvip) , serverip_fn), DEF_OPT_FUNC("nocrypt" , OFS(mon_allowed) , iprange_fn, .free_value = iprange_free_fn), DEF_OPT_INT32("aulow" , OFS(aulow) , 30), DEF_OPT_UINT8("monlevel" , OFS(mon_level) , 2), DEF_OPT_INT32("hideclient_to" , OFS(hideclient_to), 25), DEF_LAST_OPT }; #else static const struct config_list monitor_opts[] = { DEF_LAST_OPT }; #endif #ifdef WEBIF static void http_port_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { if(value) { cfg.http_port = 0; if(value[0]) { if(value[0] == '+') { if(config_enabled(WITH_SSL)) { cfg.http_use_ssl = 1; } else { fprintf(stderr, "Warning: OSCam compiled without SSL support.\n"); } cfg.http_port = strtoul(value + 1, NULL, 10); } else { cfg.http_port = strtoul(value, NULL, 10); } } return; } fprintf_conf(f, token, "%s%d\n", cfg.http_use_ssl ? "+" : "", cfg.http_port); } static void http_dyndns_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { int i; if(value) { char *ptr, *saveptr1 = NULL; memset(cfg.http_dyndns, 0, sizeof(cfg.http_dyndns)); for(i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < MAX_HTTP_DYNDNS) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++) { trim(ptr); cs_strncpy((char *)cfg.http_dyndns[i], ptr, sizeof(cfg.http_dyndns[i])); } return; } if(cs_strlen((const char *)(cfg.http_dyndns[0])) > 0 || cfg.http_full_cfg) { fprintf_conf(f, token, "%s", ""); // it should not have \n at the end for(i = 0; i < MAX_HTTP_DYNDNS; i++) { if(cfg.http_dyndns[i][0]) { fprintf(f, "%s%s", i > 0 ? "," : "", cfg.http_dyndns[i]); } } fprintf(f, "\n"); } } static bool webif_should_save_fn(void *UNUSED(var)) { return cfg.http_port; } static const struct config_list webif_opts[] = { DEF_OPT_SAVE_FUNC(webif_should_save_fn), DEF_OPT_FUNC("httpport" , OFS(http_port) , http_port_fn), DEF_OPT_FUNC("serverip" , OFS(http_srvip) , serverip_fn), DEF_OPT_STR("httpuser" , OFS(http_user) , NULL), DEF_OPT_STR("httppwd" , OFS(http_pwd) , NULL), DEF_OPT_STR("httpcss" , OFS(http_css) , NULL), DEF_OPT_STR("httpjscript" , OFS(http_jscript) , NULL), DEF_OPT_STR("httpscript" , OFS(http_script) , NULL), DEF_OPT_STR("httptpl" , OFS(http_tpl) , NULL), DEF_OPT_STR("httppiconpath" , OFS(http_piconpath) , NULL), DEF_OPT_STR("httphelplang" , OFS(http_help_lang) , "en"), DEF_OPT_STR("httplocale" , OFS(http_locale) , NULL), DEF_OPT_INT8("http_prepend_embedded_css", OFS(http_prepend_embedded_css), 0), DEF_OPT_INT32("httprefresh" , OFS(http_refresh) , 0), DEF_OPT_INT32("httppollrefresh" , OFS(poll_refresh) , 60), DEF_OPT_INT8("httphideidleclients" , OFS(http_hide_idle_clients) , 1), DEF_OPT_STR("httphidetype" , OFS(http_hide_type) , NULL), DEF_OPT_INT8("httpshowpicons" , OFS(http_showpicons) , 0), DEF_OPT_INT8("httppiconsize" , OFS(http_picon_size) , 0), DEF_OPT_INT8("httpshowmeminfo" , OFS(http_showmeminfo) , 0), DEF_OPT_INT8("httpshowuserinfo" , OFS(http_showuserinfo) , 0), DEF_OPT_INT8("httpshowreaderinfo" , OFS(http_showreaderinfo) , 0), DEF_OPT_INT8("httpshowcacheexinfo" , OFS(http_showcacheexinfo) , 0), DEF_OPT_INT8("httpshowecminfo" , OFS(http_showecminfo) , 0), DEF_OPT_INT8("httpshowloadinfo" , OFS(http_showloadinfo) , 0), DEF_OPT_FUNC("httpallowed" , OFS(http_allowed) , iprange_fn, .free_value = iprange_free_fn), DEF_OPT_INT8("httpreadonly" , OFS(http_readonly) , 0), DEF_OPT_INT8("httpsavefullcfg" , OFS(http_full_cfg) , 0), DEF_OPT_INT8("httpoverwritebakfile" , OFS(http_overwrite_bak_file) , 0), DEF_OPT_STR("httpcert" , OFS(http_cert) , NULL), DEF_OPT_INT8("https_force_secure_mode" , OFS(https_force_secure_mode) , 1), DEF_OPT_INT8("https_auto_create_cert" , OFS(https_auto_create_cert) , 1), DEF_OPT_FUNC("httpdyndns" , OFS(http_dyndns) , http_dyndns_fn), DEF_OPT_INT32("aulow" , OFS(aulow) , 30), DEF_OPT_INT32("hideclient_to" , OFS(hideclient_to) , 25), DEF_OPT_STR("httposcamlabel" , OFS(http_oscam_label) , "OSCam"), DEF_OPT_INT32("httpemmuclean" , OFS(http_emmu_clean) , 256), DEF_OPT_INT32("httpemmsclean" , OFS(http_emms_clean) , -1), DEF_OPT_INT32("httpemmgclean" , OFS(http_emmg_clean) , -1), #ifdef WEBIF_LIVELOG DEF_OPT_INT8("http_status_log" , OFS(http_status_log) , 0), #else DEF_OPT_INT8("http_status_log" , OFS(http_status_log) , 1), #endif #ifndef WEBIF_JQUERY DEF_OPT_STR("http_extern_jquery" , OFS(http_extern_jquery) , "//code.jquery.com/jquery-3.7.1.min.js"), #endif DEF_LAST_OPT }; #else static const struct config_list webif_opts[] = { DEF_LAST_OPT }; #endif #ifdef MODULE_CAMD33 static bool camd33_should_save_fn(void *UNUSED(var)) { return cfg.c33_port; } static const struct config_list camd33_opts[] = { DEF_OPT_SAVE_FUNC(camd33_should_save_fn), DEF_OPT_INT32("port" , OFS(c33_port) , 0), DEF_OPT_FUNC("serverip", OFS(c33_srvip) , serverip_fn), DEF_OPT_FUNC("nocrypt" , OFS(c33_plain) , iprange_fn, .free_value = iprange_free_fn), DEF_OPT_INT32("passive", OFS(c33_passive), 0), DEF_OPT_HEX("key" , OFS(c33_key) , SIZEOF(c33_key)), DEF_LAST_OPT }; #else static const struct config_list camd33_opts[] = { DEF_LAST_OPT }; #endif void cache_fixups_fn(void *UNUSED(var)) { if(cfg.max_cache_time < ((int32_t)(cfg.ctimeout + 500) / 1000 + 3)) { cfg.max_cache_time = ((cfg.ctimeout + 500) / 1000 + 3); } #ifdef CW_CYCLE_CHECK if(cfg.maxcyclelist > 4000) { cfg.maxcyclelist = 4000; } if(cfg.keepcycletime > 240) { cfg.keepcycletime = 240; } if(cfg.cwcycle_sensitive > 4) { cfg.cwcycle_sensitive = 4; } if(cfg.cwcycle_sensitive == 1) { cfg.cwcycle_sensitive = 2; } #endif #ifdef CS_CACHEEX_AIO // lgo-ctab -> lgo-ftab port caidtab2ftab_add(&cfg.cacheex_localgenerated_only_in_caidtab, &cfg.cacheex_lg_only_in_tab); caidtab_clear(&cfg.cacheex_localgenerated_only_in_caidtab); caidtab2ftab_add(&cfg.cacheex_localgenerated_only_caidtab, &cfg.cacheex_lg_only_tab); caidtab_clear(&cfg.cacheex_localgenerated_only_caidtab); #endif } static bool cache_should_save_fn(void *UNUSED(var)) { return cfg.delay > CS_DELAY || cfg.max_cache_time != DEFAULT_MAX_CACHE_TIME #ifdef CS_CACHEEX #ifdef CS_CACHEEX_AIO || cfg.cw_cache_size > 0 || cfg.cw_cache_memory > 0 || cfg.cw_cache_settings.cwchecknum || cfg.ecm_cache_size > 0 || cfg.ecm_cache_memory > 0 || cfg.ecm_cache_droptime > 0 || cfg.cacheex_dropdiffs > 0 || cfg.cacheex_push_lg_groups || cfg.cacheex_lg_only_remote_settings != 1 || cfg.cacheex_localgenerated_only > 0 || cfg.cacheex_localgenerated_only_caidtab.ctnum || cfg.cacheex_lg_only_tab.nfilts || cfg.cacheex_lg_only_in_aio_only > 0 || cfg.cacheex_localgenerated_only_in > 0 || cfg.cacheex_localgenerated_only_in_caidtab.ctnum || cfg.cacheex_lg_only_in_tab.nfilts || cfg.cacheex_filter_caidtab.cevnum || cfg.cacheex_filter_caidtab_aio.cevnum || cfg.cacheex_nopushafter_tab.cvnum || cfg.waittime_block_start > 0 || cfg.waittime_block_time > 0 #endif || cfg.max_hitcache_time != DEFAULT_MAX_HITCACHE_TIME || cfg.cacheex_wait_timetab.cevnum || cfg.cacheex_mode1_delay_tab.cvnum || cfg.cacheex_enable_stats > 0 || cfg.csp_port > 0 || IP_ISSET(cfg.csp_srvip) || cfg.csp.filter_caidtab.cevnum || cfg.csp.allow_request != 1 || cfg.csp.allow_reforward > 0 || cfg.cacheex_cwcheck_tab.cwchecknum || cfg.wait_until_ctimeout > 0 || cfg.csp.block_fakecws > 0 #endif #ifdef CW_CYCLE_CHECK || cfg.cwcycle_check_enable || cfg.cwcycle_check_caidtab.ctnum || cfg.maxcyclelist != 500 || cfg.keepcycletime != 15 || cfg.onbadcycle != 1 || cfg.cwcycle_dropold != 1 || cfg.cwcycle_sensitive != 4 || cfg.cwcycle_allowbadfromffb > 0 || cfg.cwcycle_usecwcfromce > 0 #endif ; } static const struct config_list cache_opts[] = { DEF_OPT_SAVE_FUNC(cache_should_save_fn), DEF_OPT_FIXUP_FUNC(cache_fixups_fn), DEF_OPT_UINT32("delay" , OFS(delay) , CS_DELAY), DEF_OPT_INT32("max_time" , OFS(max_cache_time) , DEFAULT_MAX_CACHE_TIME), #ifdef CS_CACHEEX #ifdef CS_CACHEEX_AIO DEF_OPT_UINT32("cw_cache_size" , OFS(cw_cache_size) , 0), DEF_OPT_UINT32("cw_cache_memory" , OFS(cw_cache_memory) , 0), DEF_OPT_FUNC("cw_cache_settings" , OFS(cw_cache_settings) , cacheex_cwcheck_tab_fn), DEF_OPT_UINT32("ecm_cache_size" , OFS(ecm_cache_size) , 0), DEF_OPT_UINT32("ecm_cache_memory" , OFS(ecm_cache_memory) , 0), DEF_OPT_INT32("ecm_cache_droptime" , OFS(ecm_cache_droptime) , 0), #endif DEF_OPT_INT32("max_hit_time" , OFS(max_hitcache_time) , DEFAULT_MAX_HITCACHE_TIME), DEF_OPT_FUNC("wait_time" , OFS(cacheex_wait_timetab) , cacheex_valuetab_fn), DEF_OPT_FUNC("cacheex_mode1_delay" , OFS(cacheex_mode1_delay_tab) , caidvaluetab_fn), DEF_OPT_UINT8("cacheexenablestats" , OFS(cacheex_enable_stats) , 0), #ifdef CS_CACHEEX_AIO DEF_OPT_UINT8("cacheex_dropdiffs" , OFS(cacheex_dropdiffs) , 0), DEF_OPT_FUNC("cacheex_push_lg_groups" , OFS(cacheex_push_lg_groups) , group_fn), DEF_OPT_UINT8("cacheex_lg_only_remote_settings" , OFS(cacheex_lg_only_remote_settings) , 1), DEF_OPT_UINT8("cacheex_localgenerated_only" , OFS(cacheex_localgenerated_only) , 0), DEF_OPT_FUNC("cacheex_localgenerated_only_caid" , OFS(cacheex_localgenerated_only_caidtab) , check_caidtab_fn), DEF_OPT_FUNC_X("cacheex_lg_only_tab" , OFS(cacheex_lg_only_tab) , ftab_fn, FTAB_ACCOUNT), DEF_OPT_UINT8("cacheex_lg_only_in_aio_only" , OFS(cacheex_lg_only_in_aio_only) , 0), DEF_OPT_UINT8("cacheex_localgenerated_only_in" , OFS(cacheex_localgenerated_only_in) , 0), DEF_OPT_FUNC("cacheex_localgenerated_only_in_caid", OFS(cacheex_localgenerated_only_in_caidtab), check_caidtab_fn), DEF_OPT_FUNC_X("cacheex_lg_only_in_tab" , OFS(cacheex_lg_only_in_tab) , ftab_fn, FTAB_ACCOUNT), DEF_OPT_FUNC("cacheex_ecm_filter" , OFS(cacheex_filter_caidtab) , cacheex_hitvaluetab_fn), DEF_OPT_FUNC("cacheex_ecm_filter_aio" , OFS(cacheex_filter_caidtab_aio) , cacheex_hitvaluetab_fn), #endif DEF_OPT_INT32("csp_port" , OFS(csp_port) , 0), DEF_OPT_FUNC("csp_serverip" , OFS(csp_srvip) , serverip_fn), DEF_OPT_FUNC("csp_ecm_filter" , OFS(csp.filter_caidtab) , cacheex_hitvaluetab_fn), DEF_OPT_UINT8("csp_allow_request" , OFS(csp.allow_request) , 1), DEF_OPT_UINT8("csp_allow_reforward" , OFS(csp.allow_reforward) , 0), DEF_OPT_FUNC("cacheex_cw_check" , OFS(cacheex_cwcheck_tab) , cacheex_cwcheck_tab_fn), DEF_OPT_UINT8("wait_until_ctimeout" , OFS(wait_until_ctimeout) , 0), DEF_OPT_UINT8("csp_block_fakecws" , OFS(csp.block_fakecws) , 0), #ifdef CS_CACHEEX_AIO DEF_OPT_FUNC("cacheex_nopushafter" , OFS(cacheex_nopushafter_tab) , caidvaluetab_fn), DEF_OPT_UINT8("waittime_block_start" , OFS(waittime_block_start) , 0), DEF_OPT_INT32("waittime_block_time" , OFS(waittime_block_time) , 0), #endif #endif #ifdef CW_CYCLE_CHECK DEF_OPT_INT8("cwcycle_check_enable" , OFS(cwcycle_check_enable) , 0), DEF_OPT_FUNC("cwcycle_check_caid" , OFS(cwcycle_check_caidtab) , check_caidtab_fn), DEF_OPT_INT32("cwcycle_maxlist" , OFS(maxcyclelist) , 500), DEF_OPT_INT32("cwcycle_keeptime" , OFS(keepcycletime) , 15), DEF_OPT_INT8("cwcycle_onbad" , OFS(onbadcycle) , 1), DEF_OPT_INT8("cwcycle_dropold" , OFS(cwcycle_dropold) , 1), DEF_OPT_INT8("cwcycle_sensitive" , OFS(cwcycle_sensitive) , 4), DEF_OPT_INT8("cwcycle_allowbadfromffb" , OFS(cwcycle_allowbadfromffb) , 0), DEF_OPT_INT8("cwcycle_usecwcfromce" , OFS(cwcycle_usecwcfromce) , 0), #endif DEF_LAST_OPT }; #ifdef MODULE_CAMD35 static bool camd35_should_save_fn(void *UNUSED(var)) { return cfg.c35_port; } static const struct config_list camd35_opts[] = { DEF_OPT_SAVE_FUNC(camd35_should_save_fn), DEF_OPT_INT32("port" , OFS(c35_port) , 0), DEF_OPT_FUNC("serverip" , OFS(c35_srvip) , serverip_fn), DEF_OPT_INT8("suppresscmd08", OFS(c35_udp_suppresscmd08), 0), DEF_LAST_OPT }; #else static const struct config_list camd35_opts[] = { DEF_LAST_OPT }; #endif #ifdef MODULE_NEWCAMD static void porttab_fn(const char *token, char *value, void *setting, FILE *f) { PTAB *ptab = setting; if(value) { if(cs_strlen(value) == 0) { clear_ptab(ptab); } else { chk_port_tab(value, ptab); } return; } value = mk_t_newcamd_port(); fprintf_conf(f, token, "%s\n", value); free_mk_t(value); } #endif #ifdef MODULE_CAMD35_TCP static void porttab_camd35_fn(const char *token, char *value, void *setting, FILE *f) { PTAB *ptab = setting; if(value) { if(cs_strlen(value) == 0) { clear_ptab(ptab); } else { chk_port_camd35_tab(value, ptab); } return; } value = mk_t_camd35tcp_port(); fprintf_conf(f, token, "%s\n", value); free_mk_t(value); } #endif #if defined(MODULE_NEWCAMD) || defined(MODULE_CAMD35_TCP) static void porttab_free_fn(void *setting) { clear_ptab(setting); } #endif #ifdef MODULE_CAMD35_TCP static bool cs378x_should_save_fn(void *UNUSED(var)) { return cfg.c35_tcp_ptab.nports && cfg.c35_tcp_ptab.ports[0].s_port; } static const struct config_list cs378x_opts[] = { DEF_OPT_SAVE_FUNC(cs378x_should_save_fn), DEF_OPT_FUNC("port" , OFS(c35_tcp_ptab) , porttab_camd35_fn, .free_value = porttab_free_fn), DEF_OPT_FUNC("serverip" , OFS(c35_tcp_srvip) , serverip_fn), DEF_OPT_INT8("suppresscmd08", OFS(c35_tcp_suppresscmd08), 0), DEF_LAST_OPT }; #else static const struct config_list cs378x_opts[] = { DEF_LAST_OPT }; #endif #ifdef MODULE_NEWCAMD static bool newcamd_should_save_fn(void *UNUSED(var)) { return cfg.ncd_ptab.nports && cfg.ncd_ptab.ports[0].s_port; } static const struct config_list newcamd_opts[] = { DEF_OPT_SAVE_FUNC(newcamd_should_save_fn), DEF_OPT_FUNC("port" , OFS(ncd_ptab) , porttab_fn, .free_value = porttab_free_fn), DEF_OPT_FUNC("serverip" , OFS(ncd_srvip) , serverip_fn), DEF_OPT_FUNC("allowed" , OFS(ncd_allowed) , iprange_fn, .free_value = iprange_free_fn), DEF_OPT_HEX("key" , OFS(ncd_key) , SIZEOF(ncd_key)), DEF_OPT_INT8("keepalive" , OFS(ncd_keepalive), DEFAULT_NCD_KEEPALIVE), DEF_OPT_INT8("mgclient" , OFS(ncd_mgclient) , 0), DEF_LAST_OPT }; #else static const struct config_list newcamd_opts[] = { DEF_LAST_OPT }; #endif #ifdef MODULE_CCCAM static void cccam_port_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { if(value) { int i; char *ptr, *saveptr1 = NULL; memset(cfg.cc_port, 0, sizeof(cfg.cc_port)); for(i = 0, ptr = strtok_r(value, ",", &saveptr1); ptr && i < CS_MAXPORTS; ptr = strtok_r(NULL, ",", &saveptr1)) { cfg.cc_port[i] = strtoul(ptr, NULL, 10); if(cfg.cc_port[i]) { i++; } } return; } value = mk_t_cccam_port(); fprintf_conf(f, token, "%s\n", value); free_mk_t(value); } static bool cccam_should_save_fn(void *UNUSED(var)) { return cfg.cc_port[0]; } static const struct config_list cccam_opts[] = { DEF_OPT_SAVE_FUNC(cccam_should_save_fn), DEF_OPT_FUNC("port" , OFS(cc_port) , cccam_port_fn), DEF_OPT_FUNC("serverip" , OFS(cc_srvip) , serverip_fn), DEF_OPT_HEX("nodeid" , OFS(cc_fixed_nodeid) , SIZEOF(cc_fixed_nodeid)), DEF_OPT_SSTR("version" , OFS(cc_version) , "", SIZEOF(cc_version)), DEF_OPT_INT8("reshare" , OFS(cc_reshare) , 10), DEF_OPT_INT8("reshare_mode" , OFS(cc_reshare_services) , 4), DEF_OPT_INT8("ignorereshare" , OFS(cc_ignore_reshare) , 0), DEF_OPT_INT8("forward_origin_card", OFS(cc_forward_origin_card), 0), DEF_OPT_INT8("stealth" , OFS(cc_stealth) , 0), DEF_OPT_INT32("updateinterval" , OFS(cc_update_interval) , DEFAULT_UPDATEINTERVAL), DEF_OPT_INT8("minimizecards" , OFS(cc_minimize_cards) , 0), DEF_OPT_INT8("keepconnected" , OFS(cc_keep_connected) , 1), DEF_OPT_UINT32("recv_timeout" , OFS(cc_recv_timeout) , DEFAULT_CC_RECV_TIMEOUT), DEF_LAST_OPT }; #else static const struct config_list cccam_opts[] = { DEF_LAST_OPT }; #endif #ifdef MODULE_PANDORA static bool pandora_should_save_fn(void *UNUSED(var)) { return cfg.pand_port; } static const struct config_list pandora_opts[] = { DEF_OPT_SAVE_FUNC(pandora_should_save_fn), DEF_OPT_INT32("pand_port" , OFS(pand_port) , 0), DEF_OPT_FUNC("pand_srvid" , OFS(pand_srvip) , serverip_fn), DEF_OPT_STR("pand_usr" , OFS(pand_usr) , NULL), DEF_OPT_STR("pand_pass" , OFS(pand_pass) , NULL), DEF_OPT_INT8("pand_ecm" , OFS(pand_ecm) , 0), DEF_OPT_INT8("pand_skip_send_dw", OFS(pand_skip_send_dw), 0), DEF_OPT_FUNC("pand_allowed" , OFS(pand_allowed) , iprange_fn, .free_value = iprange_free_fn), DEF_LAST_OPT }; #else static const struct config_list pandora_opts[] = { DEF_LAST_OPT }; #endif #ifdef MODULE_SCAM static bool scam_should_save_fn(void *UNUSED(var)) { return cfg.scam_port; } static const struct config_list scam_opts[] = { DEF_OPT_SAVE_FUNC(scam_should_save_fn), DEF_OPT_INT32("port" , OFS(scam_port) , 0), DEF_OPT_FUNC("serverip" , OFS(scam_srvip) , serverip_fn), DEF_OPT_FUNC("allowed" , OFS(scam_allowed), iprange_fn, .free_value = iprange_free_fn), DEF_LAST_OPT }; #else static const struct config_list scam_opts[] = { DEF_LAST_OPT }; #endif #ifdef MODULE_STREAMRELAY static bool streamrelay_should_save_fn(void *UNUSED(var)) { return cfg.stream_relay_enabled; } static const struct config_list streamrelay_opts[] = { DEF_OPT_SAVE_FUNC(streamrelay_should_save_fn), DEF_OPT_INT8("stream_relay_enabled" , OFS(stream_relay_enabled), 0), DEF_OPT_INT32("stream_relay_port" , OFS(stream_relay_port), 17999), DEF_OPT_STR("stream_relay_user" , OFS(stream_relay_user), NULL), DEF_OPT_FUNC("stream_relay_ctab" , OFS(stream_relay_ctab), check_caidtab_fn), DEF_OPT_STR("stream_source_host" , OFS(stream_source_host), "127.0.0.1"), DEF_OPT_INT8("stream_client_source_host" , OFS(stream_client_source_host), 1), DEF_OPT_INT32("stream_source_port" , OFS(stream_source_port), DEFAULT_STREAM_SOURCE_PORT), DEF_OPT_STR("stream_source_auth_user" , OFS(stream_source_auth_user), NULL), DEF_OPT_STR("stream_source_auth_password" , OFS(stream_source_auth_password), NULL), DEF_OPT_UINT32("stream_relay_buffer_time" , OFS(stream_relay_buffer_time), 0), DEF_OPT_UINT8("stream_relay_reconnect_count" , OFS(stream_relay_reconnect_count), 0), DEF_OPT_INT8("stream_display_client" , OFS(stream_display_client), 0), DEF_OPT_INT8("stream_reuse_client" , OFS(stream_reuse_client), 0), #ifdef WEBIF DEF_OPT_INT8("stream_hide_client" , OFS(stream_hide_client), 0), #endif DEF_LAST_OPT }; #else static const struct config_list streamrelay_opts[] = { DEF_LAST_OPT }; #endif #ifdef MODULE_RADEGAST static bool radegast_should_save_fn(void *UNUSED(var)) { return cfg.rad_port; } static const struct config_list radegast_opts[] = { DEF_OPT_SAVE_FUNC(radegast_should_save_fn), DEF_OPT_INT32("port" , OFS(rad_port) , 0), DEF_OPT_FUNC("serverip", OFS(rad_srvip) , serverip_fn), DEF_OPT_FUNC("allowed" , OFS(rad_allowed), iprange_fn, .free_value = iprange_free_fn), DEF_OPT_STR("user" , OFS(rad_usr) , NULL), DEF_LAST_OPT }; #else static const struct config_list radegast_opts[] = { DEF_LAST_OPT }; #endif #ifdef MODULE_SERIAL static bool serial_should_save_fn(void *UNUSED(var)) { return cfg.ser_device != NULL; } static const struct config_list serial_opts[] = { DEF_OPT_SAVE_FUNC(serial_should_save_fn), DEF_OPT_STR("device", OFS(ser_device), NULL), DEF_LAST_OPT }; #else static const struct config_list serial_opts[] = { DEF_LAST_OPT }; #endif #ifdef MODULE_GBOX static void gbox_password_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { if (value) { const char *s; s = value; if (s[strspn(s, "0123456789abcdefABCDEF")] == 0) { /* valid Hexa symbol */ cfg.gbox_password = a2i(value, 8); return; } else { cfg.gbox_password = 0; } } if (cfg.gbox_password != 0) { fprintf_conf(f, token, "%08X\n", cfg.gbox_password); } } static void gbox_block_ecm_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { if (value) { char *ptr1, *saveptr1 = NULL; const char *s; memset(cfg.gbox_block_ecm, 0, sizeof(cfg.gbox_block_ecm)); int n = 0, i; for (i = 0, ptr1 = strtok_r(value, ",", &saveptr1); (i < 4) && (ptr1); ptr1 = strtok_r(NULL, ",", &saveptr1)) { s=ptr1; if ((n < GBOX_MAX_BLOCKED_ECM) && (s[strspn(s, "0123456789abcdefABCDEF")] == 0)) { cfg.gbox_block_ecm[n++] = a2i(ptr1, 4); } } cfg.gbox_block_ecm_num = n; return; } if (cfg.gbox_block_ecm_num > 0) { value = mk_t_gbox_block_ecm(); fprintf_conf(f, token, "%s\n", value); free_mk_t(value); } } static void accept_remm_peer_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { if (value) { char *ptr1, *saveptr1 = NULL; const char *s; memset(cfg.accept_remm_peer, 0, sizeof(cfg.accept_remm_peer)); int n = 0, i; for (i = 0, ptr1 = strtok_r(value, ",", &saveptr1); (i < 4) && (ptr1); ptr1 = strtok_r(NULL, ",", &saveptr1)) { s=ptr1; if ((n < GBOX_MAX_REMM_PEERS) && (s[strspn(s, "0123456789abcdefABCDEF")] == 0)) { cfg.accept_remm_peer[n++] = a2i(ptr1, 4); } } cfg.accept_remm_peer_num = n; return; } if (cfg.accept_remm_peer_num > 0) { value = mk_t_accept_remm_peer(); fprintf_conf(f, token, "%s\n", value); free_mk_t(value); } } static void gbox_ignored_peer_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { if (value) { char *ptr1, *saveptr1 = NULL; const char *s; memset(cfg.gbox_ignored_peer, 0, sizeof(cfg.gbox_ignored_peer)); int n = 0, i; for (i = 0, ptr1 = strtok_r(value, ",", &saveptr1); (i < 4) && (ptr1); ptr1 = strtok_r(NULL, ",", &saveptr1)) { s = ptr1; if ((n < GBOX_MAX_IGNORED_PEERS) && (s[strspn(s, "0123456789abcdefABCDEF")] == 0)) { cfg.gbox_ignored_peer[n++] = a2i(ptr1, 4); } } cfg.gbox_ignored_peer_num = n; return; } if (cfg.gbox_ignored_peer_num > 0) { value = mk_t_gbox_ignored_peer(); fprintf_conf(f, token, "%s\n", value); free_mk_t(value); } } static void gbox_proxy_card_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { if (value) { char *ptr1, *saveptr1 = NULL; const char *s; memset(cfg.gbox_proxy_card, 0, sizeof(cfg.gbox_proxy_card)); int n = 0, i; for (i = 0, ptr1 = strtok_r(value, ",", &saveptr1); (i < 8) && (ptr1); ptr1 = strtok_r(NULL, ",", &saveptr1)) { s = ptr1; if ((n < GBOX_MAX_PROXY_CARDS) && (s[strspn(s, "0123456789abcdefABCDEF")] == 0)) { cfg.gbox_proxy_card[n++] = a2i(ptr1, 8); } } cfg.gbox_proxy_cards_num = n; return; } if (cfg.gbox_proxy_cards_num > 0) { value = mk_t_gbox_proxy_card(); fprintf_conf(f, token, "%s\n", value); free_mk_t(value); } } static void gbox_port_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { if(value) { int i; char *ptr, *saveptr1 = NULL; memset(cfg.gbox_port, 0, sizeof(cfg.gbox_port)); for(i = 0, ptr = strtok_r(value, ",", &saveptr1); ptr && i < CS_MAXPORTS; ptr = strtok_r(NULL, ",", &saveptr1)) { cfg.gbox_port[i] = strtoul(ptr, NULL, 10); if(cfg.gbox_port[i]) { i++; } } return; } value = mk_t_gbox_port(); fprintf_conf(f, token, "%s\n", value); free_mk_t(value); } static void gbox_my_vers_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { if(value) { const char *s; s = value; int32_t len = cs_strlen(value); if ((s[strspn(s, "0123456789abcdefABCDEF")] != 0) || (len == 0) || (len > 2)) { cfg.gbox_my_vers = GBOX_MY_VERS_DEF; } else { cfg.gbox_my_vers = a2i(value, 1); return; } } if(cfg.gbox_my_vers != GBOX_MY_VERS_DEF) { fprintf_conf(f, token, "%02X\n", cfg.gbox_my_vers); } else if(cfg.http_full_cfg) { fprintf_conf(f, token, "%02X\n", GBOX_MY_VERS_DEF); } } static void gbox_my_cpu_api_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { if(value) { const char *s; s = value; int32_t len = cs_strlen(value); if ((s[strspn(s, "0123456789abcdefABCDEF")] != 0) || (len == 0) || (len > 2)) { cfg.gbox_my_cpu_api = GBOX_MY_CPU_API_DEF; } else { cfg.gbox_my_cpu_api = a2i(value,1); return; } } if(cfg.gbox_my_cpu_api != GBOX_MY_CPU_API_DEF) { fprintf_conf(f, token, "%02X\n", cfg.gbox_my_cpu_api); } else if(cfg.http_full_cfg) { fprintf_conf(f, token, "%02X\n", GBOX_MY_CPU_API_DEF); } } static void gbox_dest_peers_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { if (value) { char *ptr1, *saveptr1 = NULL; const char *s; memset(cfg.gbox_dest_peers, 0, sizeof(cfg.gbox_dest_peers)); int n = 0; for (ptr1 = strtok_r(value, ",", &saveptr1); (ptr1); ptr1 = strtok_r(NULL, ",", &saveptr1)) { s = trim(ptr1); if ((n < GBOX_MAX_DEST_PEERS) && (s[strspn(s, "0123456789abcdefABCDEF")] == 0)) { cfg.gbox_dest_peers[n++] = a2i(trim(ptr1), cs_strlen(trim(ptr1))); } } cfg.gbox_dest_peers_num = n; return; } if ((cfg.gbox_dest_peers_num > 0) && cfg.gbox_save_gsms) { value = mk_t_gbox_dest_peers(); fprintf_conf(f, token, "%s\n", value); free_mk_t(value); } } static void gbox_msg_txt_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { if (value) { cs_strncpy(cfg.gbox_msg_txt, value, sizeof(cfg.gbox_msg_txt)); return; } if ((cfg.gbox_msg_txt[0] != '\0') && cfg.gbox_save_gsms) { fprintf_conf(f, token, "%s\n", cfg.gbox_msg_txt); } } static bool gbox_should_save_fn(void *UNUSED(var)) { return cfg.gbox_port[0]; } static const struct config_list gbox_opts[] = { DEF_OPT_SAVE_FUNC(gbox_should_save_fn), DEF_OPT_FUNC("port" , OFS(gbox_port) , gbox_port_fn), DEF_OPT_STR("hostname" , OFS(gbox_hostname) , NULL), DEF_OPT_FUNC("my_password" , OFS(gbox_password) , gbox_password_fn ), DEF_OPT_UINT32("gbox_reconnect", OFS(gbox_reconnect) , DEFAULT_GBOX_RECONNECT), DEF_OPT_FUNC("my_vers" , OFS(gbox_my_vers) , gbox_my_vers_fn), DEF_OPT_FUNC("my_cpu_api" , OFS(gbox_my_cpu_api) , gbox_my_cpu_api_fn), DEF_OPT_UINT8("gsms_disable" , OFS(gsms_dis) , 1), DEF_OPT_UINT8("dis_attack_txt" , OFS(dis_attack_txt) , 0), DEF_OPT_UINT8("log_hello" , OFS(log_hello) , 1), DEF_OPT_STR("tmp_dir" , OFS(gbox_tmp_dir) , NULL ), DEF_OPT_FUNC("ignore_peer" , OFS(gbox_ignored_peer), gbox_ignored_peer_fn ), DEF_OPT_FUNC("accept_remm_peer", OFS(accept_remm_peer) , accept_remm_peer_fn ), DEF_OPT_FUNC("block_ecm" , OFS(gbox_block_ecm) , gbox_block_ecm_fn ), DEF_OPT_FUNC("proxy_card" , OFS(gbox_proxy_card) , gbox_proxy_card_fn ), DEF_OPT_UINT8("gbox_save_gsms" , OFS(gbox_save_gsms) , 0), DEF_OPT_UINT8("gbox_msg_type" , OFS(gbox_msg_type) , 0), DEF_OPT_FUNC("gbox_dest_peers" , OFS(gbox_dest_peers) , gbox_dest_peers_fn ), DEF_OPT_FUNC("gbox_msg_txt" , OFS(gbox_msg_txt) , gbox_msg_txt_fn ), DEF_OPT_UINT8("ccc_reshare" , OFS(cc_gbx_reshare_en), 0), DEF_LAST_OPT }; #else static const struct config_list gbox_opts[] = { DEF_LAST_OPT }; #endif #ifdef HAVE_DVBAPI extern const char *boxdesc[]; static void dvbapi_boxtype_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { if(value) { int i; cfg.dvbapi_boxtype = 0; for(i = 1; i <= BOXTYPES; i++) { if(streq(value, boxdesc[i])) { cfg.dvbapi_boxtype = i; break; } } return; } if(cfg.dvbapi_boxtype) { fprintf_conf(f, token, "%s\n", boxdesc[cfg.dvbapi_boxtype]); } } static void dvbapi_services_fn(const char *UNUSED(token), char *value, void *UNUSED(setting), FILE *UNUSED(f)) { if(value) { chk_services(value, &cfg.dvbapi_sidtabs); } // THIS OPTION IS NOT SAVED } static bool dvbapi_should_save_fn(void *UNUSED(var)) { return cfg.dvbapi_enabled; } static const struct config_list dvbapi_opts[] = { DEF_OPT_SAVE_FUNC(dvbapi_should_save_fn), DEF_OPT_INT8("enabled" , OFS(dvbapi_enabled) , 0), DEF_OPT_INT8("au" , OFS(dvbapi_au) , 0), DEF_OPT_INT8("pmt_mode" , OFS(dvbapi_pmtmode) , 0), DEF_OPT_INT8("request_mode" , OFS(dvbapi_requestmode) , 0), DEF_OPT_INT32("listen_port" , OFS(dvbapi_listenport) , 0), DEF_OPT_FUNC("serverip" , OFS(dvbapi_srvip) , serverip_fn), DEF_OPT_INT32("delayer" , OFS(dvbapi_delayer) , 0), DEF_OPT_INT8("ecminfo_file" , OFS(dvbapi_ecminfo_file) , 1), DEF_OPT_INT8("ecminfo_type" , OFS(dvbapi_ecminfo_type) , 0), DEF_OPT_STR("user" , OFS(dvbapi_usr) , NULL), DEF_OPT_INT8("read_sdt" , OFS(dvbapi_read_sdt) , 0), DEF_OPT_INT8("write_sdt_prov" , OFS(dvbapi_write_sdt_prov) , 0), #ifdef WITH_EXTENDED_CW DEF_OPT_INT8("extended_cw_api", OFS(dvbapi_extended_cw_api), 0), #endif #ifdef MODULE_STREAMRELAY DEF_OPT_INT8("demuxer_fix" , OFS(dvbapi_demuxer_fix) , 0), #endif DEF_OPT_FUNC("boxtype" , OFS(dvbapi_boxtype) , dvbapi_boxtype_fn), DEF_OPT_FUNC("services" , OFS(dvbapi_sidtabs.ok) , dvbapi_services_fn), DEF_LAST_OPT }; #else static const struct config_list dvbapi_opts[] = { DEF_LAST_OPT }; #endif #ifdef LCDSUPPORT static void lcd_fixups_fn(void *UNUSED(var)) { if(cfg.lcd_write_intervall < 5) { cfg.lcd_write_intervall = 5; } } static bool lcd_should_save_fn(void *UNUSED(var)) { return cfg.enablelcd; } static const struct config_list lcd_opts[] = { DEF_OPT_SAVE_FUNC(lcd_should_save_fn), DEF_OPT_FIXUP_FUNC(lcd_fixups_fn), DEF_OPT_INT8("enablelcd" , OFS(enablelcd) , 0), DEF_OPT_STR("lcd_outputpath" , OFS(lcd_output_path) , NULL), DEF_OPT_INT32("lcd_hideidle" , OFS(lcd_hide_idle) , 0), DEF_OPT_INT32("lcd_writeintervall", OFS(lcd_write_intervall), 10), DEF_LAST_OPT }; #else static const struct config_list lcd_opts[] = { DEF_LAST_OPT }; #endif static const struct config_sections oscam_conf[] = { { "global", global_opts }, // *** MUST BE FIRST *** { "anticasc", anticasc_opts }, { "cache", cache_opts }, { "lcd", lcd_opts }, { "camd33", camd33_opts }, { "cs357x", camd35_opts }, { "cs378x", cs378x_opts }, { "newcamd", newcamd_opts }, { "radegast", radegast_opts }, { "serial", serial_opts }, { "gbox", gbox_opts }, { "cccam", cccam_opts }, { "pandora", pandora_opts }, { "scam", scam_opts }, { "streamrelay", streamrelay_opts }, { "dvbapi", dvbapi_opts }, { "monitor", monitor_opts }, { "webif", webif_opts }, { NULL, NULL } }; void config_set(char *section, const char *token, char *value) { config_set_value(oscam_conf, section, token, value, &cfg); } void config_free(void) { config_sections_free(oscam_conf, &cfg); caidvaluetab_clear(&cfg.ftimeouttab); ftab_clear(&cfg.double_check_caid); ftab_clear(&cfg.disablecrccws_only_for); #ifdef WITH_LB caidvaluetab_clear(&cfg.lb_retrylimittab); caidvaluetab_clear(&cfg.lb_nbest_readers_tab); caidtab_clear(&cfg.lb_noproviderforcaid); #endif #ifdef CS_CACHEEX #ifdef CS_CACHEEX_AIO cwcheckvaluetab_clear(&cfg.cw_cache_settings); #endif caidvaluetab_clear(&cfg.cacheex_mode1_delay_tab); #ifdef CS_CACHEEX_AIO caidvaluetab_clear(&cfg.cacheex_nopushafter_tab); caidtab_clear(&cfg.cacheex_localgenerated_only_caidtab); caidtab_clear(&cfg.cacheex_localgenerated_only_in_caidtab); ftab_clear(&cfg.cacheex_lg_only_tab); ftab_clear(&cfg.cacheex_lg_only_in_tab); cecspvaluetab_clear(&cfg.cacheex_filter_caidtab); cecspvaluetab_clear(&cfg.cacheex_filter_caidtab_aio); #endif cecspvaluetab_clear(&cfg.cacheex_wait_timetab); #endif #ifdef CW_CYCLE_CHECK caidtab_clear(&cfg.cwcycle_check_caidtab); #endif } int32_t init_config(void) { FILE *fp; if(config_enabled(WEBIF)) { fp = open_config_file(cs_conf); } else { fp = open_config_file_or_die(cs_conf); } const struct config_sections *cur_section = oscam_conf; // Global char *token; config_sections_set_defaults(oscam_conf, &cfg); if(!fp) { // no oscam.conf but webif is included in build, set it up for lan access and tweak defaults #ifdef WEBIF cfg.http_port = DEFAULT_HTTP_PORT; char *default_allowed; if ((default_allowed = cs_strdup(DEFAULT_HTTP_ALLOW))) { chk_iprange(default_allowed, &cfg.http_allowed); free(default_allowed); } #endif NULLFREE(cfg.logfile); cfg.logtostdout = 1; #ifdef HAVE_DVBAPI cfg.dvbapi_enabled = 1; #endif return 0; } if(!cs_malloc(&token, MAXLINESIZE)) { return 1; } int line = 0; int valid_section = 1; while(fgets(token, MAXLINESIZE, fp)) { ++line; int len = cs_strlen(trim(token)); if(len < 3) // a=b or [a] are at least 3 chars { continue; } if(token[0] == '#') // Skip comments { continue; } if(token[0] == '[' && token[len - 1] == ']') { token[len - 1] = '\0'; valid_section = 0; const struct config_sections *newconf = config_find_section(oscam_conf, token + 1); if(config_section_is_active(newconf) && cur_section) { config_list_apply_fixups(cur_section->config, &cfg); cur_section = newconf; valid_section = 1; } if(!newconf) { fprintf(stderr, "WARNING: %s line %d unknown section [%s].\n", cs_conf, line, token + 1); continue; } if(!config_section_is_active(newconf)) { fprintf(stderr, "WARNING: %s line %d section [%s] is ignored (support not compiled in).\n", cs_conf, line, newconf->section); } continue; } if(!valid_section) { continue; } char *value = strchr(token, '='); if(!value) // No = found, well go on { continue; } *value++ = '\0'; char *tvalue = trim(value); char *ttoken = trim(strtolower(token)); if(cur_section && !config_list_parse(cur_section->config, ttoken, tvalue, &cfg)) { fprintf(stderr, "WARNING: %s line %d section [%s] contains unknown setting '%s=%s'\n", cs_conf, line, cur_section->section, ttoken, tvalue); } } NULLFREE(token); fclose(fp); if(cur_section) { config_list_apply_fixups(cur_section->config, &cfg); } return 0; } int32_t write_config(void) { FILE *f = create_config_file(cs_conf); if(!f) { return 1; } config_sections_save(oscam_conf, f, &cfg); return flush_config_file(f, cs_conf); }