1 #define MODULE_LOG_PREFIX "config"
4 #include "oscam-conf-mk.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;
20 if (!cs_malloc(&ret
, maxlen
))
22 const char *comma
= "";
23 for(i
= 0; i
< caidtab
->ctnum
; i
++)
25 CAIDTAB_DATA
*d
= &caidtab
->ctdata
[i
];
27 pos
+= snprintf(ret
+ pos
, maxlen
- pos
, "%s%02X", comma
, d
->caid
);
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
);
33 pos
+= snprintf(ret
+ pos
, maxlen
- pos
, ":%04X", d
->cmap
);
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;
48 if (!cs_malloc(&ret
, maxlen
))
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
);
57 pos
+= snprintf(ret
+ pos
, maxlen
- pos
, ":%04X", d
->bt_caidto
);
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
))
75 if(i
> 9) { needed
+= 1; }
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
))
87 snprintf(value
+ pos
, needed
- (value
- saveptr
), "%d", i
+ 1);
88 if(i
> 8) { pos
+= 2; }
94 snprintf(value
+ pos
, needed
- (value
- saveptr
), ",%d", i
+ 1);
95 if(i
> 8) { pos
+= 3; }
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 */
116 if (!cs_malloc(&ret
, maxlen
))
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
);
125 for (j
= 0; j
< cur
->nprids
; j
++)
127 pos
+= snprintf(ret
+ pos
, maxlen
- pos
, "%s%06X", comma
, cur
->prids
[j
]);
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 */
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;
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)
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
]);
178 pos
+= snprintf(value
+ pos
, needed
- (value
- saveptr
), "%s%d", dot1
, cfg
.c35_tcp_ptab
.ports
[i
].s_port
);
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;
197 if(!cs_malloc(&value
, needed
)) { return ""; }
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
]);
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;
219 if(!cs_malloc(&value
, needed
)) { return ""; }
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
]);
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;
238 if(!cs_malloc(&value
, needed
)) { return ""; }
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
]);
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;
257 if(!cs_malloc(&value
, needed
)) { return ""; }
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
]);
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;
276 if(!cs_malloc(&value
, needed
)) { return ""; }
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
]);
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;
295 if(!cs_malloc(&value
, needed
)) { return ""; }
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
]);
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;
314 if(!cs_malloc(&value
, needed
)) { return ""; }
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
]);
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 */
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 "," */
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
;
357 if(needed
== 1) { tmp
[0] = '\0'; }
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
)
369 pos
+= snprintf(tmp
+ pos
, sizeof(tmp
) - pos
, "%04X@%06X", current
->caid
, current
->ident
);
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
);
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 */
394 if(pos
== 0 || !cs_malloc(&value
, pos
+ 1)) { return ""; }
395 memcpy(value
, tmp
, pos
+ 1);
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 */
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;
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)
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
]);
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
)
469 if(ll_count(account
->aureader_list
) == 0 || !cs_malloc(&value
, 256)) { return ""; }
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
);
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
++)
497 if(!cs_malloc(&value
, 4)) { return ""; }
498 snprintf(value
, 4, "all");
502 if(needed
== 0 || !cs_malloc(&value
, needed
* 3 + 1)) { return ""; }
504 for(i
= 0; i
< 16; i
++)
507 { pos
+= snprintf(value
+ pos
, (needed
* 3) + 1 - pos
, "%s%02x", pos
? "," : "", (i
+ 0x80)); }
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
)
521 struct s_sidtab
*sidtab
= cfg
.sidtab
;
522 if(!sidtab
|| (!sidtabs
->ok
&& !sidtabs
->no
) || !cs_malloc(&value
, 1024)) { return ""; }
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
);
532 if(sidtabs
->no
& ((SIDTABBITS
)1 << i
))
534 pos
+= snprintf(value
+ pos
, 1024 - pos
, "%s!%s", dot
, sidtab
->label
);
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");
559 if(cfg
.logtosyslog
== 1)
561 pos
+= snprintf(value
+ pos
, needed
- pos
, "%ssyslog", dot
);
566 pos
+= snprintf(value
+ pos
, needed
- pos
, "%s%s", dot
, cfg
.logfile
);
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;
581 if (!cs_malloc(&ret
, maxlen
))
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
;
591 if (cur
->caid
&& cur
->ident
)
592 pos
+= snprintf(ret
+ pos
, maxlen
- pos
, "%s%04X@%06X:", semicolon
, cur
->caid
, cur
->ident
);
594 pos
+= snprintf(ret
+ pos
, maxlen
- pos
, "%s%04X:", semicolon
, cur
->caid
);
596 pos
+= snprintf(ret
+ pos
, maxlen
- pos
, "%s@%06X:", semicolon
, cur
->ident
);
598 pos
+= snprintf(ret
+ pos
, maxlen
- pos
, "%s", semicolon
);
602 pos
+= snprintf(ret
+ pos
, maxlen
- pos
, "%s%02X", comma
, cur
->len
);
604 last
= &ecm_whitelist
->ewdata
[i
];
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;
619 if (!cs_malloc(&ret
, maxlen
))
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
;
629 if (cur
->caid
&& cur
->provid
)
630 pos
+= snprintf(ret
+ pos
, maxlen
- pos
, "%s%04X@%06X:", semicolon
, cur
->caid
, cur
->provid
);
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
);
636 pos
+= snprintf(ret
+ pos
, maxlen
- pos
, "%s", semicolon
);
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
]);
644 last
= &ecm_hdr_whitelist
->ehdata
[i
];
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
)
655 char *value
, *dot
= "";
656 int32_t needed
= 1, pos
= 0;
657 for(cip
= range
; cip
; cip
= cip
->next
) { needed
+= 32; }
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])); }
667 if(pos
== 0 || !cs_malloc(&value
, pos
+ 1)) { return ""; }
668 memcpy(value
, tmp
, pos
+ 1);
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; }
684 for(i
= 0; i
< clstab
->an
; ++i
)
686 pos
+= snprintf(tmp
+ pos
, needed
- pos
, "%s%02x", dot
, (int32_t)clstab
->aclass
[i
]);
689 for(i
= 0; i
< clstab
->bn
; ++i
)
691 pos
+= snprintf(tmp
+ pos
, needed
- pos
, "%s!%02x", dot
, (int32_t)clstab
->bclass
[i
]);
695 if(pos
== 0 || !cs_malloc(&value
, pos
+ 1)) { return ""; }
696 memcpy(value
, tmp
, pos
+ 1);
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;
709 if (!cs_malloc(&ret
, maxlen
))
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
);
718 pos
+= snprintf(ret
+ pos
, maxlen
- pos
, "%s%04X:%d", comma
, d
->caid
, d
->value
);
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","
729 if(!cs_malloc(&buf
, size
))
733 for(i
= 0; i
< tab
->cevnum
; i
++)
735 CECSPVALUETAB_DATA
*d
= &tab
->cevdata
[i
];
736 if(i
) { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), ","); }
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
); }
747 { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), "%04X", d
->caid
); }
750 { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), "&%04X", d
->cmask
); }
752 { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), "@%06X", d
->prid
); }
754 { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), "$%04X", d
->srvid
); }
756 { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), ":%d", d
->awtime
); }
758 { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), ":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
); }
764 { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), ":%d", d
->dwtime
); }
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","
777 if(!cs_malloc(&buf
, size
))
781 for(i
= 0; i
< tab
->cwchecknum
; i
++)
783 CWCHECKTAB_DATA
*d
= &tab
->cwcheckdata
[i
];
785 if(i
) { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), ","); }
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
); }
793 { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), "%04X", d
->caid
); }
796 { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), "&%04X", d
->cmask
); }
798 { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), "@%06X", d
->prid
); }
800 { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), "$%04X", d
->srvid
); }
802 { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), ":%d", d
->mode
); }
804 { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), ":%d", d
->counter
); }
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","
815 if(!cs_malloc(&buf
, size
))
819 for(i
= 0; i
< tab
->cevnum
; i
++)
821 CECSPVALUETAB_DATA
*d
= &tab
->cevdata
[i
];
822 if(i
) { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), ","); }
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
); }
828 { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), "%04X", d
->caid
); }
830 { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), "&%04X", d
->cmask
); }
832 { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), "@%06X", d
->prid
); }
834 { ptr
+= snprintf(ptr
, size
- (ptr
- buf
), "$%04X", d
->srvid
); }
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
)
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
))
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
); }
875 { num
= snprintf(pos
, needed
, "%s%d-%d", dot
, blocklen
->min
, blocklen
->max
); }
884 * makes string from binary structure
886 char *mk_t_allowedprotocols(struct s_auth
*account
)
889 if(!account
->allowedprotocols
)
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
))
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
]);
913 * return allowed time frame string from internal array content
917 char *mk_t_allowedtimeframe(struct s_auth
*account
)
920 if(!cs_malloc(&result
, MAXALLOWEDTF
))
923 if(account
->allowedtimeframe_set
)
927 uint8_t value_in_day
= 0;
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
]);
948 strcat(result
,&septime
[0]);
949 snprintf(mytime
,6,"%02d:%02d", hours
, minutes
);
950 strcat(result
,mytime
);
955 // Special case 23H59 is enabled we close the day at 24H00
956 if(((hours
*60)+minutes
)==1439) {
957 strcat(result
,"24:00");
964 snprintf(mytime
,6,"%02d:%02d", hours
, minutes
);
965 strcat(result
,mytime
);
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
); }