- fix for ticker #4787
[oscam.git] / oscam-config-reader.c
blob79f1a2e7b47bfd398d0716ce2e7ac78d96ebc88f
1 #define MODULE_LOG_PREFIX "config"
3 #include "globals.h"
4 #include "module-stat.h"
5 #include "oscam-aes.h"
6 #include "oscam-array.h"
7 #include "oscam-conf.h"
8 #include "oscam-conf-chk.h"
9 #include "oscam-conf-mk.h"
10 #include "oscam-config.h"
11 #include "oscam-garbage.h"
12 #include "oscam-lock.h"
13 #include "oscam-reader.h"
14 #include "oscam-string.h"
15 #ifdef MODULE_GBOX
16 #include "module-gbox.h"
17 #endif
19 #define cs_srvr "oscam.server"
21 extern const struct s_cardreader *cardreaders[];
22 extern char *RDR_CD_TXT[];
24 static void reader_label_fn(const char *token, char *value, void *setting, FILE *f)
26 struct s_reader *rdr = setting;
27 if(value)
29 int i, found = 0;
30 if(!strlen(value))
31 { return; }
32 for(i = 0; i < (int)strlen(value); i++)
34 if(value[i] == ' ')
36 value[i] = '_';
37 found++;
40 if(found)
41 { fprintf(stderr, "Configuration reader: corrected label to %s\n", value); }
42 cs_strncpy(rdr->label, value, sizeof(rdr->label));
43 return;
45 fprintf_conf(f, token, "%s\n", rdr->label);
48 static void ecmwhitelist_fn(const char *token, char *value, void *setting, FILE *f)
50 struct s_reader *rdr = setting;
51 if(value)
53 if(strlen(value))
54 chk_ecm_whitelist(value, &rdr->ecm_whitelist);
55 else
56 ecm_whitelist_clear(&rdr->ecm_whitelist);
57 return;
60 value = mk_t_ecm_whitelist(&rdr->ecm_whitelist);
61 if(strlen(value) > 0 || cfg.http_full_cfg)
62 { fprintf_conf(f, token, "%s\n", value); }
63 free_mk_t(value);
66 static void ecmheaderwhitelist_fn(const char *token, char *value, void *setting, FILE *f)
68 struct s_reader *rdr = setting;
69 if(value)
71 if(strlen(value))
72 chk_ecm_hdr_whitelist(value, &rdr->ecm_hdr_whitelist);
73 else
74 ecm_hdr_whitelist_clear(&rdr->ecm_hdr_whitelist);
75 return;
78 value = mk_t_ecm_hdr_whitelist(&rdr->ecm_hdr_whitelist);
79 if(strlen(value) > 0 || cfg.http_full_cfg)
80 { fprintf_conf(f, token, "%s\n", value); }
81 free_mk_t(value);
84 static void protocol_fn(const char *token, char *value, void *setting, FILE *f)
86 struct s_reader *rdr = setting;
87 if(value)
89 if(strlen(value) == 0)
90 { return; }
91 struct protocol_map
93 char *name;
94 int typ;
95 } protocols[] =
97 { "serial", R_SERIAL },
98 { "camd35", R_CAMD35 },
99 { "cs378x", R_CS378X },
100 { "cs357x", R_CAMD35 },
101 { "camd33", R_CAMD33 },
102 { "gbox", R_GBOX },
103 { "cccam", R_CCCAM },
104 { "cccam_ext", R_CCCAM },
105 { "cccam_mcs", R_CCCAM },
106 { "constcw", R_CONSTCW },
107 { "radegast", R_RADEGAST },
108 { "scam", R_SCAM },
109 { "ghttp", R_GHTTP },
110 { "newcamd", R_NEWCAMD },
111 { "newcamd525", R_NEWCAMD },
112 { "newcamd524", R_NEWCAMD },
113 { "drecas", R_DRECAS },
114 { "emu", R_EMU },
115 { NULL, 0 }
116 }, *p;
117 int i;
118 // Parse card readers
119 for(i = 0; cardreaders[i]; i++)
121 if(streq(value, cardreaders[i]->desc))
123 rdr->crdr = cardreaders[i];
124 rdr->typ = cardreaders[i]->typ;
125 return;
128 // Parse protocols
129 for(i = 0, p = &protocols[0]; p->name; p = &protocols[++i])
131 if(streq(p->name, value))
133 rdr->typ = p->typ;
134 break;
137 if(rdr->typ == R_NEWCAMD)
138 { rdr->ncd_proto = streq(value, "newcamd524") ? NCD_524 : NCD_525; }
139 if(!rdr->typ)
141 fprintf(stderr, "ERROR: '%s' is unsupported reader protocol!\n", value);
142 rdr->enable = 0;
144 return;
146 fprintf_conf(f, token, "%s\n", reader_get_type_desc(rdr, 0));
149 static void device_fn(const char *token, char *value, void *setting, FILE *f)
151 struct s_reader *rdr = setting;
152 int32_t isphysical = !is_network_reader(rdr);
153 if(value)
155 int32_t i;
156 char *ptr, *saveptr1 = NULL;
157 for(i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 3) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++)
159 trim(ptr);
160 switch(i)
162 case 0:
163 cs_strncpy(rdr->device, ptr, sizeof(rdr->device));
164 break;
165 case 1:
166 rdr->r_port = atoi(ptr);
167 break;
168 case 2:
169 rdr->l_port = atoi(ptr);
170 break;
173 return;
175 fprintf_conf(f, token, "%s", rdr->device); // it should not have \n at the end
176 if((rdr->r_port || cfg.http_full_cfg) && !isphysical)
177 { fprintf(f, ",%d", rdr->r_port); }
178 if((rdr->l_port || cfg.http_full_cfg) && !isphysical && strncmp(reader_get_type_desc(rdr, 0), "cccam", 5))
179 { fprintf(f, ",%d", rdr->l_port); }
180 fprintf(f, "\n");
183 static void reader_services_fn(const char *token, char *value, void *setting, FILE *f)
185 services_fn(token, value, setting, f);
186 if(value)
188 struct s_reader *rdr = container_of(setting, struct s_reader, sidtabs);
189 if(rdr)
190 { rdr->changes_since_shareupdate = 1; }
194 static void reader_lb_services_fn(const char *token, char *value, void *setting, FILE *f)
196 services_fn(token, value, setting, f);
197 if(value)
199 struct s_reader *rdr = container_of(setting, struct s_reader, lb_sidtabs);
200 if(rdr)
201 { rdr->changes_since_shareupdate = 1; }
205 static void reader_caid_fn(const char *token, char *value, void *setting, FILE *f)
207 check_caidtab_fn(token, value, setting, f);
208 if(value)
210 struct s_reader *rdr = container_of(setting, struct s_reader, ctab);
211 if(rdr)
212 { rdr->changes_since_shareupdate = 1; }
216 static void boxid_fn(const char *token, char *value, void *setting, FILE *f)
218 struct s_reader *rdr = setting;
219 if(value)
221 rdr->boxid = strlen(value) ? a2i(value, 4) : 0;
222 return;
224 if(rdr->boxid)
225 { fprintf_conf(f, token, "%08X\n", rdr->boxid); }
226 else if(cfg.http_full_cfg)
227 { fprintf_conf(f, token, "\n"); }
230 static void rsakey_fn(const char *token, char *value, void *setting, FILE *f)
232 struct s_reader *rdr = setting;
233 if(value)
235 int32_t len = strlen(value);
236 if(len != 128 && len != 240)
238 rdr->rsa_mod_length = 0;
239 memset(rdr->rsa_mod, 0, 120);
241 else
243 if(key_atob_l(value, rdr->rsa_mod, len))
245 fprintf(stderr, "reader rsakey parse error, %s=%s\n", token, value);
246 rdr->rsa_mod_length = 0;
247 memset(rdr->rsa_mod, 0, sizeof(rdr->rsa_mod));
249 else
251 rdr->rsa_mod_length = len/2;
254 return;
256 int32_t len = rdr->rsa_mod_length;
257 if(len > 0)
259 char tmp[len * 2 + 1];
260 fprintf_conf(f, "rsakey", "%s\n", cs_hexdump(0, rdr->rsa_mod, len, tmp, sizeof(tmp)));
262 else if(cfg.http_full_cfg)
263 { fprintf_conf(f, "rsakey", "\n"); }
266 static void deskey_fn(const char *token, char *value, void *setting, FILE *f)
268 struct s_reader *rdr = setting;
269 if(value)
271 int32_t len = strlen(value);
272 if(((len % 16) != 0) || len == 0 || len > 128*2)
274 rdr->des_key_length = 0;
275 memset(rdr->des_key, 0, sizeof(rdr->des_key));
277 else
279 if(key_atob_l(value, rdr->des_key, len))
281 fprintf(stderr, "reader 3DES key parse error, %s=%s\n", token, value);
282 rdr->des_key_length = 0;
283 memset(rdr->des_key, 0, sizeof(rdr->des_key));
285 else
287 rdr->des_key_length = len/2;
290 return;
292 int32_t len = rdr->des_key_length;
293 if(len > 0)
295 char tmp[len * 2 + 1];
296 fprintf_conf(f, "deskey", "%s\n", cs_hexdump(0, rdr->des_key, len, tmp, sizeof(tmp)));
298 else if(cfg.http_full_cfg)
299 { fprintf_conf(f, "deskey", "\n"); }
302 static void boxkey_fn(const char *token, char *value, void *setting, FILE *f)
304 struct s_reader *rdr = setting;
305 if(value)
307 int32_t len = strlen(value);
308 if(((len % 8) != 0) || len == 0 || len > 32)
310 rdr->boxkey_length = 0;
311 memset(rdr->boxkey, 0, sizeof(rdr->boxkey));
313 else
315 if(key_atob_l(value, rdr->boxkey, len))
317 fprintf(stderr, "reader boxkey parse error, %s=%s\n", token, value);
318 rdr->boxkey_length = 0;
319 memset(rdr->boxkey, 0, sizeof(rdr->boxkey));
321 else
323 rdr->boxkey_length = len/2;
326 return;
328 int32_t len = rdr->boxkey_length;
329 if(len > 0)
331 char tmp[len * 2 + 1];
332 fprintf_conf(f, "boxkey", "%s\n", cs_hexdump(0, rdr->boxkey, len, tmp, sizeof(tmp)));
334 else if(cfg.http_full_cfg)
335 { fprintf_conf(f, "boxkey", "\n"); }
338 #ifdef READER_NAGRA_MERLIN
339 static void mod1_fn(const char *token, char *value, void *setting, FILE *f)
341 struct s_reader *rdr = setting;
342 if(value)
344 int32_t len = strlen(value);
345 if(len != 224)
347 rdr->mod1_length = 0;
348 memset(rdr->mod1, 0, 112);
350 else
352 if(key_atob_l(value, rdr->mod1, len))
354 fprintf(stderr, "reader mod1 parse error, %s=%s\n", token, value);
355 rdr->mod1_length = 0;
356 memset(rdr->mod1, 0, sizeof(rdr->mod1));
358 else
360 rdr->mod1_length = len/2;
363 return;
365 int32_t len = rdr->mod1_length;
366 if(len > 0)
368 char tmp[len * 2 + 1];
369 fprintf_conf(f, "mod1", "%s\n", cs_hexdump(0, rdr->mod1, len, tmp, sizeof(tmp)));
371 else if(cfg.http_full_cfg)
372 { fprintf_conf(f, "mod1", "\n"); }
375 static void data50_fn(const char *token, char *value, void *setting, FILE *f)
377 struct s_reader *rdr = setting;
378 if(value)
380 int32_t len = strlen(value);
381 if(len != 160)
383 rdr->data50_length = 0;
384 memset(rdr->data50, 0, 80);
386 else
388 if(key_atob_l(value, rdr->data50, len))
390 fprintf(stderr, "reader data50 parse error, %s=%s\n", token, value);
391 rdr->data50_length = 0;
392 memset(rdr->data50, 0, sizeof(rdr->data50));
394 else
396 rdr->data50_length = len/2;
399 return;
401 int32_t len = rdr->data50_length;
402 if(len > 0)
404 char tmp[len * 2 + 1];
405 fprintf_conf(f, "data50", "%s\n", cs_hexdump(0, rdr->data50, len, tmp, sizeof(tmp)));
407 else if(cfg.http_full_cfg)
408 { fprintf_conf(f, "data50", "\n"); }
411 static void mod50_fn(const char *token, char *value, void *setting, FILE *f)
413 struct s_reader *rdr = setting;
414 if(value)
416 int32_t len = strlen(value);
417 if(len != 160)
419 rdr->mod50_length = 0;
420 memset(rdr->mod50, 0, 80);
422 else
424 if(key_atob_l(value, rdr->mod50, len))
426 fprintf(stderr, "reader mod50 parse error, %s=%s\n", token, value);
427 rdr->mod50_length = 0;
428 memset(rdr->mod50, 0, sizeof(rdr->mod50));
430 else
432 rdr->mod50_length = len/2;
435 return;
437 int32_t len = rdr->mod50_length;
438 if(len > 0)
440 char tmp[len * 2 + 1];
441 fprintf_conf(f, "mod50", "%s\n", cs_hexdump(0, rdr->mod50, len, tmp, sizeof(tmp)));
443 else if(cfg.http_full_cfg)
444 { fprintf_conf(f, "mod50", "\n"); }
447 static void key60_fn(const char *token, char *value, void *setting, FILE *f)
449 struct s_reader *rdr = setting;
450 if(value)
452 int32_t len = strlen(value);
453 if(len != 192)
455 rdr->key60_length = 0;
456 memset(rdr->key60, 0, 96);
458 else
460 if(key_atob_l(value, rdr->key60, len))
462 fprintf(stderr, "reader key60 parse error, %s=%s\n", token, value);
463 rdr->key60_length = 0;
464 memset(rdr->key60, 0, sizeof(rdr->key60));
466 else
468 rdr->key60_length = len/2;
471 return;
473 int32_t len = rdr->key60_length;
474 if(len > 0)
476 char tmp[len * 2 + 1];
477 fprintf_conf(f, "key60", "%s\n", cs_hexdump(0, rdr->key60, len, tmp, sizeof(tmp)));
479 else if(cfg.http_full_cfg)
480 { fprintf_conf(f, "key60", "\n"); }
483 static void exp60_fn(const char *token, char *value, void *setting, FILE *f)
485 struct s_reader *rdr = setting;
486 if(value)
488 int32_t len = strlen(value);
489 if(len != 192)
491 rdr->exp60_length = 0;
492 memset(rdr->exp60, 0, 96);
494 else
496 if(key_atob_l(value, rdr->exp60, len))
498 fprintf(stderr, "reader exp60 parse error, %s=%s\n", token, value);
499 rdr->exp60_length = 0;
500 memset(rdr->exp60, 0, sizeof(rdr->exp60));
502 else
504 rdr->exp60_length = len/2;
507 return;
509 int32_t len = rdr->exp60_length;
510 if(len > 0)
512 char tmp[len * 2 + 1];
513 fprintf_conf(f, "exp60", "%s\n", cs_hexdump(0, rdr->exp60, len, tmp, sizeof(tmp)));
515 else if(cfg.http_full_cfg)
516 { fprintf_conf(f, "exp60", "\n"); }
519 static void nuid_fn(const char *token, char *value, void *setting, FILE *f)
521 struct s_reader *rdr = setting;
522 if(value)
524 int32_t len = strlen(value);
525 if(len != 8)
527 rdr->nuid_length = 0;
528 memset(rdr->nuid, 0, 4);
530 else
532 if(key_atob_l(value, rdr->nuid, len))
534 fprintf(stderr, "reader nuid parse error, %s=%s\n", token, value);
535 rdr->nuid_length = 0;
536 memset(rdr->nuid, 0, sizeof(rdr->nuid));
538 else
540 rdr->nuid_length = len/2;
543 return;
545 int32_t len = rdr->nuid_length;
546 if(len > 0)
548 char tmp[len * 2 + 1];
549 fprintf_conf(f, "nuid", "%s\n", cs_hexdump(0, rdr->nuid, len, tmp, sizeof(tmp)));
551 else if(cfg.http_full_cfg)
552 { fprintf_conf(f, "nuid", "\n"); }
555 static void cwekey_fn(const char *token, char *value, void *setting, FILE *f)
557 struct s_reader *rdr = setting;
558 if(value)
560 int32_t len = strlen(value);
561 if(len != 32)
563 rdr->cwekey_length = 0;
564 memset(rdr->cwekey, 0, 16);
566 else
568 if(key_atob_l(value, rdr->cwekey, len))
570 fprintf(stderr, "reader cwekey parse error, %s=%s\n", token, value);
571 rdr->cwekey_length = 0;
572 memset(rdr->cwekey, 0, sizeof(rdr->cwekey));
574 else
576 rdr->cwekey_length = len/2;
579 return;
581 int32_t len = rdr->cwekey_length;
582 if(len > 0)
584 char tmp[len * 2 + 1];
585 fprintf_conf(f, "cwekey", "%s\n", cs_hexdump(0, rdr->cwekey, len, tmp, sizeof(tmp)));
587 else if(cfg.http_full_cfg)
588 { fprintf_conf(f, "cwekey", "\n"); }
590 #endif
592 static void flags_fn(const char *token, char *value, void *setting, long flag, FILE *f)
594 uint32_t *var = setting;
595 if(value)
597 int i = atoi(value);
598 if(!i && (*var & flag))
599 { *var -= flag; }
600 if(i)
601 { *var |= flag; }
602 return;
604 if((*var & flag) || cfg.http_full_cfg)
605 { fprintf_conf(f, token, "%d\n", (*var & flag) ? 1 : 0); }
608 static void ins7E_fn(const char *token, char *value, void *setting, long var_size, FILE *f)
610 uint8_t *var = setting;
611 var_size -= 1; // var_size contains sizeof(var) which is [X + 1]
612 if(value)
614 int32_t len = strlen(value);
615 if(len != var_size * 2 || key_atob_l(value, var, len))
617 if(len > 0)
618 { fprintf(stderr, "reader %s parse error, %s=%s\n", token, token, value); }
619 memset(var, 0, var_size + 1);
621 else
623 var[var_size] = 1; // found and correct
625 return;
627 if(var[var_size])
629 char tmp[var_size * 2 + 1];
630 fprintf_conf(f, token, "%s\n", cs_hexdump(0, var, var_size, tmp, sizeof(tmp)));
632 else if(cfg.http_full_cfg)
633 { fprintf_conf(f, token, "\n"); }
636 static void des_and_3des_key_fn(const char *token, char *value, void *setting, FILE *f)
638 uint8_t *var = setting;
639 if(value)
641 int32_t len = strlen(value);
642 if(((len != 16) && (len != 32)) || (key_atob_l(value, var, len)))
644 if(len > 0)
645 { fprintf(stderr, "reader %s parse error, %s=%s\n", token, token, value); }
646 memset(var, 0, 17);
648 else
650 var[16] = len/2;
652 return;
654 if(var[16])
656 char tmp[var[16] * 2 + 1];
657 fprintf_conf(f, token, "%s\n", cs_hexdump(0, var, var[16], tmp, sizeof(tmp)));
659 else if(cfg.http_full_cfg)
660 { fprintf_conf(f, token, "\n"); }
663 static void atr_fn(const char *token, char *value, void *setting, FILE *f)
665 struct s_reader *rdr = setting;
666 if(value)
668 memset(rdr->atr, 0, sizeof(rdr->atr));
669 rdr->atrlen = strlen(value);
670 if(rdr->atrlen)
672 if(rdr->atrlen > (int32_t)sizeof(rdr->atr) * 2)
673 { rdr->atrlen = (int32_t)sizeof(rdr->atr) * 2; }
674 key_atob_l(value, rdr->atr, rdr->atrlen);
676 return;
678 if(rdr->atr[0] || cfg.http_full_cfg)
680 int j;
681 fprintf_conf(f, token, "%s", ""); // it should not have \n at the end
682 if(rdr->atr[0])
684 for(j = 0; j < rdr->atrlen / 2; j++)
686 fprintf(f, "%02X", rdr->atr[j]);
689 fprintf(f, "\n");
693 static void detect_fn(const char *token, char *value, void *setting, FILE *f)
695 struct s_reader *rdr = setting;
696 if(value)
698 int i;
699 for(i = 0; RDR_CD_TXT[i]; i++)
701 if(!strcmp(value, RDR_CD_TXT[i]))
703 rdr->detect = i;
705 else
707 if(value[0] == '!' && streq(value + 1, RDR_CD_TXT[i]))
708 { rdr->detect = i | 0x80; }
711 return;
713 fprintf_conf(f, token, "%s%s\n", rdr->detect & 0x80 ? "!" : "", RDR_CD_TXT[rdr->detect & 0x7f]);
716 void ftab_fn(const char *token, char *value, void *setting, long ftab_type, FILE *f)
718 FTAB *ftab = setting;
719 if(value)
721 if(strlen(value))
722 chk_ftab(value, ftab);
723 else
724 ftab_clear(ftab);
725 return;
727 if(ftab_type & FTAB_READER)
729 struct s_reader *rdr = NULL;
730 if(ftab_type & FTAB_PROVID) { rdr = container_of(setting, struct s_reader, ftab); }
731 if(ftab_type & FTAB_CHID) { rdr = container_of(setting, struct s_reader, fchid); }
732 if(ftab_type & FTAB_FBPCAID) { rdr = container_of(setting, struct s_reader, fallback_percaid); }
733 if(ftab_type & FTAB_LOCALCARDS) { rdr = container_of(setting, struct s_reader, localcards); }
734 if(ftab_type & FTAB_IGNCHKSMCAID){ rdr = container_of(setting, struct s_reader, disablecrccws_only_for); }
735 #ifdef WITH_EMU
736 if(ftab_type & FTAB_EMUAU) { rdr = container_of(setting, struct s_reader, emu_auproviders); }
737 #endif
738 if(rdr)
739 { rdr->changes_since_shareupdate = 1; }
741 value = mk_t_ftab(ftab);
742 if(strlen(value) > 0 || cfg.http_full_cfg)
743 { fprintf_conf(f, token, "%s\n", value); }
744 free_mk_t(value);
747 static void aeskeys_fn(const char *token, char *value, void *setting, FILE *f)
749 struct s_reader *rdr = setting;
750 if(value)
752 parse_aes_keys(rdr, value);
753 return;
755 value = mk_t_aeskeys(rdr);
756 if(strlen(value) > 0 || cfg.http_full_cfg)
757 { fprintf_conf(f, token, "%s\n", value); }
758 free_mk_t(value);
761 static void emmcache_fn(const char *token, char *value, void *setting, FILE *f)
763 struct s_reader *rdr = setting;
764 if(value)
766 rdr->cachemm = 0;
767 rdr->rewritemm = 0;
768 rdr->logemm = 0;
769 rdr->deviceemm = 0;
770 if(strlen(value))
772 int i;
773 char *ptr, *saveptr1 = NULL;
774 for(i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 4) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++)
776 switch(i)
778 case 0:
779 rdr->cachemm = atoi(ptr);
780 break;
781 case 1:
782 rdr->rewritemm = atoi(ptr);
783 break;
784 case 2:
785 rdr->logemm = atoi(ptr);
786 break;
787 case 3:
788 rdr->deviceemm = atoi(ptr);
791 if(rdr->rewritemm <= 0)
793 fprintf(stderr, "Setting reader \"emmcache\" to %i,%d,%i,%i instead of %i,%i,%i,%i.",
794 rdr->cachemm, 1, rdr->logemm, rdr->deviceemm,
795 rdr->cachemm, rdr->rewritemm, rdr->logemm, rdr->deviceemm);
796 fprintf(stderr, "Zero or negative number of rewrites is silly\n");
797 rdr->rewritemm = 1;
800 return;
802 if(rdr->cachemm || rdr->logemm || cfg.http_full_cfg)
803 { fprintf_conf(f, token, "%d,%d,%d,%d\n", rdr->cachemm, rdr->rewritemm, rdr->logemm,rdr->deviceemm); }
806 static void blockemm_bylen_fn(const char *token, char *value, void *setting, FILE *f)
808 struct s_reader *rdr = setting;
809 if(value)
811 char *ptr, *saveptr1 = NULL, dash;
812 struct s_emmlen_range *blocklen;
813 uint32_t num;
815 if(!strlen(value))
817 ll_destroy_data(&rdr->blockemmbylen);
818 return;
821 if(!rdr->blockemmbylen)
822 { rdr->blockemmbylen = ll_create("blockemmbylen"); }
823 else
824 { ll_clear_data(rdr->blockemmbylen); }
826 for(ptr = strtok_r(value, ",", &saveptr1); ptr;
827 ptr = strtok_r(NULL, ",", &saveptr1))
829 if(!cs_malloc(&blocklen, sizeof(*blocklen)))
830 { return; }
831 num = sscanf(ptr, "%hd%c%hd", &blocklen->min, &dash, &blocklen->max);
832 if(num <= 0)
834 NULLFREE(blocklen);
835 fprintf(stderr, "blockemm-bylen parse error: %s\n", value);
836 continue;
838 if(num == 1) // single values: x1, x2, x3, ...
839 { blocklen->max = blocklen->min; }
840 else if(num == 2) // range values with open end: x1-
841 { blocklen->max = 0; }
842 ll_append(rdr->blockemmbylen, blocklen);
844 return;
846 value = mk_t_emmbylen(rdr);
847 if(strlen(value) > 0 || cfg.http_full_cfg)
848 { fprintf_conf(f, token, "%s\n", value); }
849 free_mk_t(value);
852 static void nano_fn(const char *token, char *value, void *setting, FILE *f)
854 uint16_t *nano = setting;
855 if(value)
857 *nano = 0;
858 if(strlen(value) > 0)
860 if(streq(value, "all"))
862 *nano = 0xFFFF;
864 else
866 int32_t i;
867 char *ptr, *saveptr1 = NULL;
868 for(ptr = strtok_r(value, ",", &saveptr1); ptr; ptr = strtok_r(NULL, ",", &saveptr1))
870 i = (byte_atob(ptr) % 0x80);
871 if(i >= 0 && i <= 16)
872 { *nano |= (1 << i); }
876 return;
878 value = mk_t_nano(*nano);
879 if(strlen(value) > 0 || cfg.http_full_cfg)
880 { fprintf_conf(f, token, "%s\n", value); }
881 free_mk_t(value);
884 static void auprovid_fn(const char *token, char *value, void *setting, FILE *f)
886 struct s_reader *rdr = setting;
887 if(value)
889 rdr->auprovid = 0;
890 if(strlen(value))
891 { rdr->auprovid = a2i(value, 3); }
892 return;
894 if(rdr->auprovid)
895 { fprintf_conf(f, token, "%06X\n", rdr->auprovid); }
896 else if(cfg.http_full_cfg)
897 { fprintf_conf(f, token, "\n"); }
900 static void ratelimitecm_fn(const char *token, char *value, void *setting, FILE *f)
902 struct s_reader *rdr = setting;
903 if(value)
905 rdr->ratelimitecm = 0;
906 if(strlen(value))
908 int i;
909 rdr->ratelimitecm = atoi(value);
910 for(i = 0; i < MAXECMRATELIMIT; i++) // reset all slots
912 rdr->rlecmh[i].srvid = -1;
913 rdr->rlecmh[i].last.time = -1;
916 return;
918 if(rdr->ratelimitecm || cfg.http_full_cfg)
919 { fprintf_conf(f, token, "%d\n", rdr->ratelimitecm); }
922 static void ecmunique_fn(const char *token, char *value, void *setting, FILE *f)
924 struct s_reader *rdr = setting;
925 if(value)
927 if(strlen(value) == 0)
929 rdr->ecmunique = 0; // default
931 else
933 rdr->ecmunique = atoi(value);
934 if(rdr->ecmunique >= 1)
935 { rdr->ecmunique = 1; }
936 else
937 { rdr->ecmunique = 0; }
939 return;
941 if((rdr->ratelimitecm && rdr->ecmunique != 0) || cfg.http_full_cfg)
942 { fprintf_conf(f, token, "%d\n", rdr->ecmunique); }
945 static void ratelimittime_fn(const char *token, char *value, void *setting, FILE *f)
947 struct s_reader *rdr = setting;
948 if(value)
950 if(strlen(value) == 0)
952 if(rdr->ratelimitecm > 0)
954 rdr->ratelimittime = 9000; // default 9 seconds
955 rdr->srvidholdtime = 2000; // default 2 seconds hold
957 else
959 rdr->ratelimitecm = 0; // in case someone set a negative value
960 rdr->ratelimittime = 0;
961 rdr->srvidholdtime = 0;
964 else
966 rdr->ratelimittime = atoi(value);
967 if (rdr->ratelimittime < 60) rdr->ratelimittime *= 1000;
969 return;
971 if(rdr->ratelimitecm || cfg.http_full_cfg)
972 { fprintf_conf(f, token, "%d\n", rdr->ratelimittime); }
975 static void srvidholdtime_fn(const char *token, char *value, void *setting, FILE *f)
977 struct s_reader *rdr = setting;
978 if(value)
980 if(strlen(value) == 0)
982 if(rdr->ratelimitecm > 0)
984 rdr->srvidholdtime = 2000; // default 2 seconds hold
986 else
988 rdr->ratelimitecm = 0; // in case someone set a negative value
989 rdr->srvidholdtime = 0;
992 else
994 rdr->srvidholdtime = atoi(value);
995 if (rdr->srvidholdtime < 60) rdr->srvidholdtime *=1000;
997 return;
999 if(rdr->ratelimitecm || cfg.http_full_cfg)
1000 { fprintf_conf(f, token, "%d\n", rdr->srvidholdtime); }
1003 static void cooldown_fn(const char *token, char *value, void *setting, FILE *f)
1005 struct s_reader *rdr = setting;
1006 if(value)
1008 if(strlen(value) == 0)
1010 rdr->cooldown[0] = 0;
1011 rdr->cooldown[1] = 0;
1013 else
1015 int32_t i;
1016 char *ptr, *saveptr1 = NULL;
1017 for(i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 2) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++)
1019 rdr->cooldown[i] = atoi(ptr);
1021 if(rdr->cooldown[0] <= 0 || rdr->cooldown[1] <= 0)
1023 fprintf(stderr, "cooldown must have 2 positive values (x,y) set values %d,%d ! cooldown deactivated\n",
1024 rdr->cooldown[0], rdr->cooldown[1]);
1025 rdr->cooldown[0] = 0;
1026 rdr->cooldown[1] = 0;
1029 return;
1031 if(rdr->cooldown[0] || cfg.http_full_cfg)
1033 fprintf_conf(f, token, "%d,%d\n", rdr->cooldown[0], rdr->cooldown[1]);
1037 static void cooldowndelay_fn(const char *UNUSED(token), char *value, void *setting, FILE *UNUSED(f))
1039 struct s_reader *rdr = setting;
1040 if(value)
1042 rdr->cooldown[0] = strlen(value) ? atoi(value) : 0;
1044 // This option is *not* written in the config file.
1045 // It is only set by WebIf as convenience
1048 static void cooldowntime_fn(const char *UNUSED(token), char *value, void *setting, FILE *UNUSED(f))
1050 struct s_reader *rdr = setting;
1051 if(value)
1053 if(strlen(value) == 0)
1055 rdr->cooldown[0] = 0; // no cooling down time means no cooling set
1056 rdr->cooldown[1] = 0;
1058 else
1060 rdr->cooldown[1] = atoi(value);
1062 return;
1064 // This option is *not* written in the config file.
1065 // It is only set by WebIf as convenience
1068 void reader_fixups_fn(void *var)
1070 struct s_reader *rdr = var;
1071 #ifdef WITH_LB
1072 if(rdr->lb_weight > 1000)
1073 { rdr->lb_weight = 1000; }
1074 else if(rdr->lb_weight <= 0)
1075 { rdr->lb_weight = 100; }
1076 #endif
1078 if(is_cascading_reader(rdr) && (rdr->typ == R_CAMD35 || rdr->typ == R_CS378X))
1080 #ifdef CS_CACHEEX
1081 if(rdr && rdr->cacheex.mode>1)
1082 { rdr->keepalive = 1; } // with cacheex, it is required!
1083 else
1084 #endif
1085 if(rdr->typ == R_CAMD35)
1086 { rdr->keepalive = 0; } // with NO-cacheex, and UDP, keepalive is not required!
1090 #define OFS(X) offsetof(struct s_reader, X)
1091 #define SIZEOF(X) sizeof(((struct s_reader *)0)->X)
1093 static const struct config_list reader_opts[] =
1095 DEF_OPT_FIXUP_FUNC(reader_fixups_fn),
1096 DEF_OPT_FUNC("label" , 0, reader_label_fn),
1097 #ifdef WEBIF
1098 DEF_OPT_STR("description" , OFS(description), NULL),
1099 #endif
1100 DEF_OPT_INT8("enable" , OFS(enable), 1),
1101 DEF_OPT_FUNC("protocol" , 0, protocol_fn),
1102 DEF_OPT_FUNC("device" , 0, device_fn),
1103 DEF_OPT_HEX("key" , OFS(ncd_key), SIZEOF(ncd_key)),
1104 DEF_OPT_SSTR("user" , OFS(r_usr), "", SIZEOF(r_usr)),
1105 DEF_OPT_SSTR("password" , OFS(r_pwd), "", SIZEOF(r_pwd)),
1106 DEF_OPT_SSTR("pincode" , OFS(pincode), "none", SIZEOF(pincode)),
1107 #ifdef MODULE_GBOX
1108 DEF_OPT_UINT8("gbox_max_distance" , OFS(gbox_maxdist), DEFAULT_GBOX_MAX_DIST),
1109 DEF_OPT_UINT8("gbox_max_ecm_send" , OFS(gbox_maxecmsend), DEFAULT_GBOX_MAX_ECM_SEND),
1110 DEF_OPT_UINT8("gbox_reshare" , OFS(gbox_reshare), DEFAULT_GBOX_RESHARE),
1111 DEF_OPT_INT8("cccam_reshare" , OFS(gbox_cccam_reshare), -1),
1112 DEF_OPT_UINT8("force_remm" , OFS(gbox_force_remm), 0),
1113 #endif
1114 DEF_OPT_STR("readnano" , OFS(emmfile), NULL),
1115 DEF_OPT_FUNC("services" , OFS(sidtabs), reader_services_fn),
1116 DEF_OPT_FUNC("lb_whitelist_services" , OFS(lb_sidtabs), reader_lb_services_fn),
1117 DEF_OPT_INT32("inactivitytimeout" , OFS(tcp_ito), DEFAULT_INACTIVITYTIMEOUT),
1118 DEF_OPT_INT32("reconnecttimeout" , OFS(tcp_rto), DEFAULT_TCP_RECONNECT_TIMEOUT),
1119 DEF_OPT_INT32("reconnectdelay" , OFS(tcp_reconnect_delay), 60000),
1120 DEF_OPT_INT32("resetcycle" , OFS(resetcycle), 0),
1121 DEF_OPT_INT8("disableserverfilter" , OFS(ncd_disable_server_filt), 0),
1122 DEF_OPT_INT8("connectoninit" , OFS(ncd_connect_on_init), 0),
1123 DEF_OPT_UINT8("keepalive" , OFS(keepalive), 0),
1124 DEF_OPT_INT8("smargopatch" , OFS(smargopatch), 0),
1125 DEF_OPT_INT8("autospeed" , OFS(autospeed), 1),
1126 DEF_OPT_UINT8("sc8in1_dtrrts_patch" , OFS(sc8in1_dtrrts_patch), 0),
1127 DEF_OPT_INT8("fallback" , OFS(fallback), 0),
1128 DEF_OPT_FUNC_X("fallback_percaid" , OFS(fallback_percaid), ftab_fn, FTAB_READER | FTAB_FBPCAID),
1129 DEF_OPT_FUNC_X("localcards" , OFS(localcards), ftab_fn, FTAB_READER | FTAB_LOCALCARDS),
1130 DEF_OPT_FUNC_X("disablecrccws_only_for" , OFS(disablecrccws_only_for), ftab_fn, FTAB_READER | FTAB_IGNCHKSMCAID),
1131 #ifdef CS_CACHEEX
1132 DEF_OPT_INT8("cacheex" , OFS(cacheex.mode), 0),
1133 DEF_OPT_INT8("cacheex_maxhop" , OFS(cacheex.maxhop), 0),
1134 DEF_OPT_FUNC("cacheex_ecm_filter" , OFS(cacheex.filter_caidtab), cacheex_hitvaluetab_fn),
1135 DEF_OPT_UINT8("cacheex_allow_request" , OFS(cacheex.allow_request), 0),
1136 DEF_OPT_UINT8("cacheex_drop_csp" , OFS(cacheex.drop_csp), 0),
1137 DEF_OPT_UINT8("cacheex_allow_filter" , OFS(cacheex.allow_filter), 1),
1138 DEF_OPT_UINT8("cacheex_block_fakecws" , OFS(cacheex.block_fakecws), 0),
1139 #endif
1140 DEF_OPT_FUNC("caid" , OFS(ctab), reader_caid_fn),
1141 DEF_OPT_FUNC("atr" , 0, atr_fn),
1142 DEF_OPT_FUNC("boxid" , 0, boxid_fn),
1143 DEF_OPT_FUNC("boxkey" , 0, boxkey_fn),
1144 DEF_OPT_FUNC("rsakey" , 0, rsakey_fn),
1145 DEF_OPT_FUNC("deskey" , 0, deskey_fn),
1146 #ifdef READER_NAGRA_MERLIN
1147 DEF_OPT_FUNC("mod1" , 0, mod1_fn),
1148 DEF_OPT_FUNC("data50" , 0, data50_fn),
1149 DEF_OPT_FUNC("mod50" , 0, mod50_fn),
1150 DEF_OPT_FUNC("key60" , 0, key60_fn),
1151 DEF_OPT_FUNC("exp60" , 0, exp60_fn),
1152 DEF_OPT_FUNC("nuid" , 0, nuid_fn),
1153 DEF_OPT_FUNC("cwekey" , 0, cwekey_fn),
1154 #endif
1155 DEF_OPT_FUNC_X("ins7e" , OFS(ins7E), ins7E_fn, SIZEOF(ins7E)),
1156 DEF_OPT_FUNC_X("ins7e11" , OFS(ins7E11), ins7E_fn, SIZEOF(ins7E11)),
1157 DEF_OPT_FUNC_X("ins2e06" , OFS(ins2e06), ins7E_fn, SIZEOF(ins2e06)),
1158 DEF_OPT_FUNC("k1_generic" , OFS(k1_generic), des_and_3des_key_fn),
1159 DEF_OPT_FUNC("k1_unique" , OFS(k1_unique), des_and_3des_key_fn),
1160 DEF_OPT_INT8("fix07" , OFS(fix_07), 1),
1161 DEF_OPT_INT8("fix9993" , OFS(fix_9993), 0),
1162 DEF_OPT_INT8("readtiers" , OFS(readtiers), 1),
1163 DEF_OPT_INT8("force_irdeto" , OFS(force_irdeto), 0),
1164 DEF_OPT_INT8("needsemmfirst" , OFS(needsemmfirst), 0),
1165 #ifdef READER_CRYPTOWORKS
1166 DEF_OPT_INT8("needsglobalfirst" , OFS(needsglobalfirst), 0),
1167 #endif
1168 DEF_OPT_UINT32("ecmnotfoundlimit" , OFS(ecmnotfoundlimit), 0),
1169 DEF_OPT_FUNC("ecmwhitelist" , 0, ecmwhitelist_fn),
1170 DEF_OPT_FUNC("ecmheaderwhitelist" , 0, ecmheaderwhitelist_fn),
1171 DEF_OPT_FUNC("detect" , 0, detect_fn),
1172 DEF_OPT_INT8("nagra_read" , OFS(nagra_read), 0),
1173 DEF_OPT_INT8("detect_seca_nagra_tunneled_card", OFS(detect_seca_nagra_tunneled_card), 1),
1174 DEF_OPT_INT32("mhz" , OFS(mhz), 357),
1175 DEF_OPT_INT32("cardmhz" , OFS(cardmhz), 357),
1176 #ifdef WITH_AZBOX
1177 DEF_OPT_INT32("mode" , OFS(azbox_mode), -1),
1178 #endif
1179 DEF_OPT_FUNC_X("ident" , OFS(ftab), ftab_fn, FTAB_READER | FTAB_PROVID),
1180 DEF_OPT_FUNC_X("chid" , OFS(fchid), ftab_fn, FTAB_READER | FTAB_CHID),
1181 DEF_OPT_FUNC("class" , OFS(cltab), class_fn),
1182 DEF_OPT_FUNC("aeskeys" , 0, aeskeys_fn),
1183 DEF_OPT_FUNC("group" , OFS(grp), group_fn),
1184 DEF_OPT_FUNC("emmcache" , 0, emmcache_fn),
1185 DEF_OPT_FUNC_X("blockemm-unknown" , OFS(blockemm), flags_fn, EMM_UNKNOWN),
1186 DEF_OPT_FUNC_X("blockemm-u" , OFS(blockemm), flags_fn, EMM_UNIQUE),
1187 DEF_OPT_FUNC_X("blockemm-s" , OFS(blockemm), flags_fn, EMM_SHARED),
1188 DEF_OPT_FUNC_X("blockemm-g" , OFS(blockemm), flags_fn, EMM_GLOBAL),
1189 DEF_OPT_FUNC_X("saveemm-unknown" , OFS(saveemm), flags_fn, EMM_UNKNOWN),
1190 DEF_OPT_FUNC_X("saveemm-u" , OFS(saveemm), flags_fn, EMM_UNIQUE),
1191 DEF_OPT_FUNC_X("saveemm-s" , OFS(saveemm), flags_fn, EMM_SHARED),
1192 DEF_OPT_FUNC_X("saveemm-g" , OFS(saveemm), flags_fn, EMM_GLOBAL),
1193 DEF_OPT_FUNC("blockemm-bylen" , 0, blockemm_bylen_fn),
1194 #ifdef WITH_LB
1195 DEF_OPT_INT32("lb_weight" , OFS(lb_weight), 100),
1196 DEF_OPT_INT8("lb_force_fallback" , OFS(lb_force_fallback), 0),
1197 #endif
1198 DEF_OPT_FUNC("savenano" , OFS(s_nano), nano_fn),
1199 DEF_OPT_FUNC("blocknano" , OFS(b_nano), nano_fn),
1200 DEF_OPT_INT8("dropbadcws" , OFS(dropbadcws), 0),
1201 DEF_OPT_INT8("disablecrccws" , OFS(disablecrccws), 0),
1202 DEF_OPT_INT32("use_gpio" , OFS(use_gpio), 0),
1203 #ifdef MODULE_PANDORA
1204 DEF_OPT_UINT8("pand_send_ecm" , OFS(pand_send_ecm), 0),
1205 #endif
1206 #ifdef MODULE_CCCAM
1207 DEF_OPT_SSTR("cccversion" , OFS(cc_version), "", SIZEOF(cc_version)),
1208 DEF_OPT_INT8("cccmaxhops" , OFS(cc_maxhops), DEFAULT_CC_MAXHOPS),
1209 DEF_OPT_INT8("cccmindown" , OFS(cc_mindown), 0),
1210 DEF_OPT_INT8("cccwantemu" , OFS(cc_want_emu), 0),
1211 DEF_OPT_INT8("ccckeepalive" , OFS(cc_keepalive), DEFAULT_CC_KEEPALIVE),
1212 DEF_OPT_INT8("cccreshare" , OFS(cc_reshare), DEFAULT_CC_RESHARE),
1213 DEF_OPT_INT32("cccreconnect" , OFS(cc_reconnect), DEFAULT_CC_RECONNECT),
1214 DEF_OPT_INT8("ccchop" , OFS(cc_hop), 0),
1215 #endif
1216 #ifdef MODULE_GHTTP
1217 DEF_OPT_UINT8("use_ssl" , OFS(ghttp_use_ssl), 0),
1218 #endif
1219 #if defined(READER_DRE) || defined(READER_DRECAS)
1220 DEF_OPT_HEX("force_ua" , OFS(force_ua), 4),
1221 DEF_OPT_STR("exec_cmd_file" , OFS(userscript), NULL),
1222 #endif
1223 #ifdef READER_DRECAS
1224 DEF_OPT_STR("stmkeys" , OFS(stmkeys), NULL),
1225 #endif
1226 #ifdef WITH_EMU
1227 DEF_OPT_FUNC_X("emu_auproviders" , OFS(emu_auproviders), ftab_fn, FTAB_READER | FTAB_EMUAU),
1228 DEF_OPT_INT8("emu_datecodedenabled" , OFS(emu_datecodedenabled), 0),
1229 #endif
1230 DEF_OPT_INT8("deprecated" , OFS(deprecated), 0),
1231 DEF_OPT_INT8("audisabled" , OFS(audisabled), 0),
1232 DEF_OPT_FUNC("auprovid" , 0, auprovid_fn),
1233 DEF_OPT_INT8("ndsversion" , OFS(ndsversion), 0),
1234 DEF_OPT_FUNC("ratelimitecm" , 0, ratelimitecm_fn),
1235 DEF_OPT_FUNC("ecmunique" , 0, ecmunique_fn),
1236 DEF_OPT_FUNC("ratelimittime" , 0, ratelimittime_fn),
1237 DEF_OPT_FUNC("srvidholdtime" , 0, srvidholdtime_fn),
1238 DEF_OPT_FUNC("cooldown" , 0, cooldown_fn),
1239 DEF_OPT_FUNC("cooldowndelay" , 0, cooldowndelay_fn),
1240 DEF_OPT_FUNC("cooldowntime" , 0, cooldowntime_fn),
1241 DEF_OPT_UINT8("read_old_classes" , OFS(read_old_classes), 1),
1242 DEF_LAST_OPT
1245 static inline bool in_list(const char *token, const char *list[])
1247 int i;
1248 for(i = 0; list[i]; i++)
1250 if(streq(token, list[i]))
1251 { return true; }
1253 return false;
1256 static bool reader_check_setting(const struct config_list *UNUSED(clist), void *config_data, const char *setting)
1258 struct s_reader *reader = config_data;
1259 // These are written only when the reader is physical reader
1260 static const char *hw_only_settings[] =
1262 "readnano", "resetcycle", "smargopatch", "autospeed", "sc8in1_dtrrts_patch", "boxid","fix07",
1263 "fix9993", "rsakey", "deskey", "ins7e", "ins7e11", "ins2e06", "k1_generic", "k1_unique", "force_irdeto", "needsemmfirst", "boxkey",
1264 "atr", "detect", "nagra_read", "mhz", "cardmhz", "readtiers", "read_old_classes", "use_gpio", "needsglobalfirst",
1265 #ifdef READER_NAGRA_MERLIN
1266 "mod1", "data50", "mod50", "key60", "exp60", "nuid", "cwekey",
1267 #endif
1268 #if defined(READER_DRE) || defined(READER_DRECAS)
1269 "exec_cmd_file",
1270 #endif
1271 #ifdef WITH_AZBOX
1272 "mode",
1273 #endif
1274 "deprecated", "ndsversion",
1277 // These are written only when the reader is network reader
1278 static const char *network_only_settings[] =
1280 "user", "inactivitytimeout", "reconnecttimeout",
1283 if(is_network_reader(reader))
1285 if(in_list(setting, hw_only_settings))
1286 { return false; }
1288 else
1290 if(in_list(setting, network_only_settings))
1291 { return false; }
1294 // These are not written in the config file
1295 static const char *deprecated_settings[] =
1297 "cooldowndelay", "cooldowntime",
1300 if(in_list(setting, deprecated_settings))
1301 { return false; }
1303 // Special settings for NEWCAMD
1304 static const char *newcamd_settings[] =
1306 "disableserverfilter", "connectoninit",
1309 if(reader->typ != R_NEWCAMD && in_list(setting, newcamd_settings))
1310 { return false; }
1311 #ifdef MODULE_CCCAM
1312 // These are written only when the reader is CCCAM
1313 static const char *cccam_settings[] =
1315 "cccversion", "cccmaxhops", "cccmindown", "cccwantemu", "ccckeepalive",
1316 "cccreconnect",
1319 // Special settings for CCCAM
1320 if(reader->typ != R_CCCAM)
1322 if(in_list(setting, cccam_settings))
1323 { return false; }
1325 else if(streq(setting, "ccchop"))
1327 return false;
1329 #endif
1331 #ifdef MODULE_PANDORA
1332 // Special settings for PANDORA
1333 if(reader->typ != R_PANDORA && streq(setting, "pand_send_ecm"))
1334 { return false; }
1335 #endif
1337 #ifdef MODULE_GBOX
1338 // These are written only when the reader is GBOX
1339 static const char *gbox_settings[] =
1341 "gbox_max_distance", "gbox_max_ecm_send", "gbox_reshare", "cccam_reshare", "force_remm",
1344 if(reader->typ != R_GBOX)
1346 if(in_list(setting, gbox_settings))
1347 { return false; }
1349 #endif
1351 return true; // Write the setting
1354 void chk_reader(char *token, char *value, struct s_reader *rdr)
1356 if(config_list_parse(reader_opts, token, value, rdr))
1357 { return; }
1358 else if(token[0] != '#')
1359 { fprintf(stderr, "Warning: keyword '%s' in reader section not recognized\n", token); }
1362 void reader_set_defaults(struct s_reader *rdr)
1364 config_list_set_defaults(reader_opts, rdr);
1367 int32_t init_readerdb(void)
1369 configured_readers = ll_create("configured_readers");
1371 FILE *fp = open_config_file(cs_srvr);
1372 if(!fp)
1373 { return 1; }
1375 int32_t tag = 0;
1376 char *value, *token;
1378 if(!cs_malloc(&token, MAXLINESIZE))
1379 { return 1; }
1381 struct s_reader *rdr;
1382 if(!cs_malloc(&rdr, sizeof(struct s_reader)))
1384 NULLFREE(token);
1385 return 1;
1388 ll_append(configured_readers, rdr);
1389 while(fgets(token, MAXLINESIZE, fp))
1391 int32_t l;
1392 if((l = strlen(trim(token))) < 3)
1393 { continue; }
1394 if((token[0] == '[') && (token[l - 1] == ']'))
1396 token[l - 1] = 0;
1397 tag = (!strcmp("reader", strtolower(token + 1)));
1398 if(rdr->label[0] && rdr->typ)
1400 struct s_reader *newreader;
1401 if(cs_malloc(&newreader, sizeof(struct s_reader)))
1403 ll_append(configured_readers, newreader);
1404 rdr = newreader;
1407 reader_set_defaults(rdr);
1408 continue;
1411 if(!tag)
1412 { continue; }
1413 if(!(value = strchr(token, '=')))
1414 { continue; }
1415 *value++ = '\0';
1416 chk_reader(trim(strtolower(token)), trim(value), rdr);
1418 NULLFREE(token);
1419 LL_ITER itr = ll_iter_create(configured_readers);
1420 while((rdr = ll_iter_next(&itr))) // build active readers list
1422 reader_fixups_fn(rdr);
1423 module_reader_set(rdr);
1425 fclose(fp);
1426 return (0);
1429 void free_reader(struct s_reader *rdr)
1431 NULLFREE(rdr->emmfile);
1433 ecm_whitelist_clear(&rdr->ecm_whitelist);
1434 ecm_hdr_whitelist_clear(&rdr->ecm_hdr_whitelist);
1436 ftab_clear(&rdr->fallback_percaid);
1437 ftab_clear(&rdr->localcards);
1438 ftab_clear(&rdr->fchid);
1439 ftab_clear(&rdr->ftab);
1441 NULLFREE(rdr->cltab.aclass);
1442 NULLFREE(rdr->cltab.bclass);
1444 caidtab_clear(&rdr->ctab);
1445 #ifdef CS_CACHEEX
1446 cecspvaluetab_clear(&rdr->cacheex.filter_caidtab);
1447 #endif
1448 lb_destroy_stats(rdr);
1450 cs_clear_entitlement(rdr);
1451 ll_destroy(&rdr->ll_entitlements);
1453 if(rdr->csystem && rdr->csystem->card_done)
1454 rdr->csystem->card_done(rdr);
1455 NULLFREE(rdr->csystem_data);
1457 ll_destroy_data(&rdr->blockemmbylen);
1459 ll_destroy_data(&rdr->emmstat);
1461 aes_clear_entries(&rdr->aes_list);
1463 config_list_gc_values(reader_opts, rdr);
1464 add_garbage(rdr);
1467 int32_t free_readerdb(void)
1469 int count = 0;
1470 struct s_reader *rdr;
1471 LL_ITER itr = ll_iter_create(configured_readers);
1472 while((rdr = ll_iter_next(&itr)))
1474 free_reader(rdr);
1475 count++;
1477 cs_log("readerdb %d readers freed", count);
1478 ll_destroy(&configured_readers);
1479 return count;
1482 int32_t write_server(void)
1484 FILE *f = create_config_file(cs_srvr);
1485 if(!f)
1486 { return 1; }
1487 struct s_reader *rdr;
1488 LL_ITER itr = ll_iter_create(configured_readers);
1489 while((rdr = ll_iter_next(&itr)))
1491 if(rdr->label[0])
1493 fprintf(f, "[reader]\n");
1494 config_list_apply_fixups(reader_opts, rdr);
1495 config_list_save_ex(f, reader_opts, rdr, cfg.http_full_cfg, reader_check_setting);
1496 fprintf(f, "\n");
1499 return flush_config_file(f, cs_srvr);
1502 void reload_readerdb(void)
1504 struct s_reader *rdr;
1505 LL_ITER itr = ll_iter_create(configured_readers);
1506 while((rdr = ll_iter_next(&itr)))
1508 // disable the current reader
1509 rdr->enable = 0;
1510 restart_cardreader(rdr,1);
1512 free_readerdb(); // release the old readerdb
1513 init_readerdb(); // reload the new readerdb
1514 init_cardreader(); // start the readers