revert breaks some stupid old compilers
[oscam.git] / oscam-conf-mk.c
blob527fb3ec549435a74b8a13362329d61146d58bf3
1 #define MODULE_LOG_PREFIX "config"
3 #include "globals.h"
4 #include "oscam-conf-mk.h"
5 #include "oscam-net.h"
6 #include "oscam-string.h"
8 const char *shortDay[8] = {"SUN","MON","TUE","WED","THU","FRI","SAT","ALL"};
9 const char *weekdstr = "SUNMONTUEWEDTHUFRISATALL";
12 * 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().
14 char *mk_t_caidtab(CAIDTAB *caidtab)
16 if (!caidtab || !caidtab->ctnum) return "";
17 // Max entry length is strlen("1234&ffff:1234,") == 15
18 int32_t i, maxlen = 16 * caidtab->ctnum, pos = 0;
19 char *ret;
20 if (!cs_malloc(&ret, maxlen))
21 return "";
22 const char *comma = "";
23 for(i = 0; i < caidtab->ctnum; i++)
25 CAIDTAB_DATA *d = &caidtab->ctdata[i];
26 if (d->caid < 0x0100)
27 pos += snprintf(ret + pos, maxlen - pos, "%s%02X", comma, d->caid);
28 else
29 pos += snprintf(ret + pos, maxlen - pos, "%s%04X", comma, d->caid);
30 if (d->mask && d->mask != 0xffff)
31 pos += snprintf(ret + pos, maxlen - pos, "&%04X", d->mask);
32 if (d->cmap)
33 pos += snprintf(ret + pos, maxlen - pos, ":%04X", d->cmap);
34 comma = ",";
36 return ret;
40 * 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().
42 char *mk_t_tuntab(TUNTAB *ttab)
44 if (!ttab || !ttab->ttnum) return "";
45 // Each entry max length is strlen("aaaa.bbbb:cccc,") == 15
46 int32_t i, maxlen = 16 * ttab->ttnum, pos = 0;
47 char *ret;
48 if (!cs_malloc(&ret, maxlen))
49 return "";
50 const char *comma = "";
51 for(i = 0; i < ttab->ttnum; i++)
53 TUNTAB_DATA *d = &ttab->ttdata[i];
54 pos += snprintf(ret + pos, maxlen - pos, "%s%04X", comma, d->bt_caidfrom);
55 pos += snprintf(ret + pos, maxlen - pos, ".%04X", d->bt_srvid);
56 if (d->bt_caidto)
57 pos += snprintf(ret + pos, maxlen - pos, ":%04X", d->bt_caidto);
58 comma = ",";
60 return ret;
64 * 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().
66 char *mk_t_group(uint64_t grp)
68 int32_t i = 0, needed = 1, pos = 0, dot = 0;
70 for(i = 0; i < 64; i++)
72 if(grp & ((uint64_t)1 << i))
74 needed += 2;
75 if(i > 9) { needed += 1; }
78 char *value;
79 if(needed == 1 || !cs_malloc(&value, needed)) { return ""; }
80 char *saveptr = value;
81 for(i = 0; i < 64; i++)
83 if(grp & ((uint64_t)1 << i))
85 if(dot == 0)
87 snprintf(value + pos, needed - (value - saveptr), "%d", i + 1);
88 if(i > 8) { pos += 2; }
89 else { pos += 1; }
90 dot = 1;
92 else
94 snprintf(value + pos, needed - (value - saveptr), ",%d", i + 1);
95 if(i > 8) { pos += 3; }
96 else { pos += 2; }
100 value[pos] = '\0';
101 return value;
105 * 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().
107 char *mk_t_ftab(FTAB *ftab)
109 if (!ftab || !ftab->nfilts) return "";
110 // Worst case scenario where each entry have different
111 // caid, ident and only one length in it is strlen("1234:123456,") == 12
112 int32_t i, j, maxlen = 13 * ftab->nfilts, pos = 0;
113 for(i = 0; i < ftab->nfilts; i++)
114 maxlen += ftab->filts[i].nprids * 7; /* strlen("123456,") == 7 */
115 char *ret;
116 if (!cs_malloc(&ret, maxlen))
117 return "";
118 const char *semicolon = "", *comma = "";
119 for(i = 0; i < ftab->nfilts; i++)
121 FILTER *cur = &ftab->filts[i];
122 pos += snprintf(ret + pos, maxlen - pos, "%s%04X:", semicolon, cur->caid);
123 semicolon = ";";
124 comma = "";
125 for (j = 0; j < cur->nprids; j++)
127 pos += snprintf(ret + pos, maxlen - pos, "%s%06X", comma, cur->prids[j]);
128 comma = ",";
131 return ret;
135 * 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().
137 char *mk_t_camd35tcp_port(void)
139 #if defined(MODULE_CAMD35) || defined(MODULE_CAMD35_TCP)
140 int32_t i, j, pos = 0, needed = 1;
142 /* Precheck to determine how long the resulting string will maximally be (might be a little bit smaller but that shouldn't hurt) */
143 for(i = 0; i < cfg.c35_tcp_ptab.nports; ++i)
145 /* Port is maximally 5 chars long, plus comma, plus the @caid, plus the :provid plus the ";" between ports */
146 needed += 18;
147 if(cfg.c35_tcp_ptab.ports[i].ncd && cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids > 0)
149 needed += cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids * 7;
152 char *value;
153 if(needed == 1 || !cs_malloc(&value, needed)) { return ""; }
154 char *saveptr = value;
155 char *dot1 = "", *dot2;
156 for(i = 0; i < cfg.c35_tcp_ptab.nports; ++i)
159 if(cfg.c35_tcp_ptab.ports[i].ncd && cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].caid)
161 pos += snprintf(value + pos, needed - (value - saveptr), "%s%d@%04X", dot1,
162 cfg.c35_tcp_ptab.ports[i].s_port,
163 cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].caid);
165 if(cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids > 0)
167 dot2 = ":";
168 for(j = 0; j < cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids; ++j)
170 pos += snprintf(value + pos, needed - (value - saveptr), "%s%06X", dot2, cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].prids[j]);
171 dot2 = ",";
174 dot1 = ";";
176 else
178 pos += snprintf(value + pos, needed - (value - saveptr), "%s%d", dot1, cfg.c35_tcp_ptab.ports[i].s_port);
179 dot1 = ";";
182 return value;
183 #else
184 return NULL;
185 #endif
188 #ifdef MODULE_CCCAM
190 * 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().
192 char *mk_t_cccam_port(void)
194 int32_t i, pos = 0, needed = CS_MAXPORTS * 6 + 8;
196 char *value;
197 if(!cs_malloc(&value, needed)) { return ""; }
198 char *dot = "";
199 for(i = 0; i < CS_MAXPORTS; i++)
201 if(!cfg.cc_port[i]) { break; }
203 pos += snprintf(value + pos, needed - pos, "%s%d", dot, cfg.cc_port[i]);
204 dot = ",";
206 return value;
208 #endif
210 #ifdef MODULE_GBOX
212 * 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().
214 char *mk_t_gbox_port(void)
216 int32_t i, pos = 0, needed = CS_MAXPORTS * 6 + 8;
218 char *value;
219 if(!cs_malloc(&value, needed)) { return ""; }
220 char *dot = "";
221 for(i = 0; i < CS_MAXPORTS; i++)
223 if(!cfg.gbox_port[i]) { break; }
225 pos += snprintf(value + pos, needed - pos, "%s%d", dot, cfg.gbox_port[i]);
226 dot = ",";
228 return value;
231 * 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().
233 char *mk_t_gbox_proxy_card(void)
235 int32_t i, pos = 0, needed = GBOX_MAX_PROXY_CARDS * 9 + 8;
237 char *value;
238 if(!cs_malloc(&value, needed)) { return ""; }
239 char *dot = "";
240 for(i = 0; i < GBOX_MAX_PROXY_CARDS; i++)
242 if(!cfg.gbox_proxy_card[i]) { break; }
244 pos += snprintf(value + pos, needed - pos, "%s%08lX", dot, cfg.gbox_proxy_card[i]);
245 dot = ",";
247 return value;
250 * 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().
252 char *mk_t_gbox_ignored_peer(void)
254 int32_t i, pos = 0, needed = GBOX_MAX_IGNORED_PEERS * 5 + 8;
256 char *value;
257 if(!cs_malloc(&value, needed)) { return ""; }
258 char *dot = "";
259 for(i = 0; i < GBOX_MAX_IGNORED_PEERS; i++)
261 if(!cfg.gbox_ignored_peer[i]) { break; }
263 pos += snprintf(value + pos, needed - pos, "%s%04hX", dot, cfg.gbox_ignored_peer[i]);
264 dot = ",";
266 return value;
269 * 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().
271 char *mk_t_accept_remm_peer(void)
273 int32_t i, pos = 0, needed = GBOX_MAX_REMM_PEERS * 5 + 8;
275 char *value;
276 if(!cs_malloc(&value, needed)) { return ""; }
277 char *dot = "";
278 for(i = 0; i < GBOX_MAX_REMM_PEERS; i++)
280 if(!cfg.accept_remm_peer[i]) { break; }
282 pos += snprintf(value + pos, needed - pos, "%s%04hX", dot, cfg.accept_remm_peer[i]);
283 dot = ",";
285 return value;
288 * 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().
290 char *mk_t_gbox_block_ecm(void)
292 int32_t i, pos = 0, needed = GBOX_MAX_BLOCKED_ECM * 5 + 8;
294 char *value;
295 if(!cs_malloc(&value, needed)) { return ""; }
296 char *dot = "";
297 for(i = 0; i < GBOX_MAX_BLOCKED_ECM; i++)
299 if(!cfg.gbox_block_ecm[i]) { break; }
301 pos += snprintf(value + pos, needed - pos, "%s%04hX", dot, cfg.gbox_block_ecm[i]);
302 dot = ",";
304 return value;
307 * 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().
309 char *mk_t_gbox_dest_peers(void)
311 int32_t i, pos = 0, needed = GBOX_MAX_DEST_PEERS * 5 + 8;
313 char *value;
314 if(!cs_malloc(&value, needed)) { return ""; }
315 char *dot = "";
316 for(i = 0; i < GBOX_MAX_DEST_PEERS; i++)
318 if(!cfg.gbox_dest_peers[i]) { break; }
319 pos += snprintf(value + pos, needed - pos, "%s%04hX", dot, cfg.gbox_dest_peers[i]);
320 dot = ",";
322 return value;
324 #endif
327 * 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().
329 char *mk_t_aeskeys(struct s_reader *rdr)
331 AES_ENTRY *current = rdr->aes_list;
332 int32_t i, pos = 0, needed = 1, prevKeyid = 0, prevCaid = 0;
333 uint32_t prevIdent = 0;
335 /* Precheck for the approximate size that we will need; it's a bit overestimated but we correct that at the end of the function */
336 while(current)
338 /* The caid, ident, "@" and the trailing ";" need to be output when they are changing */
339 if(prevCaid != current->caid || prevIdent != current->ident) { needed += 12 + (current->keyid * 2); }
340 /* "0" keys are not saved so we need to check for gaps */
341 else if(prevKeyid != current->keyid + 1) { needed += (current->keyid - prevKeyid - 1) * 2; }
342 /* The 32 byte key plus either the (heading) ":" or "," */
343 needed += 33;
344 prevCaid = current->caid;
345 prevIdent = current->ident;
346 prevKeyid = current->keyid;
347 current = current->next;
350 /* Set everything back and now create the string */
351 current = rdr->aes_list;
352 prevCaid = 0;
353 prevIdent = 0;
354 prevKeyid = 0;
355 char tmp[needed];
356 char dot;
357 if(needed == 1) { tmp[0] = '\0'; }
358 char tmpkey[33];
359 while(current)
361 /* A change in the ident or caid means that we need to output caid and ident */
362 if(prevCaid != current->caid || prevIdent != current->ident)
364 if(pos > 0)
366 tmp[pos] = ';';
367 ++pos;
369 pos += snprintf(tmp + pos, sizeof(tmp) - pos, "%04X@%06X", current->caid, current->ident);
370 prevKeyid = -1;
371 dot = ':';
373 else { dot = ','; }
374 /* "0" keys are not saved so we need to check for gaps and output them! */
375 for(i = prevKeyid + 1; i < current->keyid; ++i)
377 pos += snprintf(tmp + pos, sizeof(tmp) - pos, "%c0", dot);
378 dot = ',';
380 tmp[pos] = dot;
381 ++pos;
382 for(i = 0; i < 16; ++i) { snprintf(tmpkey + (i * 2), sizeof(tmpkey) - (i * 2), "%02X", current->plainkey[i]); }
383 /* A key consisting of only FFs has a special meaning (just return what the card outputted) and can be specified more compact */
384 if(strcmp(tmpkey, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF") == 0) { pos += snprintf(tmp + pos, sizeof(tmp) - pos, "FF"); }
385 else { pos += snprintf(tmp + pos, sizeof(tmp) - pos, "%s", tmpkey); }
386 prevCaid = current->caid;
387 prevIdent = current->ident;
388 prevKeyid = current->keyid;
389 current = current->next;
392 /* copy to result array of correct size */
393 char *value;
394 if(pos == 0 || !cs_malloc(&value, pos + 1)) { return ""; }
395 memcpy(value, tmp, pos + 1);
396 return (value);
400 * 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().
402 char *mk_t_newcamd_port(void)
404 #ifdef MODULE_NEWCAMD
405 int32_t i, j, k, pos = 0, needed = 1;
407 /* Precheck to determine how long the resulting string will maximally be (might be a little bit smaller but that shouldn't hurt) */
408 for(i = 0; i < cfg.ncd_ptab.nports; ++i)
410 /* Port is maximally 5 chars long, plus the @caid, plus the ";" between ports */
411 needed += 11;
412 if(cfg.ncd_ptab.ports[i].ncd)
414 if(cfg.ncd_ptab.ports[i].ncd->ncd_key_is_set) { needed += 30; }
415 if(cfg.ncd_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids > 0)
417 needed += cfg.ncd_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids * 7;
421 char *value;
422 if(needed == 1 || !cs_malloc(&value, needed)) { return ""; }
423 char *dot1 = "", *dot2;
425 for(i = 0; i < cfg.ncd_ptab.nports; ++i)
427 pos += snprintf(value + pos, needed - pos, "%s%d", dot1, cfg.ncd_ptab.ports[i].s_port);
429 // separate DES Key for this port
430 if(cfg.ncd_ptab.ports[i].ncd)
432 if(cfg.ncd_ptab.ports[i].ncd->ncd_key_is_set)
434 pos += snprintf(value + pos, needed - pos, "{");
435 for(k = 0; k < (int32_t)sizeof(cfg.ncd_ptab.ports[i].ncd->ncd_key); k++)
436 { pos += snprintf(value + pos, needed - pos, "%02X", cfg.ncd_ptab.ports[i].ncd->ncd_key[k]); }
437 pos += snprintf(value + pos, needed - pos, "}");
440 pos += snprintf(value + pos, needed - pos, "@%04X", cfg.ncd_ptab.ports[i].ncd->ncd_ftab.filts[0].caid);
442 if(cfg.ncd_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids > 0)
444 dot2 = ":";
445 for(j = 0; j < cfg.ncd_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids; ++j)
447 pos += snprintf(value + pos, needed - pos, "%s%06X", dot2, (int)cfg.ncd_ptab.ports[i].ncd->ncd_ftab.filts[0].prids[j]);
448 dot2 = ",";
452 dot1 = ";";
454 return value;
455 #else
456 return NULL;
457 #endif
461 * 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().
463 char *mk_t_aureader(struct s_auth *account)
465 int32_t pos = 0;
466 char *dot = "";
468 char *value;
469 if(ll_count(account->aureader_list) == 0 || !cs_malloc(&value, 256)) { return ""; }
470 value[0] = '\0';
472 struct s_reader *rdr;
473 LL_ITER itr = ll_iter_create(account->aureader_list);
474 while((rdr = ll_iter_next(&itr)))
476 pos += snprintf(value + pos, 256 - pos, "%s%s", dot, rdr->label);
477 dot = ",";
480 return value;
484 * 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().
486 char *mk_t_nano(uint16_t nano)
488 int32_t i, pos = 0, needed = 0;
490 for(i = 0; i < 16; i++)
491 if((1 << i) & nano)
492 { needed++; }
494 char *value;
495 if(nano == 0xFFFF)
497 if(!cs_malloc(&value, 4)) { return ""; }
498 snprintf(value, 4, "all");
500 else
502 if(needed == 0 || !cs_malloc(&value, needed * 3 + 1)) { return ""; }
503 value[0] = '\0';
504 for(i = 0; i < 16; i++)
506 if((1 << i) & nano)
507 { pos += snprintf(value + pos, (needed * 3) + 1 - pos, "%s%02x", pos ? "," : "", (i + 0x80)); }
510 return value;
514 * 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().
516 char *mk_t_service(SIDTABS *sidtabs)
518 int32_t i, pos;
519 char *dot;
520 char *value;
521 struct s_sidtab *sidtab = cfg.sidtab;
522 if(!sidtab || (!sidtabs->ok && !sidtabs->no) || !cs_malloc(&value, 1024)) { return ""; }
523 value[0] = '\0';
525 for(i = pos = 0, dot = ""; sidtab; sidtab = sidtab->next, i++)
527 if(sidtabs->ok & ((SIDTABBITS)1 << i))
529 pos += snprintf(value + pos, 1024 - pos, "%s%s", dot, sidtab->label);
530 dot = ",";
532 if(sidtabs->no & ((SIDTABBITS)1 << i))
534 pos += snprintf(value + pos, 1024 - pos, "%s!%s", dot, sidtab->label);
535 dot = ",";
538 return value;
542 * 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().
544 char *mk_t_logfile(void)
546 int32_t pos = 0, needed = 1;
547 char *value, *dot = "";
549 if(cfg.logtostdout == 1) { needed += 7; }
550 if(cfg.logtosyslog == 1) { needed += 7; }
551 if(cfg.logfile) { needed += strlen(cfg.logfile); }
552 if(needed == 1 || !cs_malloc(&value, needed)) { return ""; }
554 if(cfg.logtostdout == 1)
556 pos += snprintf(value + pos, needed - pos, "stdout");
557 dot = ";";
559 if(cfg.logtosyslog == 1)
561 pos += snprintf(value + pos, needed - pos, "%ssyslog", dot);
562 dot = ";";
564 if(cfg.logfile)
566 pos += snprintf(value + pos, needed - pos, "%s%s", dot, cfg.logfile);
568 return value;
572 * 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().
574 char *mk_t_ecm_whitelist(struct s_ecm_whitelist *ecm_whitelist)
576 if (!ecm_whitelist || !ecm_whitelist->ewnum) return "";
577 // Worst case scenario where each entry have different
578 // caid, ident and only one length in it is strlen("1234@123456:01;") == 15
579 int32_t i, maxlen = 16 * ecm_whitelist->ewnum, pos = 0;
580 char *ret;
581 if (!cs_malloc(&ret, maxlen))
582 return "";
583 const char *semicolon = "", *comma = "";
584 ECM_WHITELIST_DATA *last = NULL;
585 for(i = 0; i < ecm_whitelist->ewnum; i++)
587 ECM_WHITELIST_DATA *cur = &ecm_whitelist->ewdata[i];
588 bool change = !last || last->caid != cur->caid || last->ident != cur->ident;
589 if (change)
591 if (cur->caid && cur->ident)
592 pos += snprintf(ret + pos, maxlen - pos, "%s%04X@%06X:", semicolon, cur->caid, cur->ident);
593 else if (cur->caid)
594 pos += snprintf(ret + pos, maxlen - pos, "%s%04X:", semicolon, cur->caid);
595 else if (cur->ident)
596 pos += snprintf(ret + pos, maxlen - pos, "%s@%06X:", semicolon, cur->ident);
597 else
598 pos += snprintf(ret + pos, maxlen - pos, "%s", semicolon);
599 semicolon = ";";
600 comma = "";
602 pos += snprintf(ret + pos, maxlen - pos, "%s%02X", comma, cur->len);
603 comma = ",";
604 last = &ecm_whitelist->ewdata[i];
606 return ret;
610 * 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().
612 char *mk_t_ecm_hdr_whitelist(struct s_ecm_hdr_whitelist *ecm_hdr_whitelist)
614 if (!ecm_hdr_whitelist || !ecm_hdr_whitelist->ehnum) return "";
615 // Worst case scenario where each entry have different
616 // caid, provid and only one header in it is strlen("1234@123456:0102030405060708091011121314151617181920;") == 52 ((sizeof(header) / 2) + 12)
617 int32_t i, r, maxlen = 53 * ecm_hdr_whitelist->ehnum, pos = 0;
618 char *ret;
619 if (!cs_malloc(&ret, maxlen))
620 return "";
621 const char *semicolon = "", *comma = "";
622 ECM_HDR_WHITELIST_DATA *last = NULL;
623 for(i = 0; i < ecm_hdr_whitelist->ehnum; i++)
625 ECM_HDR_WHITELIST_DATA *cur = &ecm_hdr_whitelist->ehdata[i];
626 bool change = !last || last->caid != cur->caid || last->provid != cur->provid;
627 if (change)
629 if (cur->caid && cur->provid)
630 pos += snprintf(ret + pos, maxlen - pos, "%s%04X@%06X:", semicolon, cur->caid, cur->provid);
631 else if (cur->caid)
632 pos += snprintf(ret + pos, maxlen - pos, "%s%04X:", semicolon, cur->caid);
633 else if (cur->provid)
634 pos += snprintf(ret + pos, maxlen - pos, "%s@%06X:", semicolon, cur->provid);
635 else
636 pos += snprintf(ret + pos, maxlen - pos, "%s", semicolon);
637 semicolon = ";";
638 comma = "";
640 pos += snprintf(ret + pos, maxlen - pos, "%s", comma);
641 for(r = 0; r < cur->len / 2; r++)
642 pos += snprintf(ret + pos, maxlen - pos, "%02X", cur->header[r]);
643 comma = ",";
644 last = &ecm_hdr_whitelist->ehdata[i];
646 return ret;
650 * 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().
652 char *mk_t_iprange(struct s_ip *range)
654 struct s_ip *cip;
655 char *value, *dot = "";
656 int32_t needed = 1, pos = 0;
657 for(cip = range; cip; cip = cip->next) { needed += 32; }
659 char tmp[needed];
661 for(cip = range; cip; cip = cip->next)
663 pos += snprintf(tmp + pos, needed - pos, "%s%s", dot, cs_inet_ntoa(cip->ip[0]));
664 if(!IP_EQUAL(cip->ip[0], cip->ip[1])) { pos += snprintf(tmp + pos, needed - pos, "-%s", cs_inet_ntoa(cip->ip[1])); }
665 dot = ",";
667 if(pos == 0 || !cs_malloc(&value, pos + 1)) { return ""; }
668 memcpy(value, tmp, pos + 1);
669 return value;
673 * 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().
675 char *mk_t_cltab(CLASSTAB *clstab)
677 char *value, *dot = "";
678 int32_t i, needed = 1, pos = 0;
679 for(i = 0; i < clstab->an; ++i) { needed += 3; }
680 for(i = 0; i < clstab->bn; ++i) { needed += 4; }
682 char tmp[needed];
684 for(i = 0; i < clstab->an; ++i)
686 pos += snprintf(tmp + pos, needed - pos, "%s%02x", dot, (int32_t)clstab->aclass[i]);
687 dot = ",";
689 for(i = 0; i < clstab->bn; ++i)
691 pos += snprintf(tmp + pos, needed - pos, "%s!%02x", dot, (int32_t)clstab->bclass[i]);
692 dot = ",";
695 if(pos == 0 || !cs_malloc(&value, pos + 1)) { return ""; }
696 memcpy(value, tmp, pos + 1);
697 return value;
701 * Creates a string ready to write as a token into config or WebIf. You must free the returned value through free_mk_t().
703 char *mk_t_caidvaluetab(CAIDVALUETAB *caidvaluetab)
705 if (!caidvaluetab || !caidvaluetab->cvnum) return "";
706 // Max entry length is strlen("1234@65535,") == 11
707 int32_t i, maxlen = 12 * caidvaluetab->cvnum, pos = 0;
708 char *ret;
709 if (!cs_malloc(&ret, maxlen))
710 return "";
711 const char *comma = "";
712 for(i = 0; i < caidvaluetab->cvnum; i++)
714 CAIDVALUETAB_DATA *d = &caidvaluetab->cvdata[i];
715 if (d->caid < 0x0100)
716 pos += snprintf(ret + pos, maxlen - pos, "%s%02X:%d", comma, d->caid, d->value);
717 else
718 pos += snprintf(ret + pos, maxlen - pos, "%s%04X:%d", comma, d->caid, d->value);
719 comma = ",";
721 return ret;
724 char *mk_t_cacheex_valuetab(CECSPVALUETAB *tab)
726 if (!tab || !tab->cevnum) return "";
727 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","
728 char *buf;
729 if(!cs_malloc(&buf, size))
730 { return ""; }
731 char *ptr = buf;
733 for(i = 0; i < tab->cevnum; i++)
735 CECSPVALUETAB_DATA *d = &tab->cevdata[i];
736 if(i) { ptr += snprintf(ptr, size - (ptr - buf), ","); }
737 if(d->caid >= 0)
739 if(d->caid == 0)
741 if(d->awtime > 0)
742 { ptr += snprintf(ptr, size - (ptr - buf), "%d", d->caid); }
744 else if(d->caid < 256) //Do not format 0D as 000D, its a shortcut for 0Dxx:
745 { ptr += snprintf(ptr, size - (ptr - buf), "%02X", d->caid); }
746 else
747 { ptr += snprintf(ptr, size - (ptr - buf), "%04X", d->caid); }
749 if(d->cmask >= 0)
750 { ptr += snprintf(ptr, size - (ptr - buf), "&%04X", d->cmask); }
751 if(d->prid >= 0)
752 { ptr += snprintf(ptr, size - (ptr - buf), "@%06X", d->prid); }
753 if(d->srvid >= 0)
754 { ptr += snprintf(ptr, size - (ptr - buf), "$%04X", d->srvid); }
755 if(d->awtime > 0)
756 { ptr += snprintf(ptr, size - (ptr - buf), ":%d", d->awtime); }
757 if(!(d->dwtime > 0))
758 { ptr += snprintf(ptr, size - (ptr - buf), ":0"); }
759 if(d->dwtime > 0)
761 if((d->caid <= 0) && (d->prid == -1) && (d->srvid == -1) && (d->srvid == -1) && (d->awtime <= 0))
762 { ptr += snprintf(ptr, size - (ptr - buf), "%d", d->dwtime); }
763 else
764 { ptr += snprintf(ptr, size - (ptr - buf), ":%d", d->dwtime); }
767 *ptr = 0;
768 return buf;
772 char *mk_t_cacheex_cwcheck_valuetab(CWCHECKTAB *tab)
774 if(!tab || !tab->cwchecknum) { return ""; }
775 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","
776 char *buf;
777 if(!cs_malloc(&buf, size))
778 { return ""; }
779 char *ptr = buf;
781 for(i = 0; i < tab->cwchecknum; i++)
783 CWCHECKTAB_DATA *d = &tab->cwcheckdata[i];
785 if(i) { ptr += snprintf(ptr, size - (ptr - buf), ","); }
786 if(d->caid >= 0)
788 if(d->caid == 0)
789 { ptr += snprintf(ptr, size - (ptr - buf), "%d", d->caid); }
790 else if(d->caid < 256) //Do not format 0D as 000D, its a shortcut for 0Dxx:
791 { ptr += snprintf(ptr, size - (ptr - buf), "%02X", d->caid); }
792 else
793 { ptr += snprintf(ptr, size - (ptr - buf), "%04X", d->caid); }
795 if(d->cmask >= 0)
796 { ptr += snprintf(ptr, size - (ptr - buf), "&%04X", d->cmask); }
797 if(d->prid >= 0)
798 { ptr += snprintf(ptr, size - (ptr - buf), "@%06X", d->prid); }
799 if(d->srvid >= 0)
800 { ptr += snprintf(ptr, size - (ptr - buf), "$%04X", d->srvid); }
801 if(d->mode >= 0)
802 { ptr += snprintf(ptr, size - (ptr - buf), ":%d", d->mode); }
803 if(d->counter > 0)
804 { ptr += snprintf(ptr, size - (ptr - buf), ":%d", d->counter); }
806 *ptr = 0;
807 return buf;
810 char *mk_t_cacheex_hitvaluetab(CECSPVALUETAB *tab)
812 if (!tab || !tab->cevnum) return "";
813 int32_t i, size = 2 + tab->cevnum * (4 + 1 + 4 + 1 + 6 + 1 + 4 + 1); //caid&mask@provid$servid","
814 char *buf;
815 if(!cs_malloc(&buf, size))
816 { return ""; }
817 char *ptr = buf;
819 for(i = 0; i < tab->cevnum; i++)
821 CECSPVALUETAB_DATA *d = &tab->cevdata[i];
822 if(i) { ptr += snprintf(ptr, size - (ptr - buf), ","); }
823 if(d->caid > 0)
825 if(d->caid < 256) //Do not format 0D as 000D, its a shortcut for 0Dxx:
826 { ptr += snprintf(ptr, size - (ptr - buf), "%02X", d->caid); }
827 else
828 { ptr += snprintf(ptr, size - (ptr - buf), "%04X", d->caid); }
829 if(d->cmask >= 0)
830 { ptr += snprintf(ptr, size - (ptr - buf), "&%04X", d->cmask); }
831 if(d->prid >= 0)
832 { ptr += snprintf(ptr, size - (ptr - buf), "@%06X", d->prid); }
833 if(d->srvid >= 0)
834 { ptr += snprintf(ptr, size - (ptr - buf), "$%04X", d->srvid); }
837 *ptr = 0;
838 return buf;
842 * returns string of comma separated values
844 char *mk_t_emmbylen(struct s_reader *rdr)
846 char *value, *pos, *dot = "";
847 int32_t num, needed = 0;
848 struct s_emmlen_range *blocklen;
850 if(!rdr->blockemmbylen)
851 { return ""; }
853 LL_ITER it = ll_iter_create(rdr->blockemmbylen);
854 while((blocklen = ll_iter_next(&it)))
856 needed += 5 + 1; // max digits of int16 + ","
857 if(blocklen->max == 0)
858 { needed += 1 + 1; } // "-" + ","
859 else if(blocklen->min != blocklen->max)
860 { needed += 1 + 5 + 1; } // "-" + max digits of int16 + ","
862 // the trailing zero is already included: it's the first ","
863 if(!cs_malloc(&value, needed))
864 { return ""; }
866 pos = value;
867 ll_iter_reset(&it);
868 while((blocklen = ll_iter_next(&it)))
870 if(blocklen->min == blocklen->max)
871 { num = snprintf(pos, needed, "%s%d", dot, blocklen->min); }
872 else if(blocklen->max == 0)
873 { num = snprintf(pos, needed, "%s%d-", dot, blocklen->min); }
874 else
875 { num = snprintf(pos, needed, "%s%d-%d", dot, blocklen->min, blocklen->max); }
876 pos += num;
877 needed -= num;
878 dot = ",";
880 return value;
884 * makes string from binary structure
886 char *mk_t_allowedprotocols(struct s_auth *account)
889 if(!account->allowedprotocols)
890 { return ""; }
892 int16_t i, tmp = 1, pos = 0, needed = 255, tagcnt;
893 char *tag[] = {"camd33", "cs357x", "cs378x", "newcamd", "cccam", "gbox", "radegast", "dvbapi", "constcw", "serial"};
894 char *value, *dot = "";
896 if(!cs_malloc(&value, needed))
897 { return ""; }
899 tagcnt = sizeof(tag) / sizeof(char *);
900 for(i = 0; i < tagcnt; i++)
902 if((account->allowedprotocols & tmp) == tmp)
904 pos += snprintf(value + pos, needed, "%s%s", dot, tag[i]);
905 dot = ",";
907 tmp = tmp << 1;
909 return value;
913 * return allowed time frame string from internal array content
917 char *mk_t_allowedtimeframe(struct s_auth *account)
919 char *result;
920 if(!cs_malloc(&result, MAXALLOWEDTF))
921 { return ""; }
923 if(account->allowedtimeframe_set)
925 char mytime[6];
926 uint8_t day;
927 uint8_t value_in_day = 0;
928 uint8_t intime = 0;
929 uint16_t minutes =0;
930 uint16_t hours;
931 char septime[2] = {'\0'};
932 char sepday[2] = {'\0'};
934 for(day=0;day<SIZE_SHORTDAY;day++) {
935 for(hours=0;hours<24;hours++) {
936 for(minutes=0;minutes<60;minutes++) {
937 if(CHECK_BIT(account->allowedtimeframe[day][hours][minutes/30],(minutes % 30))) {
938 if(value_in_day == 0) {
939 strcat(result,&sepday[0]);
940 strcat(result,shortDay[day]);
941 strcat(result,"@");
942 value_in_day = 1;
943 intime=0;
944 sepday[0]=';';
945 septime[0]='\0';
947 if(!intime) {
948 strcat(result,&septime[0]);
949 snprintf(mytime,6,"%02d:%02d", hours, minutes);
950 strcat(result,mytime);
951 strcat(result,"-");
952 septime[0]=',';
953 intime=1;
955 // Special case 23H59 is enabled we close the day at 24H00
956 if(((hours*60)+minutes)==1439) {
957 strcat(result,"24:00");
958 intime=0;
959 septime[0]='\0';
960 value_in_day = 0;
963 else if(intime) {
964 snprintf(mytime,6,"%02d:%02d", hours, minutes);
965 strcat(result,mytime);
966 septime[0]=',';
967 intime=0;
971 value_in_day = 0;
974 else {
975 result="";
977 return result;
981 * mk_t-functions give back a constant empty string when allocation fails or when the result is an empty string.
982 * This function thus checks the stringlength and only frees if necessary.
984 void free_mk_t(char *value)
986 if(strlen(value) > 0) { NULLFREE(value); }