source: trunk/oscam-conf-mk.c@ 8456

Last change on this file since 8456 was 8456, checked in by gf, 9 years ago

Slim down struct s_port.

struct s_port contains filter array and couple of other fields that are
used only for newcamd and nothing else. They waste more than 2k in common
case.

To stop losing this much space, create private structure only for
newcamd fields and allocate it dynamically. This lowers struct s_port
size a lot and of course struct s_ptab even more because it contains
array of struct s_ports's.

New structure sizes (32-bit):

                  before  after
  struct s_port     2144     12
  struct s_ptab    68612    388
  struct s_config 141260   4812

Size report (32-bit):

    text     data      bss      dec    hex filename
  998222     1944   602344  1602510 1873ce before/oscam-1.20-unstable_svn8453-i486-slackware-linux
  998174     1944    61800  1061918 10341e  after/oscam-1.20-unstable_svn8453-i486-slackware-linux

bloat-o-meter report (32-bit):

  add/remove: 0/1 grow/shrink: 13/16 up/down: 7897/-548383 (-540486)
  function                                     old     new   delta
  modules                                     1840    9520   +7680
  ...
  cfg                                       141260    4812 -136448
  static.ptab                               411672       - -411672
File size: 21.3 KB
Line 
1#include "globals.h"
2#include "oscam-conf-mk.h"
3#include "oscam-net.h"
4#include "oscam-string.h"
5
6/*
7 * 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().
8 */
9char *mk_t_caidtab(CAIDTAB *ctab) {
10 int32_t i = 0, needed = 1, pos = 0;
11 while(ctab->caid[i]) {
12 if(ctab->mask[i]) needed += 10;
13 else needed += 5;
14 if(ctab->cmap[i]) needed += 5;
15 ++i;
16 }
17 char *value;
18 if (needed == 1 || !cs_malloc(&value, needed)) return "";
19 char *saveptr = value;
20 i = 0;
21 while(ctab->caid[i]) {
22 if (ctab->caid[i] < 0x0100) { //for "ignore provider for" option, caid-shortcut, just first 2 bytes:
23 if(i == 0) {
24 snprintf(value + pos, needed-(value-saveptr), "%02X", ctab->caid[i]);
25 pos += 2;
26 } else {
27 snprintf(value + pos, needed-(value-saveptr), ",%02X", ctab->caid[i]);
28 pos += 3;
29 }
30 } else {
31 if(i == 0) {
32 snprintf(value + pos, needed-(value-saveptr), "%04X", ctab->caid[i]);
33 pos += 4;
34 } else {
35 snprintf(value + pos, needed-(value-saveptr), ",%04X", ctab->caid[i]);
36 pos += 5;
37 }
38 }
39
40 if((ctab->mask[i]) && (ctab->mask[i] != 0xFFFF)) {
41 snprintf(value + pos, needed-(value-saveptr), "&%04X", ctab->mask[i]);
42 pos += 5;
43 }
44 if(ctab->cmap[i]) {
45 snprintf(value + pos, needed-(value-saveptr), ":%04X", ctab->cmap[i]);
46 pos += 5;
47 }
48 ++i;
49 }
50 value[pos] = '\0';
51 return value;
52}
53
54/*
55 * 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().
56 */
57char *mk_t_tuntab(TUNTAB *ttab) {
58 int32_t i, needed = 1, pos = 0;
59 for (i=0; i<ttab->n; i++) {
60 if(ttab->bt_srvid[i]) needed += 10;
61 else needed += 5;
62 if(ttab->bt_caidto[i]) needed += 5;
63 }
64 char *value;
65 if (needed == 1 || !cs_malloc(&value, needed)) return "";
66 char *saveptr = value;
67 for (i=0; i<ttab->n; i++) {
68 if(i == 0) {
69 snprintf(value + pos, needed-(value-saveptr), "%04X", ttab->bt_caidfrom[i]);
70 pos += 4;
71 } else {
72 snprintf(value + pos, needed-(value-saveptr), ",%04X", ttab->bt_caidfrom[i]);
73 pos += 5;
74 }
75 if(ttab->bt_srvid[i]) {
76 snprintf(value + pos, needed-(value-saveptr), ".%04X", ttab->bt_srvid[i]);
77 pos += 5;
78 }
79 if(ttab->bt_caidto[i]) {
80 snprintf(value + pos, needed-(value-saveptr), ":%04X", ttab->bt_caidto[i]);
81 pos += 5;
82 }
83 }
84 value[pos] = '\0';
85 return value;
86}
87
88/*
89 * 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().
90 */
91char *mk_t_group(uint64_t grp) {
92 int32_t i = 0, needed = 1, pos = 0, dot = 0;
93
94 for(i = 0; i < 64; i++) {
95 if (grp&((uint64_t)1<<i)) {
96 needed += 2;
97 if(i > 9) needed += 1;
98 }
99 }
100 char *value;
101 if (needed == 1 || !cs_malloc(&value, needed)) return "";
102 char * saveptr = value;
103 for(i = 0; i < 64; i++) {
104 if (grp&((uint64_t)1<<i)) {
105 if (dot == 0) {
106 snprintf(value + pos, needed-(value-saveptr), "%d", i+1);
107 if (i > 8)pos += 2;
108 else pos += 1;
109 dot = 1;
110 } else {
111 snprintf(value + pos, needed-(value-saveptr), ",%d", i+1);
112 if (i > 8)pos += 3;
113 else pos += 2;
114 }
115 }
116 }
117 value[pos] = '\0';
118 return value;
119}
120
121/*
122 * 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().
123 */
124char *mk_t_ftab(FTAB *ftab) {
125 int32_t i = 0, j = 0, needed = 1, pos = 0;
126
127 if (ftab->nfilts != 0) {
128 needed = ftab->nfilts * 5;
129 for (i = 0; i < ftab->nfilts; ++i)
130 needed += ftab->filts[i].nprids * 7;
131 }
132
133 char *value;
134 if (needed == 1 || !cs_malloc(&value, needed)) return "";
135 char *saveptr = value;
136 char *dot="";
137 for (i = 0; i < ftab->nfilts; ++i) {
138 snprintf(value + pos, needed-(value-saveptr), "%s%04X", dot, ftab->filts[i].caid);
139 pos += 4;
140 if (i > 0) pos += 1;
141 dot=":";
142 for (j = 0; j < ftab->filts[i].nprids; ++j) {
143 snprintf(value + pos, needed-(value-saveptr), "%s%06X", dot, ftab->filts[i].prids[j]);
144 pos += 7;
145 dot=",";
146 }
147 dot=";";
148 }
149
150 value[pos] = '\0';
151 return value;
152}
153
154/*
155 * 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().
156 */
157char *mk_t_camd35tcp_port(void) {
158 int32_t i, j, pos = 0, needed = 1;
159
160 /* Precheck to determine how long the resulting string will maximally be (might be a little bit smaller but that shouldn't hurt) */
161 for(i = 0; i < cfg.c35_tcp_ptab.nports; ++i) {
162 /* Port is maximally 5 chars long, plus the @caid, plus the ";" between ports */
163 needed += 11;
164 if (cfg.c35_tcp_ptab.ports[i].ncd && cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids > 1) {
165 needed += cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids * 7;
166 }
167 }
168 char *value;
169 if (needed == 1 || !cs_malloc(&value, needed)) return "";
170 char *saveptr = value;
171 char *dot1 = "", *dot2;
172 for(i = 0; i < cfg.c35_tcp_ptab.nports; ++i) {
173
174 if (cfg.c35_tcp_ptab.ports[i].ncd && cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].caid) {
175 pos += snprintf(value + pos, needed-(value-saveptr), "%s%d@%04X", dot1,
176 cfg.c35_tcp_ptab.ports[i].s_port,
177 cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].caid);
178
179 if (cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids > 1) {
180 dot2 = ":";
181 for (j = 0; j < cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids; ++j) {
182 pos += snprintf(value + pos, needed-(value-saveptr), "%s%X", dot2, cfg.c35_tcp_ptab.ports[i].ncd->ncd_ftab.filts[0].prids[j]);
183 dot2 = ",";
184 }
185 }
186 dot1=";";
187 } else {
188 pos += snprintf(value + pos, needed-(value-saveptr), "%d", cfg.c35_tcp_ptab.ports[i].s_port);
189 }
190 }
191 return value;
192}
193
194#ifdef MODULE_CCCAM
195/*
196 * 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().
197 */
198char *mk_t_cccam_port(void) {
199 int32_t i, pos = 0, needed = CS_MAXPORTS*6+8;
200
201 char *value;
202 if (!cs_malloc(&value, needed)) return "";
203 char *dot = "";
204 for(i = 0; i < CS_MAXPORTS; i++) {
205 if (!cfg.cc_port[i]) break;
206
207 pos += snprintf(value + pos, needed-pos, "%s%d", dot, cfg.cc_port[i]);
208 dot=",";
209 }
210 return value;
211}
212#endif
213
214
215/*
216 * 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().
217 */
218char *mk_t_aeskeys(struct s_reader *rdr) {
219 AES_ENTRY *current = rdr->aes_list;
220 int32_t i, pos = 0, needed = 1, prevKeyid = 0, prevCaid = 0;
221 uint32_t prevIdent = 0;
222
223 /* Precheck for the approximate size that we will need; it's a bit overestimated but we correct that at the end of the function */
224 while(current) {
225 /* The caid, ident, "@" and the trailing ";" need to be output when they are changing */
226 if(prevCaid != current->caid || prevIdent != current->ident) needed += 12 + (current->keyid * 2);
227 /* "0" keys are not saved so we need to check for gaps */
228 else if(prevKeyid != current->keyid + 1) needed += (current->keyid - prevKeyid - 1) * 2;
229 /* The 32 byte key plus either the (heading) ":" or "," */
230 needed += 33;
231 prevCaid = current->caid;
232 prevIdent = current->ident;
233 prevKeyid = current->keyid;
234 current = current->next;
235 }
236
237 /* Set everything back and now create the string */
238 current = rdr->aes_list;
239 prevCaid = 0;
240 prevIdent = 0;
241 prevKeyid = 0;
242 char tmp[needed];
243 char dot;
244 if(needed == 1) tmp[0] = '\0';
245 char tmpkey[33];
246 while(current) {
247 /* A change in the ident or caid means that we need to output caid and ident */
248 if(prevCaid != current->caid || prevIdent != current->ident) {
249 if(pos > 0) {
250 tmp[pos] = ';';
251 ++pos;
252 }
253 pos += snprintf(tmp+pos, sizeof(tmp)-pos, "%04X@%06X", current->caid, current->ident);
254 prevKeyid = -1;
255 dot = ':';
256 } else dot = ',';
257 /* "0" keys are not saved so we need to check for gaps and output them! */
258 for (i = prevKeyid + 1; i < current->keyid; ++i) {
259 pos += snprintf(tmp+pos, sizeof(tmp)-pos, "%c0", dot);
260 dot = ',';
261 }
262 tmp[pos] = dot;
263 ++pos;
264 for (i = 0; i < 16; ++i) snprintf(tmpkey + (i*2), sizeof(tmpkey) - (i*2), "%02X", current->plainkey[i]);
265 /* A key consisting of only FFs has a special meaning (just return what the card outputted) and can be specified more compact */
266 if(strcmp(tmpkey, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF") == 0) pos += snprintf(tmp+pos, sizeof(tmp)-pos, "FF");
267 else pos += snprintf(tmp+pos, sizeof(tmp)-pos, "%s", tmpkey);
268 prevCaid = current->caid;
269 prevIdent = current->ident;
270 prevKeyid = current->keyid;
271 current = current->next;
272 }
273
274 /* copy to result array of correct size */
275 char *value;
276 if (pos == 0 || !cs_malloc(&value, pos + 1)) return "";
277 memcpy(value, tmp, pos + 1);
278 return(value);
279}
280
281/*
282 * 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().
283 */
284char *mk_t_newcamd_port(void) {
285 int32_t i, j, k, pos = 0, needed = 1;
286
287 /* Precheck to determine how long the resulting string will maximally be (might be a little bit smaller but that shouldn't hurt) */
288 for(i = 0; i < cfg.ncd_ptab.nports; ++i) {
289 /* Port is maximally 5 chars long, plus the @caid, plus the ";" between ports */
290 needed += 11;
291 if (cfg.ncd_ptab.ports[i].ncd) {
292 if(cfg.ncd_ptab.ports[i].ncd->ncd_key_is_set) needed += 30;
293 if (cfg.ncd_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids > 0) {
294 needed += cfg.ncd_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids * 7;
295 }
296 }
297 }
298 char *value;
299 if (needed == 1 || !cs_malloc(&value, needed)) return "";
300 char *dot1 = "", *dot2;
301
302 for(i = 0; i < cfg.ncd_ptab.nports; ++i) {
303 pos += snprintf(value + pos, needed-pos, "%s%d", dot1, cfg.ncd_ptab.ports[i].s_port);
304
305 // separate DES Key for this port
306 if (cfg.ncd_ptab.ports[i].ncd) {
307 if(cfg.ncd_ptab.ports[i].ncd->ncd_key_is_set) {
308 pos += snprintf(value + pos, needed-pos, "{");
309 for (k = 0; k < (int32_t)sizeof(cfg.ncd_ptab.ports[i].ncd->ncd_key[k]); k++)
310 pos += snprintf(value + pos, needed-pos, "%02X", cfg.ncd_ptab.ports[i].ncd->ncd_key[k]);
311 pos += snprintf(value + pos, needed-pos, "}");
312 }
313
314 pos += snprintf(value + pos, needed-pos, "@%04X", cfg.ncd_ptab.ports[i].ncd->ncd_ftab.filts[0].caid);
315
316 if (cfg.ncd_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids > 0) {
317 dot2 = ":";
318 for (j = 0; j < cfg.ncd_ptab.ports[i].ncd->ncd_ftab.filts[0].nprids; ++j) {
319 pos += snprintf(value + pos, needed-pos, "%s%06X", dot2, (int)cfg.ncd_ptab.ports[i].ncd->ncd_ftab.filts[0].prids[j]);
320 dot2 = ",";
321 }
322 }
323 }
324 dot1=";";
325 }
326 return value;
327}
328
329/*
330 * 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().
331 */
332char *mk_t_aureader(struct s_auth *account) {
333 int32_t pos = 0;
334 char *dot = "";
335
336 char *value;
337 if (ll_count(account->aureader_list) == 0 || !cs_malloc(&value, 256)) return "";
338 value[0] = '\0';
339
340 struct s_reader *rdr;
341 LL_ITER itr = ll_iter_create(account->aureader_list);
342 while ((rdr = ll_iter_next(&itr))) {
343 pos += snprintf(value + pos, 256-pos, "%s%s", dot, rdr->label);
344 dot = ",";
345 }
346
347 return value;
348}
349
350/*
351 * 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().
352 */
353char *mk_t_nano(uint16_t nano) {
354 int32_t i, pos = 0, needed = 0;
355
356 for (i=0; i<16; i++)
357 if ((1 << i) & nano)
358 needed++;
359
360 char *value;
361 if (nano == 0xFFFF) {
362 if (!cs_malloc(&value, 4)) return "";
363 snprintf(value, 4, "all");
364 } else {
365 if (needed == 0 || !cs_malloc(&value, needed * 3 + 1)) return "";
366 value[0] = '\0';
367 for (i=0; i<16; i++) {
368 if ((1 << i) & nano)
369 pos += snprintf(value + pos, (needed*3)+1-pos, "%s%02x", pos ? "," : "", (i+0x80));
370 }
371 }
372 return value;
373}
374
375/*
376 * 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().
377 */
378char *mk_t_service(SIDTABS *sidtabs) {
379 int32_t i, pos;
380 char *dot;
381 char *value;
382 struct s_sidtab *sidtab = cfg.sidtab;
383 if (!sidtab || (!sidtabs->ok && !sidtabs->no) || !cs_malloc(&value, 1024)) return "";
384 value[0] = '\0';
385
386 for (i=pos=0,dot=""; sidtab; sidtab=sidtab->next,i++) {
387 if (sidtabs->ok&((SIDTABBITS)1<<i)) {
388 pos += snprintf(value + pos, 1024 - pos, "%s%s", dot, sidtab->label);
389 dot = ",";
390 }
391 if (sidtabs->no&((SIDTABBITS)1<<i)) {
392 pos += snprintf(value + pos, 1024 - pos, "%s!%s", dot, sidtab->label);
393 dot = ",";
394 }
395 }
396 return value;
397}
398
399/*
400 * 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().
401 */
402char *mk_t_logfile(void) {
403 int32_t pos = 0, needed = 1;
404 char *value, *dot = "";
405
406 if(cfg.logtostdout == 1) needed += 7;
407 if(cfg.logtosyslog == 1) needed += 7;
408 if(cfg.logfile) needed += strlen(cfg.logfile);
409 if (needed == 1 || !cs_malloc(&value, needed)) return "";
410
411 if(cfg.logtostdout == 1) {
412 pos += snprintf(value + pos, needed - pos, "stdout");
413 dot = ";";
414 }
415 if(cfg.logtosyslog == 1) {
416 pos += snprintf(value + pos, needed - pos, "%ssyslog", dot);
417 dot = ";";
418 }
419 if(cfg.logfile) {
420 pos += snprintf(value + pos, needed - pos, "%s%s", dot, cfg.logfile);
421 }
422 return value;
423}
424
425/*
426 * 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().
427 */
428char *mk_t_ecmwhitelist(struct s_ecmWhitelist *whitelist) {
429 int32_t needed = 1, pos = 0;
430 struct s_ecmWhitelist *cip;
431 struct s_ecmWhitelistIdent *cip2;
432 struct s_ecmWhitelistLen *cip3;
433 char *value, *dot = "", *dot2 = "";
434 for (cip = whitelist; cip; cip = cip->next) {
435 needed += 7;
436 for (cip2 = cip->idents; cip2; cip2 = cip2->next) {
437 needed +=7;
438 for (cip3 = cip2->lengths; cip3; cip3 = cip3->next) needed +=3;
439 }
440 }
441
442 char tmp[needed];
443
444 for (cip = whitelist; cip; cip = cip->next) {
445 for (cip2 = cip->idents; cip2; cip2 = cip2->next) {
446 if(cip2->lengths != NULL) {
447 if(cip->caid != 0) {
448 if(cip2->ident == 0)
449 pos += snprintf(tmp + pos, needed - pos, "%s%04X:", dot, cip->caid);
450 else
451 pos += snprintf(tmp + pos, needed - pos, "%s%04X@%06X:", dot, cip->caid, cip2->ident);
452 } else pos += snprintf(tmp + pos, needed - pos, "%s", dot);
453 }
454 dot2="";
455 for (cip3 = cip2->lengths; cip3; cip3 = cip3->next) {
456 pos += snprintf(tmp + pos, needed - pos, "%s%02X", dot2, cip3->len);
457 dot2=",";
458 }
459 dot=";";
460 }
461 }
462 if (pos == 0 || !cs_malloc(&value, pos + 1)) return "";
463 memcpy(value, tmp, pos + 1);
464 return value;
465}
466
467/*
468 * 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().
469 */
470char *mk_t_ecmheaderwhitelist(struct s_ecmHeaderwhitelist *headerlist){
471 int32_t needed = 1, pos = 0;
472 struct s_ecmHeaderwhitelist *cip;
473 for (cip = headerlist; cip; cip = cip->next) needed += 51;
474 char *value, *dot = "";
475 char tmp[needed];
476 int16_t i;
477 int16_t ccache = 0;
478 uint32_t pcache = 0;
479 tmp[0] = '\0';
480 for (cip = headerlist; cip; cip = cip->next){
481 dot = "";
482 if (ccache == cip->caid && pcache == cip->provid){
483 if (pos)
484 pos -= 1;
485 if (strlen(tmp))
486 pos += snprintf(tmp + pos, needed - pos, ",");
487 } else {
488 if (cip->header != NULL && cip->caid != 0 && cip->provid == 0) {
489 pos += snprintf(tmp + pos, needed - pos, "%s%04X:", dot, cip->caid);
490 ccache = cip->caid;
491 pcache = 0;
492 }
493
494 if (cip->header != NULL && cip->caid != 0 && cip->provid != 0) {
495 pos += snprintf(tmp + pos, needed - pos, "%s%04X@%06X:", dot, cip->caid, cip->provid);
496 ccache = cip->caid;
497 pcache = cip->provid;
498 }
499 }
500 if(cip->header != NULL) {
501 for (i=0; i < cip->len/2; i++) {
502 pos += snprintf(tmp + pos, needed - pos, "%s%02X", dot, cip->header[i]);
503 if (i == cip->len/2-1) pos += snprintf(tmp + pos, needed - pos, ",");
504 ccache = cip->caid;
505 pcache = cip->provid;
506 }
507 }
508 if (pos)
509 pos -= 1;
510 pos += snprintf(tmp + pos, needed - pos, ";");
511 }
512 if (pos == 0 || !cs_malloc(&value, pos + 1)) return "";
513 memcpy(value, tmp, pos-1);
514 return value;
515}
516
517/*
518 * 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().
519 */
520char *mk_t_iprange(struct s_ip *range) {
521 struct s_ip *cip;
522 char *value, *dot = "";
523 int32_t needed = 1, pos = 0;
524 for (cip = range; cip; cip = cip->next) needed += 32;
525
526 char tmp[needed];
527
528 for (cip = range; cip; cip = cip->next) {
529 pos += snprintf(tmp + pos, needed - pos, "%s%s", dot, cs_inet_ntoa(cip->ip[0]));
530 if (!IP_EQUAL(cip->ip[0], cip->ip[1])) pos += snprintf(tmp + pos, needed - pos, "-%s", cs_inet_ntoa(cip->ip[1]));
531 dot=",";
532 }
533 if (pos == 0 || !cs_malloc(&value, pos + 1)) return "";
534 memcpy(value, tmp, pos + 1);
535 return value;
536}
537
538/*
539 * 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().
540 */
541char *mk_t_cltab(CLASSTAB *clstab) {
542 char *value, *dot = "";
543 int32_t i, needed = 1, pos = 0;
544 for(i = 0; i < clstab->an; ++i) needed += 3;
545 for(i = 0; i < clstab->bn; ++i) needed += 4;
546
547 char tmp[needed];
548
549 for(i = 0; i < clstab->an; ++i) {
550 pos += snprintf(tmp + pos, needed - pos, "%s%02x", dot, (int32_t)clstab->aclass[i]);
551 dot=",";
552 }
553 for(i = 0; i < clstab->bn; ++i) {
554 pos += snprintf(tmp + pos, needed - pos, "%s!%02x", dot, (int32_t)clstab->bclass[i]);
555 dot=",";
556 }
557
558 if (pos == 0 || !cs_malloc(&value, pos + 1)) return "";
559 memcpy(value, tmp, pos + 1);
560 return value;
561}
562
563/*
564 * Creates a string ready to write as a token into config or WebIf. You must free the returned value through free_mk_t().
565 */
566char *mk_t_caidvaluetab(CAIDVALUETAB *tab)
567{
568 if (!tab->n) return "";
569 int32_t i, size = 2 + tab->n * (4 + 1 + 5 + 1); //caid + ":" + time + ","
570 char *buf;
571 if (!cs_malloc(&buf, size))
572 return "";
573 char *ptr = buf;
574
575 for (i = 0; i < tab->n; i++) {
576 if (tab->caid[i] < 0x0100) //Do not format 0D as 000D, its a shortcut for 0Dxx:
577 ptr += snprintf(ptr, size-(ptr-buf), "%s%02X:%d", i?",":"", tab->caid[i], tab->value[i]);
578 else
579 ptr += snprintf(ptr, size-(ptr-buf), "%s%04X:%d", i?",":"", tab->caid[i], tab->value[i]);
580 }
581 *ptr = 0;
582 return buf;
583}
584
585#ifdef CS_CACHEEX
586char *mk_t_cacheex_valuetab(CECSPVALUETAB *tab){
587 if (!tab->n) return "";
588 int32_t i, size = 2 + tab->n * (4 + 1 + 4 + 1 + 6 + 1 + 4 + 1 + 5 + 1 + 5 + 1); //caid&mask@provid$servid:awtime:dwtime","
589 char *buf;
590 if (!cs_malloc(&buf, size))
591 return "";
592 char *ptr = buf;
593
594 for (i = 0; i < tab->n; i++) {
595 if (i) ptr += snprintf(ptr, size-(ptr-buf), ",");
596 if (tab->caid[i]>=0) {
597 if (tab->caid[i] == 0) {
598 if (tab->awtime[i]>0)
599 ptr += snprintf(ptr, size-(ptr-buf), "%d", tab->caid[i]);
600 } else if(tab->caid[i] < 256) //Do not format 0D as 000D, its a shortcut for 0Dxx:
601 ptr += snprintf(ptr, size-(ptr-buf), "%02X", tab->caid[i]);
602 else
603 ptr += snprintf(ptr, size-(ptr-buf), "%04X", tab->caid[i]);
604 }
605 if (tab->cmask[i]>=0)
606 ptr += snprintf(ptr, size-(ptr-buf), "&%04X", tab->cmask[i]);
607 if (tab->prid[i]>=0)
608 ptr += snprintf(ptr, size-(ptr-buf), "@%06X", tab->prid[i]);
609 if (tab->srvid[i]>=0)
610 ptr += snprintf(ptr, size-(ptr-buf), "$%04X", tab->srvid[i]);
611 if (tab->awtime[i]>0)
612 ptr += snprintf(ptr, size-(ptr-buf), ":%d", tab->awtime[i]);
613 if (!tab->dwtime[i]>0)
614 ptr += snprintf(ptr, size-(ptr-buf), ":0");
615 if (tab->dwtime[i]>0) {
616 if ((tab->caid[i] <= 0) && (tab->prid[i] == -1) &&(tab->srvid[i] == -1) && (tab->srvid[i] == -1) && (tab->awtime[i] <= 0))
617 ptr += snprintf(ptr, size-(ptr-buf), "%d", tab->dwtime[i]);
618 else
619 ptr += snprintf(ptr, size-(ptr-buf), ":%d", tab->dwtime[i]);
620 }
621 }
622 *ptr = 0;
623 return buf;
624}
625
626char *mk_t_cacheex_hitvaluetab(CECSPVALUETAB *tab){
627 if (!tab->n) return "";
628 int32_t i, size = 2 + tab->n * (4 + 1 + 4 + 1 + 6 + 1 + 4 + 1); //caid&mask@provid$servid","
629 char *buf;
630 if (!cs_malloc(&buf, size))
631 return "";
632 char *ptr = buf;
633
634 for (i = 0; i < tab->n; i++) {
635 if (i) ptr += snprintf(ptr, size-(ptr-buf), ",");
636 if (tab->caid[i]>0) {
637 if(tab->caid[i] < 256) //Do not format 0D as 000D, its a shortcut for 0Dxx:
638 ptr += snprintf(ptr, size-(ptr-buf), "%02X", tab->caid[i]);
639 else
640 ptr += snprintf(ptr, size-(ptr-buf), "%04X", tab->caid[i]);
641 if (tab->cmask[i]>=0)
642 ptr += snprintf(ptr, size-(ptr-buf), "&%04X", tab->cmask[i]);
643 if (tab->prid[i]>=0)
644 ptr += snprintf(ptr, size-(ptr-buf), "@%06X", tab->prid[i]);
645 if (tab->srvid[i]>=0)
646 ptr += snprintf(ptr, size-(ptr-buf), "$%04X", tab->srvid[i]);
647 }
648 }
649 *ptr = 0;
650 return buf;
651}
652#endif
653
654/*
655 * returns string of comma separated values
656 */
657char *mk_t_emmbylen(struct s_reader *rdr) {
658
659 char *value, *dot = "";
660 int32_t pos = 0, needed = 0;
661 int8_t i;
662
663 needed = (CS_MAXEMMBLOCKBYLEN * 4) +1;
664
665 if (!cs_malloc(&value, needed)) return "";
666
667 for( i = 0; i < CS_MAXEMMBLOCKBYLEN; i++ ) {
668 if(rdr->blockemmbylen[i] != 0) {
669 pos += snprintf(value + pos, needed, "%s%d", dot, rdr->blockemmbylen[i]);
670 dot = ",";
671 }
672 }
673 return value;
674}
675
676/*
677 * makes string from binary structure
678 */
679char *mk_t_allowedprotocols(struct s_auth *account) {
680
681 if (!account->allowedprotocols)
682 return "";
683
684 int16_t i, tmp = 1, pos = 0, needed = 255, tagcnt;
685 char *tag[] = {"camd33", "camd35", "cs378x", "newcamd", "cccam", "gbox", "radegast", "dvbapi", "constcw", "serial"};
686 char *value, *dot = "";
687
688 if (!cs_malloc(&value, needed))
689 return "";
690
691 tagcnt = sizeof(tag)/sizeof(char *);
692 for (i = 0; i < tagcnt; i++) {
693 if ((account->allowedprotocols & tmp) == tmp) {
694 pos += snprintf(value + pos, needed, "%s%s", dot, tag[i]);
695 dot = ",";
696 }
697 tmp = tmp << 1;
698 }
699 return value;
700}
701
702/*
703 * mk_t-functions give back a constant empty string when allocation fails or when the result is an empty string.
704 * This function thus checks the stringlength and only frees if necessary.
705 */
706void free_mk_t(char *value) {
707 if(strlen(value) > 0) free(value);
708}
Note: See TracBrowser for help on using the repository browser.