[gbx] - try fix ecm and cw messages
[oscam.git] / module-webif.c
bloba50a4d2450cd074c99839c227dcb0beae0298f82
1 #define MODULE_LOG_PREFIX "webif"
3 #include "globals.h"
5 #ifdef WEBIF
6 //
7 // OSCam HTTP server module
8 //
9 #include <locale.h>
10 #include "cscrypt/md5.h"
11 #include "module-anticasc.h"
12 #include "module-cacheex.h"
13 #include "module-cccam.h"
14 #include "module-cccam-data.h"
15 #include "module-dvbapi.h"
16 #include "module-newcamd.h"
17 #include "module-stat.h"
18 #include "module-webif.h"
19 #include "module-webif-lib.h"
20 #include "module-webif-tpl.h"
21 #include "oscam-conf-mk.h"
22 #include "oscam-config.h"
23 #include "oscam-files.h"
24 #include "oscam-garbage.h"
25 #include "oscam-cache.h"
26 #include "oscam-client.h"
27 #include "oscam-lock.h"
28 #include "oscam-net.h"
29 #include "oscam-reader.h"
30 #include "oscam-string.h"
31 #include "oscam-time.h"
32 #include "oscam-work.h"
33 #ifdef MODULE_GBOX
34 #include "module-gbox-sms.h"
35 #include "module-gbox.h"
36 #include "module-gbox-cards.h"
37 #endif
39 extern const struct s_cardreader *cardreaders[];
40 extern char cs_confdir[];
41 extern uint32_t ecmcwcache_size;
42 extern uint8_t cs_http_use_utf8;
43 extern uint32_t cfg_sidtab_generation;
44 extern int32_t exit_oscam;
45 extern uint8_t cacheex_peer_id[8];
47 extern char *entitlement_type[];
48 extern char *RDR_CD_TXT[];
50 int32_t ssl_active = 0;
51 char noncekey[33];
52 pthread_key_t getkeepalive;
53 static pthread_key_t getip;
54 pthread_key_t getssl;
55 static CS_MUTEX_LOCK http_lock;
56 CS_MUTEX_LOCK *lock_cs;
58 static uint8_t useLocal = 1;
59 #define PRINTF_LOCAL_D useLocal ? "%'d" : "%d"
60 #define PRINTF_LOCAL_F useLocal ? "%'.0f" : "%.0f"
61 #define PRINTF_LOCAL_MB useLocal ? "%'.2f MB" : "%.2f MB"
63 static int8_t httpthread_running = 0;
64 static pthread_t httpthread;
65 static int32_t sock;
66 enum refreshtypes { REFR_ACCOUNTS, REFR_READERS, REFR_CLIENTS, REFR_SERVER, REFR_ANTICASC, REFR_SERVICES };
68 //initialize structs for calculating cpu-usage depending on time between refresh of status_page
69 static struct pstat p_stat_cur;
70 static struct pstat p_stat_old;
72 static bool use_srvid2 = false;
74 /* constants for menuactivating */
75 #define MNU_STATUS 0
76 #define MNU_LIVELOG 1
77 #define MNU_CONFIG 2
78 #define MNU_READERS 3
79 #define MNU_USERS 4
80 #define MNU_SERVICES 5
81 #define MNU_FILES 6
82 #define MNU_FAILBAN 7
83 #define MNU_CACHEEX 8
84 #define MNU_SCRIPT 9
85 #define MNU_SHUTDOWN 10
86 #define MNU_TOTAL_ITEMS 11 // sum of items above
88 /* constants for config.html submenuactivating */
89 #define MNU_CFG_GLOBAL 0
90 #define MNU_CFG_ANTICASC 1
91 #define MNU_CFG_CACHE 2
92 #define MNU_CFG_LOADBAL 3
93 #define MNU_CFG_CAMD33 4
94 #define MNU_CFG_CAMD35 5
95 #define MNU_CFG_CAMD35TCP 6
96 #define MNU_CFG_CCCAM 7
97 #define MNU_CFG_NEWCAMD 8
98 #define MNU_CFG_GBOX 9
99 #define MNU_CFG_RADEGAST 10
100 #define MNU_CFG_SCAM 11
101 #define MNU_CFG_SERIAL 12
102 #define MNU_CFG_DVBAPI 13
103 #define MNU_CFG_LCD 14
104 #define MNU_CFG_MONITOR 15
105 #define MNU_CFG_WEBIF 16
106 #define MNU_CFG_STREAMRELAY 17
108 /* constants for files.html submenuactivating */
109 #define MNU_CFG_FVERSION 0
110 #define MNU_CFG_FCONF 1
111 #define MNU_CFG_FUSER 2
112 #define MNU_CFG_FSERVER 3
113 #define MNU_CFG_FSRVID 4
114 #define MNU_CFG_FDVBAPI 5
115 #define MNU_CFG_FACLOG 6
116 #define MNU_CFG_FLOGFILE 7
117 #define MNU_CFG_FUSERFILE 8
118 #define MNU_CFG_FSERVICES 9
119 #define MNU_CFG_FPROVID 10
120 #define MNU_CFG_FTIERS 11
121 #define MNU_CFG_FRATELIMIT 12
122 #define MNU_CFG_FWHITELIST 13
123 #define MNU_CFG_FSRVID2 14
124 #define MNU_CFG_FFAKECWS 15
125 #define MNU_CFG_FCSS 16
126 #define MNU_CFG_FTWIN 17
127 #define MNU_CFG_FKEYCW 18
129 /* constants for files.html for GBOX submenuactivating */
130 #define MNU_GBX_FSCINF 19
131 #define MNU_GBX_FSHRINF 20
132 #define MNU_GBX_FSHRONL 21
133 #define MNU_GBX_FVERS 22
134 #define MNU_GBX_FATTACK 23
135 #define MNU_GBX_FSMSLOG 24
136 #define MNU_GBX_FSMSACK 25
137 #define MNU_GBX_FSMSNACK 26
138 #define MNU_GBX_FSTAINF 27
139 #define MNU_GBX_FEXPINF 28
140 #define MNU_GBX_INFOLOG 29
141 #define MNU_CFG_FSOFTCAMKEY 30
143 #define MNU_CFG_TOTAL_ITEMS 31 // sum of items above. Use it for "All inactive" in function calls too.
145 static void set_status_info_var(struct templatevars *vars, char *varname, int no_data, char *fmt, double value)
147 if (no_data)
148 tpl_addVar(vars, TPLADD, varname, "N/A");
149 else
150 tpl_printf(vars, TPLADD, varname, fmt, value);
154 * Creates vars Memory/CPU/OSCAM info in for status_page
155 * if check_available == 0 N/A will be displayed
156 * Bit mapping
157 * mem 0 total, 1 used & free, 2 buff, cached & free incl. buff, 3 share
158 * swap 4 total, 5 used & free,
159 * proc 6 count
160 * cpu 7 load
161 * oscam 8 vsize & rssize, 9 cpu user, 10 cpu sys, 11 cpu sum, 12 cpu refreshtime
162 * unused 13 - 15
164 static void set_status_info(struct templatevars *vars, struct pstat stats){
165 set_status_info_var(vars, "MEM_CUR_TOTAL", stats.check_available & (1 << 0), PRINTF_LOCAL_MB , (double)stats.mem_total/(1024.0*1024.0));
166 set_status_info_var(vars, "MEM_CUR_FREE", stats.check_available & (1 << 1), PRINTF_LOCAL_MB , (double)stats.mem_free/(1024.0*1024.0));
167 set_status_info_var(vars, "MEM_CUR_USED", stats.check_available & (1 << 1), PRINTF_LOCAL_MB , (double)stats.mem_used/(1024.0*1024.0));
168 set_status_info_var(vars, "MEM_CUR_BUFF", stats.check_available & (1 << 2), PRINTF_LOCAL_MB , (double)stats.mem_buff/(1024.0*1024.0));
169 set_status_info_var(vars, "MEM_CUR_CACHED", stats.check_available & (1 << 2), PRINTF_LOCAL_MB , (double)stats.mem_cached/(1024.0*1024.0));
170 set_status_info_var(vars, "MEM_CUR_FREEM", stats.check_available & (1 << 2), PRINTF_LOCAL_MB , (double)stats.mem_freem/(1024.0*1024.0));
171 set_status_info_var(vars, "MEM_CUR_SHARE", stats.check_available & (1 << 3), PRINTF_LOCAL_MB , (double)stats.mem_share/(1024.0*1024.0));
172 set_status_info_var(vars, "MEM_CUR_TOTSW", stats.check_available & (1 << 4), PRINTF_LOCAL_MB , (double)stats.mem_total_swap/(1024.0*1024.0));
173 set_status_info_var(vars, "MEM_CUR_FRESW", stats.check_available & (1 << 5), PRINTF_LOCAL_MB , (double)stats.mem_free_swap/(1024.0*1024.0));
174 set_status_info_var(vars, "MEM_CUR_USESW", stats.check_available & (1 << 5), PRINTF_LOCAL_MB , (double)stats.mem_used_swap/(1024.0*1024.0));
176 set_status_info_var(vars, "SERVER_PROCS", stats.check_available & (1 << 6), PRINTF_LOCAL_F , stats.info_procs);
178 set_status_info_var(vars, "CPU_LOAD_0", stats.check_available & (1 << 7), "%.2f" , stats.cpu_avg[0]);
179 set_status_info_var(vars, "CPU_LOAD_1", stats.check_available & (1 << 7), "%.2f" , stats.cpu_avg[1]);
180 set_status_info_var(vars, "CPU_LOAD_2", stats.check_available & (1 << 7), "%.2f" , stats.cpu_avg[2]);
182 set_status_info_var(vars, "OSCAM_VMSIZE", stats.check_available & (1 << 8), PRINTF_LOCAL_MB , (double)stats.vsize/(1024.0*1024.0));
183 set_status_info_var(vars, "OSCAM_RSSSIZE", stats.check_available & (1 << 8), PRINTF_LOCAL_MB , (double)stats.rss/(1024.0*1024.0));
184 set_status_info_var(vars, "OSCAM_CPU_USER", stats.check_available & (1 << 9), "%.2f %%" , stats.cpu_usage_user);
185 set_status_info_var(vars, "OSCAM_CPU_SYS", stats.check_available & (1 << 10), "%.2f %%" , stats.cpu_usage_sys);
186 double sum_cpu = stats.cpu_usage_sys + stats.cpu_usage_user;
187 set_status_info_var(vars, "OSCAM_CPU_SUM", stats.check_available & (1 << 11), "%.2f %%" , sum_cpu);
189 if (stats.check_available & (1 << 12))
191 tpl_addVar(vars, TPLADD, "OSCAM_REFRESH" , "N/A");
193 else
195 tpl_printf(vars, TPLADD, "OSCAM_REFRESH" , "%02"PRId64":%02"PRId64":%02"PRId64"h",
196 stats.gone_refresh / 3600,
197 (stats.gone_refresh / 60) % 60,
198 stats.gone_refresh % 60);
202 static void clear_account_stats(struct s_auth *account)
204 account->cwfound = 0;
205 account->cwcache = 0;
206 account->cwnot = 0;
207 account->cwtun = 0;
208 account->cwignored = 0;
209 account->cwtout = 0;
210 account->emmok = 0;
211 account->emmnok = 0;
212 #ifdef CW_CYCLE_CHECK
213 account->cwcycledchecked = 0;
214 account->cwcycledok = 0;
215 account->cwcyclednok = 0;
216 account->cwcycledign = 0;
217 #endif
218 cacheex_clear_account_stats(account);
221 static void clear_all_account_stats(void)
223 struct s_auth *account = cfg.account;
224 while(account)
226 clear_account_stats(account);
227 account = account->next;
231 #ifdef CS_CACHEEX
232 static void cacheex_clear_all_stats(void)
234 struct s_auth *account = cfg.account;
235 while(account)
237 cacheex_clear_account_stats(account);
238 account = account->next;
240 struct s_client *cl;
241 for(cl = first_client->next; cl ; cl = cl->next)
243 cacheex_clear_client_stats(cl);
244 ll_clear_data(cl->ll_cacheex_stats);
246 cacheex_clear_client_stats(first_client);
248 #endif
250 static void clear_info_clients_stats(void)
252 first_client->cwfound = 0;
253 first_client->cwcache = 0;
254 first_client->cwnot = 0;
255 first_client->cwtun = 0;
256 first_client->cwignored = 0;
257 first_client->cwtout = 0;
258 first_client->emmok = 0;
259 first_client->emmnok = 0;
260 cacheex_clear_client_stats(first_client);
263 static void clear_info_readers_stats(void)
265 int8_t i;
266 cs_writelock(__func__, &readerlist_lock);
267 LL_ITER itr = ll_iter_create(configured_readers);
268 struct s_reader *rdr;
269 while((rdr = ll_iter_next(&itr)))
271 rdr->webif_ecmsok = 0;
272 rdr->webif_ecmsnok = 0;
273 rdr->webif_ecmstout = 0;
274 rdr->webif_ecmsfilteredhead = 0;
275 rdr->webif_ecmsfilteredlen = 0;
277 for(i = 0; i < 4; i++)
279 rdr->webif_emmerror[i] = 0;
280 rdr->webif_emmwritten[i] = 0;
281 rdr->webif_emmskipped[i] = 0;
282 rdr->webif_emmblocked[i] = 0;
285 cs_writeunlock(__func__, &readerlist_lock);
288 static void set_ecm_info(struct templatevars * vars)
290 //if one of the stats overloaded, reset all stats!
291 if(first_client->cwfound<0
292 || first_client->cwnot<0
293 || first_client->cwignored<0
294 || first_client->cwtout<0
295 || first_client->cwcache<0
296 || first_client->cwtun<0
297 || first_client->emmok<0
298 || first_client->emmnok<0
299 #ifdef CS_CACHEEX
300 || first_client->cwcacheexgot<0
301 || first_client->cwcacheexpush<0
302 || first_client->cwcacheexhit<0
303 #endif
305 clear_info_clients_stats();
307 //end reset stats
309 int ecm = 0, emm = 0;
310 double ecmsum = first_client->cwfound + first_client->cwcache + first_client->cwnot + first_client->cwtout; //dont count TUN its included
311 if(ecmsum < 1) {ecmsum = 1; ecm = 1;}
312 double ecmpos = first_client->cwfound + first_client->cwcache; // dont count TUN its included
313 if(ecmpos < 1) {ecmpos = 1;}
314 double ecmneg = first_client->cwnot + first_client->cwtout; //dont count IGN its not part of neagtiv
315 if(ecmneg < 1) {ecmneg = 1;}
316 double emmsum = first_client->emmok + first_client->emmnok;
317 if(emmsum < 1) {emmsum = 1; emm = 1;}
319 tpl_printf(vars, TPLADD, "TOTAL_ECM_MIN", "%d", first_client->n_request[0]);
320 tpl_printf(vars, TPLADD, "TOTAL_CW", PRINTF_LOCAL_F, !ecm ? ecmsum : 0);
321 tpl_printf(vars, TPLADD, "TOTAL_CWOK", PRINTF_LOCAL_F, (double)first_client->cwfound);
322 tpl_printf(vars, TPLADD, "TOTAL_CWNOK", PRINTF_LOCAL_F, (double)first_client->cwnot);
323 tpl_printf(vars, TPLADD, "TOTAL_CWIGN", PRINTF_LOCAL_F, (double)first_client->cwignored);
324 tpl_printf(vars, TPLADD, "TOTAL_CWTOUT", PRINTF_LOCAL_F, (double)first_client->cwtout);
325 tpl_printf(vars, TPLADD, "TOTAL_CWCACHE", PRINTF_LOCAL_F, (double)first_client->cwcache);
326 tpl_printf(vars, TPLADD, "TOTAL_CWTUN", PRINTF_LOCAL_F, (double)first_client->cwtun);
327 tpl_printf(vars, TPLADD, "TOTAL_CWPOS", PRINTF_LOCAL_F, (double)first_client->cwfound + (double)first_client->cwcache);
328 tpl_printf(vars, TPLADD, "TOTAL_CWNEG", PRINTF_LOCAL_F, (double)first_client->cwnot + (double)first_client->cwtout);
329 tpl_printf(vars, TPLADD, "TOTAL_EM", PRINTF_LOCAL_F, !emm ? emmsum : 0);
330 tpl_printf(vars, TPLADD, "TOTAL_EMOK", PRINTF_LOCAL_F, (double)first_client->emmok);
331 tpl_printf(vars, TPLADD, "TOTAL_EMNOK", PRINTF_LOCAL_F, (double)first_client->emmnok);
332 tpl_printf(vars, TPLADD, "REL_CWOK", "%.2f", (double)first_client->cwfound * 100 / ecmsum);
333 tpl_printf(vars, TPLADD, "REL_CWNOK", "%.2f", (double)first_client->cwnot * 100 / ecmsum);
334 //tpl_printf(vars, TPLADD, "REL_CWIGN", "%.2f", (double)first_client->cwignored * 100 / ecmsum);
335 tpl_printf(vars, TPLADD, "REL_CWTOUT", "%.2f", (double)first_client->cwtout * 100 / ecmsum);
336 tpl_printf(vars, TPLADD, "REL_CWCACHE", "%.2f", (double)first_client->cwcache * 100 / ecmsum);
337 tpl_printf(vars, TPLADD, "REL_CWTUN", "%.2f", (double)first_client->cwtun * 100 / ecmsum);
338 tpl_printf(vars, TPLADD, "REL_CWPOS", "%.2f", (double)(first_client->cwfound + first_client->cwcache) * 100 / ecmsum);
339 tpl_printf(vars, TPLADD, "REL_CWNEG", "%.2f", (double)(first_client->cwnot + first_client->cwtout) * 100 / ecmsum);
340 tpl_printf(vars, TPLADD, "REL_EMOK", "%.2f", (double)first_client->emmok * 100 / emmsum);
341 tpl_printf(vars, TPLADD, "REL_EMNOK", "%.2f", (double)first_client->emmnok * 100 / emmsum);
342 tpl_printf(vars, TPLADD, "REL_CWPOSOK", "%.2f", (double)first_client->cwfound * 100 / ecmpos);
343 tpl_printf(vars, TPLADD, "REL_CWPOSCACHE", "%.2f", (double)first_client->cwcache * 100 / ecmpos);
344 tpl_printf(vars, TPLADD, "REL_CWNEGNOK", "%.2f", (double)first_client->cwnot * 100 / ecmneg);
345 //tpl_printf(vars, TPLADD, "REL_CWNEGIGN", "%.2f", (double)first_client->cwignored * 100 / ecmneg);
346 tpl_printf(vars, TPLADD, "REL_CWNEGTOUT", "%.2f", (double)first_client->cwtout * 100 / ecmneg);
348 double totalrdrneg = 0, totalrdrpos = 0;
349 double totalrdrok = 0, totalrdrnok = 0, totalrdrtout = 0;
350 double flen = 0, fhead = 0;
351 double teruk = 0, terg = 0, ters = 0, teruq = 0;
352 double twruk = 0, twrg = 0, twrs = 0, twruq = 0;
353 double tskuk = 0, tskg = 0, tsks = 0, tskuq = 0;
354 double tbluk = 0, tblg = 0, tbls = 0, tbluq = 0;
356 ecmsum = 0;
357 emmsum = 0;
359 cs_readlock(__func__, &readerlist_lock);
360 LL_ITER itr = ll_iter_create(configured_readers);
361 struct s_reader *rdr;
362 while((rdr = ll_iter_next(&itr)))
364 if (rdr->webif_ecmsok) { totalrdrok += rdr->webif_ecmsok; }
365 if (rdr->webif_ecmsnok) { totalrdrnok += rdr->webif_ecmsnok; }
366 if (rdr->webif_ecmstout) { totalrdrtout += rdr->webif_ecmstout; }
368 if (rdr->webif_ecmsfilteredlen) { flen += rdr->webif_ecmsfilteredlen; }
369 if (rdr->webif_ecmsfilteredhead) { fhead += rdr->webif_ecmsfilteredhead; }
371 if (rdr->webif_emmerror[0]) { teruk += rdr->webif_emmerror[0]; }
372 if (rdr->webif_emmerror[1]) { teruq += rdr->webif_emmerror[1]; }
373 if (rdr->webif_emmerror[2]) { ters += rdr->webif_emmerror[2]; }
374 if (rdr->webif_emmerror[3]) { terg += rdr->webif_emmerror[3]; }
376 if (rdr->webif_emmwritten[0]) { twruk += rdr->webif_emmwritten[0]; }
377 if (rdr->webif_emmwritten[1]) { twruq += rdr->webif_emmwritten[1]; }
378 if (rdr->webif_emmwritten[2]) { twrs += rdr->webif_emmwritten[2]; }
379 if (rdr->webif_emmwritten[3]) { twrg += rdr->webif_emmwritten[3]; }
381 if (rdr->webif_emmskipped[0]) { tskuk += rdr->webif_emmskipped[0]; }
382 if (rdr->webif_emmskipped[1]) { tskuq += rdr->webif_emmskipped[1]; }
383 if (rdr->webif_emmskipped[2]) { tsks += rdr->webif_emmskipped[2]; }
384 if (rdr->webif_emmskipped[3]) { tskg += rdr->webif_emmskipped[3]; }
386 if (rdr->webif_emmblocked[0]) { tbluk += rdr->webif_emmblocked[0]; }
387 if (rdr->webif_emmblocked[1]) { tbluq += rdr->webif_emmblocked[1]; }
388 if (rdr->webif_emmblocked[2]) { tbls += rdr->webif_emmblocked[2]; }
389 if (rdr->webif_emmblocked[3]) { tblg += rdr->webif_emmblocked[3]; }
391 cs_readunlock(__func__, &readerlist_lock);
393 totalrdrneg = totalrdrnok + totalrdrtout;
394 totalrdrpos = totalrdrok;
395 ecmsum = totalrdrok + totalrdrnok + totalrdrtout;
397 tpl_printf(vars, TPLADD, "TOTAL_CWOK_READERS", PRINTF_LOCAL_F, totalrdrok);
398 tpl_printf(vars, TPLADD, "TOTAL_CWNOK_READERS", PRINTF_LOCAL_F, totalrdrnok);
399 tpl_printf(vars, TPLADD, "TOTAL_CWTOUT_READERS", PRINTF_LOCAL_F, totalrdrtout);
400 tpl_printf(vars, TPLADD, "REL_CWOK_READERS", "%.2f", ecmsum ? totalrdrok * 100 / ecmsum : 0);
401 tpl_printf(vars, TPLADD, "REL_CWNOK_READERS", "%.2f", ecmsum ? totalrdrnok * 100 / ecmsum : 0);
402 tpl_printf(vars, TPLADD, "REL_CWTOUT_READERS", "%.2f", ecmsum ? totalrdrtout * 100 / ecmsum : 0);
403 tpl_printf(vars, TPLADD, "TOTAL_CWPOS_READERS", PRINTF_LOCAL_F, totalrdrpos);
404 tpl_printf(vars, TPLADD, "TOTAL_CWNEG_READERS", PRINTF_LOCAL_F, totalrdrneg);
405 tpl_printf(vars, TPLADD, "REL_CWPOS_READERS", "%.2f", ecmsum ? totalrdrpos * 100 / ecmsum : 0);
406 tpl_printf(vars, TPLADD, "REL_CWNEG_READERS", "%.2f", ecmsum ? totalrdrneg * 100 / ecmsum : 0);
407 tpl_printf(vars, TPLADD, "TOTAL_ELENR", PRINTF_LOCAL_F, flen);
408 tpl_printf(vars, TPLADD, "TOTAL_EHEADR", PRINTF_LOCAL_F, fhead);
409 tpl_printf(vars, TPLADD, "TOTAL_SUM_ALL_READERS_ECM", PRINTF_LOCAL_F, ecmsum);
411 tpl_printf(vars, TPLADD, "TOTAL_EMMERRORUK_READERS", PRINTF_LOCAL_F, teruk);
412 tpl_printf(vars, TPLADD, "TOTAL_EMMERRORG_READERS", PRINTF_LOCAL_F, terg);
413 tpl_printf(vars, TPLADD, "TOTAL_EMMERRORS_READERS", PRINTF_LOCAL_F, ters);
414 tpl_printf(vars, TPLADD, "TOTAL_EMMERRORUQ_READERS", PRINTF_LOCAL_F, teruq);
415 tpl_printf(vars, TPLADD, "TOTAL_EMMWRITTENUK_READERS", PRINTF_LOCAL_F, twruk);
416 tpl_printf(vars, TPLADD, "TOTAL_EMMWRITTENG_READERS", PRINTF_LOCAL_F, twrg);
417 tpl_printf(vars, TPLADD, "TOTAL_EMMWRITTENS_READERS", PRINTF_LOCAL_F, twrs);
418 tpl_printf(vars, TPLADD, "TOTAL_EMMWRITTENUQ_READERS", PRINTF_LOCAL_F, twruq);
419 tpl_printf(vars, TPLADD, "TOTAL_EMMSKIPPEDUK_READERS", PRINTF_LOCAL_F, tskuk);
420 tpl_printf(vars, TPLADD, "TOTAL_EMMSKIPPEDG_READERS", PRINTF_LOCAL_F, tskg);
421 tpl_printf(vars, TPLADD, "TOTAL_EMMSKIPPEDS_READERS", PRINTF_LOCAL_F, tsks);
422 tpl_printf(vars, TPLADD, "TOTAL_EMMSKIPPEDUQ_READERS", PRINTF_LOCAL_F, tskuq);
423 tpl_printf(vars, TPLADD, "TOTAL_EMMBLOCKEDUK_READERS", PRINTF_LOCAL_F, tbluk);
424 tpl_printf(vars, TPLADD, "TOTAL_EMMBLOCKEDG_READERS", PRINTF_LOCAL_F, tblg);
425 tpl_printf(vars, TPLADD, "TOTAL_EMMBLOCKEDS_READERS", PRINTF_LOCAL_F, tbls);
426 tpl_printf(vars, TPLADD, "TOTAL_EMMBLOCKEDUQ_READERS", PRINTF_LOCAL_F, tbluq);
428 emmsum = teruk + terg + ters + teruq + twruk + twrg + twrs + twruq + tskuk + tskg + tsks + tskuq + tbluk + tblg + tbls + tbluq;
430 tpl_printf(vars, TPLADD, "TOTAL_SUM_ALL_READERS_EMM", PRINTF_LOCAL_F, emmsum);
433 static void refresh_oscam(enum refreshtypes refreshtype)
436 switch(refreshtype)
438 case REFR_ACCOUNTS:
439 cs_log("Refresh Accounts requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
440 cs_accounts_chk();
441 break;
443 case REFR_READERS:
444 cs_log("Refresh Readers requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
445 reload_readerdb();
446 break;
448 case REFR_CLIENTS:
449 cs_log("Refresh Clients requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
450 cs_reinit_clients(cfg.account);
451 break;
453 case REFR_SERVER:
454 cs_log("Refresh Server requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
455 //kill(first_client->pid, SIGHUP);
456 //todo how I can refresh the server after global settings
457 break;
459 case REFR_SERVICES:
460 cs_log("Refresh Services requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
461 //init_sidtab();
462 cs_accounts_chk();
463 break;
465 #ifdef CS_ANTICASC
466 case REFR_ANTICASC:
467 cs_log("Refresh Anticascading requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
468 ac_init_stat();
469 struct s_client *cl;
470 struct s_auth *account;
471 for(cl = first_client->next; cl ; cl = cl->next)
473 if(cl->typ == 'c' && (account = cl->account))
475 cl->ac_limit = (account->ac_users * 100 + 80) * cfg.ac_stime;
478 break;
479 #endif
480 default:
481 break;
485 * load historical values from ringbuffer and return it in the right order
486 * as string. Value should be freed with free_mk_t()
488 static char *get_ecm_historystring(struct s_client *cl)
491 if(cl)
493 int32_t k, i, pos = 0, needed = 1, v;
494 char *value, *dot = "";
495 int32_t ptr = cl->cwlastresptimes_last;
497 needed = CS_ECM_RINGBUFFER_MAX * 6; //5 digits + delimiter
498 if(!cs_malloc(&value, needed)) { return ""; }
500 k = ptr + 1;
501 for(i = 0; i < CS_ECM_RINGBUFFER_MAX; i++)
503 if(k >= CS_ECM_RINGBUFFER_MAX)
504 { k = 0; }
505 v = cl->cwlastresptimes[k].duration;
506 if(v > 0 && v < (int32_t)cfg.ctimeout * 5)
508 pos += snprintf(value + pos, needed - pos, "%s%d", dot, v);
509 dot = ",";
511 k++;
513 if(strlen(value) == 0)
515 NULLFREE(value);
516 return "";
518 else { return value; }
521 else
523 return "";
527 static char *get_ecm_fullhistorystring(struct s_client *cl)
530 if(cl)
532 int32_t k, i, pos = 0, needed = 1, v;
533 char *value, *dot = "";
534 int32_t ptr = cl->cwlastresptimes_last;
536 needed = CS_ECM_RINGBUFFER_MAX * 20; //5 digits + : + returncode(2) + : + time(10) + delimiter
537 if(!cs_malloc(&value, needed)) { return ""; }
539 k = ptr + 1;
540 for(i = 0; i < CS_ECM_RINGBUFFER_MAX; i++)
542 if(k >= CS_ECM_RINGBUFFER_MAX)
543 { k = 0; }
544 v = cl->cwlastresptimes[k].duration;
545 if(v > 0 && v < (int32_t)cfg.ctimeout * 5)
547 pos += snprintf(value + pos, needed - pos, "%s%d:%d:%ld", dot, cl->cwlastresptimes[k].duration, cl->cwlastresptimes[k].rc, cl->cwlastresptimes[k].timestamp);
548 dot = ",";
550 k++;
553 return (value);
556 else
558 return "";
563 * Set the active menu to a different CSS class
565 static void setActiveMenu(struct templatevars *vars, int8_t active)
567 int8_t i;
568 for(i = 0; i < MNU_TOTAL_ITEMS; i++)
570 tpl_printf(vars, TPLADD, "TMP", "MENUACTIVE%d", i);
571 if(i == active)
572 { tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "menu_selected"); }
573 else
574 { tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "menu"); }
576 #ifdef WEBIF_LIVELOG
577 tpl_addVar(vars, TPLADD, "LOGPAGEMENU", tpl_getTpl(vars, "LOGMENU"));
578 #endif
582 * Set the active submenu to a different CSS class
584 static void setActiveSubMenu(struct templatevars *vars, int8_t active)
586 int8_t i;
587 for(i = 0; i < MNU_CFG_TOTAL_ITEMS; i++)
589 tpl_printf(vars, TPLADD, "TMP", "CMENUACTIVE%d", i);
590 if(i == active)
591 { tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "configmenu_selected"); }
592 else
593 { tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "configmenu"); }
597 static void webif_save_config(char *section, struct templatevars *vars, struct uriparams *params)
599 if(!streq(getParam(params, "action"), "execute"))
600 { return; }
601 if(cfg.http_readonly)
603 tpl_addMsg(vars, "WebIf is in readonly mode. No changes are possible!");
604 return;
606 int i;
607 int cnt = (*params).paramcount;
608 for(i = 0; i < cnt; i++)
610 char *token = (*params).params[i];
611 char *value = (*params).values[i];
612 if(!streq(token, "part") && !streq(token, "action"))
613 { config_set(section, token, value); }
615 if(write_config() == 0)
617 tpl_addMsg(vars, "Configuration was saved.");
618 enum refreshtypes ref_type = REFR_SERVER;
619 if(streq(getParam(params, "part"), "anticasc"))
620 { ref_type = REFR_ANTICASC; }
621 refresh_oscam(ref_type);
623 else
625 tpl_addMsg(vars, "ERROR: Failed to write config file!!!");
629 static char *send_oscam_config_global(struct templatevars *vars, struct uriparams *params)
631 setActiveSubMenu(vars, MNU_CFG_GLOBAL);
633 webif_save_config("global", vars, params);
635 if(IP_ISSET(cfg.srvip))
636 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.srvip)); }
637 tpl_printf(vars, TPLADD, "NICE", "%d", cfg.nice);
638 tpl_printf(vars, TPLADD, "BINDWAIT", "%d", cfg.bindwait);
640 tpl_printf(vars, TPLADD, "TMP", "NETPRIO%d", cfg.netprio);
641 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
643 tpl_printf(vars, TPLADD, "PIDFILE", "%s", ESTR(cfg.pidfile));
646 if(cfg.usrfile != NULL) { tpl_addVar(vars, TPLADD, "USERFILE", cfg.usrfile); }
647 if(cfg.disableuserfile == 0) { tpl_addVar(vars, TPLADD, "DISABLEUSERFILECHECKED", "checked"); }
648 if(cfg.usrfileflag == 1) { tpl_addVar(vars, TPLADD, "USERFILEFLAGCHECKED", "selected"); }
649 if(cfg.mailfile != NULL) { tpl_addVar(vars, TPLADD, "MAILFILE", cfg.mailfile); }
650 if(cfg.disablemail == 0) { tpl_addVar(vars, TPLADD, "DISABLEMAILCHECKED", "checked"); }
652 char *value = mk_t_logfile();
653 tpl_addVar(vars, TPLADD, "LOGFILE", value);
654 free_mk_t(value);
655 if(cfg.disablelog == 0) { tpl_addVar(vars, TPLADD, "DISABLELOGCHECKED", "checked"); }
656 tpl_printf(vars, TPLADD, "MAXLOGSIZE", "%d", cfg.max_log_size);
658 tpl_addVar(vars, TPLADD, "LOGDUPSCHECKED", (cfg.logduplicatelines == 1) ? "checked" : "");
659 tpl_printf(vars, TPLADD, "INITIALDEBUGLEVEL", "%u", cfg.initial_debuglevel);
661 if(cfg.cwlogdir != NULL) { tpl_addVar(vars, TPLADD, "CWLOGDIR", cfg.cwlogdir); }
662 if(cfg.emmlogdir != NULL) { tpl_addVar(vars, TPLADD, "EMMLOGDIR", cfg.emmlogdir); }
663 tpl_addVar(vars, TPLADD, "ECMFMT", cfg.ecmfmt);
664 tpl_printf(vars, TPLADD, "LOGHISTORYLINES", "%u", cfg.loghistorylines);
665 if(cfg.sysloghost != NULL) { tpl_addVar(vars, TPLADD, "SYSLOGHOST", cfg.sysloghost); }
666 tpl_printf(vars, TPLADD, "SYSLOGPORT", "%u", cfg.syslogport);
669 tpl_printf(vars, TPLADD, "CLIENTTIMEOUT", "%u", cfg.ctimeout);
670 tpl_printf(vars, TPLADD, "FALLBACKTIMEOUT", "%u", cfg.ftimeout);
671 tpl_printf(vars, TPLADD, "CLIENTMAXIDLE", "%u", cfg.cmaxidle);
674 value = mk_t_caidvaluetab(&cfg.ftimeouttab);
675 tpl_addVar(vars, TPLADD, "FALLBACKTIMEOUT_PERCAID", value);
676 free_mk_t(value);
678 tpl_printf(vars, TPLADD, "SLEEP", "%d", cfg.tosleep);
679 tpl_addVar(vars, TPLADD, "UNLOCKPARENTALCHECKED", (cfg.ulparent == 1) ? "checked" : "");
681 if(cfg.reload_useraccounts) { tpl_addVar(vars, TPLADD, "RELOADUSERACCOUNTSCHECKED", "checked"); }
682 if(cfg.reload_readers) { tpl_addVar(vars, TPLADD, "RELOADREADERSCHECKED", "checked"); }
683 if(cfg.reload_provid) { tpl_addVar(vars, TPLADD, "RELOADPROVIDCHECKED", "checked"); }
684 if(cfg.reload_services_ids) { tpl_addVar(vars, TPLADD, "RELOADSERVICESIDSCHECKED", "checked"); }
685 if(cfg.reload_tier_ids) { tpl_addVar(vars, TPLADD, "RELOADTIERUDSCHECKED", "checked"); }
686 if(cfg.reload_fakecws) { tpl_addVar(vars, TPLADD, "RELOADFAKECWSCHECKED", "checked"); }
687 if(cfg.reload_ac_stat) { tpl_addVar(vars, TPLADD, "RELOADACSTATCHECKED", "checked"); }
688 if(cfg.reload_log) { tpl_addVar(vars, TPLADD, "RELOADLOGCHECKED", "checked"); }
690 if(cfg.block_same_ip) { tpl_addVar(vars, TPLADD, "BLOCKSAMEIPCHECKED", "checked"); }
691 if(cfg.block_same_name) { tpl_addVar(vars, TPLADD, "BLOCKSAMENAMECHECKED", "checked"); }
693 if(cfg.waitforcards == 1) { tpl_addVar(vars, TPLADD, "WAITFORCARDSCHECKED", "checked"); }
694 tpl_printf(vars, TPLADD, "EXTRADELAY", "%d", cfg.waitforcards_extra_delay);
695 if(cfg.preferlocalcards == 1)
697 tpl_addVar(vars, TPLADD, "PREFERCACHEEX", "selected");
699 else if(cfg.preferlocalcards == 2)
701 tpl_addVar(vars, TPLADD, "PREFERLOCALCARDS", "selected");
704 if(cfg.c35_suppresscmd08)
705 { tpl_addVar(vars, TPLADD, "SUPPRESSCMD08", "checked"); }
707 if(cfg.getblockemmauprovid > 0)
709 tpl_addVar(vars, TPLADD, "GETBLOCKEMMAUPROVID", "checked");
712 if(cfg.reader_restart_seconds)
713 { tpl_printf(vars, TPLADD, "READERRESTARTSECONDS", "%d", cfg.reader_restart_seconds); }
715 tpl_addVar(vars, TPLADD, "DROPDUPSCHECKED", (cfg.dropdups == 1) ? "checked" : "");
717 if(cfg.resolve_gethostbyname == 1)
718 { tpl_addVar(vars, TPLADD, "RESOLVER1", "selected"); }
719 else
720 { tpl_addVar(vars, TPLADD, "RESOLVER0", "selected"); }
722 tpl_printf(vars, TPLADD, "FAILBANTIME", "%d", cfg.failbantime);
723 tpl_printf(vars, TPLADD, "FAILBANCOUNT", "%d", cfg.failbancount);
725 tpl_addVar(vars, TPLADD, "DCHECKCSELECTED", (cfg.double_check == 1) ? "checked" : "");
727 value = mk_t_caidtab(&cfg.double_check_caid);
728 tpl_addVar(vars, TPLADD, "DOUBLECHECKCAID", value);
729 free_mk_t(value);
731 tpl_addVar(vars, TPLADD, "DISABLECRCCWSCHECKEDGLOBAL", (cfg.disablecrccws == 1) ? "checked" : "");
733 value = mk_t_ftab(&cfg.disablecrccws_only_for);
734 tpl_addVar(vars, TPLADD, "IGNCHKSUMONLYFORGLOBAL", value);
735 free_mk_t(value);
737 #ifdef LEDSUPPORT
738 if(cfg.enableled == 1)
739 { tpl_addVar(vars, TPLADD, "ENABLELEDSELECTED1", "selected"); }
740 else if(cfg.enableled == 2)
741 { tpl_addVar(vars, TPLADD, "ENABLELEDSELECTED2", "selected"); }
742 #endif
744 return tpl_getTpl(vars, "CONFIGGLOBAL");
747 #ifdef WITH_LB
748 static char *send_oscam_config_loadbalancer(struct templatevars *vars, struct uriparams *params)
750 setActiveSubMenu(vars, MNU_CFG_LOADBAL);
752 if(strlen(getParam(params, "button")) > 0)
754 if(cfg.http_readonly)
756 tpl_addMsg(vars, "WebIf is in readonly mode. No changes are possible!");
758 else
760 if(strcmp(getParam(params, "button"), "Load Stats") == 0)
762 clear_all_stat();
763 load_stat_from_file();
764 tpl_addMsg(vars, "Stats loaded from file");
767 if(strcmp(getParam(params, "button"), "Save Stats") == 0)
769 save_stat_to_file(1);
770 tpl_addMsg(vars, "Stats saved to file");
773 if(strcmp(getParam(params, "button"), "Clear Stats") == 0)
775 clear_all_stat();
776 tpl_addMsg(vars, "Stats cleared completly");
779 if(strcmp(getParam(params, "button"), "Clear Timeouts") == 0)
781 clean_all_stats_by_rc(E_TIMEOUT, 0);
782 tpl_addMsg(vars, "Timeout cleared from Stats");
785 if(strcmp(getParam(params, "button"), "Clear Not Found") == 0)
787 clean_all_stats_by_rc(E_NOTFOUND, 0);
788 tpl_addMsg(vars, "Not Found cleared from Stats");
791 if(strcmp(getParam(params, "button"), "Clear Invalid") == 0)
793 clean_all_stats_by_rc(E_INVALID, 0);
794 tpl_addMsg(vars, "Invalid cleared from Stats");
799 webif_save_config("global", vars, params);
801 tpl_printf(vars, TPLADD, "TMP", "LBMODE%d", cfg.lb_mode);
802 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
804 tpl_printf(vars, TPLADD, "LBSAVE", "%d", cfg.lb_save);
805 if(cfg.lb_savepath) { tpl_addVar(vars, TPLADD, "LBSAVEPATH", cfg.lb_savepath); }
807 tpl_printf(vars, TPLADD, "LBNBESTREADERS", "%d", cfg.lb_nbest_readers);
808 char *value = mk_t_caidvaluetab(&cfg.lb_nbest_readers_tab);
809 tpl_addVar(vars, TPLADD, "LBNBESTPERCAID", value);
810 free_mk_t(value);
811 tpl_printf(vars, TPLADD, "LBNFBREADERS", "%d", cfg.lb_nfb_readers);
812 tpl_printf(vars, TPLADD, "LBMAXREADERS", "%d", cfg.lb_max_readers);
813 tpl_printf(vars, TPLADD, "LBMINECMCOUNT", "%d", cfg.lb_min_ecmcount);
814 tpl_printf(vars, TPLADD, "LBMAXECEMCOUNT", "%d", cfg.lb_max_ecmcount);
815 tpl_printf(vars, TPLADD, "LBRETRYLIMIT", "%d", cfg.lb_retrylimit);
817 value = mk_t_caidvaluetab(&cfg.lb_retrylimittab);
818 tpl_addVar(vars, TPLADD, "LBRETRYLIMITS", value);
819 free_mk_t(value);
821 tpl_printf(vars, TPLADD, "LBREOPENSECONDS", "%d", cfg.lb_reopen_seconds);
822 tpl_printf(vars, TPLADD, "LBCLEANUP", "%d", cfg.lb_stat_cleanup);
824 tpl_addVar(vars, TPLADD, "LBREOPENINVALID", (cfg.lb_reopen_invalid == 1) ? "checked" : "");
825 tpl_addVar(vars, TPLADD, "LBFORCEALWAYS", (cfg.lb_force_reopen_always == 1) ? "checked" : "");
827 value = mk_t_caidtab(&cfg.lb_noproviderforcaid);
828 tpl_addVar(vars, TPLADD, "LBNOPROVIDERFORCAID", value);
829 free_mk_t(value);
831 tpl_addVar(vars, TPLADD, "LBAUTOBETATUNNEL", (cfg.lb_auto_betatunnel == 1) ? "checked" : "");
833 if(cfg.lb_auto_betatunnel_mode)
835 tpl_printf(vars, TPLADD, "TMP", "LBAUTOBETATUNNELMODE%d", cfg.lb_auto_betatunnel_mode);
836 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
839 tpl_printf(vars, TPLADD, "LBPREFERBETA", "%d", cfg.lb_auto_betatunnel_prefer_beta);
841 tpl_addVar(vars, TPLADD, "LBAUTOTIMEOUT", (cfg.lb_auto_timeout == 1) ? "checked" : "");
843 tpl_printf(vars, TPLADD, "LBAUTOTIMEOUTP", "%d", cfg.lb_auto_timeout_p);
844 tpl_printf(vars, TPLADD, "LBAUTOTIMEOUTT", "%d", cfg.lb_auto_timeout_t);
846 tpl_addVar(vars, TPLADDONCE, "CONFIG_CONTROL", tpl_getTpl(vars, "CONFIGLOADBALANCERCTRL"));
848 return tpl_getTpl(vars, "CONFIGLOADBALANCER");
850 #endif
852 #ifdef MODULE_CAMD33
853 static char *send_oscam_config_camd33(struct templatevars *vars, struct uriparams *params)
855 int32_t i;
857 setActiveSubMenu(vars, MNU_CFG_CAMD33);
859 webif_save_config("camd33", vars, params);
861 if(cfg.c33_port)
863 tpl_printf(vars, TPLADD, "PORT", "%d", cfg.c33_port);
864 if(IP_ISSET(cfg.c33_srvip)) { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.c33_srvip)); }
865 tpl_addVar(vars, TPLADD, "PASSIVECHECKED", (cfg.c33_passive == 1) ? "checked" : "");
867 for(i = 0; i < (int) sizeof(cfg.c33_key); ++i) { tpl_printf(vars, TPLAPPEND, "KEY", "%02X", cfg.c33_key[i]); }
868 char *value = mk_t_iprange(cfg.c33_plain);
869 tpl_addVar(vars, TPLADD, "NOCRYPT", value);
870 free_mk_t(value);
873 return tpl_getTpl(vars, "CONFIGCAMD33");
875 #endif
877 #ifdef MODULE_CAMD35
878 static char *send_oscam_config_camd35(struct templatevars *vars, struct uriparams *params)
880 setActiveSubMenu(vars, MNU_CFG_CAMD35);
882 webif_save_config("cs357x", vars, params);
884 if(cfg.c35_port)
886 tpl_printf(vars, TPLADD, "PORT", "%d", cfg.c35_port);
887 if(IP_ISSET(cfg.c35_srvip))
888 { tpl_addVar(vars, TPLAPPEND, "SERVERIP", cs_inet_ntoa(cfg.c35_srvip)); }
890 if(cfg.c35_udp_suppresscmd08)
891 { tpl_addVar(vars, TPLADD, "SUPPRESSCMD08UDP", "checked"); }
894 return tpl_getTpl(vars, "CONFIGCAMD35");
896 #endif
898 #ifdef MODULE_CAMD35_TCP
899 static char *send_oscam_config_camd35tcp(struct templatevars *vars, struct uriparams *params)
901 setActiveSubMenu(vars, MNU_CFG_CAMD35TCP);
903 webif_save_config("cs378x", vars, params);
905 if((cfg.c35_tcp_ptab.nports > 0) && (cfg.c35_tcp_ptab.ports[0].s_port > 0))
908 char *value = mk_t_camd35tcp_port();
909 tpl_addVar(vars, TPLADD, "PORT", value);
910 free_mk_t(value);
912 if(IP_ISSET(cfg.c35_tcp_srvip))
913 { tpl_addVar(vars, TPLAPPEND, "SERVERIP", cs_inet_ntoa(cfg.c35_tcp_srvip)); }
915 if(cfg.c35_tcp_suppresscmd08)
916 { tpl_addVar(vars, TPLADD, "SUPPRESSCMD08TCP", "checked"); }
918 return tpl_getTpl(vars, "CONFIGCAMD35TCP");
920 #endif
922 static char *send_oscam_config_cache(struct templatevars *vars, struct uriparams *params)
924 setActiveSubMenu(vars, MNU_CFG_CACHE);
926 webif_save_config("cache", vars, params);
928 tpl_printf(vars, TPLADD, "CACHEDELAY", "%u", cfg.delay);
930 tpl_printf(vars, TPLADD, "MAXCACHETIME", "%d", cfg.max_cache_time);
932 #ifdef CS_CACHEEX
933 char *value = NULL;
934 value = mk_t_cacheex_valuetab(&cfg.cacheex_wait_timetab);
935 tpl_addVar(vars, TPLADD, "WAIT_TIME", value);
936 free_mk_t(value);
938 value = mk_t_caidvaluetab(&cfg.cacheex_mode1_delay_tab);
939 tpl_addVar(vars, TPLADD, "CACHEEXMODE1DELAY", value);
940 free_mk_t(value);
942 tpl_printf(vars, TPLADD, "MAX_HIT_TIME", "%d", cfg.max_hitcache_time);
944 tpl_addVar(vars, TPLADD, "CACHEEXSTATSSELECTED", (cfg.cacheex_enable_stats == 1) ? "checked" : "");
946 tpl_addVar(vars, TPLADD, "WTTCHECKED", (cfg.wait_until_ctimeout == 1) ? "checked" : "");
948 if(cfg.csp_port)
949 { tpl_printf(vars, TPLADD, "PORT", "%d", cfg.csp_port); }
951 if(IP_ISSET(cfg.csp_srvip))
952 { tpl_addVar(vars, TPLAPPEND, "SERVERIP", cs_inet_ntoa(cfg.csp_srvip)); }
954 value = mk_t_cacheex_hitvaluetab(&cfg.csp.filter_caidtab);
955 tpl_addVar(vars, TPLADD, "CSP_ECM_FILTER", value);
956 free_mk_t(value);
958 value = mk_t_cacheex_cwcheck_valuetab(&cfg.cacheex_cwcheck_tab);
959 tpl_addVar(vars, TPLADD, "CACHEEXCWCHECK", value);
960 free_mk_t(value);
962 tpl_addVar(vars, TPLADD, "ARCHECKED", (cfg.csp.allow_request == 1) ? "checked" : "");
963 tpl_addVar(vars, TPLADD, "ARFCHECKED", (cfg.csp.allow_reforward == 1) ? "checked" : "");
964 tpl_addVar(vars, TPLADD, "BLOCKFAKECWSCHECKED", (cfg.csp.block_fakecws == 1) ? "checked" : "");
965 #endif
967 #ifdef CW_CYCLE_CHECK
968 #ifndef CS_CACHEEX
969 char *value = NULL;
970 #endif
972 tpl_addVar(vars, TPLADD, "CWCYCLECHECK", (cfg.cwcycle_check_enable == 1) ? "checked" : "");
974 value = mk_t_caidtab(&cfg.cwcycle_check_caidtab);
975 tpl_addVar(vars, TPLADD, "CWCYCLECHECKCAID", value);
976 free_mk_t(value);
978 tpl_printf(vars, TPLADD, "MAXCYCLELIST", "%d", cfg.maxcyclelist);
979 tpl_printf(vars, TPLADD, "KEEPCYCLETIME", "%d", cfg.keepcycletime);
981 if(cfg.onbadcycle)
983 tpl_printf(vars, TPLADD, "TMP", "ONBADCYCLE%d", cfg.onbadcycle);
984 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
987 tpl_addVar(vars, TPLADD, "DROPOLD", (cfg.cwcycle_dropold == 1) ? "checked" : "");
989 if(cfg.cwcycle_sensitive)
991 tpl_printf(vars, TPLADD, "TMP", "CWCSEN%d", cfg.cwcycle_sensitive);
992 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
995 tpl_addVar(vars, TPLADD, "ALLOWBADFROMFFB", (cfg.cwcycle_allowbadfromffb == 1) ? "checked" : "");
997 tpl_addVar(vars, TPLADD, "USECWCFROMCE", (cfg.cwcycle_usecwcfromce == 1) ? "checked" : "");
1000 #endif
1002 return tpl_getTpl(vars, "CONFIGCACHE");
1005 #ifdef MODULE_NEWCAMD
1006 static char *send_oscam_config_newcamd(struct templatevars *vars, struct uriparams *params)
1008 int32_t i;
1010 setActiveSubMenu(vars, MNU_CFG_NEWCAMD);
1012 webif_save_config("newcamd", vars, params);
1014 if((cfg.ncd_ptab.nports > 0) && (cfg.ncd_ptab.ports[0].s_port > 0))
1017 char *value = mk_t_newcamd_port();
1018 tpl_addVar(vars, TPLADD, "PORT", value);
1019 free_mk_t(value);
1021 if(IP_ISSET(cfg.ncd_srvip))
1022 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.ncd_srvip)); }
1024 for(i = 0; i < (int32_t)sizeof(cfg.ncd_key); i++)
1025 { tpl_printf(vars, TPLAPPEND, "KEY", "%02X", cfg.ncd_key[i]); }
1027 value = mk_t_iprange(cfg.ncd_allowed);
1028 tpl_addVar(vars, TPLADD, "ALLOWED", value);
1029 free_mk_t(value);
1031 if(cfg.ncd_keepalive)
1032 { tpl_addVar(vars, TPLADD, "KEEPALIVE", "checked"); }
1033 if(cfg.ncd_mgclient)
1034 { tpl_addVar(vars, TPLADD, "MGCLIENTCHK", "checked"); }
1036 return tpl_getTpl(vars, "CONFIGNEWCAMD");
1038 #endif
1040 #ifdef MODULE_GBOX
1041 static char *send_oscam_config_gbox(struct templatevars *vars, struct uriparams *params)
1043 uint8_t i=0;
1044 char local_gbox_save_gsms[2],local_gbox_msg_type[3], local_gbox_dest_peers[GBOX_MAX_DEST_PEERS*5], tmp_gbox_dest_peers[GBOX_MAX_DEST_PEERS*5] ;
1045 int n=0, len_gbox_save_gsms=0, len_gbox_msg_type=0, len_gbox_dest_peers=0, len_gbox_msg_txt=0;
1046 char *ptr1, *saveptr1, *isbroadcast = NULL;
1047 const char *s;
1048 uint16_t gbox_dest_peers_tmp;
1050 setActiveSubMenu(vars, MNU_CFG_GBOX);
1051 webif_save_config("gbox", vars, params);
1053 * Action when GetOnlinePeers is pressed
1055 if(streq(getParam(params, "action"), "Online peers"))
1057 gbox_get_online_peers();
1058 // init var
1059 len_gbox_save_gsms=strlen(getParam(params, "gbox_msg_type"));
1060 len_gbox_msg_type=strlen(getParam(params, "gbox_msg_type"));
1061 len_gbox_msg_txt=strlen(getParam(params, "gbox_msg_txt"));
1062 if(len_gbox_msg_txt>GBOX_MAX_MSG_TXT) { len_gbox_msg_txt=GBOX_MAX_MSG_TXT; }
1063 // retrieve value from Webif
1064 cs_strncpy(local_gbox_save_gsms, getParam(params, "gbox_save_gsms"), len_gbox_save_gsms+1);
1065 cfg.gbox_save_gsms=atoi(local_gbox_save_gsms);
1066 cs_strncpy(local_gbox_msg_type, getParam(params, "gbox_msg_type"), len_gbox_msg_type+1);
1067 cfg.gbox_msg_type=atoi(local_gbox_msg_type);
1068 cs_strncpy(cfg.gbox_msg_txt,getParam(params, "gbox_msg_txt"), len_gbox_msg_txt+1);
1071 * Action when ResetGSMS button is pressed
1073 if(streq(getParam(params, "action"), "resetallgsms"))
1075 cfg.gbox_save_gsms = 0;
1076 cfg.gbox_msg_type = 0;
1077 for(i = 0; i < GBOX_MAX_DEST_PEERS; i++)
1079 cfg.gbox_dest_peers[i]='\0';
1081 cfg.gbox_dest_peers_num=0;
1082 for(i = 0; i < GBOX_MAX_MSG_TXT; i++)
1084 cfg.gbox_msg_txt[i]='\0';
1086 tpl_addMsg(vars, "GBOX: Reset GSMS datas done!");
1089 * Action when Send GSMS is pressed
1091 if(streq(getParam(params, "action"), "Send GSMS"))
1093 // init var
1094 len_gbox_msg_type=strlen(getParam(params, "gbox_msg_type"));
1095 len_gbox_dest_peers=strlen(trim(getParam(params, "gbox_dest_peers")));
1096 len_gbox_msg_txt=strlen(getParam(params, "gbox_msg_txt"));
1097 if(len_gbox_msg_txt>GBOX_MAX_MSG_TXT) { len_gbox_msg_txt=GBOX_MAX_MSG_TXT; }
1098 // retrieve value from Webif
1099 cs_strncpy(local_gbox_msg_type, getParam(params, "gbox_msg_type"), len_gbox_msg_type+1);
1100 cfg.gbox_msg_type=atoi(local_gbox_msg_type);
1101 cs_strncpy(local_gbox_dest_peers, strtoupper(trim(getParam(params, "gbox_dest_peers"))), len_gbox_dest_peers+1);
1102 cs_strncpy(tmp_gbox_dest_peers, strtoupper(trim(getParam(params, "gbox_dest_peers"))), len_gbox_dest_peers+1);
1103 cs_strncpy(cfg.gbox_msg_txt,getParam(params, "gbox_msg_txt"), len_gbox_msg_txt+1);
1104 n=0;
1105 for (ptr1 = strtok_r(tmp_gbox_dest_peers, ",", &saveptr1); (ptr1); ptr1 = strtok_r(NULL, ",", &saveptr1))
1107 s=trim(ptr1);
1108 if ((n < GBOX_MAX_DEST_PEERS) && (s[strspn(s, "0123456789abcdefABCDEF")] == 0))
1109 { cfg.gbox_dest_peers[n++] = a2i(trim(ptr1), strlen(trim(ptr1))); }
1111 cfg.gbox_dest_peers_num = n;
1113 Start sending GBox SMS
1115 if((strlen(cfg.gbox_msg_txt) > 5))
1117 isbroadcast=strstr(local_gbox_dest_peers, "FFFF");
1118 if(isbroadcast == NULL)
1120 n =0;
1121 for (i = 0, ptr1 = strtok_r(local_gbox_dest_peers, ",", &saveptr1); (i < 4) && (ptr1); ptr1 = strtok_r(NULL, ",", &saveptr1))
1123 s=ptr1;
1124 if ((n < GBOX_MAX_DEST_PEERS) && (s[strspn(s, "0123456789abcdefABCDEF")] == 0))
1126 gbox_dest_peers_tmp = a2i(ptr1, 4);
1127 if(gbox_direct_send_gsms(gbox_dest_peers_tmp, cfg.gbox_msg_type, cfg.gbox_msg_txt)) { cs_log("GBOX message sent to[%04X] type[%d] text[%s] ", gbox_dest_peers_tmp, cfg.gbox_msg_type, cfg.gbox_msg_txt);}
1128 n++;
1131 tpl_addMsg(vars, "GBOX Send SMS: individual messages started.");
1133 else
1135 if(gbox_direct_send_gsms(0xFFFF, cfg.gbox_msg_type, cfg.gbox_msg_txt)) { cs_log("GBOX broadcast message sent type[%d] text[%s] ", cfg.gbox_msg_type, cfg.gbox_msg_txt);}
1136 tpl_addMsg(vars, "GBOX Send SMS: broadcast started.");
1139 else
1141 cs_log("GBox SMS: destination peers or message text not specified or too short");
1142 tpl_addMsg(vars, "GBOX: Send SMS failed - error in input fields: dest peers or text message.");
1146 tpl_addVar(vars, TPLADD, "HOSTNAME", xml_encode(vars, cfg.gbox_hostname));
1147 char *value0 = mk_t_gbox_port();
1148 tpl_addVar(vars, TPLAPPEND, "PORT", value0);
1149 free_mk_t(value0);
1150 tpl_printf(vars, TPLADD, "MYGBOXPASSWORD", "%08X", cfg.gbox_password);
1151 tpl_printf(vars, TPLADD, "MYGBOXID", "%04X", gbox_get_local_gbox_id());
1152 tpl_printf(vars, TPLADD, "GBOXRECONNECT", "%d", cfg.gbox_reconnect);
1153 tpl_printf(vars, TPLADD, "GBOXMYVERS", "%02X", cfg.gbox_my_vers);
1154 tpl_printf(vars, TPLAPPEND, "GBOXMYCPUAPI", "%02X", cfg.gbox_my_cpu_api);
1155 #ifdef MODULE_CCCAM
1156 if(cfg.ccc_reshare == 1) { tpl_addVar(vars, TPLADD, "GBOXCCCRESHARE", "checked"); }
1157 tpl_addVar(vars, TPLAPPEND, "CCCDEPENDINGCONFIG", tpl_getTpl(vars, "CCCAMRESHAREBIT"));
1158 #endif
1159 if(cfg.log_hello == 1) { tpl_addVar(vars, TPLADD, "GBOXLOGHELLO", "checked"); }
1160 if(cfg.gsms_dis == 1) { tpl_addVar(vars, TPLADD, "GBOXGSMSDISABLE", "checked"); }
1161 if(cfg.dis_attack_txt == 1) { tpl_addVar(vars, TPLADD, "GBOXDISATTACKTXT", "checked"); }
1162 if(cfg.gbox_tmp_dir != NULL) { tpl_addVar(vars, TPLADD, "GBOXTMPDIR", cfg.gbox_tmp_dir); }
1163 char *value1 = mk_t_gbox_proxy_card();
1164 tpl_addVar(vars, TPLAPPEND, "GBOXPROXYCARD", value1);
1165 free_mk_t(value1);
1166 char *value2 = mk_t_gbox_ignored_peer();
1167 tpl_addVar(vars, TPLAPPEND, "GBOXIGNOREDPEER", value2);
1168 free_mk_t(value2);
1169 char *value3 = mk_t_gbox_block_ecm();
1170 tpl_addVar(vars, TPLAPPEND, "GBOXBLOCKECM", value3);
1171 free_mk_t(value3);
1172 char *value4 = mk_t_accept_remm_peer();
1173 tpl_addVar(vars, TPLAPPEND, "GBOXACCEPTREMM", value4);
1174 free_mk_t(value4);
1176 * GBOX SMS
1178 tpl_addVar(vars, TPLADD, "GBOXSAVEGSMS", (cfg.gbox_save_gsms == 1) ? "checked" : "");
1179 if(cfg.gbox_msg_type == 0)
1181 tpl_addVar(vars, TPLADD, "GBOXMSGTYPENORMAL", "selected");
1183 else if(cfg.gbox_msg_type == 1)
1185 tpl_addVar(vars, TPLADD, "GBOXMSGTYPEOSD", "selected");
1187 char *gmsg_dest_peers = mk_t_gbox_dest_peers();
1188 tpl_addVar(vars, TPLADD, "GBOXMSGDESTPEERS", gmsg_dest_peers);
1189 free_mk_t(gmsg_dest_peers);
1190 tpl_addVar(vars, TPLADD, "GBOXMSGTXT", cfg.gbox_msg_txt);
1192 return tpl_getTpl(vars, "CONFIGGBOX");
1194 #endif
1196 #ifdef MODULE_RADEGAST
1197 static char *send_oscam_config_radegast(struct templatevars *vars, struct uriparams *params)
1199 setActiveSubMenu(vars, MNU_CFG_RADEGAST);
1201 webif_save_config("radegast", vars, params);
1203 tpl_printf(vars, TPLADD, "PORT", "%d", cfg.rad_port);
1204 if(IP_ISSET(cfg.rad_srvip))
1205 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.rad_srvip)); }
1206 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, cfg.rad_usr));
1208 char *value = mk_t_iprange(cfg.rad_allowed);
1209 tpl_addVar(vars, TPLADD, "ALLOWED", value);
1210 free_mk_t(value);
1212 return tpl_getTpl(vars, "CONFIGRADEGAST");
1214 #endif
1216 #ifdef MODULE_SCAM
1217 static char *send_oscam_config_scam(struct templatevars *vars, struct uriparams *params)
1219 setActiveSubMenu(vars, MNU_CFG_SCAM);
1221 webif_save_config("scam", vars, params);
1223 tpl_printf(vars, TPLADD, "PORT", "%d", cfg.scam_port);
1224 if(IP_ISSET(cfg.scam_srvip))
1225 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.scam_srvip)); }
1227 char *value = mk_t_iprange(cfg.scam_allowed);
1228 tpl_addVar(vars, TPLADD, "ALLOWED", value);
1229 free_mk_t(value);
1231 return tpl_getTpl(vars, "CONFIGSCAM");
1233 #endif
1235 #ifdef WITH_EMU
1236 static char *send_oscam_config_streamrelay(struct templatevars *vars, struct uriparams *params)
1238 char *value;
1240 setActiveSubMenu(vars, MNU_CFG_STREAMRELAY);
1242 webif_save_config("streamrelay", vars, params);
1244 tpl_printf(vars, TPLADD, "STREAM_SOURCE_HOST", "%s", cfg.emu_stream_source_host);
1245 tpl_printf(vars, TPLADD, "STREAM_SOURCE_PORT", "%d", cfg.emu_stream_source_port);
1246 if(cfg.emu_stream_source_auth_user)
1247 { tpl_printf(vars, TPLADD, "STREAM_SOURCE_AUTH_USER", "%s", cfg.emu_stream_source_auth_user); }
1248 if(cfg.emu_stream_source_auth_password)
1249 { tpl_printf(vars, TPLADD, "STREAM_SOURCE_AUTH_PASSWORD", "%s", cfg.emu_stream_source_auth_password); }
1250 tpl_printf(vars, TPLADD, "STREAM_RELAY_PORT", "%d", cfg.emu_stream_relay_port);
1251 tpl_printf(vars, TPLADD, "STREAM_ECM_DELAY", "%d", cfg.emu_stream_ecm_delay);
1253 tpl_printf(vars, TPLADD, "TMP", "STREAMRELAYENABLEDSELECTED%d", cfg.emu_stream_relay_enabled);
1254 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1256 tpl_printf(vars, TPLADD, "TMP", "STREAMEMMENABLEDSELECTED%d", cfg.emu_stream_emm_enabled);
1257 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1259 value = mk_t_caidtab(&cfg.emu_stream_relay_ctab);
1260 tpl_addVar(vars, TPLADD, "STREAM_RELAY_CTAB", value);
1261 free_mk_t(value);
1263 return tpl_getTpl(vars, "CONFIGSTREAMRELAY");
1265 #endif
1267 #ifdef MODULE_CCCAM
1268 static char *send_oscam_config_cccam(struct templatevars *vars, struct uriparams *params)
1271 setActiveSubMenu(vars, MNU_CFG_CCCAM);
1273 if(strcmp(getParam(params, "button"), "Refresh list") == 0)
1275 cs_log_dbg(D_TRACE, "Entitlements: Refresh Shares start");
1276 #ifdef MODULE_CCCSHARE
1277 refresh_shares();
1278 #endif
1279 cs_log_dbg(D_TRACE, "Entitlements: Refresh Shares finished");
1280 tpl_addMsg(vars, "Refresh Shares started");
1283 webif_save_config("cccam", vars, params);
1285 if(streq(getParam(params, "action"), "execute") && !cfg.http_readonly)
1286 { cc_update_nodeid(); }
1288 char *value = mk_t_cccam_port();
1289 tpl_addVar(vars, TPLAPPEND, "PORT", value);
1290 free_mk_t(value);
1292 if(IP_ISSET(cfg.cc_srvip))
1293 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.cc_srvip)); }
1295 tpl_printf(vars, TPLADD, "RESHARE", "%d", cfg.cc_reshare);
1297 if(!strcmp((char *)cfg.cc_version, "2.0.11"))
1299 tpl_addVar(vars, TPLADD, "VERSIONSELECTED0", "selected");
1301 else if(!strcmp((char *)cfg.cc_version, "2.1.1"))
1303 tpl_addVar(vars, TPLADD, "VERSIONSELECTED1", "selected");
1305 else if(!strcmp((char *)cfg.cc_version, "2.1.2"))
1307 tpl_addVar(vars, TPLADD, "VERSIONSELECTED2", "selected");
1309 else if(!strcmp((char *)cfg.cc_version, "2.1.3"))
1311 tpl_addVar(vars, TPLADD, "VERSIONSELECTED3", "selected");
1313 else if(!strcmp((char *)cfg.cc_version, "2.1.4"))
1315 tpl_addVar(vars, TPLADD, "VERSIONSELECTED4", "selected");
1317 else if(!strcmp((char *)cfg.cc_version, "2.2.0"))
1319 tpl_addVar(vars, TPLADD, "VERSIONSELECTED5", "selected");
1321 else if(!strcmp((char *)cfg.cc_version, "2.2.1"))
1323 tpl_addVar(vars, TPLADD, "VERSIONSELECTED6", "selected");
1325 else if(!strcmp((char *)cfg.cc_version, "2.3.0"))
1327 tpl_addVar(vars, TPLADD, "VERSIONSELECTED7", "selected");
1329 else if(!strcmp((char *)cfg.cc_version, "2.3.1"))
1331 tpl_addVar(vars, TPLADD, "VERSIONSELECTED8", "selected");
1333 else if(!strcmp((char *)cfg.cc_version, "2.3.2"))
1335 tpl_addVar(vars, TPLADD, "VERSIONSELECTED9", "selected");
1338 tpl_printf(vars, TPLADD, "UPDATEINTERVAL", "%d", cfg.cc_update_interval);
1339 tpl_printf(vars, TPLADD, "RECV_TIMEOUT", "%u", cfg.cc_recv_timeout);
1341 tpl_addVar(vars, TPLADD, "STEALTH", (cfg.cc_stealth == 1) ? "checked" : "");
1343 tpl_printf(vars, TPLADD, "NODEID", "%02X%02X%02X%02X%02X%02X%02X%02X",
1344 cfg.cc_fixed_nodeid[0], cfg.cc_fixed_nodeid[1], cfg.cc_fixed_nodeid[2], cfg.cc_fixed_nodeid[3],
1345 cfg.cc_fixed_nodeid[4], cfg.cc_fixed_nodeid[5], cfg.cc_fixed_nodeid[6], cfg.cc_fixed_nodeid[7]);
1347 tpl_printf(vars, TPLADD, "TMP", "MINIMIZECARDSELECTED%d", cfg.cc_minimize_cards);
1348 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1350 tpl_printf(vars, TPLADD, "TMP", "RESHAREMODE%d", cfg.cc_reshare_services);
1351 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1353 tpl_printf(vars, TPLADD, "TMP", "IGNRSHRSELECTED%d", cfg.cc_ignore_reshare);
1354 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1356 tpl_addVar(vars, TPLADD, "FORWARDORIGINCARD", (cfg.cc_forward_origin_card == 1) ? "checked" : "");
1358 tpl_addVar(vars, TPLADD, "KEEPCONNECTED", (cfg.cc_keep_connected == 1) ? "checked" : "");
1360 tpl_addVar(vars, TPLADDONCE, "CONFIG_CONTROL", tpl_getTpl(vars, "CONFIGCCCAMCTRL"));
1362 return tpl_getTpl(vars, "CONFIGCCCAM");
1364 #endif
1366 static bool is_ext(const char *path, const char *ext)
1368 size_t lenpath = strlen(path);
1369 size_t lenext = strlen(ext);
1370 if(lenext > lenpath)
1371 { return 0; }
1372 return memcmp(path + lenpath - lenext, ext, lenext) == 0;
1375 static char *send_oscam_config_webif(struct templatevars *vars, struct uriparams *params)
1377 int32_t i;
1379 setActiveSubMenu(vars, MNU_CFG_WEBIF);
1381 webif_save_config("webif", vars, params);
1383 tpl_printf(vars, TPLADD, "HTTPPORT", "%s%d", cfg.http_use_ssl ? "+" : "", cfg.http_port);
1384 if(IP_ISSET(cfg.http_srvip))
1385 { tpl_addVar(vars, TPLAPPEND, "SERVERIP", cs_inet_ntoa(cfg.http_srvip)); }
1387 tpl_addVar(vars, TPLADD, "HTTPUSER", cfg.http_user);
1388 tpl_addVar(vars, TPLADD, "HTTPPASSWORD", cfg.http_pwd);
1389 tpl_addVar(vars, TPLADD, "HTTPOSCAMLABEL", cfg.http_oscam_label);
1391 // css style selector
1392 tpl_printf(vars, TPLADD, "CSSOPTIONS", "\t\t\t\t\t\t<option value=\"\"%s>embedded</option>\n",
1393 !cfg.http_css ? " selected" : "");
1395 if(cfg.http_tpl)
1397 char path[255];
1398 tpl_getFilePathInSubdir(cfg.http_tpl, "", "style", ".css", path, 255);
1399 if(file_exists(path))
1400 tpl_printf(vars, TPLAPPEND, "CSSOPTIONS", "\t\t\t\t\t\t<option value=\"%s\"%s>%s (template)</option>\n",
1401 path,
1402 cfg.http_css && strstr(cfg.http_css, path) ? " selected" : "",
1403 path);
1406 struct dirent **namelist;
1407 int count;
1408 count = scandir(cs_confdir, &namelist, 0, alphasort );
1410 if( count >= 0 )
1412 for( i = 0 ; i < count; i++ )
1414 if(is_ext(namelist[i]->d_name, ".css"))
1416 tpl_printf(vars, TPLAPPEND, "CSSOPTIONS", "\t\t\t\t\t\t<option value=\"%s%s\"%s>%s%s</option>\n",
1417 cs_confdir,
1418 namelist[i]->d_name,
1419 cfg.http_css && strstr(cfg.http_css, namelist[i]->d_name) ? " selected" : "",
1420 cs_confdir, namelist[i]->d_name);
1422 free( namelist[i] );
1424 free(namelist);
1427 if(cfg.http_prepend_embedded_css)
1428 { tpl_addVar(vars, TPLADD, "HTTPPREPENDEMBEDDEDCSS", "checked"); }
1430 tpl_addVar(vars, TPLADD, "HTTPHELPLANG", cfg.http_help_lang);
1431 tpl_addVar(vars, TPLADD, "HTTPLOCALE", cfg.http_locale);
1432 tpl_printf(vars, TPLADD, "HTTPEMMUCLEAN", "%d", cfg.http_emmu_clean);
1433 tpl_printf(vars, TPLADD, "HTTPEMMSCLEAN", "%d", cfg.http_emms_clean);
1434 tpl_printf(vars, TPLADD, "HTTPEMMGCLEAN", "%d", cfg.http_emmg_clean);
1435 tpl_printf(vars, TPLADD, "HTTPREFRESH", "%d", cfg.http_refresh);
1436 tpl_printf(vars, TPLADD, "HTTPPOLLREFRESH", "%d", cfg.poll_refresh);
1437 tpl_addVar(vars, TPLADD, "HTTPTPL", cfg.http_tpl);
1438 tpl_addVar(vars, TPLADD, "HTTPPICONPATH", cfg.http_piconpath);
1439 tpl_addVar(vars, TPLADD, "HTTPSCRIPT", cfg.http_script);
1440 tpl_addVar(vars, TPLADD, "HTTPJSCRIPT", cfg.http_jscript);
1441 #ifndef WEBIF_JQUERY
1442 tpl_addVar(vars, TPLADD, "HTTPEXTERNJQUERY", cfg.http_extern_jquery);
1443 #endif
1444 tpl_printf(vars, TPLADD, "HTTPPICONSIZE", "%d", cfg.http_picon_size);
1446 if(cfg.http_hide_idle_clients > 0) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
1447 tpl_addVar(vars, TPLADD, "HTTPHIDETYPE", cfg.http_hide_type);
1448 if(cfg.http_status_log > 0) { tpl_addVar(vars, TPLADD, "SHOWLOGCHECKED", "checked"); }
1449 if(cfg.http_showpicons > 0) { tpl_addVar(vars, TPLADD, "SHOWPICONSCHECKED", "checked"); }
1450 if(cfg.http_showmeminfo > 0) { tpl_addVar(vars, TPLADD, "SHOWMEMINFOCHECKED", "checked"); }
1451 if(cfg.http_showuserinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWUSERINFOCHECKED", "checked"); }
1452 if(cfg.http_showreaderinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWREADERINFOCHECKED", "checked"); }
1453 if(cfg.http_showcacheexinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWCACHEEXINFOCHECKED", "checked"); }
1454 if(cfg.http_showloadinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWLOADINFOCHECKED", "checked"); }
1455 if(cfg.http_showecminfo > 0) { tpl_addVar(vars, TPLADD, "SHOWECMINFOCHECKED", "checked"); }
1457 char *value = mk_t_iprange(cfg.http_allowed);
1458 tpl_addVar(vars, TPLADD, "HTTPALLOW", value);
1459 free_mk_t(value);
1461 for(i = 0; i < MAX_HTTP_DYNDNS; i++)
1463 if(cfg.http_dyndns[i][0])
1465 tpl_addVar(vars, TPLAPPEND, "HTTPDYNDNS", i > 0 ? "," : "");
1466 tpl_addVar(vars, TPLAPPEND, "HTTPDYNDNS", (char *)cfg.http_dyndns[i]);
1470 tpl_addVar(vars, TPLADD, "HTTPSAVEFULLSELECT", (cfg.http_full_cfg == 1) ? "checked" : "");
1471 tpl_addVar(vars, TPLADD, "HTTPOVERWRITEBAKFILE", (cfg.http_overwrite_bak_file == 1) ? "checked" : "");
1472 tpl_addVar(vars, TPLADD, "HTTPREADONLY", (cfg.http_readonly == 1) ? "checked" : "");
1475 #ifdef WITH_SSL
1476 if(cfg.http_cert != NULL) { tpl_addVar(vars, TPLADD, "HTTPCERT", cfg.http_cert); }
1477 tpl_addVar(vars, TPLADD, "HTTPFORCESECUREMODESELECT", (cfg.https_force_secure_mode == 1) ? "checked" : "");
1478 #endif
1480 #ifndef WEBIF_JQUERY
1481 tpl_addVar(vars, TPLADDONCE, "CONFIGWEBIFJQUERY", tpl_getTpl(vars, "CONFIGWEBIFJQUERYBIT"));
1482 #endif
1484 tpl_printf(vars, TPLADD, "AULOW", "%d", cfg.aulow);
1485 tpl_printf(vars, TPLADD, "HIDECLIENTTO", "%d", cfg.hideclient_to);
1487 return tpl_getTpl(vars, "CONFIGWEBIF");
1490 #ifdef LCDSUPPORT
1491 static char *send_oscam_config_lcd(struct templatevars *vars, struct uriparams *params)
1493 setActiveSubMenu(vars, MNU_CFG_LCD);
1495 webif_save_config("lcd", vars, params);
1497 tpl_addVar(vars, TPLADD, "ENABLELCDSELECTED", (cfg.enablelcd == 1) ? "checked" : "");
1499 if(cfg.lcd_output_path != NULL)
1500 { tpl_addVar(vars, TPLADD, "LCDOUTPUTPATH", cfg.lcd_output_path); }
1502 tpl_addVar(vars, TPLADD, "LCDHIDEIDLE", (cfg.lcd_hide_idle == 1) ? "checked" : "");
1504 tpl_printf(vars, TPLADD, "LCDREFRESHINTERVAL", "%d", cfg.lcd_write_intervall);
1506 return tpl_getTpl(vars, "CONFIGLCD");
1508 #endif
1510 #ifdef MODULE_MONITOR
1511 static char *send_oscam_config_monitor(struct templatevars *vars, struct uriparams *params)
1513 setActiveSubMenu(vars, MNU_CFG_MONITOR);
1515 webif_save_config("monitor", vars, params);
1517 tpl_printf(vars, TPLADD, "MONPORT", "%d", cfg.mon_port);
1518 if(IP_ISSET(cfg.mon_srvip))
1519 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.mon_srvip)); }
1521 tpl_printf(vars, TPLADD, "AULOW", "%d", cfg.aulow);
1522 tpl_printf(vars, TPLADD, "HIDECLIENTTO", "%d", cfg.hideclient_to);
1524 char *value = mk_t_iprange(cfg.mon_allowed);
1525 tpl_addVar(vars, TPLADD, "NOCRYPT", value);
1526 free_mk_t(value);
1528 //Monlevel selector
1529 tpl_printf(vars, TPLADD, "TMP", "MONSELECTED%d", cfg.mon_level);
1530 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1532 return tpl_getTpl(vars, "CONFIGMONITOR");
1534 #endif
1536 #ifdef MODULE_SERIAL
1537 static char *send_oscam_config_serial(struct templatevars *vars, struct uriparams *params)
1539 setActiveSubMenu(vars, MNU_CFG_SERIAL);
1541 webif_save_config("serial", vars, params);
1543 if(cfg.ser_device)
1545 char sdevice[strlen(cfg.ser_device)];
1546 cs_strncpy(sdevice, cfg.ser_device, sizeof(sdevice));
1547 char *ptr, *saveptr1 = NULL;
1548 char delimiter[2];
1549 delimiter[0] = 1;
1550 delimiter[1] = '\0';
1551 for(ptr = strtok_r(sdevice, delimiter, &saveptr1); ptr; ptr = strtok_r(NULL, delimiter, &saveptr1))
1553 tpl_addVar(vars, TPLADD, "SERIALDEVICE", xml_encode(vars, ptr));
1554 tpl_addVar(vars, TPLAPPEND, "DEVICES", tpl_getTpl(vars, "CONFIGSERIALDEVICEBIT"));
1558 tpl_addVar(vars, TPLADD, "SERIALDEVICE", "");
1559 tpl_addVar(vars, TPLAPPEND, "DEVICES", tpl_getTpl(vars, "CONFIGSERIALDEVICEBIT"));
1561 return tpl_getTpl(vars, "CONFIGSERIAL");
1563 #endif
1565 #ifdef HAVE_DVBAPI
1566 extern const char *boxdesc[];
1568 static char *send_oscam_config_dvbapi(struct templatevars *vars, struct uriparams *params)
1570 int32_t i;
1572 setActiveSubMenu(vars, MNU_CFG_DVBAPI);
1574 webif_save_config("dvbapi", vars, params);
1576 if(cfg.dvbapi_enabled > 0)
1577 { tpl_addVar(vars, TPLADD, "ENABLEDCHECKED", "checked"); }
1579 if(cfg.dvbapi_au > 0)
1580 { tpl_addVar(vars, TPLADD, "AUCHECKED", "checked"); }
1582 if(cfg.dvbapi_delayer > 0)
1583 { tpl_printf(vars, TPLADD, "DELAYER", "%d", cfg.dvbapi_delayer); }
1585 tpl_printf(vars, TPLADD, "BOXTYPE", "<option value=\"\"%s>None</option>\n", cfg.dvbapi_boxtype == 0 ? " selected" : "");
1586 for(i = 1; i <= BOXTYPES; i++)
1588 tpl_printf(vars, TPLAPPEND, "BOXTYPE", "<option%s>%s</option>\n", cfg.dvbapi_boxtype == i ? " selected" : "", boxdesc[i]);
1591 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, cfg.dvbapi_usr));
1593 //PMT Mode
1594 tpl_printf(vars, TPLADD, "TMP", "PMTMODESELECTED%d", cfg.dvbapi_pmtmode);
1595 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1597 //Request Mode
1598 tpl_printf(vars, TPLADD, "TMP", "REQMODESELECTED%d", cfg.dvbapi_requestmode);
1599 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1601 //ecminfo_file
1602 if(cfg.dvbapi_ecminfo_file > 0)
1603 { tpl_addVar(vars, TPLADD, "ECMINFOFILECHECKED", "checked"); }
1605 //ecminfo_type
1606 tpl_printf(vars, TPLADD, "TMP", "ECMINFOTYPESELECTED%d", cfg.dvbapi_ecminfo_type);
1607 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1609 //read_sdt
1610 tpl_printf(vars, TPLADD, "TMP", "READSDTSELECTED%d", cfg.dvbapi_read_sdt);
1611 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1613 //extended_cw_api
1614 tpl_printf(vars, TPLADD, "TMP", "EXTENDEDCWAPISELECTED%d", cfg.dvbapi_extended_cw_api);
1615 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1617 //write_sdt_prov
1618 if(cfg.dvbapi_write_sdt_prov > 0)
1619 { tpl_addVar(vars, TPLADD, "WRITESDTPROVCHECKED", "checked"); }
1621 //TCP listen port
1622 if(cfg.dvbapi_listenport > 0)
1623 { tpl_printf(vars, TPLADD, "LISTENPORT", "%d", cfg.dvbapi_listenport); }
1625 return tpl_getTpl(vars, "CONFIGDVBAPI");
1627 #endif
1629 #ifdef CS_ANTICASC
1630 static char *send_oscam_config_anticasc(struct templatevars *vars, struct uriparams *params)
1632 setActiveSubMenu(vars, MNU_CFG_ANTICASC);
1634 webif_save_config("anticasc", vars, params);
1636 if(cfg.ac_enabled > 0) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
1637 tpl_printf(vars, TPLADD, "NUMUSERS", "%d", cfg.ac_users);
1638 tpl_printf(vars, TPLADD, "SAMPLETIME", "%d", cfg.ac_stime);
1639 tpl_printf(vars, TPLADD, "SAMPLES", "%d", cfg.ac_samples);
1641 tpl_printf(vars, TPLADD, "TMP", "PENALTY%d", cfg.ac_penalty);
1642 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1644 if(cfg.ac_logfile)
1645 { tpl_addVar(vars, TPLADD, "ACLOGFILE", cfg.ac_logfile); }
1646 tpl_printf(vars, TPLADD, "FAKEDELAY", "%d", cfg.ac_fakedelay);
1647 tpl_printf(vars, TPLADD, "DENYSAMPLES", "%d", cfg.ac_denysamples);
1649 if(cfg.acosc_enabled == 1)
1650 { tpl_addVar(vars, TPLADD, "ACOSC_CHECKED", "checked"); }
1651 tpl_printf(vars, TPLADD, "ACOSC_MAX_ECMS_PER_MINUTE", "%d", cfg.acosc_max_ecms_per_minute);
1652 tpl_printf(vars, TPLADD, "ACOSC_MAX_ACTIVE_SIDS", "%d", cfg.acosc_max_active_sids);
1653 tpl_printf(vars, TPLADD, "ACOSC_ZAP_LIMIT", "%d", cfg.acosc_zap_limit);
1654 tpl_printf(vars, TPLADD, "TMP", "ACOSC_PENALTY%d", cfg.acosc_penalty);
1655 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1656 tpl_printf(vars, TPLADD, "ACOSC_PENALTY_DURATION", "%d", cfg.acosc_penalty_duration);
1657 tpl_printf(vars, TPLADD, "ACOSC_DELAY", "%d", cfg.acosc_delay);
1659 return tpl_getTpl(vars, "CONFIGANTICASC");
1661 #endif
1663 static char *send_oscam_config(struct templatevars *vars, struct uriparams *params)
1666 setActiveMenu(vars, MNU_CONFIG);
1668 char *part = getParam(params, "part");
1669 if(!strcmp(part, "webif")) { return send_oscam_config_webif(vars, params); }
1670 #ifdef MODULE_MONITOR
1671 else if(!strcmp(part, "monitor")) { return send_oscam_config_monitor(vars, params); }
1672 #endif
1673 #ifdef LCDSUPPORT
1674 else if(!strcmp(part, "lcd")) { return send_oscam_config_lcd(vars, params); }
1675 #endif
1676 #ifdef MODULE_CAMD33
1677 else if(!strcmp(part, "camd33")) { return send_oscam_config_camd33(vars, params); }
1678 #endif
1679 #ifdef MODULE_CAMD35
1680 else if(!strcmp(part, "camd35")) { return send_oscam_config_camd35(vars, params); }
1681 #endif
1682 #ifdef MODULE_CAMD35_TCP
1683 else if(!strcmp(part, "camd35tcp")) { return send_oscam_config_camd35tcp(vars, params); }
1684 #endif
1685 else if(!strcmp(part, "cache")) { return send_oscam_config_cache(vars, params); }
1686 #ifdef MODULE_NEWCAMD
1687 else if(!strcmp(part, "newcamd")) { return send_oscam_config_newcamd(vars, params); }
1688 #endif
1689 #ifdef MODULE_RADEGAST
1690 else if(!strcmp(part, "radegast")) { return send_oscam_config_radegast(vars, params); }
1691 #endif
1692 #ifdef MODULE_SCAM
1693 else if(!strcmp(part, "scam")) { return send_oscam_config_scam(vars, params); }
1694 #endif
1695 #ifdef WITH_EMU
1696 else if(!strcmp(part, "streamrelay")) { return send_oscam_config_streamrelay(vars, params); }
1697 #endif
1698 #ifdef MODULE_CCCAM
1699 else if(!strcmp(part, "cccam")) { return send_oscam_config_cccam(vars, params); }
1700 #endif
1701 #ifdef MODULE_GBOX
1702 else if(!strcmp(part, "gbox")) { return send_oscam_config_gbox(vars, params); }
1703 #endif
1704 #ifdef HAVE_DVBAPI
1705 else if(!strcmp(part, "dvbapi")) { return send_oscam_config_dvbapi(vars, params); }
1706 #endif
1707 #ifdef CS_ANTICASC
1708 else if(!strcmp(part, "anticasc")) { return send_oscam_config_anticasc(vars, params); }
1709 #endif
1710 #ifdef MODULE_SERIAL
1711 else if(!strcmp(part, "serial")) { return send_oscam_config_serial(vars, params); }
1712 #endif
1713 #ifdef WITH_LB
1714 else if(!strcmp(part, "loadbalancer")) { return send_oscam_config_loadbalancer(vars, params); }
1715 #endif
1716 else { return send_oscam_config_global(vars, params); }
1719 static void inactivate_reader(struct s_reader *rdr)
1721 struct s_client *cl = rdr->client;
1722 if(cl)
1723 { kill_thread(cl); }
1726 static bool picon_exists(char *name)
1728 char picon_name[64], path[255];
1729 char *tpl_path;
1730 tpl_path = cfg.http_piconpath ? cfg.http_piconpath : cfg.http_tpl;
1731 if(!tpl_path)
1732 { return false; }
1733 snprintf(picon_name, sizeof(picon_name) - 1, "IC_%s", name);
1734 return strlen(tpl_getTplPath(picon_name, tpl_path, path, sizeof(path) - 1)) && file_exists(path);
1737 static void clear_rdr_stats(struct s_reader *rdr)
1739 int i;
1740 for(i = 0; i < 4; i++)
1742 rdr->emmerror[i] = 0;
1743 rdr->emmwritten[i] = 0;
1744 rdr->emmskipped[i] = 0;
1745 rdr->emmblocked[i] = 0;
1747 rdr->ecmsok = 0;
1748 rdr->ecmsnok = 0;
1749 rdr->ecmstout = 0;
1750 rdr->ecmshealthok = 0;
1751 rdr->ecmshealthnok = 0;
1752 rdr->ecmshealthtout = 0;
1753 rdr->ecmsfilteredhead = 0;
1754 rdr->ecmsfilteredlen = 0;
1757 static void clear_all_rdr_stats(void)
1759 struct s_reader *rdr;
1760 LL_ITER itr = ll_iter_create(configured_readers);
1761 while((rdr = ll_iter_next(&itr)))
1763 clear_rdr_stats(rdr);
1767 static char *send_oscam_reader(struct templatevars *vars, struct uriparams *params, int32_t apicall)
1769 struct s_reader *rdr;
1770 int32_t i;
1771 uint8_t md5tmp[MD5_DIGEST_LENGTH];
1773 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
1774 if(!apicall)
1776 if(strcmp(getParam(params, "action"), "resetallrdrstats") == 0)
1778 clear_all_rdr_stats();
1782 tpl_addVar(vars, TPLADD, "READERACTIONCOLS", config_enabled(WITH_LB) ? "6" : "5");
1784 if(strcmp(getParam(params, "action"), "resetuserstats") == 0)
1786 clear_info_clients_stats();
1788 if(strcmp(getParam(params, "action"), "resetreaderstats") == 0)
1790 clear_info_readers_stats();
1792 if(strcmp(getParam(params, "action"), "reloadreaders") == 0)
1794 if(!cfg.http_readonly)
1795 { refresh_oscam(REFR_READERS); }
1797 if((strcmp(getParam(params, "action"), "disable") == 0) || (strcmp(getParam(params, "action"), "enable") == 0))
1799 if(cfg.http_readonly)
1801 tpl_addMsg(vars, "WebIf is in readonly mode. Enabling or disabling readers is not possible!");
1803 else
1805 rdr = get_reader_by_label(getParam(params, "label"));
1806 if(rdr)
1808 if(strcmp(getParam(params, "action"), "enable") == 0)
1810 if(!rdr->enable)
1812 rdr->enable = 1;
1815 else
1817 if(rdr->enable)
1819 rdr->enable = 0;
1823 if(rdr->typ != R_GBOX)
1825 restart_cardreader(rdr, 1);
1827 #ifdef MODULE_GBOX
1828 else
1830 restart_gbox_peer(rdr->label, 0, 0);
1831 cs_log("gbox -> you must restart oscam so that setting becomes effective");
1833 #endif
1834 cs_log("reader %s %s by WebIf", rdr->label, rdr->enable == 1 ? "enabled":"disabled");
1836 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
1841 if(strcmp(getParam(params, "action"), "delete") == 0)
1843 if(cfg.http_readonly)
1845 tpl_addMsg(vars, "WebIf is in readonly mode. No deletion will be made!");
1847 else
1849 rdr = get_reader_by_label(getParam(params, "label"));
1850 if(rdr)
1852 inactivate_reader(rdr);
1853 ll_remove(configured_readers, rdr);
1855 free_reader(rdr);
1857 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
1862 if(strcmp(getParam(params, "action"), "reread") == 0)
1864 rdr = get_reader_by_label(getParam(params, "label"));
1865 if(rdr)
1867 struct s_client *cl = rdr->client;
1868 //reset the counters
1869 for(i = 0; i < 4; i++)
1871 rdr->emmerror[i] = 0;
1872 rdr->emmwritten[i] = 0;
1873 rdr->emmskipped[i] = 0;
1874 rdr->emmblocked[i] = 0;
1877 if(rdr->enable == 1 && cl && cl->typ == 'r')
1879 add_job(cl, ACTION_READER_CARDINFO, NULL, 0);
1884 LL_ITER itr = ll_iter_create(configured_readers);
1886 if(!apicall)
1888 for(i = 0, rdr = ll_iter_next(&itr); rdr && rdr->label[0]; rdr = ll_iter_next(&itr), i++) { ; }
1889 tpl_printf(vars, TPLADD, "NEXTREADER", "Reader-%d", i); //Next Readername
1892 int jsondelimiter = 0;
1893 int existing_insert = 0;
1895 int32_t total_readers = 0;
1896 int32_t disabled_readers = 0;
1897 int32_t active_readers = 0;
1898 int32_t connected_readers = 0;
1900 ll_iter_reset(&itr); //going to iterate all configured readers
1901 while((rdr = ll_iter_next(&itr)))
1903 struct s_client *cl = rdr->client;
1904 if(rdr->label[0] && rdr->typ)
1906 total_readers += 1;
1908 // used for API and WebIf
1909 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
1911 MD5((uint8_t *)rdr->label, strlen(rdr->label), md5tmp);
1912 int z;
1913 tpl_addVar(vars, TPLADD, "LABELMD5","id_");
1914 for (z = 0; z < MD5_DIGEST_LENGTH; z++)
1916 tpl_printf(vars, TPLAPPEND, "LABELMD5", "%02x", md5tmp[z]);
1918 #ifdef MODULE_GBOX
1919 if(apicall)
1921 tpl_addVar(vars, TPLADD, "LASTGSMS", "");
1922 tpl_addVar(vars, TPLADD, "LASTGSMS", rdr->last_gsms);
1924 #endif
1925 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, rdr->label));
1926 if(!existing_insert)
1928 tpl_printf(vars, TPLADD, "EXISTING_INS", "'%s'", urlencode(vars, rdr->label));
1929 existing_insert++;
1930 }else
1932 tpl_printf(vars, TPLAPPEND, "EXISTING_INS", ",'%s'", urlencode(vars, rdr->label));
1934 tpl_addVar(vars, TPLADD, "CTYP", reader_get_type_desc(rdr, 0));
1935 tpl_addVar(vars, TPLADD, "CTYPSORT", reader_get_type_desc(rdr, 0));
1937 tpl_addVar(vars, TPLADD, "READERCLASS", rdr->enable ? "enabledreader" : "disabledreader");
1939 if(rdr->enable) { active_readers += 1; }
1940 else { disabled_readers += 1; }
1942 if(rdr->tcp_connected) { connected_readers += 1; }
1944 if(rdr->description)
1945 tpl_printf(vars, TPLADD, "DESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, rdr->description));
1946 else
1947 tpl_addVar(vars, TPLADD, "DESCRIPTION", "");
1949 if(cfg.http_showpicons && !apicall)
1951 tpl_addVar(vars, TPLADD, "READERBIT", tpl_getTpl(vars, picon_exists(xml_encode(vars, rdr->label)) ? "READERNAMEBIT" : "READERNOICON"));
1952 tpl_addVar(vars, TPLADD, "CTYP", picon_exists(xml_encode(vars, reader_get_type_desc(rdr, 0))) ? tpl_getTpl(vars, "READERCTYPBIT") : tpl_getTpl(vars, "READERCTYPNOICON"));
1954 else
1955 tpl_addVar(vars, TPLADD, "READERBIT", tpl_getTpl(vars, "READERLABEL"));
1957 char *value = mk_t_group(rdr->grp);
1958 tpl_addVar(vars, TPLADD, "GROUPS", value);
1959 free_mk_t(value);
1960 tpl_printf(vars, TPLADD, "EMMERRORUK", PRINTF_LOCAL_D, rdr->emmerror[UNKNOWN]);
1961 tpl_printf(vars, TPLADD, "EMMERRORG", PRINTF_LOCAL_D, rdr->emmerror[GLOBAL]);
1962 tpl_printf(vars, TPLADD, "EMMERRORS", PRINTF_LOCAL_D, rdr->emmerror[SHARED]);
1963 tpl_printf(vars, TPLADD, "EMMERRORUQ", PRINTF_LOCAL_D, rdr->emmerror[UNIQUE]);
1965 tpl_printf(vars, TPLADD, "EMMWRITTENUK", PRINTF_LOCAL_D, rdr->emmwritten[UNKNOWN]);
1966 tpl_printf(vars, TPLADD, "EMMWRITTENG", PRINTF_LOCAL_D, rdr->emmwritten[GLOBAL]);
1967 tpl_printf(vars, TPLADD, "EMMWRITTENS", PRINTF_LOCAL_D, rdr->emmwritten[SHARED]);
1968 tpl_printf(vars, TPLADD, "EMMWRITTENUQ", PRINTF_LOCAL_D, rdr->emmwritten[UNIQUE]);
1970 tpl_printf(vars, TPLADD, "EMMSKIPPEDUK", PRINTF_LOCAL_D, rdr->emmskipped[UNKNOWN]);
1971 tpl_printf(vars, TPLADD, "EMMSKIPPEDG", PRINTF_LOCAL_D, rdr->emmskipped[GLOBAL]);
1972 tpl_printf(vars, TPLADD, "EMMSKIPPEDS", PRINTF_LOCAL_D, rdr->emmskipped[SHARED]);
1973 tpl_printf(vars, TPLADD, "EMMSKIPPEDUQ", PRINTF_LOCAL_D, rdr->emmskipped[UNIQUE]);
1975 tpl_printf(vars, TPLADD, "EMMBLOCKEDUK", PRINTF_LOCAL_D, rdr->emmblocked[UNKNOWN]);
1976 tpl_printf(vars, TPLADD, "EMMBLOCKEDG", PRINTF_LOCAL_D, rdr->emmblocked[GLOBAL]);
1977 tpl_printf(vars, TPLADD, "EMMBLOCKEDS", PRINTF_LOCAL_D, rdr->emmblocked[SHARED]);
1978 tpl_printf(vars, TPLADD, "EMMBLOCKEDUQ", PRINTF_LOCAL_D, rdr->emmblocked[UNIQUE]);
1980 tpl_printf(vars, TPLADD, "ECMSOK", PRINTF_LOCAL_D, rdr->ecmsok);
1981 tpl_printf(vars, TPLADD, "ECMSOKREL", " (%.2f %%)", rdr->ecmshealthok);
1982 tpl_printf(vars, TPLADD, "ECMSNOK", PRINTF_LOCAL_D, rdr->ecmsnok);
1983 tpl_printf(vars, TPLADD, "ECMSNOKREL", " (%.2f %%)",rdr->ecmshealthnok);
1984 tpl_printf(vars, TPLADD, "ECMSTOUT", PRINTF_LOCAL_D, rdr->ecmstout);
1985 tpl_printf(vars, TPLADD, "ECMSTOUTREL", " (%.2f %%)",rdr->ecmshealthtout);
1986 tpl_printf(vars, TPLADD, "ECMSFILTEREDHEAD", PRINTF_LOCAL_D, rdr->ecmsfilteredhead);
1987 tpl_printf(vars, TPLADD, "ECMSFILTEREDLEN", PRINTF_LOCAL_D, rdr->ecmsfilteredlen);
1988 #ifdef WITH_LB
1989 tpl_printf(vars, TPLADD, "LBWEIGHT", "%d", rdr->lb_weight);
1990 #endif
1991 if(!is_network_reader(rdr)) //reader is physical
1993 tpl_addVar(vars, TPLADD, "REFRICO", "image?i=ICREF");
1994 tpl_addVar(vars, TPLADD, "READERREFRESH", tpl_getTpl(vars, "READERREFRESHBIT"));
1995 tpl_addVar(vars, TPLADD, "ENTICO", "image?i=ICENT");
1996 tpl_addVar(vars, TPLADD, "ENTITLEMENT", tpl_getTpl(vars, "READERENTITLEBIT"));
1998 else
2000 tpl_addVar(vars, TPLADD, "READERREFRESH", "");
2001 if(rdr->typ == R_CCCAM)
2003 tpl_addVar(vars, TPLADD, "ENTICO", "image?i=ICENT");
2004 tpl_addVar(vars, TPLADD, "ENTITLEMENT", tpl_getTpl(vars, "READERENTITLEBIT"));
2006 else
2008 tpl_addVar(vars, TPLADD, "ENTITLEMENT", "");
2012 if(rdr->enable == 0)
2014 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICENA");
2015 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Enable");
2016 tpl_addVar(vars, TPLADD, "SWITCH", "enable");
2017 tpl_addVar(vars, TPLADD, "WRITEEMM", "");
2019 else
2021 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICDIS");
2022 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Disable");
2023 tpl_addVar(vars, TPLADD, "SWITCH", "disable");
2025 tpl_addVar(vars, TPLADD, "EMMICO", "image?i=ICEMM");
2026 tpl_addVar(vars, TPLADD, "WRITEEMM", tpl_getTpl(vars, "READERWRITEEMMBIT"));
2029 if(!apicall)
2031 // Add to WebIf Template
2032 tpl_addVar(vars, TPLAPPEND, "READERLIST", tpl_getTpl(vars, "READERSBIT"));
2034 else
2037 // used only for API
2038 tpl_addVar(vars, TPLADD, "APIREADERENABLED", !rdr->enable ? "0" : "1");
2039 if(cl)
2041 tpl_printf(vars, TPLADD, "APIREADERTYPE", "%c", cl->typ ? cl->typ : 'x');
2044 if(apicall==1)
2046 // Add to API Template
2047 tpl_addVar(vars, TPLAPPEND, "APIREADERLIST", tpl_getTpl(vars, "APIREADERSBIT"));
2049 if(apicall==2)
2051 tpl_printf(vars, TPLAPPEND, "APIREADERLIST","%s%s",jsondelimiter?",":"", tpl_getTpl(vars, "JSONREADERBIT"));
2052 jsondelimiter++;
2059 tpl_printf(vars, TPLADD, "TOTAL_READERS", "%d", total_readers);
2060 tpl_printf(vars, TPLADD, "TOTAL_DISABLED_READERS", "%d", disabled_readers);
2061 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE_READERS", "%d", active_readers);
2062 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED_READERS", "%d", connected_readers);
2064 //CM info
2065 tpl_addVar(vars, TPLADD, "DISPLAYUSERINFO", "hidden"); // no userinfo in readers
2066 set_ecm_info(vars);
2068 if(!apicall)
2070 #ifdef MODULE_CAMD33
2071 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>camd33</option>\n");
2072 #endif
2073 #ifdef MODULE_CAMD35
2074 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>cs357x</option>\n");
2075 #endif
2076 #ifdef MODULE_CAMD35_TCP
2077 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>cs378x</option>\n");
2078 #endif
2079 #ifdef MODULE_NEWCAMD
2080 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>newcamd</option>\n");
2081 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>newcamd524</option>\n");
2082 #endif
2083 #ifdef MODULE_CCCAM
2084 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>cccam</option>\n");
2085 #endif
2086 #ifdef MODULE_GBOX
2087 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>gbox</option>\n");
2088 #endif
2089 #ifdef MODULE_RADEGAST
2090 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>radegast</option>\n");
2091 #endif
2092 #ifdef MODULE_SERIAL
2093 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>serial</option>\n");
2094 #endif
2095 #ifdef MODULE_CONSTCW
2096 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>constcw</option>\n");
2097 #endif
2098 #ifdef MODULE_SCAM
2099 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>scam</option>\n");
2100 #endif
2102 for(i = 0; cardreaders[i]; i++)
2104 tpl_printf(vars, TPLAPPEND, "ADDPROTOCOL", "<option>%s</option>\n", xml_encode(vars, cardreaders[i]->desc));
2106 return tpl_getTpl(vars, "READERS");
2108 else
2110 if(apicall == 1)
2112 return tpl_getTpl(vars, "APIREADERS");
2114 else
2116 return tpl_getTpl(vars, "JSONREADER");
2121 static char *send_oscam_reader_config(struct templatevars *vars, struct uriparams *params)
2123 int32_t i;
2124 int32_t apicall = 0;
2125 char *reader_ = getParam(params, "label");
2126 char *value;
2128 struct s_reader *rdr;
2130 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
2132 if(strcmp(getParam(params, "action"), "Add") == 0)
2134 // Add new reader
2135 struct s_reader *newrdr;
2136 if(!cs_malloc(&newrdr, sizeof(struct s_reader))) { return "0"; }
2137 for(i = 0; i < (*params).paramcount; ++i)
2139 if(strcmp((*params).params[i], "action"))
2140 { chk_reader((*params).params[i], (*params).values[i], newrdr); }
2142 module_reader_set(newrdr);
2143 reader_ = newrdr->label;
2144 reader_set_defaults(newrdr);
2145 newrdr->enable = 0; // do not start the reader because must configured before
2146 ll_append(configured_readers, newrdr);
2147 tpl_addMsg(vars, "New Reader has been added with default settings");
2149 else if(strcmp(getParam(params, "action"), "Save") == 0)
2152 rdr = get_reader_by_label(getParam(params, "label"));
2153 if(!rdr)
2154 { return NULL; }
2155 //if (is_network_reader(rdr))
2156 // inactivate_reader(rdr); //Stop reader before reinitialization
2157 char servicelabels[1024] = "";
2158 char servicelabelslb[1024] = "";
2160 for(i = 0; i < (*params).paramcount; ++i)
2162 if((strcmp((*params).params[i], "reader")) && (strcmp((*params).params[i], "action")))
2164 if(!strcmp((*params).params[i], "services"))
2165 { snprintf(servicelabels + strlen(servicelabels), sizeof(servicelabels) - strlen(servicelabels), "%s,", (*params).values[i]); }
2166 else if(!strcmp((*params).params[i], "lb_whitelist_services"))
2167 { snprintf(servicelabelslb + strlen(servicelabelslb), sizeof(servicelabelslb) - strlen(servicelabelslb), "%s,", (*params).values[i]); }
2168 else
2169 /*if(strlen((*params).values[i]) > 0)*/
2170 { chk_reader((*params).params[i], (*params).values[i], rdr); }
2172 //printf("param %s value %s\n",(*params).params[i], (*params).values[i]);
2174 chk_reader("services", servicelabels, rdr);
2175 chk_reader("lb_whitelist_services", servicelabelslb, rdr);
2177 if(is_network_reader(rdr) || rdr->typ == R_EMU) //physical readers make trouble if re-started
2179 if(rdr)
2181 if(rdr->typ != R_GBOX)
2183 restart_cardreader(rdr, 1);
2185 #ifdef MODULE_GBOX
2186 else
2188 //cs_log("SAVE - single gbox reader %s restarted by WebIf", rdr->label);
2189 restart_gbox_peer(rdr->label, 0, 0);
2191 #endif
2195 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); } else { tpl_addMsg(vars, "Reader config updated and saved"); }
2199 rdr = get_reader_by_label(reader_);
2200 if(!rdr)
2201 { return NULL; }
2203 // Label, Description
2204 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
2205 tpl_addVar(vars, TPLADD, "DESCRIPTION", xml_encode(vars, rdr->description));
2207 // enabled
2208 if(!apicall)
2210 tpl_addVar(vars, TPLADD, "ENABLED", (rdr->enable == 1) ? "checked" : "");
2212 else
2214 tpl_addVar(vars, TPLADD, "ENABLEDVALUE", (rdr->enable == 1) ? "1" : "0");
2217 tpl_addVar(vars, TPLADD, "PASSWORD", xml_encode(vars, rdr->r_pwd));
2218 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, rdr->r_usr));
2219 tpl_addVar(vars, TPLADD, "PASS", xml_encode(vars, rdr->r_pwd));
2221 // Key Newcamd
2222 for(i = 0; i < (int32_t)sizeof(rdr->ncd_key); i++)
2223 { tpl_printf(vars, TPLAPPEND, "NCD_KEY", "%02X", rdr->ncd_key[i]); }
2225 // Pincode
2226 tpl_addVar(vars, TPLADD, "PINCODE", rdr->pincode);
2228 // Emmfile Path
2229 if(rdr->emmfile) { tpl_addVar(vars, TPLADD, "EMMFILE", (char *)rdr->emmfile); }
2231 // Inactivity timeout
2232 tpl_printf(vars, TPLADD, "INACTIVITYTIMEOUT", "%d", rdr->tcp_ito);
2234 // Receive timeout
2235 tpl_printf(vars, TPLADD, "RECEIVETIMEOUT", "%d", rdr->tcp_rto);
2237 // keepalive
2238 tpl_addVar(vars, TPLADD, "RDRKEEPALIVE", (rdr->keepalive == 1) ? "checked" : "");
2240 // Connect on init (newcamd)
2241 if(!apicall)
2243 tpl_addVar(vars, TPLADD, "CONNECTONINITCHECKED", (rdr->ncd_connect_on_init == 1) ? "checked" : "");
2245 else
2247 tpl_addVar(vars, TPLADD, "CONNECTONINITCHECKED", (rdr->ncd_connect_on_init == 1) ? "1" : "0");
2250 // Reset Cycle
2251 tpl_printf(vars, TPLADD, "RESETCYCLE", "%d", rdr->resetcycle);
2253 // Disable Serverfilter
2254 if(!apicall)
2256 tpl_addVar(vars, TPLADD, "DISABLESERVERFILTERCHECKED", (rdr->ncd_disable_server_filt == 1) ? "checked" : "");
2258 else
2260 tpl_addVar(vars, TPLADD, "DISABLESERVERFILTERVALUE", (rdr->ncd_disable_server_filt == 1) ? "1" : "0");
2263 #ifdef MODULE_GHTTP
2264 // Use SSL
2265 if(!apicall)
2267 tpl_addVar(vars, TPLADD, "USESSLCHECKED", (rdr->ghttp_use_ssl == 1) ? "checked" : "");
2269 else
2271 tpl_addVar(vars, TPLADD, "USESSLVALUE", (rdr->ghttp_use_ssl == 1) ? "1" : "0");
2273 #endif
2275 // Fallback
2276 if(!apicall)
2278 tpl_addVar(vars, TPLADD, "FALLBACKCHECKED", (rdr->fallback == 1) ? "checked" : "");
2280 else
2282 tpl_addVar(vars, TPLADD, "FALLBACKVALUE", (rdr->fallback == 1) ? "1" : "0");
2285 // Fallback per caid
2286 value = mk_t_ftab(&rdr->fallback_percaid);
2287 tpl_addVar(vars, TPLADD, "FALLBACK_PERCAID", value);
2288 free_mk_t(value);
2290 // disable checksum test only for selected caid/provid
2291 value = mk_t_ftab(&rdr->disablecrccws_only_for);
2292 tpl_addVar(vars, TPLADD, "IGN_CHKSUM_ONLYFOR", value);
2293 free_mk_t(value);
2295 #ifdef WITH_LB
2296 tpl_addVar(vars, TPLADD, "LBFORCEFALLBACK", (rdr->lb_force_fallback == 1) ? "checked" : "");
2297 #endif
2299 #ifdef CS_CACHEEX
2300 // Cacheex
2301 if(!apicall)
2303 tpl_printf(vars, TPLADD, "TMP", "CACHEEXSELECTED%d", rdr->cacheex.mode);
2304 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
2306 else
2308 tpl_printf(vars, TPLADD, "CACHEEX", "%d", rdr->cacheex.mode);
2310 tpl_printf(vars, TPLADD, "CACHEEX_MAXHOP", "%d", rdr->cacheex.maxhop);
2311 value = mk_t_cacheex_hitvaluetab(&rdr->cacheex.filter_caidtab);
2312 //if (strlen(value) > 0)
2313 tpl_printf(vars, TPLADD, "CACHEEX_ECM_FILTER", "%s", value);
2314 free_mk_t(value);
2316 tpl_addVar(vars, TPLADD, "DCCHECKED", (rdr->cacheex.drop_csp == 1) ? "checked" : "");
2317 tpl_addVar(vars, TPLADD, "ARCHECKED", (rdr->cacheex.allow_request == 1) ? "checked" : "");
2318 tpl_addVar(vars, TPLADD, "AFCHECKED", (rdr->cacheex.allow_filter == 1) ? "checked" : "");
2319 tpl_addVar(vars, TPLADD, "BLOCKFAKECWSCHECKED", (rdr->cacheex.block_fakecws == 1) ? "checked" : "");
2320 #endif
2322 // BoxID
2323 if(rdr->boxid)
2324 { tpl_printf(vars, TPLADD, "BOXID", "%08X", rdr->boxid); }
2326 // Filt 07
2327 if(!apicall)
2329 tpl_addVar(vars, TPLADD, "FIX07CHECKED", (rdr->fix_07 == 1) ? "checked" : "");
2331 else
2333 tpl_addVar(vars, TPLADD, "FIX07VALUE", (rdr->fix_07 == 1) ? "1" : "0");
2337 // Fix 9993
2338 if(!apicall)
2340 tpl_addVar(vars, TPLADD, "FIX9993CHECKED", (rdr->fix_9993 == 1) ? "checked" : "");
2342 else
2344 tpl_addVar(vars, TPLADD, "FIX9993VALUE", (rdr->fix_9993 == 1) ? "1" : "0");
2347 // Drop CWs with wrong checksum:
2348 if(!apicall)
2350 tpl_addVar(vars, TPLADD, "DROPBADCWSCHECKED", (rdr->dropbadcws == 1) ? "checked" : "");
2352 else
2354 tpl_addVar(vars, TPLADD, "DROPBADCWSVALUE", (rdr->dropbadcws == 1) ? "1" : "0");
2357 // Disable CWs checksum test:
2358 if(!apicall)
2360 tpl_addVar(vars, TPLADD, "DISABLECRCCWSCHECKED", (rdr->disablecrccws == 1) ? "checked" : "");
2362 else
2364 tpl_addVar(vars, TPLADD, "DISABLECRCCWSVALUE", (rdr->disablecrccws == 1) ? "1" : "0");
2367 // Set reader to use GPIO
2368 if(!apicall)
2370 tpl_addVar(vars, TPLADD, "USE_GPIOCHECKED", rdr->use_gpio ? "checked" : "");
2372 else
2374 tpl_addVar(vars, TPLADD, "USE_GPIOVALUE", rdr->use_gpio ? "1" : "0");
2377 // AUdisabled
2378 if(!apicall)
2380 tpl_addVar(vars, TPLADD, "AUDISABLED", (rdr->audisabled == 1) ? "checked" : "");
2382 else
2384 tpl_addVar(vars, TPLADD, "AUDISABLEDVALUE", (rdr->audisabled == 1) ? "1" : "0");
2387 // AUprovid
2388 if(rdr->auprovid)
2389 { tpl_printf(vars, TPLADD, "AUPROVID", "%06X", rdr->auprovid); }
2391 if(rdr->ecmnotfoundlimit)
2392 { tpl_printf(vars, TPLADD, "ECMNOTFOUNDLIMIT", "%u", rdr->ecmnotfoundlimit); }
2394 // Force Irdeto
2395 if(!apicall)
2397 tpl_addVar(vars, TPLADD, "FORCEIRDETOCHECKED", (rdr->force_irdeto == 1) ? "checked" : "");
2399 else
2401 tpl_addVar(vars, TPLADD, "FORCEIRDETOVALUE", (rdr->force_irdeto == 1) ? "1" : "0");
2404 // needsemmfirst
2406 if(!apicall)
2408 tpl_addVar(vars, TPLADD, "NEEDSEMMFIRST", (rdr->needsemmfirst == 1) ? "checked" : "");
2410 else
2412 tpl_addVar(vars, TPLADD, "NEEDSEMMFIRST", (rdr->needsemmfirst == 1) ? "1" : "0");
2415 #ifdef READER_CRYPTOWORKS
2416 // needsglobalfirst
2417 if(!apicall)
2419 tpl_addVar(vars, TPLADD, "NEEDSGLOBALFIRST", (rdr->needsglobalfirst == 1) ? "checked" : "");
2421 else
2423 tpl_addVar(vars, TPLADD, "NEEDSGLOBALFIRST", (rdr->needsglobalfirst == 1) ? "1" : "0");
2425 #endif
2427 // RSA Key
2428 int32_t len = rdr->rsa_mod_length;
2429 if(len > 0)
2431 for(i = 0; i < len; i++) { tpl_printf(vars, TPLAPPEND, "RSAKEY", "%02X", rdr->rsa_mod[i]); }
2434 // 3DES Key
2435 len = rdr->des_key_length;
2436 if(len > 0)
2438 for(i = 0; i < len; i++) { tpl_printf(vars, TPLAPPEND, "DESKEY", "%02X", rdr->des_key[i]); }
2441 // BoxKey
2442 len = rdr->boxkey_length;
2443 if(len > 0)
2445 for(i = 0; i < len ; i++)
2446 { tpl_printf(vars, TPLAPPEND, "BOXKEY", "%02X", rdr->boxkey[i]); }
2449 #ifdef READER_NAGRA_MERLIN
2450 // mod1 (CAK7)
2451 len = rdr->mod1_length;
2452 if(len > 0)
2454 for(i = 0; i < len ; i++)
2455 { tpl_printf(vars, TPLAPPEND, "MOD1", "%02X", rdr->mod1[i]); }
2458 // data50 (CAK7)
2459 len = rdr->data50_length;
2460 if(len > 0)
2462 for(i = 0; i < len ; i++)
2463 { tpl_printf(vars, TPLAPPEND, "DATA50", "%02X", rdr->data50[i]); }
2466 // mod50 (CAK7)
2467 len = rdr->mod50_length;
2468 if(len > 0)
2470 for(i = 0; i < len ; i++)
2471 { tpl_printf(vars, TPLAPPEND, "MOD50", "%02X", rdr->mod50[i]); }
2474 // key60 (CAK7)
2475 len = rdr->key60_length;
2476 if(len > 0)
2478 for(i = 0; i < len ; i++)
2479 { tpl_printf(vars, TPLAPPEND, "KEY60", "%02X", rdr->key60[i]); }
2482 // exp60 (CAK7)
2483 len = rdr->exp60_length;
2484 if(len > 0)
2486 for(i = 0; i < len ; i++)
2487 { tpl_printf(vars, TPLAPPEND, "EXP60", "%02X", rdr->exp60[i]); }
2490 // nuid (CAK7)
2491 len = rdr->nuid_length;
2492 if(len > 0)
2494 for(i = 0; i < len ; i++)
2495 { tpl_printf(vars, TPLAPPEND, "NUID", "%02X", rdr->nuid[i]); }
2498 // cwekey (CAK7)
2499 len = rdr->cwekey_length;
2500 if(len > 0)
2502 for(i = 0; i < len ; i++)
2503 { tpl_printf(vars, TPLAPPEND, "CWEKEY", "%02X", rdr->cwekey[i]); }
2505 #endif
2507 // ins7E
2508 if(rdr->ins7E[0x1A])
2510 for(i = 0; i < 26 ; i++) { tpl_printf(vars, TPLAPPEND, "INS7E", "%02X", rdr->ins7E[i]); }
2513 // ins7E11
2514 if(rdr->ins7E11[0x01])
2516 tpl_printf(vars, TPLAPPEND, "INS7E11", "%02X", rdr->ins7E11[0]);
2519 // ins2e06
2520 if(rdr->ins2e06[0x04])
2522 for(i = 0; i < 4 ; i++) { tpl_printf(vars, TPLAPPEND, "INS2E06", "%02X", rdr->ins2e06[i]); }
2525 // k1 for generic pairing mode
2526 if(rdr->k1_generic[0x10])
2528 for(i = 0; i < rdr->k1_generic[0x10] ; i++) { tpl_printf(vars, TPLAPPEND, "K1_GENERIC", "%02X", rdr->k1_generic[i]); }
2531 // k1 for unique pairing mode
2532 if(rdr->k1_unique[0x10])
2534 for(i = 0; i < rdr->k1_unique[0x10] ; i++) { tpl_printf(vars, TPLAPPEND, "K1_UNIQUE", "%02X", rdr->k1_unique[i]); }
2537 // ATR
2538 if(rdr->atr[0])
2539 for(i = 0; i < rdr->atrlen / 2; i++)
2540 { tpl_printf(vars, TPLAPPEND, "ATR", "%02X", rdr->atr[i]); }
2542 // ECM Whitelist
2543 value = mk_t_ecm_whitelist(&rdr->ecm_whitelist);
2544 tpl_addVar(vars, TPLADD, "ECMWHITELIST", value);
2545 free_mk_t(value);
2547 // ECM Header Whitelist
2548 value = mk_t_ecm_hdr_whitelist(&rdr->ecm_hdr_whitelist);
2549 tpl_addVar(vars, TPLADD, "ECMHEADERWHITELIST", value);
2550 free_mk_t(value);
2552 // Deprecated
2553 if(!apicall)
2555 tpl_addVar(vars, TPLADD, "DEPRECATEDCHECKED", (rdr->deprecated == 1) ? "checked" : "");
2557 else
2559 tpl_addVar(vars, TPLADD, "DEPRECATEDVALUE", (rdr->deprecated == 1) ? "1" : "0");
2562 // Smargopatch
2563 if(!apicall)
2565 tpl_addVar(vars, TPLADD, "SMARGOPATCHCHECKED", (rdr->smargopatch == 1) ? "checked" : "");
2567 else
2569 tpl_addVar(vars, TPLADD, "SMARGOPATCHVALUE", (rdr->smargopatch == 1) ? "1" : "0");
2572 // Autospeed
2573 if(!apicall)
2575 tpl_addVar(vars, TPLADD, "AUTOSPEEDCHECKED", (rdr->autospeed == 1) ? "checked" : "");
2577 else
2579 tpl_addVar(vars, TPLADD, "AUTOSPEEDVALUE", (rdr->autospeed == 1) ? "1" : "0");
2581 // sc8in1 dtrrts patch
2582 if(!apicall)
2584 tpl_addVar(vars, TPLADD, "SC8IN1DTRRTSPATCHCHECKED", (rdr->sc8in1_dtrrts_patch == 1) ? "checked" : "");
2586 else
2588 tpl_addVar(vars, TPLADD, "SC8IN1DTRRTSPATCHVALUE", (rdr->sc8in1_dtrrts_patch == 1) ? "1" : "0");
2591 if(!apicall)
2593 tpl_addVar(vars, TPLADD, "READOLDCLASSES", (rdr->read_old_classes == 1) ? "checked" : "");
2595 else
2597 tpl_addVar(vars, TPLADD, "READOLDCLASSES", (rdr->read_old_classes == 1) ? "1" : "0");
2600 // Detect
2601 if(rdr->detect & 0x80)
2602 { tpl_printf(vars, TPLADD, "DETECT", "!%s", RDR_CD_TXT[rdr->detect & 0x7f]); }
2603 else
2604 { tpl_addVar(vars, TPLADD, "DETECT", RDR_CD_TXT[rdr->detect & 0x7f]); }
2606 // Ratelimit
2607 if(rdr->ratelimitecm)
2609 tpl_printf(vars, TPLADD, "RATELIMITECM", "%d", rdr->ratelimitecm);
2610 // ECMUNIQUE
2611 if(!apicall)
2613 tpl_addVar(vars, TPLADD, "ECMUNIQUECHECKED", (rdr->ecmunique == 1) ? "checked" : "");
2615 else
2617 tpl_addVar(vars, TPLADD, "ECMUNIQUE", (rdr->ecmunique == 1) ? "1" : "0");
2619 tpl_printf(vars, TPLADD, "RATELIMITTIME", "%d", rdr->ratelimittime);
2620 tpl_printf(vars, TPLADD, "SRVIDHOLDTIME", "%d", rdr->srvidholdtime);
2622 // Cooldown
2623 if(rdr->cooldown[0] && rdr->cooldown[1])
2625 tpl_printf(vars, TPLADD, "COOLDOWNDELAY", "%d", rdr->cooldown[0]);
2626 tpl_printf(vars, TPLADD, "COOLDOWNTIME", "%d", rdr->cooldown[1]);
2628 // Frequencies
2629 tpl_printf(vars, TPLADD, "MHZ", "%d", rdr->mhz);
2630 tpl_printf(vars, TPLADD, "CARDMHZ", "%d", rdr->cardmhz);
2632 // Device
2633 if(!apicall)
2635 tpl_addVar(vars, TPLADD, "DEVICE", xml_encode(vars, rdr->device));
2637 else
2639 tpl_addVar(vars, TPLADD, "DEVICE", rdr->device);
2642 if(rdr->r_port)
2643 { tpl_printf(vars, TPLAPPEND, "DEVICE", ",%d", rdr->r_port); }
2644 if(rdr->l_port)
2646 if(rdr->r_port)
2647 { tpl_printf(vars, TPLAPPEND, "DEVICE", ",%d", rdr->l_port); }
2648 else
2649 { tpl_printf(vars, TPLAPPEND, "DEVICE", ",,%d", rdr->l_port); }
2652 // Group
2653 value = mk_t_group(rdr->grp);
2654 tpl_addVar(vars, TPLADD, "GRP", value);
2655 free_mk_t(value);
2657 #ifdef WITH_LB
2658 if(rdr->lb_weight)
2659 { tpl_printf(vars, TPLADD, "LBWEIGHT", "%d", rdr->lb_weight); }
2660 #endif
2662 //services
2663 if(!apicall)
2665 struct s_sidtab *sidtab = cfg.sidtab;
2666 //build matrix
2667 i = 0;
2668 while(sidtab != NULL)
2670 tpl_addVar(vars, TPLADD, "SIDLABEL", xml_encode(vars, sidtab->label));
2671 if(rdr->sidtabs.ok & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
2672 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
2673 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "READERCONFIGSIDOKBIT"));
2674 if(rdr->sidtabs.no & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
2675 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
2676 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "READERCONFIGSIDNOBIT"));
2677 if(rdr->lb_sidtabs.ok & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
2678 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
2679 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "READERCONFIGSIDLBOKBIT"));
2680 sidtab = sidtab->next;
2681 i++;
2683 if(i){
2684 tpl_addVar(vars, TPLADD, "READERCONFIGSIDINS", tpl_getTpl(vars, "READERCONFIGSID"));
2687 else
2689 value = mk_t_service(&rdr->sidtabs);
2690 if(strlen(value) > 0)
2691 { tpl_addVar(vars, TPLADD, "SERVICES", value); }
2692 free_mk_t(value);
2695 // CAID
2696 value = mk_t_caidtab(&rdr->ctab);
2697 tpl_addVar(vars, TPLADD, "CAIDS", value);
2698 free_mk_t(value);
2700 // AESkeys
2701 value = mk_t_aeskeys(rdr);
2702 tpl_addVar(vars, TPLADD, "AESKEYS", value);
2703 free_mk_t(value);
2705 //ident
2706 value = mk_t_ftab(&rdr->ftab);
2707 tpl_addVar(vars, TPLADD, "IDENTS", value);
2708 free_mk_t(value);
2710 //CHID
2711 value = mk_t_ftab(&rdr->fchid);
2712 tpl_addVar(vars, TPLADD, "CHIDS", value);
2713 free_mk_t(value);
2715 //Local cards
2716 value = mk_t_ftab(&rdr->localcards);
2717 tpl_addVar(vars, TPLADD, "LOCALCARDS", value);
2718 free_mk_t(value);
2720 //class
2721 value = mk_t_cltab(&rdr->cltab);
2722 tpl_addVar(vars, TPLADD, "CLASS", value);
2723 free_mk_t(value);
2725 if(rdr->cachemm || rdr->logemm)
2726 { tpl_printf(vars, TPLADD, "EMMCACHE", "%d,%d,%d,%d", rdr->cachemm, rdr->rewritemm, rdr->logemm, rdr->deviceemm); }
2728 //savenano
2729 value = mk_t_nano(rdr->s_nano);
2730 tpl_addVar(vars, TPLADD, "SAVENANO", value);
2731 free_mk_t(value);
2733 //blocknano
2734 value = mk_t_nano(rdr->b_nano);
2735 tpl_addVar(vars, TPLADD, "BLOCKNANO", value);
2736 free_mk_t(value);
2738 // Blocke EMM
2739 if(!apicall)
2741 tpl_addVar(vars, TPLADD, "BLOCKEMMUNKNOWNCHK", (rdr->blockemm & EMM_UNKNOWN) ? "checked" : "");
2742 tpl_addVar(vars, TPLADD, "BLOCKEMMUNIQCHK", (rdr->blockemm & EMM_UNIQUE) ? "checked" : "");
2743 tpl_addVar(vars, TPLADD, "BLOCKEMMSHAREDCHK", (rdr->blockemm & EMM_SHARED) ? "checked" : "");
2744 tpl_addVar(vars, TPLADD, "BLOCKEMMGLOBALCHK", (rdr->blockemm & EMM_GLOBAL) ? "checked" : "");
2746 else
2748 tpl_addVar(vars, TPLADD, "BLOCKEMMUNKNOWNVALUE", (rdr->blockemm & EMM_UNKNOWN) ? "1" : "0");
2749 tpl_addVar(vars, TPLADD, "BLOCKEMMUNIQVALUE", (rdr->blockemm & EMM_UNIQUE) ? "1" : "0");
2750 tpl_addVar(vars, TPLADD, "BLOCKEMMSHAREDVALUE", (rdr->blockemm & EMM_SHARED) ? "1" : "0");
2751 tpl_addVar(vars, TPLADD, "BLOCKEMMGLOBALVALUE", (rdr->blockemm & EMM_GLOBAL) ? "1" : "0");
2754 // Save EMM
2755 if(!apicall)
2757 tpl_addVar(vars, TPLADD, "SAVEEMMUNKNOWNCHK", (rdr->saveemm & EMM_UNKNOWN) ? "checked" : "");
2758 tpl_addVar(vars, TPLADD, "SAVEEMMUNIQCHK", (rdr->saveemm & EMM_UNIQUE) ? "checked" : "");
2759 tpl_addVar(vars, TPLADD, "SAVEEMMSHAREDCHK", (rdr->saveemm & EMM_SHARED) ? "checked" : "");
2760 tpl_addVar(vars, TPLADD, "SAVEEMMGLOBALCHK", (rdr->saveemm & EMM_GLOBAL) ? "checked" : "");
2762 else
2764 tpl_addVar(vars, TPLADD, "SAVEEMMUNKNOWNVALUE", (rdr->saveemm & EMM_UNKNOWN) ? "1" : "0");
2765 tpl_addVar(vars, TPLADD, "SAVEEMMUNIQVALUE", (rdr->saveemm & EMM_UNIQUE) ? "1" : "0");
2766 tpl_addVar(vars, TPLADD, "SAVEEMMSHAREDVALUE", (rdr->saveemm & EMM_SHARED) ? "1" : "0");
2767 tpl_addVar(vars, TPLADD, "SAVEEMMGLOBALVALUE", (rdr->saveemm & EMM_GLOBAL) ? "1" : "0");
2770 value = mk_t_emmbylen(rdr);
2771 if(strlen(value) > 0)
2772 { tpl_addVar(vars, TPLADD, "BLOCKEMMBYLEN", value); }
2773 free_mk_t(value);
2775 #ifdef MODULE_CCCAM
2776 if(!strcmp(rdr->cc_version, "2.0.11"))
2778 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED0", "selected");
2780 else if(!strcmp(rdr->cc_version, "2.1.1"))
2782 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED1", "selected");
2784 else if(!strcmp(rdr->cc_version, "2.1.2"))
2786 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED2", "selected");
2788 else if(!strcmp(rdr->cc_version, "2.1.3"))
2790 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED3", "selected");
2792 else if(!strcmp(rdr->cc_version, "2.1.4"))
2794 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED4", "selected");
2796 else if(!strcmp(rdr->cc_version, "2.2.0"))
2798 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED5", "selected");
2800 else if(!strcmp(rdr->cc_version, "2.2.1"))
2802 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED6", "selected");
2804 else if(!strcmp(rdr->cc_version, "2.3.0"))
2806 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED7", "selected");
2808 else if(!strcmp(rdr->cc_version, "2.3.1"))
2810 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED8", "selected");
2812 else if(!strcmp(rdr->cc_version, "2.3.2"))
2814 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED9", "selected");
2816 #endif
2818 tpl_printf(vars, TPLADD, "TMP", "NDSVERSION%d", rdr->ndsversion);
2819 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
2821 tpl_printf(vars, TPLADD, "TMP", "NDSREADTIERS%d", rdr->readtiers);
2822 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
2824 tpl_printf(vars, TPLADD, "TMP", "NAGRAREAD%d", rdr->nagra_read);
2825 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
2827 if(rdr->detect_seca_nagra_tunneled_card)
2828 { tpl_addVar(vars, TPLADD, "NAGRADETECTSECACARDCHECKED", "checked"); }
2830 #ifdef MODULE_CCCAM
2831 tpl_printf(vars, TPLADD, "CCCMAXHOPS", "%d", rdr->cc_maxhops);
2832 tpl_printf(vars, TPLADD, "CCCMINDOWN", "%d", rdr->cc_mindown);
2833 tpl_printf(vars, TPLADD, "CCCRESHARE", "%d", rdr->cc_reshare);
2834 tpl_printf(vars, TPLADD, "RESHARE", "%d", cfg.cc_reshare);
2835 tpl_printf(vars, TPLADD, "CCCRECONNECT", "%d", rdr->cc_reconnect);
2837 if(rdr->cc_want_emu)
2838 { tpl_addVar(vars, TPLADD, "CCCWANTEMUCHECKED", "checked"); }
2839 if(rdr->cc_keepalive)
2840 { tpl_addVar(vars, TPLADD, "KEEPALIVECHECKED", "checked"); }
2841 #endif
2843 #ifdef MODULE_GBOX
2844 tpl_printf(vars, TPLADD, "GBOXMAXDISTANCE", "%d", rdr->gbox_maxdist);
2845 tpl_printf(vars, TPLADD, "GBOXMAXECMSEND", "%d", rdr->gbox_maxecmsend);
2846 tpl_printf(vars, TPLADD, "GBOXRESHARE", "%d", rdr->gbox_reshare);
2847 tpl_printf(vars, TPLADD, "PEERGBOXID", "%04X", gbox_convert_password_to_id((uint32_t)a2i(rdr->r_pwd, 4)));
2848 tpl_addVar(vars, TPLADD, "PEERONLSTAT", (get_peer_onl_status(gbox_convert_password_to_id((uint32_t)a2i(rdr->r_pwd, 4)))) ? "checked" : "");
2849 tpl_printf(vars, TPLADD, "FORCEREMM", "%d", rdr->gbox_force_remm);
2851 if(rdr->blockemm & 0x80)
2853 tpl_addVar(vars, TPLADD, "REMMCNLDCHK", "checked");
2854 tpl_printf(vars, TPLADD, "GBOXREMMPEER", "%04X", rdr->gbox_remm_peer);
2855 tpl_addVar(vars, TPLADD, "REMMUNIQCHK", (rdr->blockemm & EMM_UNIQUE) ? "" : "checked");
2856 tpl_addVar(vars, TPLADD, "REMMSHAREDCHK", (rdr->blockemm & EMM_SHARED) ? "" : "checked");
2857 tpl_addVar(vars, TPLADD, "REMMGLOBALCHK", (rdr->blockemm & EMM_GLOBAL) ? "" : "checked");
2858 tpl_addVar(vars, TPLADD, "REMMEMMUNKNOWNCHK", (rdr->blockemm & EMM_UNKNOWN) ? "" : "checked");
2860 if(rdr->gbox_gsms_peer)
2862 tpl_printf(vars, TPLADD, "LASTGSMS", "%s", rdr->last_gsms);
2863 tpl_printf(vars, TPLADD, "GBOXGSMSPEER", "%04X", rdr->gbox_gsms_peer);
2865 #endif
2867 #ifdef READER_DRECAS
2868 tpl_addVar(vars, TPLADD, "STMKEYS", rdr->stmkeys);
2869 #endif
2871 #if defined(READER_DRE) || defined(READER_DRECAS)
2872 tpl_addVar(vars, TPLADD, "USERSCRIPT", rdr->userscript);
2873 #endif
2875 #ifdef WITH_EMU
2876 //emu_auproviders
2877 value = mk_t_ftab(&rdr->emu_auproviders);
2878 tpl_addVar(vars, TPLADD, "EMUAUPROVIDERS", value);
2879 free_mk_t(value);
2881 // Date-coded BISS keys
2882 if(!apicall)
2884 tpl_addVar(vars, TPLADD, "EMUDATECODEDENABLED", (rdr->emu_datecodedenabled == 1) ? "checked" : "");
2886 else
2888 tpl_addVar(vars, TPLADD, "EMUDATECODEDENABLED", (rdr->emu_datecodedenabled == 1) ? "1" : "0");
2890 #endif
2892 tpl_addVar(vars, TPLADD, "PROTOCOL", reader_get_type_desc(rdr, 0));
2894 // Show only parameters which needed for the reader
2895 switch(rdr->typ)
2897 case R_CONSTCW:
2898 case R_DB2COM1:
2899 case R_DB2COM2:
2900 case R_MOUSE :
2901 case R_DRECAS :
2902 case R_MP35:
2903 case R_SC8in1 :
2904 case R_SMART :
2905 case R_INTERNAL:
2906 case R_SERIAL :
2907 case R_PCSC :
2908 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGSTDHWREADERBIT"));
2909 break;
2910 case R_CAMD35 :
2911 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGCAMD35BIT"));
2912 break;
2913 case R_EMU :
2914 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGEMUBIT"));
2915 break;
2916 case R_CS378X :
2917 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGCS378XBIT"));
2918 break;
2919 case R_RADEGAST:
2920 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGRADEGASTBIT"));
2921 break;
2922 case R_SCAM:
2923 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGSCAMBIT"));
2924 break;
2925 case R_GHTTP:
2926 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGGHTTPBIT"));
2927 break;
2928 case R_GBOX:
2929 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGGBOXBIT"));
2930 #if defined (MODULE_CCCAM) && defined (MODULE_GBOX)
2931 tpl_printf(vars, TPLADD, "GBOXCCCAMRESHARE", "%d", rdr->gbox_cccam_reshare);
2932 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "GBOXCCCAMRESHAREBIT"));
2933 #endif
2934 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERINFOGBOXREMM"));
2935 break;
2936 case R_NEWCAMD:
2937 if(rdr->ncd_proto == NCD_525)
2939 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGNCD525BIT"));
2941 else if(rdr->ncd_proto == NCD_524)
2943 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGNCD524BIT"));
2945 break;
2946 #ifdef MODULE_CCCAM
2947 case R_CCCAM :
2948 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGCCCAMBIT"));
2949 break;
2950 #endif
2951 default :
2952 tpl_addMsg(vars, "Error: protocol not resolvable");
2953 break;
2957 #ifdef MODULE_CCCAM
2958 if(rdr->typ != R_CCCAM && rdr->typ != R_GBOX)
2960 tpl_printf(vars, TPLADD, "CCCHOP", "%d", rdr->cc_hop);
2961 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGHOPBIT"));
2963 #endif
2965 return tpl_getTpl(vars, "READERCONFIG");
2968 static char *send_oscam_reader_stats(struct templatevars *vars, struct uriparams *params, int32_t apicall)
2971 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
2973 int8_t error;
2974 struct s_client *cl = NULL;
2975 struct s_reader *rdr;
2977 rdr = get_reader_by_label(getParam(params, "label"));
2978 error = (rdr ? 0 : 1);
2980 if(!error && rdr)
2982 cl = rdr->client;
2983 error = (cl ? 0 : 1);
2986 if(error)
2988 tpl_addVar(vars, TPLAPPEND, "READERSTATSROW", tpl_getTpl(vars, "READERSTATSROWBIT"));
2989 if(!apicall)
2990 { return tpl_getTpl(vars, "READERSTATS"); }
2991 else
2992 { return tpl_getTpl(vars, "APIREADERSTATS"); }
2995 #ifdef WITH_LB
2996 char *stxt[] = {"found", "cache1", "cache2", "cache3",
2997 "not found", "timeout", "sleeping",
2998 "fake", "invalid", "corrupt", "no card", "expdate",
2999 "disabled", "stopped"
3002 if(strcmp(getParam(params, "action"), "resetstat") == 0)
3004 char *rcs = getParam(params, "rc");
3005 int32_t retval = 0;
3006 if(strlen(rcs) > 0)
3008 int8_t rc;
3009 rc = atoi(rcs);
3010 retval = clean_stat_by_rc(rdr, rc, 0);
3011 cs_log("Reader %s stats %d %s entr%s deleted by WebIF from %s",
3012 rdr->label, retval, stxt[rc],
3013 retval == 1 ? "y" : "ies",
3014 cs_inet_ntoa(GET_IP()));
3016 else
3018 clear_reader_stat(rdr);
3019 cs_log("Reader %s stats resetted by WebIF from %s", rdr->label, cs_inet_ntoa(GET_IP()));
3024 if(strcmp(getParam(params, "action"), "deleterecord") == 0)
3026 char *record = getParam(params, "record");
3027 if(strlen(record) > 0)
3029 int32_t retval = 0;
3030 uint32_t caid, provid, sid, cid, len;
3031 sscanf(record, "%4x@%6x:%4x:%4x:%4x", &caid, &provid, &sid, &cid, &len);
3032 retval = clean_stat_by_id(rdr, caid, provid, sid, cid, len);
3033 cs_log("Reader %s stats %d entr%s deleted by WebIF from %s",
3034 rdr->label, retval,
3035 retval == 1 ? "y" : "ies",
3036 cs_inet_ntoa(GET_IP()));
3040 if(strcmp(getParam(params, "action"), "updateecmlen") == 0)
3042 update_ecmlen_from_stat(rdr);
3043 write_server();
3046 #endif
3048 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
3049 tpl_addVar(vars, TPLADD, "LABEL", xml_encode(vars, rdr->label));
3050 tpl_addVar(vars, TPLADD, "ENCODEDLABEL", urlencode(vars, rdr->label));
3052 if(apicall)
3054 int32_t i, emmcount = 0;
3055 char *ttxt[] = {"unknown", "unique", "shared", "global"};
3057 for(i = 0; i < 4; i++)
3059 tpl_addVar(vars, TPLADD, "EMMRESULT", "error");
3060 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
3061 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmerror[i]);
3062 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
3063 emmcount += rdr->emmerror[i];
3064 tpl_printf(vars, TPLADD, "TOTALERROR", "%d", emmcount);
3066 emmcount = 0;
3067 for(i = 0; i < 4; i++)
3069 tpl_addVar(vars, TPLADD, "EMMRESULT", "written");
3070 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
3071 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmwritten[i]);
3072 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
3073 emmcount += rdr->emmwritten[i];
3074 tpl_printf(vars, TPLADD, "TOTALWRITTEN", "%d", emmcount);
3076 emmcount = 0;
3077 for(i = 0; i < 4; i++)
3079 tpl_addVar(vars, TPLADD, "EMMRESULT", "skipped");
3080 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
3081 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmskipped[i]);
3082 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
3083 emmcount += rdr->emmskipped[i];
3084 tpl_printf(vars, TPLADD, "TOTALSKIPPED", "%d", emmcount);
3086 emmcount = 0;
3087 for(i = 0; i < 4; i++)
3089 tpl_addVar(vars, TPLADD, "EMMRESULT", "blocked");
3090 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
3091 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmblocked[i]);
3092 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
3093 emmcount += rdr->emmblocked[i];
3094 tpl_printf(vars, TPLADD, "TOTALBLOCKED", "%d", emmcount);
3098 if(apicall)
3100 char *txt = "UNDEF";
3101 switch(rdr->card_status)
3103 case NO_CARD:
3104 if(rdr->typ == R_GBOX)
3105 { txt = "ONL no crd"; }
3106 else
3107 { txt = "OFF"; }
3108 break;
3109 case UNKNOWN:
3110 txt = "UNKNOWN";
3111 break;
3112 case READER_DEVICE_ERROR:
3113 txt = "READER DEVICE ERROR";
3114 break;
3115 case CARD_NEED_INIT:
3116 if(rdr->typ == R_GBOX)
3117 { txt = "OFFLINE"; }
3118 else
3119 { txt = "NEEDINIT"; }
3120 break;
3121 case CARD_INSERTED:
3122 if(cl->typ == 'p')
3124 if(rdr->typ == R_GBOX)
3125 { txt = "ONL w/crd"; }
3126 else
3127 { txt = "CONNECTED"; }
3129 else
3130 { txt = "CARDOK"; }
3131 break;
3132 case CARD_FAILURE:
3133 txt = "ERROR";
3134 break;
3135 default:
3136 txt = "UNDEF";
3138 tpl_addVar(vars, TPLADD, "READERSTATUS", txt);
3139 tpl_printf(vars, TPLADD, "READERCAID", "%04X", rdr->caid);
3142 int32_t rowcount = 0;
3143 uint64_t ecmcount = 0;
3144 time_t lastaccess = 0;
3146 #ifdef WITH_LB
3147 int32_t rc2hide = (-1);
3148 if(strlen(getParam(params, "hide")) > 0)
3149 { rc2hide = atoi(getParam(params, "hide")); }
3151 int32_t rc2show = (-1);
3152 if(strlen(getParam(params, "show")) > 0)
3153 { rc2show = atoi(getParam(params, "show")); }
3155 if(rdr->lb_stat)
3157 int32_t statsize;
3158 // @todo alno: sort by click, 0=ascending, 1=descending (maybe two buttons or reverse on second click)
3159 READER_STAT **statarray = get_sorted_stat_copy(rdr, 0, &statsize);
3160 char channame[CS_SERVICENAME_SIZE];
3161 for(; rowcount < statsize; ++rowcount)
3163 READER_STAT *s = statarray[rowcount];
3164 if(!(s->rc == rc2hide) && ((rc2show == -1) || (s->rc == rc2show)))
3166 struct tm lt;
3167 localtime_r(&s->last_received.time, &lt); // fixme we need walltime!
3168 ecmcount += s->ecm_count;
3169 if(!apicall)
3171 tpl_printf(vars, TPLADD, "CHANNEL", "%04X@%06X:%04X:%04X", s->caid, s->prid, s->srvid, s->chid);
3172 tpl_addVar(vars, TPLADD, "CHANNELNAME", xml_encode(vars, get_servicename(cur_client(), s->srvid, s->prid, s->caid, channame, sizeof(channame))));
3173 tpl_printf(vars, TPLADD, "ECMLEN", "%04hX", s->ecmlen);
3174 tpl_addVar(vars, TPLADD, "RC", stxt[s->rc]);
3175 tpl_printf(vars, TPLADD, "TIME", PRINTF_LOCAL_D " ms", s->time_avg);
3176 if(s->time_stat[s->time_idx])
3177 { tpl_printf(vars, TPLADD, "TIMELAST", PRINTF_LOCAL_D " ms", s->time_stat[s->time_idx]); }
3178 else
3179 { tpl_addVar(vars, TPLADD, "TIMELAST", ""); }
3180 tpl_printf(vars, TPLADD, "COUNT", PRINTF_LOCAL_D, s->ecm_count);
3182 if(s->last_received.time)
3184 tpl_printf(vars, TPLADD, "LAST", "%02d.%02d.%02d %02d:%02d:%02d", lt.tm_mday, lt.tm_mon + 1, lt.tm_year % 100, lt.tm_hour, lt.tm_min, lt.tm_sec);
3187 else
3189 tpl_addVar(vars, TPLADD, "LAST", "never");
3192 else
3194 tpl_printf(vars, TPLADD, "ECMCAID", "%04X", s->caid);
3195 tpl_printf(vars, TPLADD, "ECMPROVID", "%06X", s->prid);
3196 tpl_printf(vars, TPLADD, "ECMSRVID", "%04X", s->srvid);
3197 tpl_printf(vars, TPLADD, "ECMLEN", "%04hX", s->ecmlen);
3198 tpl_addVar(vars, TPLADD, "ECMCHANNELNAME", xml_encode(vars, get_servicename(cur_client(), s->srvid, s->prid, s->caid, channame, sizeof(channame))));
3199 tpl_printf(vars, TPLADD, "ECMTIME", PRINTF_LOCAL_D, s->time_avg);
3200 tpl_printf(vars, TPLADD, "ECMTIMELAST", PRINTF_LOCAL_D, s->time_stat[s->time_idx]);
3201 tpl_printf(vars, TPLADD, "ECMRC", "%d", s->rc);
3202 tpl_addVar(vars, TPLADD, "ECMRCS", stxt[s->rc]);
3203 if(s->last_received.time)
3205 char tbuffer [30];
3206 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &lt);
3207 tpl_addVar(vars, TPLADD, "ECMLAST", tbuffer);
3209 else
3211 tpl_addVar(vars, TPLADD, "ECMLAST", "");
3213 tpl_printf(vars, TPLADD, "ECMCOUNT", PRINTF_LOCAL_D, s->ecm_count);
3215 if(s->last_received.time > lastaccess)
3216 { lastaccess = s->last_received.time; }
3219 if(!apicall)
3221 if(s->rc == E_NOTFOUND)
3223 tpl_addVar(vars, TPLAPPEND, "READERSTATSROWNOTFOUND", tpl_getTpl(vars, "READERSTATSBIT"));
3224 tpl_addVar(vars, TPLADD, "RESETA", urlencode(vars, rdr->label));
3225 tpl_addVar(vars, TPLADD, "READERSTATSNFHEADLINE", tpl_getTpl(vars, "READERSTATSROWNOTFOUNDBIT"));
3227 else if(s->rc == E_TIMEOUT)
3229 tpl_addVar(vars, TPLAPPEND, "READERSTATSROWTIMEOUT", tpl_getTpl(vars, "READERSTATSBIT"));
3230 tpl_addVar(vars, TPLADD, "RESETB", urlencode(vars, rdr->label));
3231 tpl_addVar(vars, TPLADD, "READERSTATSTOHEADLINE", tpl_getTpl(vars, "READERSTATSROWTIMEOUTBIT"));
3233 else if(s->rc == E_INVALID)
3235 tpl_addVar(vars, TPLAPPEND, "READERSTATSROWINVALID", tpl_getTpl(vars, "READERSTATSBIT"));
3236 tpl_addVar(vars, TPLADD, "RESETC", urlencode(vars, rdr->label));
3237 tpl_addVar(vars, TPLADD, "READERSTATSIVHEADLINE", tpl_getTpl(vars, "READERSTATSROWINVALIDBIT"));
3239 else
3240 { tpl_addVar(vars, TPLAPPEND, "READERSTATSROWFOUND", tpl_getTpl(vars, "READERSTATSBIT")); }
3242 else
3245 tpl_addVar(vars, TPLAPPEND, "ECMSTATS", tpl_getTpl(vars, "APIREADERSTATSECMBIT"));
3249 NULLFREE(statarray);
3251 else
3252 #endif
3253 tpl_addVar(vars, TPLAPPEND, "READERSTATSROW", tpl_getTpl(vars, "READERSTATSNOSTATS"));
3255 tpl_printf(vars, TPLADD, "ROWCOUNT", "%d", rowcount);
3257 if(lastaccess > 0)
3259 char tbuffer [30];
3260 struct tm lt;
3261 localtime_r(&lastaccess, &lt);
3262 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &lt);
3263 tpl_addVar(vars, TPLADD, "LASTACCESS", tbuffer);
3265 else
3267 tpl_addVar(vars, TPLADD, "LASTACCESS", "");
3270 if(apicall)
3272 if(cl)
3274 char *value = get_ecm_historystring(cl);
3275 tpl_addVar(vars, TPLADD, "ECMHISTORY", value);
3276 free_mk_t(value);
3280 tpl_printf(vars, TPLADD, "TOTALECM", "%'" PRIu64, ecmcount);
3282 if(!apicall)
3283 { return tpl_getTpl(vars, "READERSTATS"); }
3284 else
3285 { return tpl_getTpl(vars, "APIREADERSTATS"); }
3288 static char *send_oscam_user_config_edit(struct templatevars *vars, struct uriparams *params, int32_t apicall)
3290 struct s_auth *account, *ptr, *chk;
3291 char user[sizeof(first_client->account->usr)];
3293 int32_t i;
3294 int existing_insert = 0;
3296 if(!apicall) { setActiveMenu(vars, MNU_USERS); }
3298 if(strcmp(getParam(params, "action"), "Save As") == 0) { cs_strncpy(user, getParam(params, "newuser"), sizeof(user)); }
3299 else { cs_strncpy(user, getParam(params, "user"), sizeof(user)); }
3301 account = NULL;
3302 for(chk = cfg.account; chk != NULL; chk = chk->next)
3304 if(strcmp(user, chk->usr) == 0)
3305 { account = chk; }
3306 if(!existing_insert)
3308 tpl_printf(vars, TPLADD, "EXISTING_INS", "'%s'", urlencode(vars, chk->usr));
3309 existing_insert++;
3311 else
3313 tpl_printf(vars, TPLAPPEND, "EXISTING_INS", ",'%s'", urlencode(vars, chk->usr));
3317 // Create a new user if it doesn't yet
3318 if(account == NULL)
3320 i = 1;
3321 while(strlen(user) < 1)
3323 snprintf(user, sizeof(user) / sizeof(char) - 1, "NEWUSER%d", i);
3324 for(account = cfg.account; account != NULL && strcmp(user, account->usr) != 0; account = account->next) { ; }
3325 if(account != NULL) { user[0] = '\0'; }
3326 ++i;
3328 if(!cs_malloc(&account, sizeof(struct s_auth))) { return "0"; }
3329 if(cfg.account == NULL) { cfg.account = account; }
3330 else
3332 for(ptr = cfg.account; ptr != NULL && ptr->next != NULL; ptr = ptr->next) { ; }
3333 ptr->next = account;
3335 account_set_defaults(account);
3336 account->disabled = 1;
3337 cs_strncpy((char *)account->usr, user, sizeof(account->usr));
3338 if(!account->grp)
3339 { account->grp = 1; }
3340 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
3341 else if(strcmp(getParam(params, "action"), "Save As") == 0) { tpl_addMsg(vars, "New user has been added with cloned settings"); }
3342 else { tpl_addMsg(vars, "New user has been added with default settings"); }
3343 // no need to refresh anything here as the account is disabled by default and there's no client with this new account anyway!
3346 if((strcmp(getParam(params, "action"), "Save") == 0) || (strcmp(getParam(params, "action"), "Save As") == 0))
3348 char servicelabels[1024] = "";
3350 for(i = 0; i < (*params).paramcount; i++)
3352 if((strcmp((*params).params[i], "action")) &&
3353 (strcmp((*params).params[i], "user")) &&
3354 (strcmp((*params).params[i], "newuser")) &&
3355 (strcmp((*params).params[i], "part")))
3358 if(!strcmp((*params).params[i], "services"))
3359 { snprintf(servicelabels + strlen(servicelabels), sizeof(servicelabels) - strlen(servicelabels), "%s,", (*params).values[i]); }
3360 else
3361 { chk_account((*params).params[i], (*params).values[i], account); }
3364 chk_account("services", servicelabels, account);
3366 refresh_oscam(REFR_CLIENTS);
3368 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
3369 else if(strcmp(getParam(params, "action"), "Save As") != 0) { tpl_addMsg(vars, "User Account updated and saved"); }
3372 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, account->usr));
3373 tpl_addVar(vars, TPLADD, "PASSWORD", xml_encode(vars, account->pwd));
3374 tpl_addVar(vars, TPLADD, "DESCRIPTION", xml_encode(vars, account->description));
3376 //Disabled
3377 if(!apicall)
3379 if(account->disabled)
3380 { tpl_addVar(vars, TPLADD, "DISABLEDCHECKED", "checked"); }
3382 else
3384 tpl_printf(vars, TPLADD, "DISABLEDVALUE", "%d", account->disabled);
3387 //Expirationdate
3388 struct tm timeinfo;
3389 cs_gmtime_r(&account->expirationdate, &timeinfo);
3390 char buf [80];
3391 strftime(buf, 80, "%Y-%m-%d", &timeinfo);
3392 if(strcmp(buf, "1970-01-01")) { tpl_addVar(vars, TPLADD, "EXPDATE", buf); }
3394 //Allowed TimeFrame
3395 char *allowedtf = mk_t_allowedtimeframe(account);
3396 tpl_printf(vars, TPLADD, "ALLOWEDTIMEFRAME", "%s", allowedtf);
3397 free_mk_t(allowedtf);
3399 //Group
3400 char *value = mk_t_group(account->grp);
3401 tpl_addVar(vars, TPLADD, "GROUPS", value);
3402 free_mk_t(value);
3404 // allowed protocols
3405 value = mk_t_allowedprotocols(account);
3406 tpl_addVar(vars, TPLADD, "ALLOWEDPROTOCOLS", value);
3407 free_mk_t(value);
3409 //Hostname
3410 tpl_addVar(vars, TPLADD, "DYNDNS", xml_encode(vars, account->dyndns));
3412 //Uniq
3413 if(!apicall)
3415 tpl_printf(vars, TPLADD, "TMP", "UNIQSELECTED%d", account->uniq);
3416 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3418 else
3420 tpl_printf(vars, TPLADD, "UNIQVALUE", "%d", account->uniq);
3423 //Sleep
3424 if(!account->tosleep) { tpl_addVar(vars, TPLADD, "SLEEP", "0"); }
3425 else { tpl_printf(vars, TPLADD, "SLEEP", "%d", account->tosleep); }
3427 //Monlevel selector
3428 if(!apicall)
3430 tpl_printf(vars, TPLADD, "TMP", "MONSELECTED%d", account->monlvl);
3431 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3433 else
3435 tpl_printf(vars, TPLADD, "MONVALUE", "%d", account->monlvl);
3438 //Au
3439 if(account->autoau == 1)
3440 { tpl_addVar(vars, TPLADD, "AUREADER", "1"); }
3441 else if(account->aureader_list)
3443 value = mk_t_aureader(account);
3444 tpl_addVar(vars, TPLADD, "AUREADER", value);
3445 free_mk_t(value);
3448 if(!apicall)
3450 /* SERVICES */
3451 struct s_sidtab *sidtab = cfg.sidtab;
3452 //build matrix
3453 i = 0;
3454 while(sidtab != NULL)
3456 tpl_addVar(vars, TPLADD, "SIDLABEL", xml_encode(vars, sidtab->label));
3457 if(account->sidtabs.ok & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
3458 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
3459 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "USEREDITSIDOKBIT"));
3460 if(account->sidtabs.no & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
3461 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
3462 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "USEREDITSIDNOBIT"));
3463 sidtab = sidtab->next;
3464 i++;
3466 if(i){
3467 tpl_addVar(vars, TPLADD, "USEREDITSIDINS", tpl_getTpl(vars, "USEREDITSID"));
3470 else
3472 value = mk_t_service(&account->sidtabs);
3473 if(strlen(value) > 0)
3474 { tpl_addVar(vars, TPLADD, "SERVICES", value); }
3475 free_mk_t(value);
3478 // CAID
3479 value = mk_t_caidtab(&account->ctab);
3480 tpl_addVar(vars, TPLADD, "CAIDS", value);
3481 free_mk_t(value);
3483 //ident
3484 value = mk_t_ftab(&account->ftab);
3485 tpl_addVar(vars, TPLADD, "IDENTS", value);
3486 free_mk_t(value);
3488 //CHID
3489 value = mk_t_ftab(&account->fchid);
3490 tpl_addVar(vars, TPLADD, "CHIDS", value);
3491 free_mk_t(value);
3493 //class
3494 value = mk_t_cltab(&account->cltab);
3495 tpl_addVar(vars, TPLADD, "CLASS", value);
3496 free_mk_t(value);
3498 //Betatunnel
3499 value = mk_t_tuntab(&account->ttab);
3500 tpl_addVar(vars, TPLADD, "BETATUNNELS", value);
3501 free_mk_t(value);
3503 //SUPPRESSCMD08
3504 if(!apicall)
3506 if(account->c35_suppresscmd08)
3507 { tpl_addVar(vars, TPLADD, "SUPPRESSCMD08", "selected"); }
3509 else
3511 tpl_printf(vars, TPLADD, "SUPPRESSCMD08VALUE", "%d", account->c35_suppresscmd08);
3514 //Sleepsend
3515 if(account->c35_sleepsend)
3517 tpl_printf(vars, TPLADD, "SLEEPSEND", "selected");
3520 //max_connections
3521 tpl_printf(vars, TPLADD, "MAXCONNECTIONS", "%d", account->max_connections);
3523 //User Max Idle
3524 tpl_printf(vars, TPLADD, "UMAXIDLE", "%d", account->umaxidle);
3526 //EMM Reassembly selector
3527 if(!apicall)
3529 tpl_printf(vars, TPLADD, "TMP", "EMMRSELECTED%d", account->emm_reassembly);
3530 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3532 else
3534 tpl_printf(vars, TPLADD, "EMMRVALUE", "%d", account->emm_reassembly);
3537 //Prefer local cards
3538 if(!apicall)
3540 tpl_printf(vars, TPLADD, "TMP", "PREFERLOCALCARDS%d", account->preferlocalcards);
3541 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3542 char *tmp = NULL;
3543 switch(cfg.preferlocalcards)
3545 case -1:
3546 tmp = "-1 - Use Global prefer local cards";
3547 break;
3548 case 0:
3549 tmp = "0 - local cards like proxied";
3550 break;
3551 case 1:
3552 tmp = "1 - prefer cache-ex then local cards";
3553 break;
3554 case 2:
3555 tmp = "2 - prefer local cards above cache-ex";
3556 break;
3558 tpl_addVar(vars, TPLADD, "CFGPREFERLOCALCARDS", tmp);
3560 else
3562 tpl_printf(vars, TPLADD, "PREFERLOCALCARDSVALUE", "%d", account->preferlocalcards);
3565 #ifdef CS_CACHEEX
3566 // Cacheex
3567 if(!apicall)
3569 tpl_printf(vars, TPLADD, "TMP", "CACHEEXSELECTED%d", account->cacheex.mode);
3570 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3573 else
3575 tpl_printf(vars, TPLADD, "CACHEEX", "%d", account->cacheex.mode);
3577 tpl_printf(vars, TPLADD, "CACHEEX_MAXHOP", "%d", account->cacheex.maxhop);
3579 value = mk_t_cacheex_hitvaluetab(&account->cacheex.filter_caidtab);
3580 //if (strlen(value) > 0)
3581 tpl_printf(vars, TPLADD, "CACHEEX_ECM_FILTER", "%s", value);
3582 free_mk_t(value);
3584 tpl_addVar(vars, TPLADD, "DCCHECKED", (account->cacheex.drop_csp == 1) ? "checked" : "");
3585 tpl_addVar(vars, TPLADD, "ARCHECKED", (account->cacheex.allow_request == 1) ? "checked" : "");
3586 tpl_addVar(vars, TPLADD, "AFCHECKED", (account->cacheex.allow_filter == 1) ? "checked" : "");
3587 tpl_addVar(vars, TPLADD, "BLOCKFAKECWSCHECKED", (account->cacheex.block_fakecws == 1) ? "checked" : "");
3588 tpl_addVar(vars, TPLADD, "NWTCHECKED", (account->no_wait_time == 1) ? "checked" : "");
3589 tpl_addVar(vars, TPLADD, "DISABLECRCCEX4USER", (account->disablecrccacheex == 1) ? "checked" : "");
3590 value = mk_t_ftab(&account->disablecrccacheex_only_for);
3591 tpl_addVar(vars, TPLADD, "IGNCRCCEX4USERONLYFOR", value);
3592 free_mk_t(value);
3594 #endif
3596 #ifdef CW_CYCLE_CHECK
3597 tpl_addVar(vars, TPLADD, "USERCWCYCLEDISABLE", (account->cwc_disable == 1) ? "checked" : "");
3598 #endif
3600 //Keepalive
3601 if(!apicall)
3603 if(account->ncd_keepalive)
3604 { tpl_addVar(vars, TPLADD, "KEEPALIVE", "checked"); }
3606 else
3608 tpl_printf(vars, TPLADD, "KEEPALIVEVALUE", "%d", account->ncd_keepalive);
3611 #ifdef CS_ANTICASC
3612 tpl_printf(vars, TPLADD, "AC_USERS", "%d", account->ac_users);
3613 tpl_printf(vars, TPLADD, "CFGNUMUSERS", "%d", cfg.ac_users);
3614 if(!apicall)
3616 tpl_printf(vars, TPLADD, "TMP", "PENALTY%d", account->ac_penalty);
3617 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3618 char *tmp = NULL;
3619 switch(cfg.ac_penalty)
3621 case 0:
3622 tmp = "(0) Only write to log";
3623 break;
3624 case 1:
3625 tmp = "(1) NULL CW";
3626 break;
3627 case 2:
3628 tmp = "(2) Ban";
3629 break;
3630 case 3:
3631 tmp = "(3) Real CW delayed";
3632 break;
3634 tpl_addVar(vars, TPLADD, "CFGPENALTY", tmp);
3636 else
3638 tpl_printf(vars, TPLADD, "PENALTYVALUE", "%d", account->ac_penalty);
3640 tpl_printf(vars, TPLADD, "ACOSC_MAX_ECMS_PER_MINUTE", "%d", account->acosc_max_ecms_per_minute);
3641 tpl_printf(vars, TPLADD, "ACOSC_MAX_ACTIVE_SIDS", "%d", account->acosc_max_active_sids);
3642 tpl_printf(vars, TPLADD, "CFG_ACOSC_MAX_ECMS_PER_MINUTE", "%d", cfg.acosc_max_ecms_per_minute);
3643 tpl_printf(vars, TPLADD, "CFG_ACOSC_MAX_ACTIVE_SIDS", "%d", cfg.acosc_max_active_sids);
3644 tpl_printf(vars, TPLADD, "ACOSC_ZAP_LIMIT", "%d", account->acosc_zap_limit);
3645 tpl_printf(vars, TPLADD, "CFG_ACOSC_ZAP_LIMIT", "%d", cfg.acosc_zap_limit);
3646 if(!apicall)
3648 tpl_printf(vars, TPLADD, "TMP", "ACOSC_PENALTY%d", account->acosc_penalty);
3649 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3650 char *tmp = NULL;
3651 switch(cfg.acosc_penalty)
3653 case -1:
3654 tmp = "(-1) Use Global Value";
3655 break;
3656 case 0:
3657 tmp = "(0) Only write to log";
3658 break;
3659 case 1:
3660 tmp = "(1) NULL CW";
3661 break;
3662 case 2:
3663 tmp = "(2) Ban";
3664 break;
3665 case 3:
3666 tmp = "(3) CW delayed";
3667 break;
3668 case 4:
3669 tmp = "(4) Hidecards";
3670 break;
3672 tpl_addVar(vars, TPLADD, "CFG_ACOSC_PENALTY", tmp);
3673 } else
3675 tpl_printf(vars, TPLADD, "ACOSC_PENALTYVALUE", "%d", account->acosc_penalty);
3678 tpl_printf(vars, TPLADD, "ACOSC_PENALTY_DURATION", "%d", account->acosc_penalty_duration);
3679 tpl_printf(vars, TPLADD, "CFG_ACOSC_PENALTY_DURATION", "%d", cfg.acosc_penalty_duration);
3680 tpl_printf(vars, TPLADD, "ACOSC_DELAY", "%d", account->acosc_delay);
3681 tpl_printf(vars, TPLADD, "CFG_ACOSC_DELAY", "%d", cfg.acosc_delay);
3682 #endif
3684 #ifdef MODULE_CCCAM
3685 tpl_printf(vars, TPLADD, "CCCMAXHOPS", "%d", account->cccmaxhops);
3686 tpl_printf(vars, TPLADD, "CCCRESHARE", "%d", account->cccreshare);
3687 tpl_printf(vars, TPLADD, "RESHARE", "%d", cfg.cc_reshare);
3689 //CCcam Ignore Reshare
3690 tpl_printf(vars, TPLADD, "TMP", "CCCIGNRSHRSELECTED%d", account->cccignorereshare);
3691 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3692 tpl_addVar(vars, TPLADD, "CFGIGNORERESHARE",
3693 cfg.cc_ignore_reshare == 0 ?
3694 "0 - use reshare level of Server" : "1 - use reshare level of Reader or User");
3696 //CCcam Stealth Mode
3697 tpl_printf(vars, TPLADD, "TMP", "CCCSTEALTHSELECTED%d", account->cccstealth);
3698 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3700 tpl_addVar(vars, TPLADD, "STEALTH", cfg.cc_stealth ? "enable" : "disable");
3701 #endif
3703 //Failban
3704 tpl_printf(vars, TPLADD, "FAILBAN", "%d", account->failban);
3706 if(!apicall)
3707 { return tpl_getTpl(vars, "USEREDIT"); }
3708 else
3709 { return tpl_getTpl(vars, "APIUSEREDIT"); }
3713 static void webif_add_client_proto(struct templatevars *vars, struct s_client *cl, const char *proto, int8_t apicall)
3715 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTO", "");
3716 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOSORT", "");
3717 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOTITLE", "");
3718 tpl_addVar(vars, TPLADDONCE, "PROTOICON", "");
3719 if(!cl) { return; }
3720 #ifdef MODULE_NEWCAMD
3721 if(streq(proto, "newcamd") && cl->typ == 'c')
3723 tpl_printf(vars, TPLADD, "CLIENTPROTO", "%s (%s)", proto, newcamd_get_client_name(cl->ncd_client_id));
3724 tpl_printf(vars, TPLADD, "CLIENTPROTOSORT", "%s (%s)", proto, newcamd_get_client_name(cl->ncd_client_id));
3725 if(cfg.http_showpicons )
3727 char picon_name[32];
3728 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s_%s", (char *)proto, newcamd_get_client_name(cl->ncd_client_id));
3729 if(picon_exists(picon_name))
3731 if (!apicall)
3733 tpl_addVar(vars, TPLADD, "NCMDA", (char *)proto);
3734 tpl_addVar(vars, TPLADD, "NCMDB", (char *)newcamd_get_client_name(cl->ncd_client_id));
3735 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTONEWCAMDPIC"));
3737 else
3739 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s_%s",(char *)proto, (char *)newcamd_get_client_name(cl->ncd_client_id));
3742 else
3744 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s_%s.tpl", proto, newcamd_get_client_name(cl->ncd_client_id));
3747 return;
3749 #endif
3750 #ifdef MODULE_CCCAM
3751 if(strncmp(proto, "cccam", 5) == 0)
3753 struct cc_data *cc = cl->cc;
3754 if(cc && *cc->remote_version && *cc->remote_build)
3756 tpl_printf(vars, TPLADD, "CLIENTPROTO", "%s (%s-%s)", proto, cc->remote_version, cc->remote_build);
3757 tpl_printf(vars, TPLADD, "CLIENTPROTOSORT", "%s (%s-%s)", proto, cc->remote_version, cc->remote_build);
3758 if(cccam_client_multics_mode(cl))
3760 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "Multics, revision r%d", cc->multics_version[0] | (cc->multics_version[1] << 8));
3762 else
3764 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", cc->extended_mode ? cc->remote_oscam : "");
3767 if(cfg.http_showpicons)
3769 char picon_name[32];
3771 int8_t is_other_proto = 0;
3772 if(cccam_client_multics_mode(cl)) { is_other_proto = 1; }
3774 switch(is_other_proto)
3776 case 1:
3777 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s_r_%d", proto, cc->multics_version[0] | (cc->multics_version[1] << 8));
3778 if(picon_exists(picon_name))
3780 if (!apicall)
3782 tpl_addVar(vars, TPLADD, "CCA", (char *)proto);
3783 tpl_addVar(vars, TPLADD, "CCB", "r");
3784 tpl_printf(vars, TPLADD, "CCC", "%d", cc->multics_version[0] | (cc->multics_version[1] << 8));
3785 tpl_addVar(vars, TPLADD, "CCD", "");
3786 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTOCCCAMPIC"));
3788 else
3790 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s_r_%d",(char *)proto, cc->multics_version[0] | (cc->multics_version[1] << 8));
3793 else
3795 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "Multics, revision r%d missing icon: IC_%s_r_%d.tpl",
3796 cc->multics_version[0] | (cc->multics_version[1] << 8), proto, cc->multics_version[0] | (cc->multics_version[1] << 8));
3798 break;
3800 default:
3801 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s_%s_%s", proto, cc->remote_version, cc->remote_build);
3802 if(picon_exists(picon_name))
3804 if (!apicall)
3806 tpl_addVar(vars, TPLADD, "CCA", (char *)proto);
3807 tpl_addVar(vars, TPLADD, "CCB", cc->remote_version);
3808 tpl_addVar(vars, TPLADD, "CCC", cc->remote_build);
3809 tpl_addVar(vars, TPLADD, "CCD", cc->extended_mode ? cc->remote_oscam : "");
3810 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTOCCCAMPIC"));
3812 else
3814 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s_%s_%s",(char *)proto, cc->remote_version, cc->remote_build);
3817 else
3819 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "%s missing icon: IC_%s_%s_%s.tpl",
3820 cc->extended_mode ? cc->remote_oscam : "", proto, cc->remote_version, cc->remote_build);
3822 break;
3826 return;
3828 #endif
3829 #ifdef HAVE_DVBAPI
3830 if(streq(proto, "dvbapi") && cl->typ == 'c' && strcmp(dvbapi_get_client_name(), ""))
3832 if (!apicall)
3833 tpl_printf(vars, TPLADD, "CLIENTPROTO", "<A HREF=\"#\" CLASS=\"tooltip\">%s<SPAN>client: %s<BR>protocol version: %d</SPAN></A>", proto, dvbapi_get_client_name(), dvbapi_get_client_proto_version());
3834 else
3835 tpl_printf(vars, TPLADD, "CLIENTPROTO", "%s (client: %s, protocol version: %d)", proto, dvbapi_get_client_name(), dvbapi_get_client_proto_version());
3836 tpl_printf(vars, TPLADD, "CLIENTPROTOSORT", "%s", proto);
3837 return;
3839 #endif
3840 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTO", (char *)proto);
3841 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOSORT", (char *)proto);
3842 if(cfg.http_showpicons)
3844 char picon_name[32];
3845 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", proto);
3846 if(picon_exists(picon_name))
3848 if (!apicall)
3850 tpl_addVar(vars, TPLADD, "OTHER", (char *)proto);
3851 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTOOTHERPIC"));
3853 else
3855 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s",(char *)proto);
3858 else
3860 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s.tpl", proto);
3865 static void kill_account_thread(struct s_auth *account)
3867 struct s_client *cl;
3868 for(cl = first_client->next; cl ; cl = cl->next)
3870 if(cl->account == account)
3872 if(get_module(cl)->type & MOD_CONN_NET)
3874 kill_thread(cl);
3876 else
3878 cl->account = first_client->account;
3884 static char *send_oscam_user_config(struct templatevars *vars, struct uriparams *params, int32_t apicall)
3886 struct s_auth *account;
3887 struct s_client *cl;
3888 char *user = getParam(params, "user");
3889 int32_t found = 0;
3890 uint8_t md5tmp[MD5_DIGEST_LENGTH];
3892 if(!apicall)
3894 setActiveMenu(vars, MNU_USERS);
3896 if(strcmp(getParam(params, "action"), "reinit") == 0)
3898 if(!cfg.http_readonly)
3899 { refresh_oscam(REFR_ACCOUNTS); }
3901 if(strcmp(getParam(params, "action"), "delete") == 0)
3903 if(cfg.http_readonly)
3905 tpl_addMsg(vars, "WebIf is in readonly mode. No deletion will be made!");
3907 else
3909 struct s_auth *account_prev = NULL;
3911 for(account = cfg.account; (account); account = account->next)
3913 if(strcmp(account->usr, user) == 0)
3915 if(account_prev == NULL)
3916 { cfg.account = account->next; }
3917 else
3918 { account_prev->next = account->next; }
3919 ll_clear(account->aureader_list);
3920 kill_account_thread(account);
3921 add_garbage(account);
3922 found = 1;
3923 break;
3925 account_prev = account;
3927 if(found > 0)
3929 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
3931 else { tpl_addMsg(vars, "Sorry but the specified user doesn't exist. No deletion will be made!"); }
3935 if((strcmp(getParam(params, "action"), "disable") == 0) || (strcmp(getParam(params, "action"), "enable") == 0))
3937 account = get_account_by_name(getParam(params, "user"));
3938 if(account)
3940 if(strcmp(getParam(params, "action"), "disable") == 0)
3942 account->disabled = 1;
3943 kill_account_thread(account);
3945 else
3946 { account->disabled = 0; }
3947 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
3949 else
3951 tpl_addMsg(vars, "Sorry but the specified user doesn't exist. No deletion will be made!");
3955 if(strcmp(getParam(params, "action"), "resetstats") == 0)
3957 account = get_account_by_name(getParam(params, "user"));
3958 if(account) { clear_account_stats(account); }
3961 if(strcmp(getParam(params, "action"), "resetuserstats") == 0)
3963 clear_info_clients_stats();
3966 if(strcmp(getParam(params, "action"), "resetreaderstats") == 0)
3968 clear_info_readers_stats();
3971 if(strcmp(getParam(params, "action"), "resetalluserstats") == 0)
3973 clear_all_account_stats();
3976 if((strcmp(getParam(params, "part"), "adduser") == 0) && (!cfg.http_readonly))
3978 tpl_addVar(vars, TPLAPPEND, "NEWUSERFORM", tpl_getTpl(vars, "ADDNEWUSER"));
3981 /* List accounts*/
3982 char *status, *expired, *classname, *lastchan;
3983 time_t now = time((time_t *)0);
3984 int32_t isec = 0, chsec = 0;
3986 char *filter = NULL;
3987 int32_t clientcount = 0;
3988 if(apicall)
3990 filter = getParam(params, "label");
3992 int8_t grp_set = 0;
3993 int8_t expdate_set = 0;
3994 int32_t total_users = 0;
3995 int32_t disabled_users = 0;
3996 int32_t expired_users = 0;
3997 int32_t expired_or_disabled_users = 0;
3998 int32_t connected_users = 0;
3999 int32_t online_users = 0;
4000 int8_t isactive;
4001 int32_t casc_users = 0;
4002 int32_t casc_users2 = 0;
4003 int32_t n_request = 0;
4004 int existing_insert = 0;
4006 for(account = cfg.account; (account); account = account->next)
4008 if(account->expirationdate){
4009 expdate_set = 1;
4012 if(account->next){
4013 if(account->grp != account->next->grp){
4014 grp_set = 1;
4017 if(expdate_set && grp_set)
4018 break;
4021 for(account = cfg.account; (account); account = account->next)
4023 //clear for next client
4024 total_users++;
4025 isactive = 1;
4027 status = "offline";
4028 expired = "";
4029 classname = "offline";
4030 isec = 0;
4031 chsec = 0;
4033 //reset caid/srevid template variables
4034 tpl_addVar(vars, TPLADD, "CLIENTCAID", "");
4035 tpl_addVar(vars, TPLADD, "CLIENTPROVID", "");
4036 tpl_addVar(vars, TPLADD, "CLIENTSRVID", "");
4037 tpl_addVar(vars, TPLADD, "LASTCHANNEL", "");
4038 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", "");
4039 tpl_addVar(vars, TPLADD, "USERMD5", "");
4040 tpl_addVar(vars, TPLADD, "CWLASTRESPONSET", "");
4041 tpl_addVar(vars, TPLADD, "CWLASTRESPONSETMS", "");
4042 tpl_addVar(vars, TPLADD, "CLIENTIP", "");
4043 tpl_addVar(vars, TPLADD, "LASTCHANNELTITLE", "");
4044 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", "");
4045 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNELAPI", "");
4046 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", "");
4047 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEP", "");
4048 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEPAPI", "");
4049 tpl_addVar(vars, TPLADD, "IDLESECS", "");
4050 tpl_addVar(vars, TPLADD, "UNOTIFY", "");
4052 if(account->expirationdate && account->expirationdate < now)
4054 expired = " (expired)";
4055 classname = "expired";
4056 expired_users++;
4057 isactive = 0;
4059 else
4061 expired = "";
4064 if(account->disabled != 0)
4066 expired = " (disabled)";
4067 classname = "disabled";
4068 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICENA");
4069 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Enable");
4070 tpl_addVar(vars, TPLADD, "SWITCH", "enable");
4071 disabled_users++;
4072 isactive = 0;
4074 else
4076 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICDIS");
4077 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Disable");
4078 tpl_addVar(vars, TPLADD, "SWITCH", "disable");
4080 if((account->expirationdate && account->expirationdate < now)||account->disabled != 0)
4082 expired_or_disabled_users++;
4085 int32_t lastresponsetm = 0, latestactivity = 0;
4086 const char *proto = "";
4087 double cwrate = 0.0, cwrate2 = 0.0;
4089 //search account in active clients
4090 isactive = 0;
4091 int16_t nrclients = 0;
4092 struct s_client *latestclient = NULL;
4093 for(cl = first_client->next; cl ; cl = cl->next)
4095 if(cl->account && !strcmp(cl->account->usr, account->usr))
4097 if(cl->lastecm > latestactivity || cl->login > latestactivity)
4099 if(cl->lastecm > cl->login) { latestactivity = cl->lastecm; }
4100 else { latestactivity = cl->login; }
4101 latestclient = cl;
4103 nrclients++;
4106 if(account->cwfound + account->cwnot + account->cwcache > 0)
4108 cwrate = now - account->firstlogin;
4109 cwrate /= (account->cwfound + account->cwnot + account->cwcache);
4112 casc_users = 0;
4113 casc_users2 = 0;
4114 int8_t conn = 0;
4115 if(latestclient != NULL)
4117 char channame[CS_SERVICENAME_SIZE];
4118 status = (!apicall) ? "<B>connected</B>" : "connected";
4119 if(account->expirationdate && account->expirationdate < now) { classname = "expired"; }
4120 else { classname = "connected";conn = 1; }
4122 proto = client_get_proto(latestclient);
4123 int clientcaid = latestclient->last_caid;
4124 int clientsrvid = latestclient->last_srvid;
4125 int clientprovid = latestclient->last_provid;
4126 tpl_printf(vars, TPLADD, "CLIENTCAID", "%04X", clientcaid);
4127 tpl_printf(vars, TPLADD, "CLIENTPROVID", "%06X", clientprovid);
4128 tpl_printf(vars, TPLADD, "CLIENTSRVID", "%04X", clientsrvid);
4130 if(clientsrvid != NO_SRVID_VALUE || clientcaid != NO_CAID_VALUE)
4132 lastchan = xml_encode(vars, get_servicename(latestclient, clientsrvid, clientprovid, clientcaid, channame, sizeof(channame)));
4133 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", lastchan);
4135 else
4137 lastchan = "";
4138 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", "~~~~~");
4141 tpl_addVar(vars, TPLADDONCE, "LASTCHANNEL", lastchan);
4142 tpl_addVar(vars, TPLADD, "LASTCHANNELTITLE", lastchan);
4144 if(cfg.http_showpicons )
4146 char picon_name[128];
4147 char picon_channame[128];
4148 int8_t picon_ok = 0;
4150 get_picon_servicename_or_null(latestclient, clientsrvid, clientprovid, clientcaid, picon_channame, sizeof(picon_channame));
4151 if(picon_channame[0])
4153 snprintf(picon_name, sizeof(picon_name) / sizeof(char), "%s", picon_channame);
4154 picon_ok = picon_exists(picon_name);
4156 if(!picon_ok && picon_servicename_remve_hd(picon_channame, sizeof(picon_channame)))
4158 snprintf(picon_name, sizeof(picon_name) / sizeof(char), "%s", picon_channame);
4159 picon_ok = picon_exists(picon_name);
4162 if(!picon_ok)
4164 snprintf(picon_name, sizeof(picon_name) / sizeof(char), "%04X_%06X_%04X", clientcaid, clientprovid, clientsrvid);
4165 picon_ok = picon_exists(picon_name);
4167 if(!picon_ok)
4169 snprintf(picon_name, sizeof(picon_name) / sizeof(char), "%04X_%04X", clientcaid, clientsrvid);
4170 picon_ok = picon_exists(picon_name);
4172 if(!picon_ok)
4174 snprintf(picon_name, sizeof(picon_name) / sizeof(char), "0000_%04X", clientsrvid);
4175 picon_ok = picon_exists(picon_name);
4177 if(picon_ok)
4179 tpl_addVar(vars, TPLADDONCE, "LCA", picon_name);
4180 tpl_addVar(vars, TPLADDONCE, "LCB", lastchan);
4181 if(!apicall)
4183 tpl_addVar(vars, TPLADDONCE, "LASTCHANNEL", tpl_getTpl(vars, "USERCONFIGLASTCHANEL"));
4186 else
4188 tpl_printf(vars, TPLADD, "LASTCHANNELTITLE", "missing icon: IC_%s.tpl", picon_name);
4192 lastresponsetm = latestclient->cwlastresptime;
4193 tpl_addVar(vars, TPLADD, "CLIENTIP", cs_inet_ntoa(latestclient->ip));
4194 connected_users++;
4195 casc_users = ll_count(latestclient->cascadeusers);
4196 LL_ITER it = ll_iter_create(latestclient->cascadeusers);
4197 struct s_cascadeuser *cu;
4198 while((cu = ll_iter_next(&it)))
4200 if(cu->cwrate > 0)
4201 { casc_users2++; }
4203 if(latestactivity > 0)
4205 isec = now - latestactivity;
4206 chsec = latestclient->lastswitch ? now - latestclient->lastswitch : 0;
4207 if(isec < cfg.hideclient_to)
4209 isactive = 1;
4210 status = (!apicall) ? "<B>online</B>" : "online";
4211 if(account->expirationdate && account->expirationdate < now) { classname = "expired"; }
4212 else { classname = "online"; }
4213 if(latestclient->cwfound + latestclient->cwnot + latestclient->cwcache > 0)
4215 cwrate2 = now - latestclient->login;
4216 cwrate2 /= (latestclient->cwfound + latestclient->cwnot + latestclient->cwcache);
4217 tpl_printf(vars, TPLADDONCE, "CWRATE2", " (%.2f)", cwrate2);
4218 online_users++;
4224 n_request = 0;
4225 if(latestclient != NULL){
4226 n_request = latestclient->n_request[0];
4229 tpl_addVar(vars, TPLADD, "EXPIREVIEW", expdate_set ? "" : "exp");
4230 tpl_addVar(vars, TPLADD, "GRPVIEW", grp_set ? "" : "grp");
4231 #ifdef CS_ANTICASC
4232 tpl_addVar(vars, TPLADD, "ANTICASCVIEW", cfg.ac_enabled ? "" : "acas");
4233 #endif
4234 tpl_printf(vars, TPLADD, "CWOK", PRINTF_LOCAL_D, account->cwfound);
4235 tpl_printf(vars, TPLADD, "CWNOK", PRINTF_LOCAL_D, account->cwnot);
4236 tpl_printf(vars, TPLADD, "CWIGN", PRINTF_LOCAL_D, account->cwignored);
4237 tpl_printf(vars, TPLADD, "CWTOUT", PRINTF_LOCAL_D, account->cwtout);
4238 #ifdef CW_CYCLE_CHECK
4239 tpl_addVar(vars, TPLADD, "CWCCYCVIEW", cfg.cwcycle_check_enable ? "" : "cwc");
4240 tpl_printf(vars, TPLADD, "CWCYCLECHECKED", "%d", account->cwcycledchecked);
4241 tpl_printf(vars, TPLADD, "CWCYCLEOK", "%d", account->cwcycledok);
4242 tpl_printf(vars, TPLADD, "CWCYCLENOK", "%d", account->cwcyclednok);
4243 tpl_printf(vars, TPLADD, "CWCYCLEIGN", "%d", account->cwcycledign);
4244 #endif
4245 tpl_printf(vars, TPLADD, "CWCACHE", PRINTF_LOCAL_D, account->cwcache);
4246 tpl_printf(vars, TPLADD, "CWTUN", PRINTF_LOCAL_D, account->cwtun);
4247 tpl_printf(vars, TPLADD, "EMMOK", PRINTF_LOCAL_D, account->emmok);
4248 tpl_printf(vars, TPLADD, "EMMNOK", PRINTF_LOCAL_D, account->emmnok);
4249 tpl_printf(vars, TPLADD, "CWRATE", "%.2f", cwrate);
4250 tpl_printf(vars, TPLADD, "CASCUSERS", "%d", casc_users);
4251 tpl_printf(vars, TPLADD, "CASCUSERS2", "%d", casc_users2);
4252 tpl_printf(vars, TPLADD, "CASCUSERSCOMB", "%d/%d", casc_users, casc_users2);
4253 tpl_printf(vars, TPLADD, "N_REQUEST_MIN", "%d", n_request);
4255 if(isactive > 0 || conn > 0)
4257 if(casc_users+casc_users2>0)
4259 tpl_printf(vars, TPLADD, "CWLASTRESPONSET", "%d", lastresponsetm);
4260 tpl_printf(vars, TPLADD, "CWLASTRESPONSETMS", PRINTF_LOCAL_D " ms", lastresponsetm);
4262 tpl_addVar(vars, TPLADD, "IDLESECS", sec2timeformat(vars, isec));
4265 if(isactive > 0)
4267 tpl_printf(vars, TPLADD, "CLIENTTIMEONCHANNELAPI", "%d", chsec);
4268 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", sec2timeformat(vars, chsec));
4270 if(account->tosleep)
4272 if(account->tosleep >0){
4273 tpl_printf(vars, TPLADD, "CLIENTTIMETOSLEEP", "Sleeping in %d minutes", account->tosleep - (chsec / 60));
4274 } else {
4275 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEP", "Sleeping");
4277 tpl_printf(vars, TPLADD, "CLIENTTIMETOSLEEPAPI", "%d", account->tosleep - (chsec / 60));
4278 } else {
4279 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEPAPI", "undefined");
4283 webif_add_client_proto(vars, latestclient, proto, apicall);
4285 tpl_addVar(vars, TPLADD, "CLASSNAME", classname);
4286 MD5((uint8_t *)account->usr, strlen(account->usr), md5tmp);
4287 int z;
4288 tpl_addVar(vars, TPLADD, "USERMD5","id_");
4289 for (z = 0; z < MD5_DIGEST_LENGTH; z++)
4291 tpl_printf(vars, TPLAPPEND, "USERMD5", "%02x", md5tmp[z]);
4293 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, account->usr));
4294 tpl_addVar(vars, TPLADD, "USERNAMEENC", urlencode(vars, account->usr));
4295 if(!existing_insert)
4297 tpl_printf(vars, TPLADD, "EXISTING_INS", "'%s'", urlencode(vars, account->usr));
4298 existing_insert++;
4299 }else
4301 tpl_printf(vars, TPLAPPEND, "EXISTING_INS", ",'%s'", urlencode(vars, account->usr));
4304 if(account->description)
4305 tpl_printf(vars, TPLADD, "DESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, account->description));
4306 else
4307 tpl_addVar(vars, TPLADD, "DESCRIPTION", "");
4309 if(cfg.http_showpicons && !apicall)
4310 tpl_addVar(vars, TPLADD, "USERBIT", tpl_getTpl(vars, picon_exists(xml_encode(vars, account->usr)) ? "USERICON" : "USERNOICON"));
4311 else
4312 tpl_addVar(vars, TPLADD, "USERBIT", tpl_getTpl(vars, "USERLABEL"));
4314 char *value = mk_t_group(account->grp);
4315 tpl_addVar(vars, TPLADD, "GROUPS", value);
4316 free_mk_t(value);
4317 tpl_addVar(vars, TPLADD, "STATUS", status);
4318 tpl_addVar(vars, TPLAPPEND, "STATUS", expired);
4320 if(nrclients > 1)
4322 tpl_printf(vars, TPLADD, "UNOTIFY", "%d", nrclients);
4323 tpl_addVar(vars, TPLADDONCE, "CLIENTCOUNTNOTIFIER", tpl_getTpl(vars, "CLIENTCOUNTNOTIFIERBIT"));
4326 //Expirationdate
4327 struct tm timeinfo;
4328 cs_gmtime_r(&account->expirationdate, &timeinfo);
4329 char buf [80];
4330 strftime(buf, 80, "%Y-%m-%d", &timeinfo);
4331 if(strcmp(buf, "1970-01-01")) { tpl_addVar(vars, TPLADD, "EXPDATE", buf); }
4332 else { tpl_addVar(vars, TPLADD, "EXPDATE", ""); }
4334 // append row to table template
4335 if(!apicall)
4336 { tpl_addVar(vars, TPLAPPEND, "USERCONFIGS", tpl_getTpl(vars, "USERCONFIGLISTBIT")); }
4337 else if(!filter || strcmp(filter, account->usr) == 0 || strcmp(filter, "all") == 0 || strlen(filter) == 0)
4339 if(apicall == 1){
4340 tpl_addVar(vars, TPLAPPEND, "APIUSERCONFIGS", tpl_getTpl(vars, "APIUSERCONFIGLISTBIT"));
4341 } else if (apicall == 2){
4342 tpl_printf(vars, TPLADD, "JSONDELIMITER", "%s", (total_users > 1)?",":"");
4343 tpl_addVar(vars, TPLAPPEND, "APIUSERCONFIGS", tpl_getTpl(vars, "JSONUSERBIT"));
4345 ++clientcount;
4349 tpl_printf(vars, TPLADD, "TOTAL_USERS", "%d", total_users);
4350 tpl_printf(vars, TPLADD, "TOTAL_DISABLED", "%d", disabled_users);
4351 tpl_printf(vars, TPLADD, "TOTAL_EXPIRED", "%d", expired_users);
4352 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE", "%d", total_users - expired_or_disabled_users);
4353 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED", "%d", connected_users);
4354 tpl_printf(vars, TPLADD, "TOTAL_ONLINE", "%d", online_users);
4356 //CM info
4357 tpl_addVar(vars, TPLADD, "DISPLAYREADERINFO", "hidden"); // no readerinfo in users
4358 set_ecm_info(vars);
4360 if(!apicall)
4361 { return tpl_getTpl(vars, "USERCONFIGLIST"); }
4362 else
4364 if(!filter || clientcount > 0)
4366 return tpl_getTpl(vars, (apicall==1)?"APIUSERCONFIGLIST":"JSONUSER");
4368 else
4370 tpl_printf(vars, TPLADD, "APIERRORMESSAGE", "Invalid client %s", xml_encode(vars, filter));
4371 return tpl_getTpl(vars, "APIERROR");
4377 #define ENTITLEMENT_PAGE_SIZE 500
4379 #ifdef MODULE_CCCSHARE
4380 static void print_cards(struct templatevars *vars, struct uriparams *params, struct cc_card **cardarray, int32_t cardsize,
4381 int8_t show_global_list, struct s_reader *rdr, int32_t offset, int32_t apicall)
4383 if(cardarray)
4385 uint8_t serbuf[8];
4386 int32_t i, count = 0;
4387 char provname[83];
4388 struct cc_card *card;
4389 int32_t cardcount = 0;
4390 int32_t providercount = 0;
4391 int32_t nodecount = 0;
4393 char *provider = "";
4395 // @todo alno: sort by click, 0=ascending, 1=descending (maybe two buttons or reverse on second click)
4396 for(i = offset; i < cardsize; ++i)
4398 card = cardarray[i];
4399 if(count == ENTITLEMENT_PAGE_SIZE)
4400 { break; }
4401 count++;
4403 if(!apicall)
4405 if(show_global_list)
4406 { rdr = card->origin_reader; }
4407 if(rdr)
4408 { tpl_printf(vars, TPLADD, "HOST", "%s:%d", xml_encode(vars, rdr->device), rdr->r_port); }
4409 tpl_printf(vars, TPLADD, "CAID", "%04X", card->caid);
4410 tpl_printf(vars, TPLADD, "CARDTYPE", "%02X", card->card_type);
4412 else
4414 tpl_printf(vars, TPLADD, "APICARDNUMBER", "%d", cardcount);
4415 tpl_printf(vars, TPLADD, "APICAID", "%04X", card->caid);
4416 tpl_printf(vars, TPLADD, "APICARDTYPE", "%02X", card->card_type);
4419 if(cc_UA_valid(card->hexserial)) //Add UA:
4421 cc_UA_cccam2oscam(card->hexserial, serbuf, card->caid);
4422 char tmp[20];
4423 tpl_printf(vars, TPLAPPEND, "HOST", "<BR>\nUA_OSCam:%s", cs_hexdump(0, serbuf, 8, tmp, 20));
4424 tpl_printf(vars, TPLAPPEND, "HOST", "<BR>\nUA_CCcam:%s", cs_hexdump(0, card->hexserial, 8, tmp, 20));
4426 if(!apicall)
4428 int32_t n;
4429 char channame[CS_SERVICENAME_SIZE];
4430 int8_t sidname = 0;
4431 LL_ITER its = ll_iter_create(card->goodsids);
4432 struct cc_srvid *srv;
4433 n = 0;
4434 if(strcmp(getParam(params, "button"), "Show detail list") == 0)
4435 { sidname = 1; }
4437 tpl_addVar(vars, TPLADD, "SERVICESGOOD", "");
4438 while((srv = ll_iter_next(&its)))
4440 if(sidname)
4442 tpl_printf(vars, TPLAPPEND, "SERVICESGOOD", "%04X - %s<BR>", srv->sid, xml_encode(vars, get_servicename(cur_client(), srv->sid, 0, card->caid, channame, sizeof(channame))));
4443 } else {
4444 tpl_printf(vars, TPLAPPEND, "SERVICESGOOD", "%04X%s", srv->sid, ++n % 10 == 0 ? "<BR>\n" : " ");
4448 its = ll_iter_create(card->badsids);
4449 n = 0;
4450 tpl_addVar(vars, TPLADD, "SERVICESBAD", "");
4451 while((srv = ll_iter_next(&its)))
4453 if(sidname)
4455 tpl_printf(vars, TPLAPPEND, "SERVICESBAD", "%04X - %s<BR>", srv->sid, xml_encode(vars, get_servicename(cur_client(), srv->sid, 0, card->caid, channame, sizeof(channame))));
4456 } else {
4457 tpl_printf(vars, TPLAPPEND, "SERVICESBAD", "%04X%s", srv->sid, ++n % 10 == 0 ? "<BR>\n" : " ");
4462 tpl_addVar(vars, TPLADD, "SYSTEM", get_cardsystem_desc_by_caid(card->caid));
4464 tpl_printf(vars, TPLADD, "SHAREID", "%08X", card->id);
4465 tpl_printf(vars, TPLADD, "REMOTEID", "%08X", card->remote_id);
4466 tpl_printf(vars, TPLADD, "UPHOPS", "%d", card->hop);
4467 tpl_printf(vars, TPLADD, "MAXDOWN", "%d", card->reshare);
4469 LL_ITER pit = ll_iter_create(card->providers);
4470 struct cc_provider *prov;
4472 providercount = 0;
4474 if(!apicall)
4475 { tpl_addVar(vars, TPLADD, "PROVIDERS", ""); }
4476 else
4477 { tpl_addVar(vars, TPLADD, "PROVIDERLIST", ""); }
4479 while((prov = ll_iter_next(&pit)))
4481 provider = xml_encode(vars, get_provider(prov->prov, card->caid, provname, sizeof(provname)));
4483 if(!apicall)
4485 if(prov->sa[0] || prov->sa[1] || prov->sa[2] || prov->sa[3])
4487 tpl_printf(vars, TPLAPPEND, "PROVIDERS", "%s SA:%02X%02X%02X%02X<BR>\n", provider, prov->sa[0], prov->sa[1], prov->sa[2], prov->sa[3]);
4489 else
4491 tpl_printf(vars, TPLAPPEND, "PROVIDERS", "%s<BR>\n", provider);
4494 else
4496 if(prov->sa[0] || prov->sa[1] || prov->sa[2] || prov->sa[3])
4497 { tpl_printf(vars, TPLADD, "APIPROVIDERSA", "%02X%02X%02X%02X", prov->sa[0], prov->sa[1], prov->sa[2], prov->sa[3]); }
4498 else
4499 { tpl_addVar(vars, TPLADD, "APIPROVIDERSA", ""); }
4500 tpl_printf(vars, TPLADD, "APIPROVIDERCAID", "%04X", card->caid);
4501 tpl_printf(vars, TPLADD, "APIPROVIDERPROVID", "%06X", prov->prov);
4502 tpl_printf(vars, TPLADD, "APIPROVIDERNUMBER", "%d", providercount);
4503 tpl_addVar(vars, TPLADD, "APIPROVIDERNAME", xml_encode(vars, provider));
4504 tpl_addVar(vars, TPLAPPEND, "PROVIDERLIST", tpl_getTpl(vars, "APICCCAMCARDPROVIDERBIT"));
4507 providercount++;
4508 tpl_printf(vars, TPLADD, "APITOTALPROVIDERS", "%d", providercount);
4511 LL_ITER nit = ll_iter_create(card->remote_nodes);
4512 uint8_t *node;
4514 nodecount = 0;
4515 if(!apicall) { tpl_addVar(vars, TPLADD, "NODES", ""); }
4516 else { tpl_addVar(vars, TPLADD, "NODELIST", ""); }
4518 while((node = ll_iter_next(&nit)))
4521 if(!apicall)
4523 tpl_printf(vars, TPLAPPEND, "NODES", "%02X%02X%02X%02X%02X%02X%02X%02X<BR>\n",
4524 node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7]);
4526 else
4528 tpl_printf(vars, TPLADD, "APINODE", "%02X%02X%02X%02X%02X%02X%02X%02X", node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7]);
4529 tpl_printf(vars, TPLADD, "APINODENUMBER", "%d", nodecount);
4530 tpl_addVar(vars, TPLAPPEND, "NODELIST", tpl_getTpl(vars, "APICCCAMCARDNODEBIT"));
4532 nodecount++;
4533 tpl_printf(vars, TPLADD, "APITOTALNODES", "%d", nodecount);
4536 if(!apicall)
4537 { tpl_addVar(vars, TPLAPPEND, "CCCAMSTATSENTRY", tpl_getTpl(vars, "ENTITLEMENTCCCAMENTRYBIT")); }
4538 else
4539 { tpl_addVar(vars, TPLAPPEND, "CARDLIST", tpl_getTpl(vars, "APICCCAMCARDBIT")); }
4541 cardcount++;
4543 // set previous Link if needed
4544 if(offset >= ENTITLEMENT_PAGE_SIZE)
4546 tpl_printf(vars, TPLAPPEND, "CONTROLS", "<A HREF=\"entitlements.html?offset=%d&globallist=%s&amp;label=%s\"> << PREVIOUS < </A>",
4547 offset - ENTITLEMENT_PAGE_SIZE,
4548 getParam(params, "globallist"),
4549 urlencode(vars, getParam(params, "label")));
4552 // set next link if needed
4553 if(cardsize > count && offset < cardsize)
4555 tpl_printf(vars, TPLAPPEND, "CONTROLS", "<A HREF=\"entitlements.html?offset=%d&globallist=%s&amp;label=%s\"> > NEXT >> </A>",
4556 offset + ENTITLEMENT_PAGE_SIZE,
4557 getParam(params, "globallist"),
4558 urlencode(vars, getParam(params, "label")));
4561 if(!apicall)
4563 tpl_printf(vars, TPLADD, "TOTALS", "card count=%d", cardsize);
4564 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTCCCAMBIT"));
4566 else
4568 tpl_printf(vars, TPLADD, "APITOTALCARDS", "%d", cardsize);
4572 else
4574 if(!apicall)
4576 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTGENERICBIT"));
4577 tpl_addVar(vars, TPLADD, "LOGHISTORY", "no cards found<BR>\n");
4579 else
4581 tpl_printf(vars, TPLADD, "APITOTALCARDS", "%d", 0);
4586 #endif
4588 static char *send_oscam_entitlement(struct templatevars *vars, struct uriparams *params, int32_t apicall)
4590 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
4591 char *reader_ = getParam(params, "label");
4592 #ifdef MODULE_CCCAM
4593 char *sharelist_ = getParam(params, "globallist");
4594 int32_t show_global_list = sharelist_ && sharelist_[0] == '1';
4596 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
4597 if(show_global_list || strlen(reader_) || (rdr && rdr->typ == R_CCCAM))
4600 if(show_global_list || (rdr && rdr->typ == R_CCCAM && rdr->enable))
4603 if(show_global_list)
4605 tpl_addVar(vars, TPLADD, "READERNAME", "GLOBAL");
4606 tpl_addVar(vars, TPLADD, "APIHOST", "GLOBAL");
4607 tpl_addVar(vars, TPLADD, "APIHOSTPORT", "GLOBAL");
4609 else
4611 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
4612 tpl_addVar(vars, TPLADD, "APIHOST", xml_encode(vars, rdr->device));
4613 tpl_printf(vars, TPLADD, "APIHOSTPORT", "%d", rdr->r_port);
4616 #ifdef MODULE_CCCSHARE
4617 int32_t offset = atoi(getParam(params, "offset")); //should be 0 if parameter is missed on very first call
4618 int32_t cardsize;
4619 if(show_global_list)
4621 int32_t i;
4622 LLIST **sharelist = get_and_lock_sharelist();
4623 LLIST *sharelist2 = ll_create("web-sharelist");
4624 for(i = 0; i < CAID_KEY; i++)
4626 if(sharelist[i])
4627 { ll_putall(sharelist2, sharelist[i]); }
4629 unlock_sharelist();
4630 struct cc_card **cardarray = get_sorted_card_copy(sharelist2, 0, &cardsize);
4631 ll_destroy(&sharelist2);
4632 print_cards(vars, params, cardarray, cardsize, 1, NULL, offset, apicall);
4633 NULLFREE(cardarray);
4635 else
4637 struct s_client *rc = rdr->client;
4638 struct cc_data *rcc = (rc) ? rc->cc : NULL;
4639 if(rcc && rcc->cards)
4641 struct cc_card **cardarray = get_sorted_card_copy(rcc->cards, 0, &cardsize);
4642 print_cards(vars, params, cardarray, cardsize, 0, rdr, offset, apicall);
4643 NULLFREE(cardarray);
4646 #endif
4649 else
4651 #else
4652 if(strlen(reader_))
4655 struct s_reader *rdr;
4656 #endif
4657 tpl_addVar(vars, TPLADD, "LOGHISTORY", "->");
4658 // normal non-cccam reader
4660 rdr = get_reader_by_label(reader_);
4662 if(rdr)
4664 struct s_client *cl = rdr->client;
4665 if(rdr->ll_entitlements)
4668 time_t now = time((time_t *)0);
4670 struct tm start_t, end_t;
4671 LL_ITER itr = ll_iter_create(rdr->ll_entitlements);
4672 S_ENTITLEMENT *item;
4674 tpl_addVar(vars, TPLAPPEND, "LOGHISTORY", "<BR><BR>New Structure:<BR>");
4675 char tbuffer[83];
4676 #ifdef WITH_EMU
4677 char keyBuffer[1024];
4678 #endif
4679 int jsondelimiter = 0;
4680 while((item = ll_iter_next(&itr)))
4682 #ifdef WITH_EMU
4683 if(item->isKey)
4685 tpl_addVar(vars, TPLADD, "ENTSTARTDATE", "");
4686 tpl_addVar(vars, TPLADD, "ENTENDDATE", "");
4687 cs_hexdump(0, item->key, item->keyLength, keyBuffer, sizeof(keyBuffer));
4688 tpl_addVar(vars, TPLADD, "ENTEXPIERED", "e_valid");
4689 tpl_printf(vars, TPLADD, "ENTCAID", "%04X", item->caid);
4690 tpl_printf(vars, TPLADD, "ENTPROVID", "%08X", item->provid);
4691 tpl_addVar(vars, TPLADD, "ENTID", item->name);
4692 tpl_addVar(vars, TPLADD, "ENTCLASS", keyBuffer);
4693 if(item->isData) { tpl_addVar(vars, TPLADD, "ENTTYPE", "data"); }
4694 else { tpl_addVar(vars, TPLADD, "ENTTYPE", "key"); }
4695 tpl_addVar(vars, TPLADD, "ENTRESNAME", "");
4697 if((strcmp(getParam(params, "hideexpired"), "1") != 0) || (item->end > now))
4698 { tpl_addVar(vars, TPLAPPEND, "READERENTENTRY", tpl_getTpl(vars, "ENTITLEMENTITEMBIT")); }
4700 continue;
4702 #endif
4704 localtime_r(&item->start, &start_t);
4705 localtime_r(&item->end, &end_t);
4707 if(!apicall)
4708 { strftime(tbuffer, 30, "%Y-%m-%d", &start_t); }
4709 else
4710 { strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &start_t); }
4711 tpl_addVar(vars, TPLADD, "ENTSTARTDATE", tbuffer);
4713 if(!apicall)
4714 { strftime(tbuffer, 30, "%Y-%m-%d", &end_t); }
4715 else
4716 { strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &end_t); }
4717 tpl_addVar(vars, TPLADD, "ENTENDDATE", tbuffer);
4719 tpl_addVar(vars, TPLADD, "ENTEXPIERED", item->end > now ? "e_valid" : "e_expired");
4720 tpl_printf(vars, TPLADD, "ENTCAID", "%04X", item->caid);
4721 tpl_printf(vars, TPLADD, "ENTPROVID", "%06X", item->provid);
4722 tpl_printf(vars, TPLADD, "ENTID", "%08X%08X", (uint32_t)(item->id >> 32), (uint32_t)item->id);
4723 tpl_printf(vars, TPLADD, "ENTCLASS", "%08X", item->class);
4724 tpl_addVar(vars, TPLADD, "ENTTYPE", entitlement_type[item->type]);
4726 char *entresname;
4727 entresname = xml_encode(vars, get_tiername((uint16_t)(item->id & 0xFFFF), item->caid, tbuffer));
4728 if(!tbuffer[0])
4729 { entresname = xml_encode(vars, get_provider(item->provid, item->caid, tbuffer, sizeof(tbuffer))); }
4730 tpl_addVar(vars, TPLADD, "ENTRESNAME", entresname);
4732 if((strcmp(getParam(params, "hideexpired"), "1") != 0) || (item->end > now))
4733 { tpl_addVar(vars, TPLAPPEND, "READERENTENTRY", tpl_getTpl(vars, "ENTITLEMENTITEMBIT")); }
4735 if(apicall==2)
4737 tpl_printf(vars, TPLAPPEND, "APIENTITLEMENTLIST","%s%s",jsondelimiter?",":"", tpl_getTpl(vars, "JSONENTITLEMENTBIT"));
4738 jsondelimiter++;
4743 if(cl && cl->typ)
4744 { tpl_printf(vars, TPLADD, "READERTYPE", "%c", cl->typ); }
4745 else
4746 { tpl_addVar(vars, TPLADD, "READERTYPE", "null"); }
4747 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
4749 int8_t i, j;
4750 for(i = 0; i < 15; i++) { tpl_printf(vars, TPLAPPEND, "READERROM", "%c", rdr->rom[i]); }
4751 if(rdr->hexserial[0] || rdr->hexserial[1]) { i = 0; }
4752 else { i = 2; }
4753 if(rdr->hexserial[6] || rdr->hexserial[7]) { j = 8; }
4754 else { j = 6; }
4755 for(; i < j; i++) { tpl_printf(vars, TPLAPPEND, "READERSERIAL", "%02X%s", rdr->hexserial[i], i < j - 1 ? " " : ""); }
4756 for(i = 0; i < rdr->nprov; i++)
4758 for(j = 0; j < 4; j++) { tpl_printf(vars, TPLAPPEND, "READERPROVIDS", "%02X ", rdr->prid[i][j]); }
4759 tpl_addVar(vars, TPLAPPEND, "READERPROVIDS", i == 0 ? "(sysid)<BR>\n" : "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>\n");
4762 //CountryCode Vg card
4763 char add_nds_line = 0;
4764 if(rdr->VgCountryC[0])
4766 for(i = 0; i < 3; i++) { tpl_printf(vars, TPLAPPEND, "READERCOUNTRYC", "%c", rdr->VgCountryC[i]); }
4767 add_nds_line = 1;
4769 else
4771 tpl_addVar(vars, TPLADD, "READERCOUNTRYC", "n/a");
4774 //regional code for Vg card
4775 if(rdr->VgRegionC[0])
4777 for(i = 0; i < 8; i++) { tpl_printf(vars, TPLAPPEND, "READER_RCODE", "%c", rdr->VgRegionC[i]); }
4778 add_nds_line = 1;
4780 else
4782 tpl_addVar(vars, TPLADD, "READER_RCODE", "n/a");
4785 //Pin Vg card
4786 if(rdr->VgPin)
4788 tpl_printf(vars, TPLAPPEND, "READERPIN", "%04i", rdr->VgPin);
4789 add_nds_line = 1;
4791 else
4793 tpl_addVar(vars, TPLADD, "READERPIN", "n/a");
4796 //Fuse Vg card
4797 if(rdr->VgFuse)
4799 tpl_printf(vars, TPLAPPEND, "READERFUSE", "%02X", rdr->VgFuse);
4800 add_nds_line = 1;
4803 if(caid_is_videoguard(rdr->caid))
4805 tpl_printf(vars, TPLAPPEND, "READERPAYLOAD", "%02X %02X %02X %02X %02X %02X", rdr->VgLastPayload[0],
4806 rdr->VgLastPayload[1], rdr->VgLastPayload[2], rdr->VgLastPayload[3], rdr->VgLastPayload[4], rdr->VgLastPayload[5]);
4807 add_nds_line = 1;
4810 //credit on Vg card
4811 if(rdr->VgCredit)
4813 tpl_printf(vars, TPLAPPEND, "READERCREDIT", "%i", rdr->VgCredit);
4814 add_nds_line = 1;
4816 else
4818 tpl_addVar(vars, TPLADD, "READERCREDIT", "n/a");
4821 if(rdr->card_valid_to)
4823 struct tm vto_t;
4824 char vtobuffer[30];
4825 localtime_r(&rdr->card_valid_to, &vto_t);
4826 strftime(vtobuffer, 30, "%Y-%m-%d", &vto_t);
4827 tpl_addVar(vars, TPLADD, "READERCARDVALIDTO", vtobuffer);
4829 else
4831 tpl_addVar(vars, TPLADD, "READERCARDVALIDTO", "n/a");
4834 if(rdr->irdId[0])
4836 for(i = 0; i < 4; i++) { tpl_printf(vars, TPLAPPEND, "READERIRDID", "%02X ", rdr->irdId[i]); }
4838 else
4840 tpl_addVar(vars, TPLADD, "READERIRDID", "n/a");
4843 if(rdr->card_atr_length)
4844 for(i = 0; i < rdr->card_atr_length; i++) { tpl_printf(vars, TPLAPPEND, "READERATR", "%02X ", rdr->card_atr[i]); }
4846 if(caid_is_seca(rdr->caid) || caid_is_viaccess(rdr->caid))
4848 if(rdr->maturity == 0xF)
4850 tpl_printf(vars, TPLAPPEND, "READERMATURITY", "%s ", "no limit");
4852 else
4854 tpl_printf(vars, TPLAPPEND, "READERMATURITY", "%d+", rdr->maturity);
4857 else
4859 tpl_printf(vars, TPLAPPEND, "READERMATURITY", "%s ", "n/a");
4862 if (rdr->csystem)
4863 tpl_addVar(vars, TPLADD, "READERCSYSTEM", rdr->csystem->desc);
4865 if(add_nds_line)
4867 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENTNDS", tpl_getTpl(vars, "ENTITLEMENTBITNDS"));
4869 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTBIT"));
4871 else
4873 tpl_addMsg(vars, "Reader does not exist or is not started!");
4878 else
4880 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTGENERICBIT"));
4883 if(!apicall)
4884 { return tpl_getTpl(vars, "ENTITLEMENTS"); }
4885 else
4887 if(apicall==1)
4888 { return tpl_getTpl(vars, "APICCCAMCARDLIST"); }
4889 else
4890 { return tpl_getTpl(vars, "JSONENTITLEMENTS"); }
4894 #ifdef WEBIF_LIVELOG
4895 static char *send_oscam_logpoll(struct templatevars * vars, struct uriparams * params)
4898 uint64_t lastid = 0;
4900 #ifdef WITH_DEBUG
4901 tpl_addVar(vars, TPLADD, "LOG_DEBUGMENU", tpl_getTpl(vars, "LOGDEBUGMENU"));
4902 #endif
4903 tpl_addVar(vars, TPLADD, "LOG_SIZEMENU", tpl_getTpl(vars, "LOGSIZEMENU"));
4904 tpl_addVar(vars, TPLADD, "TITLEADD1", "Move mouse over log-window to stop scroll");
4906 if(strcmp(getParam(params, "lastid"), "start") == 0){
4907 setActiveMenu(vars, MNU_LIVELOG);
4908 return tpl_getTpl(vars, "LOGPAGE");
4910 else
4912 lastid = strtoull(getParam(params, "lastid"), NULL, 10);
4915 char *dot = ""; //Delimiter
4917 #ifdef WITH_DEBUG
4918 char *debuglvl = getParam(params, "debug");
4919 if(strlen(debuglvl) > 0) {
4920 int32_t dblvl = atoi(debuglvl);
4921 if(cs_dblevel != dblvl) {
4922 if(dblvl >= 0 && dblvl <= 65535) { cs_dblevel = dblvl; }
4923 cs_log("%s debug_level=%d", "all", cs_dblevel);
4926 tpl_printf(vars, TPLAPPEND, "DATA","%s\"debug\":\"%d\"", dot, cs_dblevel);
4927 dot = ",";
4928 tpl_printf(vars, TPLAPPEND, "DATA","%s\"maxdebug\":\"%d\"",dot, MAX_DEBUG_LEVELS);
4929 #endif
4931 if(cfg.loghistorylines == 0){
4932 tpl_printf(vars, TPLAPPEND, "DATA","%s\"logdisabled\":\"1\"",dot);
4933 return tpl_getTpl(vars, "POLL");
4936 if(log_history)
4938 LL_ITER it = ll_iter_create(log_history);
4939 struct s_log_history *hist;
4941 tpl_printf(vars, TPLAPPEND, "DATA", "%s\"lines\":[", dot);
4943 dot = "";
4945 while((hist = (struct s_log_history*)ll_iter_next(&it)))
4947 char p_usr[32];
4948 size_t pos1 = strcspn(hist->txt, "\t") + 1;
4949 cs_strncpy(p_usr, hist->txt , pos1 > sizeof(p_usr) ? sizeof(p_usr) : pos1);
4951 char *p_txt = hist->txt + pos1;
4953 pos1 = strcspn(p_txt, "\n") + 1;
4954 char str_out[pos1];
4955 cs_strncpy(str_out, p_txt, pos1);
4956 uint64_t id = hist->counter;
4958 size_t b64_str_in = strlen(xml_encode(vars, str_out));
4959 size_t b64_str_out = 32 + BASE64_LENGTH(b64_str_in);
4960 char *b64_str_out_buf;
4961 if(!cs_malloc(&b64_str_out_buf, b64_str_out))
4962 { continue; }
4963 base64_encode(xml_encode(vars, str_out), b64_str_in, b64_str_out_buf, b64_str_out);
4965 if(id > lastid){
4966 tpl_printf(vars, TPLAPPEND, "DATA","%s{\"id\":\"%" PRIu64 "\",\"usr\":\"%s\",\"line\":\"%s\"}",
4967 dot,
4969 urlencode(vars, xml_encode(vars, p_usr)),
4970 b64_str_out_buf);
4971 dot = ","; // next in Array with leading delimiter
4973 NULLFREE(b64_str_out_buf);
4977 tpl_addVar(vars, TPLAPPEND, "DATA", "]");
4978 return tpl_getTpl(vars, "POLL");
4980 #endif
4982 static char *send_oscam_status(struct templatevars * vars, struct uriparams * params, int32_t apicall)
4984 int32_t i;
4985 const char *usr;
4986 int32_t lsec, isec, chsec, con, cau = 0;
4987 time_t now = time((time_t *)0);
4988 struct tm lt;
4989 int delimiter=0;
4991 if(!apicall)
4993 setActiveMenu(vars, MNU_STATUS);
4994 if (config_enabled(WITH_LB))
4995 tpl_addVar(vars, TPLADD, "STATUSCOL14HEAD","LB Value/");
4997 if(strcmp(getParam(params, "action"), "kill") == 0)
4999 char *cptr = getParam(params, "threadid");
5000 struct s_client *cl = NULL;
5001 if(strlen(cptr) > 1)
5002 { sscanf(cptr, "%p", (void **)(void *)&cl); }
5004 if(cl && is_valid_client(cl))
5006 if(is_dvbapi_usr(cl->account->usr))
5008 cs_log("WebIF from %s requests to kill dvbapi client %s -> ignoring!", cs_inet_ntoa(GET_IP()), cl->account->usr);
5010 else
5012 kill_thread(cl);
5013 cs_log("Client %s killed by WebIF from %s", cl->account->usr, cs_inet_ntoa(GET_IP()));
5018 if(strcmp(getParam(params, "action"), "resetuserstats") == 0)
5020 clear_info_clients_stats();
5022 if(strcmp(getParam(params, "action"), "resetreaderstats") == 0)
5024 clear_info_readers_stats();
5026 if(strcmp(getParam(params, "action"), "restart") == 0)
5028 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
5029 if(rdr)
5031 if(rdr->typ != R_GBOX)
5033 add_job(rdr->client, ACTION_READER_RESTART, NULL, 0);
5035 #ifdef MODULE_GBOX
5036 else
5038 restart_gbox_peer(rdr->label, 0, 0);
5040 #endif
5041 cs_log("Reader %s restarted by WebIF from %s", rdr->label, cs_inet_ntoa(GET_IP()));
5045 char *debuglvl = getParam(params, "debug");
5046 if(strlen(debuglvl) > 0)
5048 #ifndef WITH_DEBUG
5049 cs_log("*** Warning: Debug Support not compiled in ***");
5050 #else
5051 int32_t dblvl = atoi(debuglvl);
5052 if(dblvl >= 0 && dblvl <= 65535) { cs_dblevel = dblvl; }
5053 cs_log("%s debug_level=%d", "all", cs_dblevel);
5054 #endif
5057 char *hide = getParam(params, "hide");
5058 if(strlen(hide) > 0)
5060 struct s_client *hideidx = NULL;
5061 sscanf(hide, "%p", (void **)(void *)&hideidx);
5063 if(hideidx && is_valid_client(hideidx))
5064 { hideidx->wihidden = 1; }
5067 char *hideidle = getParam(params, "hideidle");
5068 if(strlen(hideidle) > 0)
5070 if(atoi(hideidle) == 2)
5072 struct s_client *cl;
5073 for(cl = first_client; cl ; cl = cl->next)
5075 if(cl->typ == 's' || cl->typ == 'h' || cl->typ == 'm'){
5076 cl->wihidden = 0;
5080 else if(atoi(hideidle) == 3)
5082 struct s_client *cl;
5083 for(cl = first_client; cl ; cl = cl->next)
5085 if(cl->typ == 'r'){
5086 cl->wihidden = 0;
5090 else if(atoi(hideidle) == 4)
5092 struct s_client *cl;
5093 for(cl = first_client; cl ; cl = cl->next)
5095 if(cl->typ == 'p'){
5096 cl->wihidden = 0;
5100 else if(atoi(hideidle) == 5)
5102 struct s_client *cl;
5103 for(cl = first_client; cl ; cl = cl->next)
5105 if(cl->typ == 'c'){
5106 cl->wihidden = 0;
5110 else
5112 int32_t oldval = cfg.http_hide_idle_clients;
5113 config_set("webif", "httphideidleclients", hideidle);
5114 if(oldval != cfg.http_hide_idle_clients)
5116 refresh_oscam(REFR_SERVER);
5121 if(cfg.http_hide_idle_clients > 0) { tpl_addVar(vars, TPLADD, "HIDEIDLECLIENTSSELECTED1", "selected"); }
5122 else { tpl_addVar(vars, TPLADD, "HIDEIDLECLIENTSSELECTED0", "selected"); }
5124 tpl_addVar(vars, TPLADD, "SRVIDFILE", use_srvid2 ? "oscam.srvid2" : "oscam.srvid");
5126 int32_t user_count_all = 0, user_count_shown = 0, user_count_active = 0;
5127 int32_t reader_count_all = 0, reader_count_conn = 0, reader_count_off = 0;
5128 int32_t proxy_count_all = 0, proxy_count_conn = 0, proxy_count_off = 0;
5129 int32_t server_count_all = 0, server_count_shown = 0, server_count_hidden = 0;
5130 int32_t monitor_count_all = 0, monitor_count_shown = 0;
5131 int32_t shown;
5133 int32_t total_readers = 0;
5134 int32_t active_readers = 0;
5135 int32_t disabled_readers = 0;
5136 int32_t connected_readers = 0;
5138 struct s_client *cl;
5139 int8_t filtered;
5141 cs_readlock(__func__, &readerlist_lock);
5142 cs_readlock(__func__, &clientlist_lock);
5143 for(i = 0, cl = first_client; cl ; cl = cl->next, i++)
5145 if(cl->kill) { continue; }
5146 #ifdef CS_CACHEEX
5147 if(get_module(cl)->listenertype != LIS_CSPUDP)
5149 #endif
5151 // Reset template variables
5152 tpl_addVar(vars, TPLADD, "LBLRPSTRVALUE", "");
5153 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", "");
5154 tpl_addVar(vars, TPLADD, "LASTREADER", "");
5155 tpl_addVar(vars, TPLADD, "CLIENTPROTO", "");
5156 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
5157 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIME", "");
5158 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIMEHIST", "");
5159 tpl_addVar(vars, TPLADD, "UPICMISSING" , "");
5160 tpl_addVar(vars, TPLADD, "ENTITLEMENTS", "");
5162 if(cl->typ == 'c')
5163 { user_count_all++; }
5164 else if(cl->typ == 'p')
5166 proxy_count_all++;
5167 if((cl->reader->typ == R_GBOX && cl->reader->card_status != CARD_INSERTED && cl->reader->card_status != NO_CARD) ||
5168 (cl->reader->typ != R_GBOX && cl->reader->card_status != CARD_INSERTED))
5169 { proxy_count_off++; }
5171 else if(cl->typ == 'r')
5172 { reader_count_all++; if(cl->reader->card_status != CARD_INSERTED) { reader_count_off++; } }
5173 else if(cl->typ == 's' || cl->typ == 'h')
5174 { server_count_all++; if(cl->wihidden) {server_count_hidden++;} }
5175 else if(cl->typ == 'm')
5176 { monitor_count_all++; }
5178 shown = 0;
5179 if(cl->wihidden != 1)
5181 filtered = !(cfg.http_hide_idle_clients != 1 || cl->typ != 'c' || (now - cl->lastecm) <= cfg.hideclient_to);
5182 if(!filtered && cfg.http_hide_type)
5184 char *p = cfg.http_hide_type;
5185 while(*p && !filtered)
5187 char type = *p++;
5188 #ifdef CS_CACHEEX
5189 filtered = (type == cl->typ) || (type == 'x' && (cl->typ == 'p' || cl->typ == 'r') && (cl->reader && cl->reader->cacheex.mode));
5190 #else
5191 filtered = (type == cl->typ);
5192 #endif
5193 #ifdef WITH_EMU
5194 if(type == 'e' && cl->typ == 'r' && cl->reader->typ == R_EMU) filtered = 1;
5195 #endif
5199 if(!filtered)
5201 if(cl->typ == 'c')
5203 user_count_shown++;
5204 if(cfg.http_hide_idle_clients != 1 && cfg.hideclient_to > 0 && (now - cl->lastecm) <= cfg.hideclient_to)
5206 user_count_active++;
5209 else if(cl->typ == 's' || cl->typ == 'h')
5211 server_count_shown++;
5213 else if(cl->typ == 'm')
5215 monitor_count_shown++;
5217 else if(cl->typ == 'r')
5219 reader_count_conn++;
5221 else if(cl->typ == 'p')
5223 proxy_count_conn++;
5226 if(cl->typ == 'c' || cl->typ == 'r' || cl->typ == 'p')
5228 if(cl->lastecm >= cl->login && cl->lastecm >= cl->logout) { isec = now - cl->lastecm; }
5229 else if(cl->logout >= cl->login) { isec = now - cl->logout; }
5230 else { isec = now - cl->login; }
5232 else { isec = now - cl->last; }
5234 shown = 1;
5235 lsec = now - cl->login;
5236 chsec = now - cl->lastswitch;
5237 usr = username(cl);
5239 if((cl->typ == 'r') || (cl->typ == 'p')) { usr = cl->reader->label; }
5241 if(cl->dup) { con = 2; }
5242 else if((cl->tosleep) && (now - cl->lastswitch > cl->tosleep)) { con = 1; }
5243 else { con = 0; }
5245 // no AU reader == 0 / AU ok == 1 / Last EMM > aulow == -1
5246 if(cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r')
5248 if((cl->typ == 'c' && ll_count(cl->aureader_list) == 0) || ((cl->typ == 'p' || cl->typ == 'r') && cl->reader->audisabled)) { cau = 0; }
5249 else if((now - cl->lastemm) / 60 > cfg.aulow) { cau = -1; }
5250 else { cau = 1; }
5252 if(cau == 0)
5254 tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", "OFF");
5256 else
5258 if(cau == -1)
5259 { tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", !apicall?"<A HREF=\"#\" CLASS=\"tooltip\">ON":""); }
5260 else
5261 { tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", !apicall?"<A HREF=\"#\" CLASS=\"tooltip\">ACTIVE":""); }
5262 tpl_addVar(vars, TPLAPPEND, "CLIENTCAUHTTP", !apicall?"<SPAN>":"");
5263 if(cl->typ == 'c')
5265 struct s_reader *rdr;
5266 LL_ITER itr = ll_iter_create(cl->aureader_list);
5267 while((rdr = ll_iter_next(&itr)))
5269 if(rdr->audisabled)
5270 { tpl_printf(vars, TPLAPPEND, "CLIENTCAUHTTP", "(%s)<BR>", xml_encode(vars, rdr->label)); }
5271 else
5272 { tpl_printf(vars, TPLAPPEND, "CLIENTCAUHTTP", "%s<BR>", xml_encode(vars, rdr->label)); }
5275 else { tpl_addVar(vars, TPLAPPEND, "CLIENTCAUHTTP", xml_encode(vars, cl->reader->label)); }
5276 tpl_addVar(vars, TPLAPPEND, "CLIENTCAUHTTP", !apicall?"</SPAN></A>":"");
5279 else
5281 cau = 0;
5282 tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", "");
5284 localtime_r(&cl->login, &lt);
5286 if(cl->typ == 'c' || cl->typ == 'm')
5288 if(cl->account && cl->account->description)
5289 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->account->description));
5290 else
5291 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
5293 else if(cl->typ == 'p' || cl->typ == 'r')
5295 if(cl->reader && cl->reader->description)
5296 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->reader->description));
5297 else
5298 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
5300 if(!apicall)
5302 tpl_addVar(vars, TPLADD, "LBL", xml_encode(vars, usr));
5303 tpl_printf(vars, TPLADD, "CID", "%p", cl);
5304 if(cl->typ == 'c' || cl->typ == 'm')
5306 tpl_addVar(vars, TPLADD, "TARGET", "User");
5307 tpl_addVar(vars, TPLADD, "CSIDX", tpl_getTpl(vars, "STATUSKBUTTON"));
5309 else if(cl->typ == 'p')
5311 tpl_addVar(vars, TPLADD, "TARGET", "Proxy");
5312 tpl_addVar(vars, TPLADD, "LBLENC", urlencode(vars, usr));
5313 tpl_addVar(vars, TPLADD, "CSIDX", tpl_getTpl(vars, "STATUSRBUTTON"));
5315 else if(cl->typ == 'r')
5317 tpl_addVar(vars, TPLADD, "TARGET", "Reader");
5318 tpl_addVar(vars, TPLADD, "LBLENC", urlencode(vars, usr));
5319 tpl_addVar(vars, TPLADD, "CSIDX", tpl_getTpl(vars, "STATUSRBUTTON"));
5321 else if (cl->typ == 'h' || cl->typ == 's')
5323 tpl_addVar(vars, TPLADD, "TARGET", "Server");
5324 tpl_addVar(vars, TPLADD, "CSIDX", "");
5326 tpl_addVar(vars, TPLADD, "HIDEIDX", tpl_getTpl(vars, "STATUSHBUTTON"));
5327 tpl_printf(vars, TPLADD, "CSIDXPLAIN", "id_%p", cl);
5329 else
5331 tpl_printf(vars, TPLADD, "HIDEIDX", "%p", cl);
5332 tpl_printf(vars, TPLADD, "CSIDX", "id_%p", cl);
5334 tpl_printf(vars, TPLADD, "CLIENTTYPE", "%c", cl->typ);
5335 tpl_printf(vars, TPLADD, "CLIENTCNR", "%d", get_threadnum(cl));
5336 tpl_addVar(vars, TPLADD, "CLIENTUSER", xml_encode(vars, usr));
5338 tpl_addVar(vars, TPLADD, "STATUSUSERICON", xml_encode(vars, usr));
5339 if (cl->typ == 'c' || cl->typ == 'm')
5341 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, usr));
5342 tpl_addVar(vars, TPLADD, "USERENC", urlencode(vars, usr));
5344 else if (cl->typ == 'p' || cl->typ == 'r')
5346 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, usr));
5347 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, usr));
5350 bool picon_shown = false;
5351 const char *status_user_icon_tpl = NULL;
5353 char picon_name[32];
5354 if(cfg.http_showpicons)
5356 if(picon_exists(xml_encode(vars, usr)))
5358 switch (cl->typ)
5360 case 'm': // Fall through
5361 case 'c': status_user_icon_tpl = "SUSERICON"; picon_shown = true; break;
5362 case 'p': // Fall through
5363 case 'r': status_user_icon_tpl = "SREADERICON"; picon_shown = true; break;
5366 else
5367 tpl_printf(vars, TPLADD, "UPICMISSING", "%smissing icon: IC_%s.tpl",!apicall?"&#13;":"",xml_encode(vars, usr));
5370 if (!picon_shown)
5372 switch (cl->typ)
5374 case 'm': // Fall through
5375 case 'c': status_user_icon_tpl = "SUSER"; break;
5376 case 'p': // Fall through
5377 case 'r': status_user_icon_tpl = "SREADER"; break;
5381 if (status_user_icon_tpl)
5382 tpl_addVar(vars, TPLADD, "STATUSUSERICON", tpl_getTpl(vars, status_user_icon_tpl));
5384 tpl_printf(vars, TPLADD, "CLIENTCAU", "%d", cau);
5385 if(!apicall)
5387 if(cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r')
5389 if(cl->crypted) { tpl_addVar(vars, TPLADD, "CLIENTCRYPTED", "ON"); }
5390 else { tpl_addVar(vars, TPLADD, "CLIENTCRYPTED", "OFF"); }
5392 else { tpl_addVar(vars, TPLADD, "CLIENTCRYPTED", ""); }
5394 else { tpl_printf(vars, TPLADD, "CLIENTCRYPTED", "%d", cl->crypted); }
5395 tpl_addVar(vars, TPLADD, "CLIENTIP", cs_inet_ntoa(cl->ip));
5396 tpl_printf(vars, TPLADD, "CLIENTPORT", "%d", cl->port);
5397 const char *proto = client_get_proto(cl);
5398 webif_add_client_proto(vars, cl, proto, apicall);
5400 if(!apicall)
5402 if((cl->typ != 'p' && cl->typ != 'r') || cl->reader->card_status == CARD_INSERTED)
5404 tpl_printf(vars, TPLADD, "CLIENTLOGINDATE", "%02d.%02d.%02d<BR>%02d:%02d:%02d", lt.tm_mday, lt.tm_mon + 1, lt.tm_year % 100, lt.tm_hour, lt.tm_min, lt.tm_sec);
5405 tpl_addVar(vars, TPLADD, "CLIENTLOGINSECS", sec2timeformat(vars, lsec));
5407 else
5409 tpl_addVar(vars, TPLADD, "CLIENTLOGINDATE", "");
5410 tpl_addVar(vars, TPLADD, "CLIENTLOGINSECS", "");
5413 else
5415 tpl_printf(vars, TPLADD, "CLIENTLOGINDATEFMT", "%02d.%02d.%02d %02d:%02d:%02d", lt.tm_mday, lt.tm_mon + 1, lt.tm_year % 100, lt.tm_hour, lt.tm_min, lt.tm_sec);
5416 char tbuffer [30];
5417 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &lt);
5418 tpl_addVar(vars, TPLADD, "CLIENTLOGINDATE", tbuffer);
5419 tpl_printf(vars, TPLADD, "CLIENTLOGINSECS", "%d", lsec);
5422 //load historical values from ringbuffer
5423 char *value = get_ecm_historystring(cl);
5424 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIMEHIST", value);
5425 free_mk_t(value);
5427 if((isec < cfg.hideclient_to || cfg.hideclient_to == 0 || is_dvbapi_usr(cl->account->usr)) && (cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r'))
5429 if(((cl->typ == 'c')) && (cl->lastreader[0]))
5431 tpl_printf(vars, TPLADD, "MSVALUE", PRINTF_LOCAL_D, cl->cwlastresptime);
5432 if(apicall)
5434 tpl_addVar(vars, TPLADD, "LASTREADER", (cl->last_caid == NO_CAID_VALUE || isec > cfg.hideclient_to ) ? "" : cl->lastreader);
5435 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, cl->lastreader));
5437 else
5439 #ifdef WITH_LB
5440 tpl_addVar(vars, TPLADD, "LBLVALUE", xml_encode(vars, cl->lastreader));
5441 if(strstr(cl->lastreader, " (cache)"))
5443 char lastreader_tmp[strlen(cl->lastreader) - 8];
5444 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", tpl_getVar(vars, "LBLRPSTRVALUE"));
5445 cs_strncpy(lastreader_tmp, cl->lastreader, sizeof(lastreader_tmp));
5446 tpl_addVar(vars, TPLADD, "LBLVALUEENC", urlencode(vars, lastreader_tmp));
5447 tpl_addVar(vars, TPLADD, "LBLVALUETITLE", xml_encode(vars, lastreader_tmp));
5449 else
5451 tpl_addVar(vars, TPLADD, "LBLVALUEENC", urlencode(vars, cl->lastreader));
5452 tpl_addVar(vars, TPLADD, "LBLVALUETITLE", xml_encode(vars, cl->lastreader));
5454 tpl_addVar(vars, TPLAPPEND, "CLIENTLBVALUE", tpl_getTpl(vars, "CLIENTLBLVALUEBIT"));
5455 #else
5456 tpl_printf(vars, TPLAPPEND, "CLIENTLBVALUE", "%s (%'d ms)", xml_encode(vars, cl->lastreader), cl->cwlastresptime);
5457 #endif
5459 if(cl->last_caid == NO_CAID_VALUE || isec > cfg.hideclient_to) tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", "");
5461 if(cl->last_caid != NO_CAID_VALUE || cl->last_srvid != NO_SRVID_VALUE)
5463 char channame[CS_SERVICENAME_SIZE];
5464 const char *lastprovidername;
5466 get_servicename_or_null(cl, cl->last_srvid, cl->last_provid, cl->last_caid, channame, sizeof(channame));
5467 if(channame[0] == '\0')
5469 cs_strncpy(channame, "unknown", sizeof(channame));
5472 lastprovidername = get_cl_lastprovidername(cl);
5474 tpl_printf(vars, TPLADD, "CLIENTCAID", "%04X", cl->last_caid);
5475 tpl_printf(vars, TPLADD, "CLIENTPROVID", "%06X", cl->last_provid);
5476 tpl_printf(vars, TPLADD, "CLIENTSRVID", "%04X", cl->last_srvid);
5477 tpl_printf(vars, TPLADD, "CLIENTSRVPROVIDER", "%s%s%s", (lastprovidername[0] != '\0' && strcmp(lastprovidername, " ")) ? " [" : "", xml_encode(vars, lastprovidername), (lastprovidername[0] != '\0' && strcmp(lastprovidername, " ")) ? "]" : "");
5478 tpl_addVar(vars, TPLADD, "CLIENTSRVNAME", xml_encode(vars, channame));
5479 tpl_printf(vars, TPLADD, "CLIENTLASTRESPONSETIME", "%d", cl->cwlastresptime ? cl->cwlastresptime : 1);
5480 tpl_addVar(vars, TPLADD, "CLIENTSRVTYPE", cl->last_srvidptr && cl->last_srvidptr->type ? xml_encode(vars, cl->last_srvidptr->type) : "");
5481 tpl_addVar(vars, TPLADD, "CLIENTSRVDESCRIPTION", cl->last_srvidptr && cl->last_srvidptr->desc ? xml_encode(vars, cl->last_srvidptr->desc) : "");
5482 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", sec2timeformat(vars, chsec));
5483 if(cfg.http_showpicons && cl->last_srvid)
5485 char picon_channame[30];
5486 int8_t picon_ok = 0;
5488 get_picon_servicename_or_null(cl, cl->last_srvid, cl->last_provid, cl->last_caid, picon_channame, sizeof(picon_channame));
5489 if(picon_channame[0])
5491 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", picon_channame);
5492 picon_ok = picon_exists(picon_name);
5493 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
5495 if(!picon_ok && picon_servicename_remve_hd(picon_channame, sizeof(picon_channame)))
5497 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", picon_channame);
5498 picon_ok = picon_exists(picon_name);
5499 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
5502 if(!picon_ok)
5504 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%04X_%06X_%04X", cl->last_caid, cl->last_provid, cl->last_srvid);
5505 tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
5506 picon_ok = picon_exists(picon_name);
5508 if(!picon_ok)
5510 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%04X_%04X", cl->last_caid, cl->last_srvid);
5511 picon_ok = picon_exists(picon_name);
5512 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
5514 if(!picon_ok)
5516 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "0000_%04X", cl->last_srvid);
5517 picon_ok = picon_exists(picon_name);
5518 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
5520 if(picon_ok)
5522 tpl_addVar(vars, TPLADDONCE, "CURRENTPICON", tpl_getTpl(vars, "CLIENTCURRENTCHANNELPIC"));
5524 else
5526 tpl_addVar(vars, TPLADDONCE, "CURRENTPICON", tpl_getTpl(vars, "CLIENTCURRENTCHANNEL"));
5527 tpl_addVar(vars, TPLADD, "PICONNAME", "");
5530 else
5532 tpl_addVar(vars, TPLADDONCE, "CURRENTPICON", tpl_getTpl(vars, "CLIENTCURRENTCHANNELBIT"));
5533 tpl_addVar(vars, TPLADD, "PICONNAME", "0000_0000");
5536 else
5538 tpl_addVar(vars, TPLADD, "CLIENTCAID", "0000");
5539 tpl_addVar(vars, TPLADD, "CLIENTPROVID", "000000");
5540 tpl_printf(vars, TPLADD, "CLIENTSRVID", "0000");
5543 else
5545 tpl_addVar(vars, TPLADD, "CLIENTCAID", "0000");
5546 tpl_addVar(vars, TPLADD, "CLIENTPROVID", "000000");
5547 tpl_addVar(vars, TPLADD, "CLIENTSRVID", "0000");
5548 tpl_addVar(vars, TPLADD, "CURRENTPICON", "");
5549 tpl_addVar(vars, TPLADD, "CLIENTSRVPROVIDER", "");
5550 tpl_addVar(vars, TPLADD, "CLIENTSRVNAME", "");
5551 tpl_addVar(vars, TPLADD, "CLIENTSRVTYPE", "");
5552 tpl_addVar(vars, TPLADD, "CLIENTSRVDESCRIPTION", "");
5553 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", "");
5554 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", "");
5557 if(!apicall)
5559 tpl_addVar(vars, TPLADD, "CLIENTIDLESECS", sec2timeformat(vars, isec));
5561 if((cl->typ != 'p' && cl->typ != 'r') || cl->reader->card_status == CARD_INSERTED)
5562 { tpl_addVar(vars, TPLADD, "CLIENTIDLESECSCLASS", "idlesec_normal"); }
5563 else
5564 { tpl_addVar(vars, TPLADD, "CLIENTIDLESECSCLASS", "idlesec_alert"); }
5566 else
5568 tpl_printf(vars, TPLADD, "CLIENTIDLESECS", "%d", isec);
5571 if(con == 2) { tpl_addVar(vars, TPLADD, "CLIENTCON", "Duplicate"); }
5572 else if(con == 1) { tpl_addVar(vars, TPLADD, "CLIENTCON", "Sleep"); }
5573 else
5575 struct s_reader *rdr = cl->reader;
5576 char *txt = "OK";
5577 if(!rdr && (cl->typ == 'r' || cl->typ == 'p')) { txt = "UNKNOWN"; }
5579 else if(cl->typ == 'r' || cl->typ == 'p') //reader or proxy
5581 #ifdef WITH_LB
5582 if(rdr->lbvalue)
5584 tpl_printf(vars, TPLADD, "LBLRPSTRVALUE", "%d", rdr->lbvalue);
5586 else
5588 tpl_addVar(vars, TPLADD, "LBLRPSTRVALUE", "no data");
5590 tpl_addVar(vars, TPLADD, "LBLRPVALUE", rdr->label);
5591 tpl_addVar(vars, TPLADD, "LBLRPVALUEENC", urlencode(vars, rdr->label));
5592 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", tpl_getTpl(vars, "CLIENTLBLVALUERP"));
5593 #else
5594 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", tpl_getVar(vars, "LBLRPSTRVALUE"));
5595 #endif
5596 switch(rdr->card_status)
5598 case NO_CARD:
5599 if(rdr->typ == R_GBOX)
5600 { txt = "ONL"; }
5601 else
5602 { txt = "OFF"; }
5603 break;
5604 case UNKNOWN:
5605 txt = "UNKNOWN";
5606 break;
5607 case READER_DEVICE_ERROR:
5608 txt = "READER DEVICE ERROR";
5609 break;
5610 case CARD_NEED_INIT:
5611 if(rdr->typ == R_GBOX)
5612 { txt = "OFFLINE"; }
5613 #ifdef CS_CACHEEX
5614 else if (cl->reader->cacheex.mode > 0)
5615 { txt = "CCcam CacheEX"; }
5616 #endif
5617 else
5618 { txt = "NEEDINIT"; }
5619 break;
5620 case CARD_INSERTED:
5621 if(cl->typ == 'p')
5623 if(rdr->typ == R_GBOX)
5624 { txt = "ONL"; }
5625 else
5626 { txt = "CONNECTED"; }
5628 else
5629 { txt = "CARDOK"; }
5630 break;
5631 case CARD_FAILURE:
5632 txt = "ERROR";
5633 break;
5634 default:
5635 txt = "UNDEF";
5637 #ifdef MODULE_GBOX
5638 if(rdr->typ == R_GBOX)
5640 struct gbox_peer *peer = cl->gbox;
5641 char gbx_txt[44];
5642 memset(gbx_txt, 0, sizeof(gbx_txt));
5643 if(!strcmp(txt, "OFFLINE"))
5645 snprintf(gbx_txt, sizeof(gbx_txt), "%s | ID: %04X", txt, peer->gbox.id);
5647 else
5649 snprintf(gbx_txt, sizeof(gbx_txt), "%s | crd: %d | ID: %04X", txt, gbox_count_peer_cards(peer->gbox.id), peer->gbox.id);
5651 txt = gbx_txt;
5653 #endif
5656 tpl_addVar(vars, TPLADD, "CLIENTCON", txt);
5658 if(rdr && (cl->typ == 'r')) //reader
5660 if(rdr->ll_entitlements)
5662 LL_ITER itr = ll_iter_create(rdr->ll_entitlements);
5663 S_ENTITLEMENT *ent;
5664 uint16_t total_ent = 0;
5665 uint16_t active_ent = 0;
5666 struct tm end_t;
5667 tpl_addVar(vars, TPLADD, "TMPSPAN", "<SPAN>");
5668 while((ent = ll_iter_next(&itr)))
5670 total_ent++;
5671 if((ent->end > now) && (ent->type != 7))
5673 if(active_ent) {tpl_addVar(vars, TPLAPPEND, "TMPSPAN", "<BR><BR>");}
5674 active_ent++;
5675 localtime_r(&ent->end, &end_t);
5676 tpl_printf(vars, TPLAPPEND, "TMPSPAN", "%04X@%06X<BR>exp:%04d/%02d/%02d",
5677 ent->caid, ent->provid,
5678 end_t.tm_year + 1900, end_t.tm_mon + 1, end_t.tm_mday);
5679 tpl_printf(vars, TPLAPPEND, "ENTITLEMENTS", "%s{\"caid\":\"%04X\",\"provid\":\"%06X\",\"exp\":\"%04d/%02d/%02d\"}",
5680 active_ent > 1 ? ",": "",
5681 ent->caid, ent->provid,
5682 end_t.tm_year + 1900, end_t.tm_mon + 1, end_t.tm_mday);
5685 tpl_printf(vars, TPLADD, "TOTENTITLEMENTS", "%d", total_ent);
5686 if(((total_ent) && (active_ent == 0)) || (total_ent == 0))
5688 tpl_addVar(vars, TPLAPPEND, "TMPSPAN", "No active entitlements found");
5690 tpl_addVar(vars, TPLAPPEND, "TMPSPAN", "</SPAN>");
5691 if(active_ent)
5693 tpl_printf(vars, TPLADD, "TMP", "(%d entitlement%s)", active_ent, (active_ent != 1) ? "s" : "");
5695 else
5697 tpl_addVar(vars, TPLADD, "TMP", "(no entitlements)");
5699 tpl_addVar(vars, TPLADD, "ENTLABEL", urlencode(vars, cl->reader->label));
5700 tpl_addVar(vars, TPLADD, "ENTVALUE", active_ent > 0 ? "" : "1");
5701 if (!apicall) tpl_addVar(vars, TPLAPPEND, "CLIENTCON", tpl_getTpl(vars, "FOUNDENTITLEMENTS"));
5703 else
5705 tpl_addVar(vars, TPLADD, "ENTLABEL", urlencode(vars, cl->reader->label));
5706 if (!apicall) tpl_addVar(vars, TPLAPPEND, "CLIENTCON", tpl_getTpl(vars, "NOENTITLEMENTS"));
5709 #ifdef MODULE_CCCAM
5710 if(!apicall || apicall == 2)
5712 if(rdr && (cl->typ == 'r' || cl->typ == 'p') && strncmp(proto, "cccam", 5) == 0 && rdr->tcp_connected && rdr->card_status != CARD_FAILURE)
5714 struct cc_data *rcc = cl->cc;
5715 if(rcc)
5717 LLIST *cards = rcc->cards;
5718 if(cards)
5720 int32_t cnt = ll_count(cards);
5721 int32_t locals = rcc->num_hop1;
5722 if(!apicall)
5724 tpl_printf(vars, TPLADD, "TMP", "(%d of %d card%s)", locals, cnt, (cnt > 1) ? "s" : "");
5725 tpl_printf(vars, TPLADD, "CCCOUNT", "%d", cnt);
5726 tpl_printf(vars, TPLADD, "CCCHOP1", "%d", rcc->num_hop1);
5727 tpl_printf(vars, TPLADD, "CCCHOP2", "%d", rcc->num_hop2);
5728 tpl_printf(vars, TPLADD, "CCCHOPX", "%d", rcc->num_hopx);
5729 tpl_printf(vars, TPLADD, "CCCCURR", "%d", cl->reader->currenthops);
5730 tpl_printf(vars, TPLADD, "CCCRES0", "%d", rcc->num_reshare0);
5731 tpl_printf(vars, TPLADD, "CCCRES1", "%d", rcc->num_reshare1);
5732 tpl_printf(vars, TPLADD, "CCCRES2", "%d", rcc->num_reshare2);
5733 tpl_printf(vars, TPLADD, "CCCRESX", "%d", rcc->num_resharex);
5734 tpl_addVar(vars, TPLADD, "TMPSPAN", tpl_getTpl(vars, "CCENTITLEMENTS"));
5735 tpl_addVar(vars, TPLADD, "CCCLABEL", urlencode(vars, cl->reader->label));
5736 tpl_addVar(vars, TPLADD, "CCCRESHARE", rcc->num_reshare0 > 0 ? "1" : "");
5737 tpl_addVar(vars, TPLADD, "CCCTMP", tpl_getVar(vars, "TMP"));
5738 tpl_addVar(vars, TPLADD, "CCCTMPSPAN", tpl_getVar(vars, "TMPSPAN"));
5739 tpl_addVar(vars, TPLAPPEND, "CLIENTCON", tpl_getTpl(vars, "CCENTITLETOOLTIP"));
5741 if (apicall == 2)
5743 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, cl->reader->label));
5744 tpl_printf(vars, TPLADD, "ENTITLEMENTS", "{\"locals\":\"%d\",\"cccount\":\"%d\",\"ccchop1\":\"%d\",\"ccchop2\":\"%d\",\"ccchopx\":\"%d\",\"ccccurr\":\"%d\",\"cccres0\":\"%d\",\"cccres1\":\"%d\",\"cccres2\":\"%d\",\"cccresx\":\"%d\",\"cccreshare\":\"%s\"}",
5745 locals, cnt, rcc->num_hop1, rcc->num_hop2, rcc->num_hopx, cl->reader->currenthops,
5746 rcc->num_reshare0, rcc->num_reshare1, rcc->num_reshare2, rcc->num_resharex,
5747 rcc->num_reshare0 > 0 ? "1" : "");
5749 cs_log_dbg(D_TRACE, "Reader %s has total %d local%s hop1 %d hopx %d from total of %d card%s", cl->reader->label, locals, (locals > 1) ? "s" : "", rcc->num_hop2, rcc->num_hopx, cnt, (cnt > 1) ? "s" : "");
5754 #endif
5758 if(!apicall)
5760 // select right suborder
5761 if(cl->typ == 'c')
5763 if(shown) { tpl_addVar(vars, TPLAPPEND, "CLIENTSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT")); }
5764 if(cfg.http_hide_idle_clients != 1 && cfg.hideclient_to > 0)
5766 tpl_printf(vars, TPLADD, "UCAC", "%d", user_count_active);
5767 tpl_printf(vars, TPLADD, "CFGH", "%d", cfg.hideclient_to);
5768 tpl_addVar(vars, TPLADD, "CHEADADD", tpl_getTpl(vars, "CLIENTHEADLINEADD"));
5771 tpl_printf(vars, TPLADD, "UCS", "%d", user_count_shown);
5772 tpl_printf(vars, TPLADD, "UCA", "%d", user_count_all);
5773 tpl_addVar(vars, TPLADD, "HIDEIDLE", "5");
5774 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "User");
5775 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTHEADLINE"));
5776 tpl_addVar(vars, TPLADD, "CLIENTOPTIONADD", tpl_getTpl(vars, "CLIENTHEADLINEBIT"));
5777 tpl_addVar(vars, TPLADD, "CLIENTHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
5778 tpl_addVar(vars, TPLADD, "CLIENTOPTIONADD", "");
5780 else if(cl->typ == 'r')
5782 if(shown)
5784 tpl_addVar(vars, TPLAPPEND, "READERSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT"));
5787 tpl_printf(vars, TPLADD, "RCC", "%d", reader_count_conn);
5788 tpl_printf(vars, TPLADD, "RCA", "%d", reader_count_all);
5790 if(reader_count_off)
5792 tpl_printf(vars, TPLADD, "RCO", "%d", reader_count_all-reader_count_off);
5793 tpl_addVar(vars, TPLADD, "RHEADADD", tpl_getTpl(vars, "CLIENTRHEADLINEADD"));
5796 tpl_addVar(vars, TPLADD, "HIDEIDLE", "3");
5797 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "Reader");
5798 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTRHEADLINE"));
5799 tpl_addVar(vars, TPLADD, "READERHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
5801 else if(cl->typ == 'p')
5803 if(shown)
5805 tpl_addVar(vars, TPLAPPEND, "PROXYSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT"));
5808 tpl_printf(vars, TPLADD, "PCC", "%d", proxy_count_conn);
5809 tpl_printf(vars, TPLADD, "PCA", "%d", proxy_count_all);
5811 if(proxy_count_off)
5813 tpl_printf(vars, TPLADD, "PCO", "%d", proxy_count_all-proxy_count_off);
5814 tpl_addVar(vars, TPLADD, "PHEADADD", tpl_getTpl(vars, "CLIENTPHEADLINEADD"));
5817 tpl_addVar(vars, TPLADD, "HIDEIDLE", "4");
5818 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "Proxy");
5819 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTPHEADLINE"));
5820 tpl_addVar(vars, TPLADD, "PROXYHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
5822 else if(cl->typ == 'm' || cl->typ == 's' || cl->typ == 'h')
5824 if(shown)
5826 tpl_addVar(vars, TPLAPPEND, "SERVERSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT"));
5829 tpl_addVar(vars, TPLADD, "HIDEIDLE", "2");
5830 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "Server");
5832 if(cl->typ == 's' || cl->typ == 'h')
5834 tpl_printf(vars, TPLADD, "SCS", "%d", server_count_shown);
5835 tpl_printf(vars, TPLADD, "SCA", "%d", server_count_all);
5836 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTSHEADLINE"));
5838 if(shown || cl->wihidden)
5840 tpl_addVar(vars, TPLADD, "SERVERHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
5841 usr = username(cl);
5844 else
5846 tpl_addVar(vars, TPLADD, "SHOWHIDDENADD", " & Monitors");
5847 tpl_printf(vars, TPLADD, "MCS", "%d", monitor_count_shown);
5848 tpl_printf(vars, TPLADD, "MCA", "%d", monitor_count_all);
5849 tpl_addVar(vars, TPLADD, "MHEADADD", tpl_getTpl(vars, "CLIENTMHEADLINE"));
5850 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTSHEADLINE"));
5851 tpl_addVar(vars, TPLADD, "SERVERHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
5852 tpl_addVar(vars, TPLADD, "SHOWHIDDENADD", "");
5856 else
5858 if(shown)
5860 if(apicall == 1)
5862 tpl_addVar(vars, TPLAPPEND, "APISTATUSBITS", tpl_getTpl(vars, "APISTATUSBIT"));
5865 if(apicall == 2)
5867 tpl_addVar(vars, TPLADD, "JSONARRAYDELIMITER", delimiter?",":"");
5868 tpl_addVar(vars, TPLAPPEND, "JSONSTATUSBITS", tpl_getTpl(vars, "JSONSTATUSBIT"));
5869 delimiter++;
5874 #ifdef CS_CACHEEX
5876 #endif
5880 LL_ITER itr = ll_iter_create(configured_readers);
5881 struct s_reader *rdrr;
5882 while((rdrr = ll_iter_next(&itr)))
5884 if(rdrr->label[0] && rdrr->typ)
5886 total_readers += 1;
5888 if(rdrr->enable) { active_readers += 1; }
5889 else { disabled_readers += 1; }
5891 if(rdrr->tcp_connected) { connected_readers += 1; }
5895 cs_readunlock(__func__, &clientlist_lock);
5896 cs_readunlock(__func__, &readerlist_lock);
5898 uint8_t is_touch = 0;
5899 if(config_enabled(TOUCH) && streq(tpl_getVar(vars, "SUBDIR"), TOUCH_SUBDIR))
5900 {is_touch=1;}
5902 if(cfg.http_status_log || (apicall == 1 && strcmp(getParam(params, "appendlog"), "1") == 0) || is_touch)
5904 if(cfg.loghistorylines && log_history)
5906 LL_ITER it = ll_iter_create(log_history);
5907 struct s_log_history *hist;
5909 while((hist = (struct s_log_history*)ll_iter_next(&it)))
5911 char p_usr[32];
5912 size_t pos1 = strcspn(hist->txt, "\t") + 1;
5913 cs_strncpy(p_usr, hist->txt , pos1 > sizeof(p_usr) ? sizeof(p_usr) : pos1);
5915 char *p_txt = hist->txt + pos1;
5917 if(!apicall)
5919 if(p_txt[0]) tpl_printf(vars, TPLAPPEND, "LOGHISTORY","\t\t<SPAN CLASS=\"%s\">%s\t\t</SPAN><BR>\n", xml_encode(vars, p_usr), xml_encode(vars, p_txt));
5921 else
5923 tpl_addVar(vars, TPLAPPEND, "LOGHISTORY", p_txt);
5927 else
5929 tpl_addVar(vars, TPLADD, "LOGHISTORY", "loghistorylines is set to 0 in your configuration");
5933 #ifdef CS_CACHEEX
5934 char *getting = "<IMG SRC=\"image?i=ICARRL\" ALT=\"Getting\">";
5935 char *pushing = "<IMG SRC=\"image?i=ICARRR\" ALT=\"Pushing\">";
5937 float cachesum = first_client ? first_client->cwcacheexgot : 1;
5938 if(cachesum < 1)
5940 cachesum = 1;
5942 tpl_printf(vars, TPLADD, "TOTAL_CACHEXPUSH", "%d", first_client ? first_client->cwcacheexpush : 0);
5943 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXPUSH_IMG", pushing);
5944 tpl_printf(vars, TPLADD, "TOTAL_CACHEXGOT", "%d", first_client ? first_client->cwcacheexgot : 0);
5945 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXGOT_IMG", getting);
5946 tpl_printf(vars, TPLADD, "TOTAL_CACHEXHIT", "%d", first_client ? first_client->cwcacheexhit : 0);
5947 tpl_printf(vars, TPLADD, "TOTAL_CACHESIZE", "%d", cache_size());
5948 tpl_printf(vars, TPLADD, "REL_CACHEXHIT", "%.2f", (first_client ? first_client->cwcacheexhit : 0) * 100 / cachesum);
5949 tpl_addVar(vars, TPLADD, "CACHEEXSTATS", tpl_getTpl(vars, "STATUSCACHEX"));
5950 #endif
5951 //User info
5952 struct s_auth *account;
5953 int32_t total_users = 0;
5954 int32_t disabled_users = 0;
5955 int32_t expired_users = 0;
5956 int32_t expired_or_disabled_users = 0;
5957 int32_t connected_users = 0;
5958 int32_t online_users = 0;
5960 for(account = cfg.account; (account); account = account->next)
5962 total_users++;
5963 if(account->expirationdate && account->expirationdate < now)
5965 expired_users++;
5967 if(account->disabled != 0)
5969 disabled_users++;
5971 if((account->expirationdate && account->expirationdate < now)||account->disabled != 0)
5973 expired_or_disabled_users++;
5975 int32_t latestactivity = 0;
5976 struct s_client *latestclient = NULL;
5977 for(cl = first_client->next; cl ; cl = cl->next)
5979 if(cl->account && !strcmp(cl->account->usr, account->usr))
5981 if(cl->lastecm > latestactivity || cl->login > latestactivity)
5983 if(cl->lastecm > cl->login) { latestactivity = cl->lastecm; }
5984 else { latestactivity = cl->login; }
5985 latestclient = cl;
5990 if(latestclient != NULL)
5992 connected_users++;
5994 if(latestactivity > 0)
5996 if((now - latestactivity) < cfg.hideclient_to)
5998 if(latestclient->cwfound + latestclient->cwnot + latestclient->cwcache > 0)
6000 online_users++;
6006 tpl_printf(vars, TPLADD, "TOTAL_USERS", "%d", total_users);
6007 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE", "%d", total_users - expired_or_disabled_users);
6008 tpl_printf(vars, TPLADD, "TOTAL_EXPIRED", "%d", expired_users);
6009 tpl_printf(vars, TPLADD, "TOTAL_DISABLED", "%d", disabled_users);
6010 tpl_printf(vars, TPLADD, "TOTAL_ONLINE", "%d", online_users);
6011 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED", "%d", connected_users);
6013 tpl_printf(vars, TPLADD, "TOTAL_READERS", "%d", total_readers);
6014 tpl_printf(vars, TPLADD, "TOTAL_DISABLED_READERS", "%d", disabled_readers);
6015 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE_READERS", "%d", active_readers);
6016 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED_READERS", "%d", connected_readers);
6018 //CM info
6019 set_ecm_info(vars);
6021 //copy struct to p_stat_old for cpu_usage calculation
6022 p_stat_old = p_stat_cur;
6025 * check_available Bit mapping
6026 * mem 0 total, 1 used & free, 2 buff, cached & free incl. buff, 3 share
6027 * swap 4 total, 5 used & free,
6028 * proc 6 count
6029 * cpu 7 load
6030 * oscam 8 vsize & rssize, 9 cpu user, 10 cpu sys, 11 cpu sum, 12 cpu refreshtime
6031 * unused 13 - 15
6033 //Memory-CPU Info for linux based systems
6034 #if defined(__linux__)
6035 //get actual stats
6036 if(!get_stats_linux(getpid(),&p_stat_cur)){
6037 if(p_stat_old.cpu_total_time != 0){
6038 calc_cpu_usage_pct(&p_stat_cur, &p_stat_old);
6041 else{
6042 //something went wrong, so fill with "N/A"
6043 p_stat_cur.check_available = 65535;
6045 #else // if not linux, fill with "N/A" but probably in future gets filled also for other platforms
6046 p_stat_cur.check_available = 65535;
6047 #endif
6048 set_status_info(vars, p_stat_cur);
6050 if(cfg.http_showmeminfo || cfg.http_showuserinfo || cfg.http_showreaderinfo || cfg.http_showloadinfo || cfg.http_showecminfo || (cfg.http_showcacheexinfo && config_enabled(CS_CACHEEX))){
6051 tpl_addVar(vars, TPLADD, "DISPLAYINFO", "visible");
6053 else{
6054 tpl_addVar(vars, TPLADD, "DISPLAYINFO", "hidden");
6057 tpl_addVar(vars, TPLADD, "DISPLAYSYSINFO", cfg.http_showmeminfo ? "visible" : "hidden");
6058 tpl_addVar(vars, TPLADD, "DISPLAYUSERINFO", cfg.http_showuserinfo ? "visible" : "hidden");
6059 tpl_addVar(vars, TPLADD, "DISPLAYREADERINFO", cfg.http_showreaderinfo ? "visible" : "hidden");
6060 tpl_addVar(vars, TPLADD, "DISPLAYLOADINFO", cfg.http_showloadinfo ?"visible" : "hidden");
6061 tpl_addVar(vars, TPLADD, "DISPLAYECMINFO", cfg.http_showecminfo ? "visible" : "hidden");
6062 tpl_addVar(vars, TPLADD, "DISPLAYECMINFO_READERS", cfg.http_showecminfo ? "visible" : "hidden");
6064 if(cfg.http_showcacheexinfo == 1 && config_enabled(CS_CACHEEX)){
6065 tpl_addVar(vars, TPLADD, "DISPLAYCACHEEXINFO", "visible");
6067 else{
6068 tpl_addVar(vars, TPLADD, "DISPLAYCACHEEXINFO", "hidden");
6071 #ifdef WITH_DEBUG
6072 if(cfg.http_status_log || is_touch)
6074 // Debuglevel Selector
6075 int32_t lvl;
6076 for(i = 0; i < MAX_DEBUG_LEVELS; i++)
6078 lvl = 1 << i;
6079 tpl_printf(vars, TPLADD, "TMPC", "DCLASS%d", lvl);
6080 tpl_printf(vars, TPLADD, "TMPV", "DEBUGVAL%d", lvl);
6081 if(cs_dblevel & lvl)
6083 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugls");
6084 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel - lvl);
6086 else
6088 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugl");
6089 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel + lvl);
6093 if(cs_dblevel == D_ALL_DUMP)
6094 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugls"); }
6095 else
6096 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugl"); }
6098 tpl_addVar(vars, TPLADD, "NEXTPAGE", "status.html");
6099 tpl_addVar(vars, TPLADD, "DCLASS", "debugl"); //default
6100 tpl_printf(vars, TPLADD, "ACTDEBUG", "%d", cs_dblevel);
6101 tpl_addVar(vars, TPLADD, "SDEBUG", tpl_getTpl(vars, "DEBUGSELECT"));
6103 #endif
6105 if(cfg.http_status_log || is_touch)
6106 tpl_addVar(vars, TPLADDONCE, "LOG_HISTORY", tpl_getTpl(vars, "LOGHISTORYBIT"));
6108 if(apicall)
6110 if(apicall == 1)
6111 { return tpl_getTpl(vars, "APISTATUS"); }
6112 if(apicall == 2)
6114 tpl_printf(vars, TPLADD, "UCS", "%d", user_count_shown);
6115 tpl_printf(vars, TPLADD, "UCA", "%d", user_count_all);
6116 if(cfg.http_hide_idle_clients != 1 && cfg.hideclient_to > 0){
6117 tpl_printf(vars, TPLADD, "UCAC", "%d", user_count_active);
6119 tpl_printf(vars, TPLADD, "CFGH", "%d", cfg.hideclient_to);
6120 tpl_printf(vars, TPLADD, "MCS", "%d", monitor_count_shown);
6121 tpl_printf(vars, TPLADD, "MCA", "%d", monitor_count_all);
6122 tpl_printf(vars, TPLADD, "SCS", "%d", server_count_shown);
6123 tpl_printf(vars, TPLADD, "SCH", "%d", server_count_hidden);
6124 tpl_printf(vars, TPLADD, "SCA", "%d", server_count_all);
6125 tpl_printf(vars, TPLADD, "RCC", "%d", reader_count_conn);
6126 tpl_printf(vars, TPLADD, "RCO", "%d", reader_count_off);
6127 tpl_printf(vars, TPLADD, "RCA", "%d", reader_count_all);
6128 tpl_printf(vars, TPLADD, "PCC", "%d", proxy_count_conn);
6129 tpl_printf(vars, TPLADD, "PCO", "%d", proxy_count_off);
6130 tpl_printf(vars, TPLADD, "PCA", "%d", proxy_count_all);
6131 tpl_printf(vars, TPLADD, "PICONENABLED", "%d", cfg.http_showpicons?1:0);
6132 tpl_printf(vars, TPLADD, "SRVIDFILE", "%s", use_srvid2 ? "oscam.srvid2" : "oscam.srvid");
6133 return tpl_getTpl(vars, "JSONSTATUS");
6137 if(is_touch)
6138 { return tpl_getTpl(vars, "TOUCH_STATUS"); }
6139 else
6140 { return tpl_getTpl(vars, "STATUS"); }
6143 static char *send_oscam_services_edit(struct templatevars * vars, struct uriparams * params)
6145 struct s_sidtab *sidtab, *ptr;
6146 char label[sizeof(cfg.sidtab->label)];
6147 int32_t i;
6149 setActiveMenu(vars, MNU_SERVICES);
6151 cs_strncpy(label, strtolower(getParam(params, "service")), sizeof(label));
6152 ++cfg_sidtab_generation;
6153 for(sidtab = cfg.sidtab; sidtab != NULL && strcmp(label, sidtab->label) != 0; sidtab = sidtab->next) { ; }
6155 if(sidtab == NULL)
6157 i = 1;
6158 while(strlen(label) < 1)
6160 snprintf(label, sizeof(label) / sizeof(char) - 1, "newservice%d", i);
6161 for(sidtab = cfg.sidtab; sidtab != NULL && strcmp(label, sidtab->label) != 0; sidtab = sidtab->next) { ; }
6162 if(sidtab != NULL) { label[0] = '\0'; }
6163 ++i;
6165 if(!cs_malloc(&sidtab, sizeof(struct s_sidtab))) { return "0"; }
6167 if(cfg.sidtab == NULL) { cfg.sidtab = sidtab; }
6168 else
6170 for(ptr = cfg.sidtab; ptr != NULL && ptr->next != NULL; ptr = ptr->next) { ; }
6171 ptr->next = sidtab;
6173 cs_strncpy((char *)sidtab->label, label, sizeof(sidtab->label));
6174 ++cfg_sidtab_generation;
6175 tpl_addMsg(vars, "New service has been added");
6176 // Adding is uncritical as the new service is appended to sidtabs.ok/sidtabs.no and accounts/clients/readers have zeros there
6177 if(write_services() != 0) { tpl_addMsg(vars, "Writing services to disk failed!"); }
6180 if(strcmp(getParam(params, "action"), "Save") == 0)
6182 for(i = 0; i < (*params).paramcount; i++)
6184 if((strcmp((*params).params[i], "action")) && (strcmp((*params).params[i], "service")))
6186 chk_sidtab((*params).params[i], (*params).values[i], sidtab);
6189 ++cfg_sidtab_generation;
6190 tpl_addMsg(vars, "Services updated");
6191 // We don't need any refresh here as accounts/clients/readers sidtabs.ok/sidtabs.no are unaffected!
6192 if(write_services() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
6194 for(sidtab = cfg.sidtab; sidtab != NULL && strcmp(label, sidtab->label) != 0; sidtab = sidtab->next) { ; }
6197 tpl_addVar(vars, TPLADD, "LABEL", xml_encode(vars, sidtab->label));
6198 tpl_addVar(vars, TPLADD, "LABELENC", urlencode(vars, sidtab->label));
6200 if(sidtab)
6202 for(i = 0; i < sidtab->num_caid; i++)
6204 if(i == 0) { tpl_printf(vars, TPLADD, "CAIDS", "%04X", sidtab->caid[i]); }
6205 else { tpl_printf(vars, TPLAPPEND, "CAIDS", ",%04X", sidtab->caid[i]); }
6207 for(i = 0; i < sidtab->num_provid; i++)
6209 if(i == 0) { tpl_printf(vars, TPLADD, "PROVIDS", "%06X", sidtab->provid[i]); }
6210 else { tpl_printf(vars, TPLAPPEND, "PROVIDS", ",%06X", sidtab->provid[i]); }
6212 for(i = 0; i < sidtab->num_srvid; i++)
6214 if(i == 0) { tpl_printf(vars, TPLADD, "SRVIDS", "%04X", sidtab->srvid[i]); }
6215 else { tpl_printf(vars, TPLAPPEND, "SRVIDS", ",%04X", sidtab->srvid[i]); }
6218 return tpl_getTpl(vars, "SERVICEEDIT");
6221 static void delete_from_SIDTABBITS(SIDTABBITS * orgsidtab, int32_t position, int32_t sidtablength)
6223 if(*orgsidtab)
6225 int32_t i;
6226 SIDTABBITS newsidtab = 0;
6227 for(i = 0; i < position; ++i)
6229 if(*orgsidtab & ((SIDTABBITS)1 << i))
6230 { newsidtab |= ((SIDTABBITS)1 << i); }
6232 for(; i < sidtablength; ++i)
6234 if(*orgsidtab & ((SIDTABBITS)1 << (i + 1)))
6235 { newsidtab |= ((SIDTABBITS)1 << i); }
6237 *orgsidtab = newsidtab;
6241 static char *send_oscam_services(struct templatevars * vars, struct uriparams * params)
6243 struct s_sidtab *sidtab;
6244 char *service = getParam(params, "service");
6245 char channame[CS_SERVICENAME_SIZE];
6246 int32_t i, counter = 0;
6248 setActiveMenu(vars, MNU_SERVICES);
6250 if(strcmp(getParam(params, "action"), "delete") == 0)
6252 if(cfg.http_readonly)
6254 tpl_addMsg(vars, "Sorry, Webif is in readonly mode. No deletion will be made!");
6256 else
6258 struct s_sidtab *sidtab_prev = NULL;
6259 int32_t sidtablength = -1;
6260 int32_t position = 0;
6262 // Calculate sidtablength before deletion so that updating sidtabs is faster
6263 for(sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next)
6264 { ++sidtablength; }
6266 for(sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next)
6268 if(strcmp(sidtab->label, service) == 0)
6270 struct s_auth *account;
6271 struct s_client *cl;
6272 struct s_reader *rdr;
6274 if(!sidtab_prev)
6275 { cfg.sidtab = sidtab->next; }
6276 else
6277 { sidtab_prev->next = sidtab->next; }
6279 for(account = cfg.account; (account); account = account->next)
6281 delete_from_SIDTABBITS(&account->sidtabs.ok, position, sidtablength);
6282 delete_from_SIDTABBITS(&account->sidtabs.no, position, sidtablength);
6284 for(cl = first_client->next; cl ; cl = cl->next)
6286 if(account == cl->account)
6288 cl->sidtabs.ok = account->sidtabs.ok;
6289 cl->sidtabs.no = account->sidtabs.no;
6294 LL_ITER itr = ll_iter_create(configured_readers);
6295 while((rdr = ll_iter_next(&itr)))
6297 delete_from_SIDTABBITS(&rdr->sidtabs.ok, position, sidtablength);
6298 delete_from_SIDTABBITS(&rdr->sidtabs.no, position, sidtablength);
6299 delete_from_SIDTABBITS(&rdr->lb_sidtabs.ok, position, sidtablength);
6301 free_sidtab(sidtab);
6302 ++counter;
6303 break;
6305 sidtab_prev = sidtab;
6306 position++;
6308 if(counter > 0)
6310 ++cfg_sidtab_generation;
6311 tpl_addMsg(vars, "Service has been deleted!");
6312 if(write_services() != 0) { tpl_addMsg(vars, "Writing services to disk failed!"); }
6314 else { tpl_addMsg(vars, "Sorry but the specified service doesn't exist. No deletion will be made!"); }
6318 sidtab = cfg.sidtab;
6319 // Show List
6320 counter = 0;
6321 while(sidtab != NULL)
6323 tpl_addVar(vars, TPLADD, "SID", "");
6324 if((strcmp(getParam(params, "service"), sidtab->label) == 0) && (strcmp(getParam(params, "action"), "list") == 0))
6326 tpl_addVar(vars, TPLADD, "SIDCLASS", "sidlist");
6327 tpl_addVar(vars, TPLAPPEND, "SID", "<DIV CLASS=\"sidlistclose\"><A HREF=\"services.html\">X</A></DIV>");
6328 for(i = 0; i < sidtab->num_srvid; i++)
6330 tpl_printf(vars, TPLAPPEND, "SID", "%04X : %s<BR>", sidtab->srvid[i],
6331 xml_encode(vars, get_servicename(cur_client(), sidtab->srvid[i], sidtab->num_provid ? sidtab->provid[0] : 0,
6332 sidtab->num_caid ? sidtab->caid[0] : 0, channame, sizeof(channame))));
6335 else
6337 tpl_addVar(vars, TPLADD, "SIDCLASS", "");
6338 tpl_printf(vars, TPLADD, "SID", "<A HREF=\"services.html?service=%s&amp;action=list\">Show Services</A>", urlencode(vars, sidtab->label));
6340 tpl_addVar(vars, TPLADD, "LABELENC", urlencode(vars, sidtab->label));
6341 tpl_addVar(vars, TPLADD, "LABEL", xml_encode(vars, sidtab->label));
6342 tpl_addVar(vars, TPLADD, "SIDLIST", tpl_getTpl(vars, "SERVICECONFIGSIDBIT"));
6344 tpl_addVar(vars, TPLAPPEND, "SERVICETABS", tpl_getTpl(vars, "SERVICECONFIGLISTBIT"));
6345 sidtab = sidtab->next;
6346 counter++;
6348 if(counter >= MAX_SIDBITS)
6350 tpl_addVar(vars, TPLADD, "BTNDISABLED", "DISABLED");
6351 tpl_addMsg(vars, "Maximum Number of Services is reached");
6353 return tpl_getTpl(vars, "SERVICECONFIGLIST");
6356 static char *send_oscam_savetpls(struct templatevars * vars)
6358 if(cfg.http_tpl)
6360 tpl_printf(vars, TPLADD, "CNT", "%d", tpl_saveIncludedTpls(cfg.http_tpl));
6361 tpl_addVar(vars, TPLADD, "PATH", cfg.http_tpl);
6363 else { tpl_addVar(vars, TPLADD, "CNT", "0"); }
6364 return tpl_getTpl(vars, "SAVETEMPLATES");
6367 static char *send_oscam_shutdown(struct templatevars * vars, FILE * f, struct uriparams * params, int8_t apicall, int8_t *keepalive, char *extraheader)
6369 if(!apicall) { setActiveMenu(vars, MNU_SHUTDOWN); }
6370 if(strcmp(strtolower(getParam(params, "action")), "shutdown") == 0)
6372 *keepalive = 0;
6373 if(!apicall)
6375 char *CSS = tpl_getUnparsedTpl("CSS", 1, "");
6376 tpl_addVar(vars, TPLADD, "STYLESHEET", CSS);
6377 NULLFREE(CSS);
6378 tpl_printf(vars, TPLADD, "REFRESHTIME", "%d", SHUTDOWNREFRESH);
6379 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
6380 tpl_printf(vars, TPLADD, "SECONDS", "%d", SHUTDOWNREFRESH);
6381 char *result = tpl_getTpl(vars, "SHUTDOWN");
6382 send_headers(f, 200, "OK", extraheader, "text/html", 0, strlen(result), NULL, 0);
6383 webif_write(result, f);
6384 cs_log("Shutdown requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
6386 else
6388 tpl_addVar(vars, TPLADD, "APICONFIRMMESSAGE", "shutdown");
6389 cs_log("Shutdown requested by XMLApi from %s", cs_inet_ntoa(GET_IP()));
6391 cs_exit_oscam();
6393 if(!apicall)
6394 { return "1"; }
6395 else
6396 { return tpl_getTpl(vars, "APICONFIRMATION"); }
6399 else if(strcmp(strtolower(getParam(params, "action")), "restart") == 0)
6401 *keepalive = 0;
6402 if(!apicall)
6404 char *CSS = tpl_getUnparsedTpl("CSS", 1, "");
6405 tpl_addVar(vars, TPLADD, "STYLESHEET", CSS);
6406 NULLFREE(CSS);
6407 tpl_addVar(vars, TPLADD, "REFRESHTIME", "5");
6408 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
6409 tpl_addVar(vars, TPLADD, "SECONDS", "5");
6410 char *result = tpl_getTpl(vars, "SHUTDOWN");
6411 send_headers(f, 200, "OK", extraheader, "text/html", 0, strlen(result), NULL, 0);
6412 webif_write(result, f);
6413 cs_log("Restart requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
6415 else
6417 tpl_addVar(vars, TPLADD, "APICONFIRMMESSAGE", "restart");
6418 cs_log("Restart requested by XMLApi from %s", cs_inet_ntoa(GET_IP()));
6420 cs_restart_oscam();
6422 if(!apicall)
6423 { return "1"; }
6424 else
6425 { return tpl_getTpl(vars, "APICONFIRMATION"); }
6428 else
6430 return tpl_getTpl(vars, "PRESHUTDOWN");
6434 static char *send_oscam_script(struct templatevars * vars, struct uriparams * params)
6436 setActiveMenu(vars, MNU_SCRIPT);
6437 tpl_printf(vars, TPLADD, "SCRIPTOPTIONS", "<option value=\"\">----select script----</option>\n");
6439 if(!cfg.http_readonly && cfg.http_script)
6441 struct dirent **namelist;
6442 int count, i;
6443 count = scandir(cfg.http_script, &namelist, 0, alphasort );
6444 if( count >= 0 )
6446 for( i = 0 ; i < count; i++ )
6448 if(is_ext(namelist[i]->d_name, ".script") || is_ext(namelist[i]->d_name, ".sh"))
6450 tpl_printf(vars, TPLAPPEND, "SCRIPTOPTIONS", "<option value=\"script.html?scriptname=%s\">%s</option>\n",namelist[i]->d_name,namelist[i]->d_name);
6452 free( namelist[i] );
6454 free(namelist);
6457 char *scriptname = getParam(params, "scriptname");
6458 char *scriptparam = getParam(params, "scriptparam");
6459 char system_str[256];
6460 struct stat s;
6461 snprintf(system_str, sizeof(system_str), "%s/%s", cfg.http_script, scriptname);
6463 if(!stat(system_str,&s))
6465 if(s.st_mode & S_IFREG)
6467 if(s.st_mode & S_IXUSR)
6469 int32_t rc;
6470 FILE *fp;
6471 char buf[256];
6473 if((scriptparam != NULL) && (sizeof(scriptparam) > 0))
6475 strcat(system_str, " ");
6476 strcat(system_str, scriptparam);
6479 fp = popen(system_str,"r");
6481 while (fgets(buf, sizeof(buf), fp) != NULL)
6483 tpl_addVar(vars, TPLAPPEND, "SCRIPTRESULTOUT", buf);
6486 rc = pclose(fp)/256;
6488 tpl_printf(vars, TPLAPPEND, "CODE", "returncode: %d", rc);
6489 tpl_printf(vars, TPLADD, "SCRIPTNAME", "scriptname: %s", scriptname);
6491 else
6493 tpl_printf(vars, TPLADD, "SCRIPTRESULTOUT", "[Error]: Script \"%s\" not executable!", scriptname);
6497 else
6499 tpl_printf(vars, TPLADD, "SCRIPTRESULTOUT", "[Error]: Script \"%s\" not found!", scriptname);
6503 return tpl_getTpl(vars, "SCRIPT");
6506 static char *send_oscam_scanusb(struct templatevars * vars)
6508 setActiveMenu(vars, MNU_READERS);
6509 #if !defined(__CYGWIN__)
6510 FILE *fp;
6511 char path[1035];
6513 fp = popen("lsusb -v | egrep '^Bus|^ *iSerial|^ *iProduct'", "r");
6514 if(!fgets(path, sizeof(path) - 1, fp) || !fp)
6516 tpl_addVar(vars, TPLADD, "USBENTRY", "<b>lsusb:</b> Failed to run or not installed!");
6517 tpl_addVar(vars, TPLADD, "USBBIT", tpl_getTpl(vars, "SCANUSBBIT"));
6519 else
6522 tpl_addVar(vars, TPLADD, "USBENTRYCLASS", "");
6523 if(strstr(path, "Bus "))
6525 tpl_addVar(vars, TPLADD, "USBENTRY", path);
6526 tpl_addVar(vars, TPLADD, "USBENTRYCLASS", "CLASS=\"scanusbsubhead\"");
6528 else
6530 tpl_printf(vars, TPLADD, "USBENTRY", "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%s", path);
6532 tpl_addVar(vars, TPLAPPEND, "USBBIT", tpl_getTpl(vars, "SCANUSBBIT"));
6534 while(fgets(path, sizeof(path) - 1, fp) != NULL);
6536 pclose(fp);
6537 #else
6538 tpl_addMsg(vars, "Function not supported in CYGWIN environment");
6539 #endif
6540 return tpl_getTpl(vars, "SCANUSB");
6543 static void webif_process_logfile(struct templatevars * vars, struct uriparams * params, char *targetfile, size_t targetfile_len)
6545 snprintf(targetfile, targetfile_len, "%s", cfg.logfile);
6546 if(strcmp(getParam(params, "clear"), "logfile") == 0)
6548 if(strlen(targetfile) > 0)
6550 FILE *file = fopen(targetfile, "w");
6551 fclose(file);
6554 #ifdef WITH_DEBUG
6555 // Debuglevel Selector
6556 int32_t i, lvl;
6557 for(i = 0; i < MAX_DEBUG_LEVELS; i++)
6559 lvl = 1 << i;
6560 tpl_printf(vars, TPLADD, "TMPC", "DCLASS%d", lvl);
6561 tpl_printf(vars, TPLADD, "TMPV", "DEBUGVAL%d", lvl);
6562 if(cs_dblevel & lvl)
6564 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugls");
6565 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel - lvl);
6567 else
6569 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugl");
6570 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel + lvl);
6573 if(cs_dblevel == D_ALL_DUMP)
6574 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugls"); }
6575 else
6576 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugl"); }
6577 tpl_addVar(vars, TPLADD, "CUSTOMPARAM", "&file=logfile");
6578 tpl_printf(vars, TPLADD, "ACTDEBUG", "%d", cs_dblevel);
6579 tpl_addVar(vars, TPLADD, "SDEBUG", tpl_getTpl(vars, "DEBUGSELECT"));
6580 tpl_addVar(vars, TPLADD, "NEXTPAGE", "files.html");
6581 #endif
6582 if(!cfg.disablelog)
6584 tpl_printf(vars, TPLADD, "SWITCH", "%d", 1);
6585 tpl_addVar(vars, TPLADD, "TEXT", "Stop Log");
6586 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUDISABLELOG"));
6589 else
6591 tpl_printf(vars, TPLADD, "SWITCH", "%d", 0);
6592 tpl_addVar(vars, TPLADD, "TEXT", "Start Log");
6593 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUDISABLELOG"));
6595 tpl_addVar(vars, TPLAPPEND, "LOGMENU", tpl_getTpl(vars, "CLEARLOG"));
6596 return;
6599 static void webif_process_userfile(struct templatevars * vars, struct uriparams * params, char *targetfile, size_t targetfile_len)
6601 snprintf(targetfile, targetfile_len, "%s", cfg.usrfile);
6602 if(strcmp(getParam(params, "clear"), "usrfile") == 0)
6604 if(strlen(targetfile) > 0)
6606 FILE *file = fopen(targetfile, "w");
6607 fclose(file);
6610 if(!cfg.disableuserfile)
6612 tpl_printf(vars, TPLADD, "SWITCH", "%d", 1);
6613 tpl_addVar(vars, TPLADD, "TEXT", "Stop Log");
6614 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUONOFF"));
6616 else
6618 tpl_printf(vars, TPLADD, "SWITCH", "%d", 0);
6619 tpl_addVar(vars, TPLADD, "TEXT", "Start Log");
6620 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUONOFF"));
6622 tpl_addVar(vars, TPLAPPEND, "LOGMENU", tpl_getTpl(vars, "CLEARUSERLOG"));
6623 tpl_addVar(vars, TPLADD, "FFVAL", "all");
6624 tpl_addVar(vars, TPLADD, "FILTERFORMOPTIONS", tpl_getTpl(vars, "LOGMENUFILTERFORM"));
6625 struct s_auth *account;
6626 for(account = cfg.account; account; account = account->next)
6628 tpl_addVar(vars, TPLADD, "FFVAL", xml_encode(vars, account->usr));
6629 tpl_addVar(vars, TPLADD, "FFSEL", strcmp(getParam(params, "filter"), account->usr) ? "" : "selected");
6630 tpl_addVar(vars, TPLAPPEND, "FILTERFORMOPTIONS", tpl_getTpl(vars, "LOGMENUFILTERFORM"));
6632 tpl_addVar(vars, TPLADD, "FILTERFORM", tpl_getTpl(vars, "FILTERFORM"));
6635 enum file_types { FTYPE_CONFIG, FTYPE_VERSION, FTYPE_ANTICASC, FTYPE_LOGFILE, FTYPE_USERFILE , FTYPE_GBOX };
6637 struct files
6639 char *file;
6640 int menu_id;
6641 enum file_types type;
6644 static char *send_oscam_files(struct templatevars * vars, struct uriparams * params, int8_t apicall)
6646 bool writable = false;
6647 const struct files *entry;
6648 static struct files config_files[] =
6650 // id are used
6651 // new entry after last entry before first ifdef entry
6652 // ifdef must be add to end
6653 { "oscam.version", MNU_CFG_FVERSION, FTYPE_VERSION }, // id 0
6654 { "oscam.conf", MNU_CFG_FCONF, FTYPE_CONFIG }, // id 1
6655 { "oscam.user", MNU_CFG_FUSER, FTYPE_CONFIG }, // id 2
6656 { "oscam.server", MNU_CFG_FSERVER, FTYPE_CONFIG }, // id 3
6657 { "oscam.srvid", MNU_CFG_FSRVID, FTYPE_CONFIG }, // id 4
6658 { "oscam.srvid2", MNU_CFG_FSRVID2, FTYPE_CONFIG }, // id 5
6659 { "logfile", MNU_CFG_FLOGFILE, FTYPE_LOGFILE }, // id 6
6660 { "userfile", MNU_CFG_FUSERFILE, FTYPE_USERFILE }, // id 7
6661 { "css_file_name", MNU_CFG_FCSS, FTYPE_CONFIG }, // id 8
6662 { "oscam.services", MNU_CFG_FSERVICES, FTYPE_CONFIG }, // id 9
6663 { "oscam.provid", MNU_CFG_FPROVID, FTYPE_CONFIG }, // id 10
6664 { "oscam.tiers", MNU_CFG_FTIERS, FTYPE_CONFIG }, // id 11
6665 { "oscam.ratelimit", MNU_CFG_FRATELIMIT,FTYPE_CONFIG }, // id 12
6666 { "oscam.whitelist", MNU_CFG_FWHITELIST,FTYPE_CONFIG }, // id 13
6667 #ifdef HAVE_DVBAPI
6668 { "oscam.dvbapi", MNU_CFG_FDVBAPI, FTYPE_CONFIG }, // id 14
6669 #endif
6670 #ifdef CS_CACHEEX
6671 { "oscam.fakecws", MNU_CFG_FFAKECWS, FTYPE_CONFIG }, // id 15
6672 #endif
6673 #ifdef CS_ANTICASC
6674 { "anticasc", MNU_CFG_FACLOG, FTYPE_ANTICASC }, // id 16
6675 #endif
6676 #ifdef MODULE_SERIAL
6677 { "oscam.twin", MNU_CFG_FTWIN, FTYPE_CONFIG }, // id 17
6678 #endif
6679 #ifdef MODULE_CONSTCW
6680 { "constant.cw", MNU_CFG_FKEYCW, FTYPE_CONFIG }, // id 18
6681 #endif
6682 #ifdef MODULE_GBOX
6683 { "sc.info", MNU_GBX_FSCINF, FTYPE_GBOX }, // id 19
6684 { "share.info", MNU_GBX_FSHRINF, FTYPE_GBOX }, // id 20
6685 { "share.onl", MNU_GBX_FSHRONL, FTYPE_GBOX }, // id 21
6686 { "gbox.ver", MNU_GBX_FVERS, FTYPE_GBOX }, // id 22
6687 { "attack.txt", MNU_GBX_FATTACK, FTYPE_GBOX }, // id 23
6688 { "gsms.log", MNU_GBX_FSMSLOG, FTYPE_GBOX }, // id 24
6689 { "gsms.ack", MNU_GBX_FSMSACK, FTYPE_GBOX }, // id 25
6690 { "gsms.nack", MNU_GBX_FSMSNACK, FTYPE_GBOX }, // id 26
6691 { "stats.info", MNU_GBX_FSTAINF, FTYPE_GBOX }, // id 27
6692 { "expired.info", MNU_GBX_FEXPINF, FTYPE_GBOX }, // id 28
6693 { "info.log", MNU_GBX_INFOLOG, FTYPE_GBOX }, // id 29
6694 #endif
6695 #ifdef WITH_EMU
6696 { "SoftCam.Key", MNU_CFG_FSOFTCAMKEY,FTYPE_CONFIG }, // id 30
6697 #endif
6698 { NULL, 0, 0 },
6701 if(use_srvid2)
6703 config_files[4].menu_id = MNU_CFG_FSRVID2;
6704 config_files[5].menu_id = MNU_CFG_FSRVID;
6707 if(cfg.http_css)
6709 if(strchr(cfg.http_css,'/'))
6710 config_files[8].file = strrchr(cfg.http_css, '/')+1;
6711 else if(strchr(cfg.http_css,'\\'))
6712 config_files[8].file = strrchr(cfg.http_css, '\\')+1;
6713 else
6714 config_files[8].file = cfg.http_css;
6715 tpl_addVar(vars, TPLADD, "FILE_USER_CSS", xml_encode(vars, config_files[8].file));
6718 if(!apicall) { setActiveMenu(vars, MNU_FILES); }
6720 tpl_addVar(vars, TPLADD, "APIFILENAME", "null");
6721 tpl_addVar(vars, TPLADD, "APIWRITABLE", "0");
6723 if(use_srvid2)
6725 tpl_printf(vars, TPLADD, "SRVID", "%s", "oscam.srvid2");
6726 tpl_printf(vars, TPLADD, "SRVIDSUB", "%s", "oscam.srvid");
6728 else
6730 tpl_printf(vars, TPLADD, "SRVID", "%s", "oscam.srvid");
6731 tpl_printf(vars, TPLADD, "SRVIDSUB", "%s", "oscam.srvid2");
6734 char *stoplog = getParam(params, "stoplog");
6735 if(strlen(stoplog) > 0)
6736 { cs_disable_log(atoi(stoplog)); }
6738 char *stopusrlog = getParam(params, "stopusrlog");
6739 if(strlen(stopusrlog) > 0)
6740 { cfg.disableuserfile = atoi(stopusrlog); }
6742 char *debuglvl = getParam(params, "debug");
6743 if(strlen(debuglvl) > 0)
6745 #ifndef WITH_DEBUG
6746 cs_log("*** Warning: Debug Support not compiled in ***");
6747 #else
6748 int32_t dblvl = atoi(debuglvl);
6749 if(dblvl >= 0 && dblvl <= 65535) { cs_dblevel = dblvl; }
6750 cs_log("%s debug_level=%d", "all", cs_dblevel);
6751 #endif
6753 // Process config files
6754 char *file = getParam(params, "file");
6755 char targetfile[256] = { 0 };
6756 int menu_id = 0;
6757 for(entry = config_files; entry->file; entry++)
6759 if(streq(file, entry->file))
6761 if(!apicall) { setActiveSubMenu(vars, entry->menu_id); }
6762 menu_id = entry->menu_id;
6763 tpl_addVar(vars, TPLADD, "APIWRITABLE", writable ? "1" : "0");
6764 switch(entry->type)
6766 case FTYPE_CONFIG:
6767 writable = 1;
6768 get_config_filename(targetfile, sizeof(targetfile), entry->file);
6769 break;
6770 case FTYPE_VERSION:
6771 get_tmp_dir_filename(targetfile, sizeof(targetfile), entry->file);
6772 break;
6773 case FTYPE_ANTICASC:
6774 #ifdef CS_ANTICASC
6775 if(!apicall) { snprintf(targetfile, sizeof(targetfile), "%s", ESTR(cfg.ac_logfile)); }
6776 #endif
6777 break;
6778 case FTYPE_LOGFILE:
6779 if(!apicall) { webif_process_logfile(vars, params, targetfile, sizeof(targetfile)); }
6780 break;
6781 case FTYPE_USERFILE:
6782 if(!apicall) { webif_process_userfile(vars, params, targetfile, sizeof(targetfile)); }
6783 break;
6784 case FTYPE_GBOX:
6785 #ifdef MODULE_GBOX
6786 get_gbox_filename(targetfile, sizeof(targetfile), entry->file);
6787 #endif
6788 break;
6790 tpl_addVar(vars, TPLADD, "APIFILENAME", entry->file);
6791 break;
6795 if(cfg.http_css)
6797 tpl_addVar(vars, TPLADD, "VIEW_FILEMENUCSS", tpl_getTpl(vars, "FILEMENUCSS"));
6800 if(!strstr(targetfile, "/dev/"))
6802 if(strcmp(getParam(params, "action"), "Save") == 0)
6804 if((strlen(targetfile) > 0) /*&& (file_exists(targetfile) == 1)*/)
6806 FILE *fpsave;
6807 char *fcontent = getParam(params, "filecontent");
6808 if((fpsave = fopen(targetfile, "w")))
6810 int32_t i, lastpos = 0, len = strlen(fcontent) + 1;
6811 //write submitted file line by line to disk and remove windows linebreaks
6812 for(i = 0; i < len; ++i)
6814 char tmp = fcontent[i];
6815 if(tmp == '\r' || tmp == '\n' || tmp == 0)
6817 fcontent[i] = 0;
6818 fprintf(fpsave, "%s%s", fcontent + lastpos, tmp == 0 ? "" : "\n");
6819 if(tmp == '\r' && fcontent[i + 1] == '\n') { ++i; }
6820 lastpos = i + 1;
6823 fclose(fpsave);
6824 tpl_addVar(vars, TPLAPPEND, "APIFILENAME", " saved!");
6825 // Reinit on save
6826 switch(menu_id)
6828 case MNU_CFG_FSRVID:
6829 case MNU_CFG_FSRVID2:
6830 init_srvid();
6831 break;
6832 case MNU_CFG_FPROVID:
6833 init_provid();
6834 break;
6835 case MNU_CFG_FUSER:
6836 cs_accounts_chk();
6837 break;
6838 case MNU_CFG_FDVBAPI:
6839 dvbapi_read_priority();
6840 break;
6841 case MNU_CFG_FWHITELIST:
6842 global_whitelist_read();
6843 break;
6844 case MNU_CFG_FFAKECWS:
6845 init_fakecws();
6846 break;
6847 default:
6848 break;
6854 if((strlen(targetfile) > 0) && (file_exists(targetfile) == 1))
6856 FILE *fp;
6857 char buffer[256];
6859 if((fp = fopen(targetfile, "r")) == NULL) { return "0"; }
6860 while(fgets(buffer, sizeof(buffer), fp) != NULL)
6861 if(!strcmp(getParam(params, "filter"), "all"))
6862 { tpl_addVar(vars, TPLAPPEND, "FILECONTENT", buffer); }
6863 else if(strstr(buffer, getParam(params, "filter")))
6864 { tpl_addVar(vars, TPLAPPEND, "FILECONTENT", buffer); }
6865 fclose(fp);
6867 else
6869 tpl_addVar(vars, TPLAPPEND, "FILECONTENT", "File does not exist or no file selected!");
6872 else
6874 tpl_addVar(vars, TPLAPPEND, "FILECONTENT", "File not valid!");
6877 tpl_addVar(vars, TPLADD, "PART", file);
6879 if(!writable)
6881 tpl_addVar(vars, TPLADD, "WRITEPROTECTION", tpl_getTpl(vars, "WRITEPROTECTION"));
6882 tpl_addVar(vars, TPLADD, "BTNDISABLED", "DISABLED");
6885 if(!apicall)
6886 { return tpl_getTpl(vars, "FILE"); }
6887 else
6888 { return tpl_getTpl(vars, "APIFILE"); }
6891 static char *send_oscam_failban(struct templatevars * vars, struct uriparams * params, int8_t apicall)
6893 IN_ADDR_T ip2delete;
6894 set_null_ip(&ip2delete);
6895 LL_ITER itr = ll_iter_create(cfg.v_list);
6896 V_BAN *v_ban_entry;
6897 //int8_t apicall = 0; //remove before flight
6899 if(!apicall) { setActiveMenu(vars, MNU_FAILBAN); }
6901 if(strcmp(getParam(params, "action"), "delete") == 0)
6903 if(strcmp(getParam(params, "intip"), "all") == 0)
6905 // clear whole list
6906 while((v_ban_entry = ll_iter_next(&itr)))
6908 ll_iter_remove_data(&itr);
6911 else
6913 //we have a single IP
6914 cs_inet_addr(getParam(params, "intip"), &ip2delete);
6915 while((v_ban_entry = ll_iter_next(&itr)))
6917 if(IP_EQUAL(v_ban_entry->v_ip, ip2delete))
6919 ll_iter_remove_data(&itr);
6920 break;
6925 ll_iter_reset(&itr);
6927 struct timeb now;
6928 cs_ftime(&now);
6930 while((v_ban_entry = ll_iter_next(&itr)))
6932 tpl_printf(vars, TPLADD, "IPADDRESS", "%s@%d", cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port);
6933 tpl_addVar(vars, TPLADD, "VIOLATIONUSER", v_ban_entry->info ? v_ban_entry->info : "unknown");
6934 struct tm st ;
6935 localtime_r(&v_ban_entry->v_time.time, &st); // fix me, we need walltime!
6936 if(!apicall)
6938 tpl_printf(vars, TPLADD, "VIOLATIONDATE", "%02d.%02d.%02d %02d:%02d:%02d",
6939 st.tm_mday, st.tm_mon + 1,
6940 st.tm_year % 100, st.tm_hour,
6941 st.tm_min, st.tm_sec);
6943 else
6945 char tbuffer [30];
6946 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &st);
6947 tpl_addVar(vars, TPLADD, "VIOLATIONDATE", tbuffer);
6950 tpl_printf(vars, TPLADD, "VIOLATIONCOUNT", "%d", v_ban_entry->v_count);
6952 int64_t gone = comp_timeb(&now, &v_ban_entry->v_time);
6953 if(!apicall)
6955 if(!v_ban_entry->acosc_entry)
6956 { tpl_addVar(vars, TPLADD, "LEFTTIME", sec2timeformat(vars, (cfg.failbantime * 60) - (gone / 1000))); }
6957 else
6958 { tpl_addVar(vars, TPLADD, "LEFTTIME", sec2timeformat(vars, v_ban_entry->acosc_penalty_dur - (gone / 1000))); }
6960 else
6962 if(!v_ban_entry->acosc_entry)
6963 { tpl_printf(vars, TPLADD, "LEFTTIME", "%"PRId64"", (cfg.failbantime * 60) - (gone / 1000)); }
6964 else
6965 { tpl_printf(vars, TPLADD, "LEFTTIME", "%"PRId64"", v_ban_entry->acosc_penalty_dur - (gone / 1000)); }
6968 tpl_addVar(vars, TPLADD, "INTIP", cs_inet_ntoa(v_ban_entry->v_ip));
6970 if(!apicall)
6971 { tpl_addVar(vars, TPLAPPEND, "FAILBANROW", tpl_getTpl(vars, "FAILBANBIT")); }
6972 else
6973 { tpl_addVar(vars, TPLAPPEND, "APIFAILBANROW", tpl_getTpl(vars, "APIFAILBANBIT")); }
6975 if(!apicall)
6976 { return tpl_getTpl(vars, "FAILBAN"); }
6977 else
6978 { return tpl_getTpl(vars, "APIFAILBAN"); }
6981 static bool send_EMM(struct s_reader * rdr, uint16_t caid, const struct s_cardsystem *csystem, const uint8_t *emmhex, uint32_t len)
6983 if(NULL != rdr && NULL != emmhex && 0 != len)
6985 EMM_PACKET *emm_pack = NULL;
6987 if(cs_malloc(&emm_pack, sizeof(EMM_PACKET)))
6989 struct s_client *webif_client = cur_client();
6990 webif_client->grp = 0xFF; /* to access to all readers */
6992 memset(emm_pack, '\0', sizeof(EMM_PACKET));
6993 emm_pack->client = webif_client;
6994 emm_pack->emmlen = len;
6995 memcpy(emm_pack->emm, emmhex, len);
6997 emm_pack->caid[0] = (caid >> 8) & 0xFF;
6998 emm_pack->caid[1] = caid & 0xFF;
7000 if(csystem && csystem->get_emm_type)
7002 if(!csystem->get_emm_type(emm_pack, rdr))
7004 rdr_log_dbg(rdr, D_EMM, "get_emm_type() returns error");
7008 cs_log_dbg(D_EMM, "emm is being sent to reader %s.", rdr->label);
7009 add_job(rdr->client, ACTION_READER_EMM, emm_pack, sizeof(EMM_PACKET));
7010 return true;
7014 return false;
7017 static bool process_single_emm(struct templatevars * vars, struct s_reader * rdr, uint16_t caid, const struct s_cardsystem *csystem, const char *ep)
7020 if(NULL != vars && NULL != rdr && NULL != ep)
7022 char emmdata[1025] = {'\0'}; /*1024 + '\0'*/
7023 uint8_t emmhex[513] = {'\0'};
7024 char buff[7] = {'\0'};
7025 uint16_t len = 0;
7026 cs_strncpy(emmdata, ep, sizeof(emmdata));
7027 remove_white_chars(emmdata);
7029 if('\0' != emmdata[0])
7031 len = strlen(emmdata);
7032 tpl_addVar(vars, TPLADD, "EP", strtoupper(emmdata));
7033 if(key_atob_l(emmdata, emmhex, len))
7035 tpl_addMsg(vars, "Single EMM has not been sent due to wrong value!");
7037 else
7039 len /= 2;
7040 snprintf(buff, sizeof(buff), "0x%02X", len);
7041 tpl_addVar(vars, TPLADD, "EP", strtoupper(emmdata));
7042 tpl_addVar(vars, TPLADD, "SIZE", buff);
7044 if(send_EMM(rdr, caid, csystem, emmhex, len))
7046 tpl_addMsg(vars, "Single EMM has been sent.");
7047 return true;
7052 tpl_addVar(vars, TPLADD, "SIZE", "0x00");
7053 return false;
7056 static bool process_emm_file(struct templatevars * vars, struct s_reader * rdr, uint16_t caid, const struct s_cardsystem *csystem, const char *sFilePath)
7059 bool bret = false;
7060 uint32_t fsize = 0;
7061 uint32_t rlines = 0;
7062 uint32_t wemms = 0;
7063 uint32_t errsize = 0;
7064 char numerrl[256] = {'\0'};
7065 char buff[20] = {'\0'};
7067 if(NULL != rdr && NULL != sFilePath && '\0' != sFilePath[0])
7069 char sMessage[128] = {0};
7070 if(true == file_exists(sFilePath))
7072 FILE *fp;
7073 if((fp = fopen(sFilePath, "r")))
7075 char line[2048] = {'\0'};
7076 uint8_t emmhex[513] = {'\0'};
7077 uint32_t len = 0;
7079 tpl_addMsg(vars, "EMM file has been processed.");
7080 while(fgets(line, sizeof(line), fp))
7082 ++rlines;
7083 len = strlen(remove_white_chars(line));
7085 // wrong emm
7086 if(len > (sizeof(emmhex) * 2) ||
7087 key_atob_l(line, emmhex, len))
7089 errsize += snprintf(numerrl + errsize, sizeof(numerrl) - errsize, "%d, ", rlines);
7090 continue;
7092 len /= 2;
7093 if(send_EMM(rdr, caid, csystem, emmhex, len))
7095 ++wemms;
7096 /* Give time to process EMM, otherwise, too many jobs can be added*/
7097 cs_sleepms(1000); //TODO: use oscam signal to catch reader answer
7100 fsize = ftell(fp);
7101 fclose(fp);
7103 else
7105 snprintf(sMessage, sizeof(sMessage), "Cannot open file '%s' (errno=%d: %s)\n", sFilePath, errno, strerror(errno));
7106 tpl_addMsg(vars, sMessage);
7109 else
7111 snprintf(sMessage, sizeof(sMessage), "FILE \"%s\" not found!", sFilePath);
7112 tpl_addMsg(vars, sMessage);
7114 bret = true;
7117 snprintf(buff, sizeof(buff), "%d bytes", fsize);
7118 tpl_addVar(vars, TPLADD, "FSIZE", buff);
7119 snprintf(buff, sizeof(buff), "%d", rlines);
7120 tpl_addVar(vars, TPLADD, "NUMRLINE", buff);
7121 snprintf(buff, sizeof(buff), "%d", wemms);
7122 tpl_addVar(vars, TPLADD, "NUMWEMM", buff);
7123 tpl_addVar(vars, TPLADD, "ERRLINE", numerrl);
7125 return bret;
7128 static char *send_oscam_EMM_running(struct templatevars * vars, struct uriparams * params)
7131 struct s_reader *rdr = NULL;
7133 setActiveMenu(vars, MNU_READERS);
7134 tpl_addVar(vars, TPLADD, "READER", getParam(params, "label"));
7135 tpl_addVar(vars, TPLADD, "FNAME", getParam(params, "emmfile"));
7137 rdr = get_reader_by_label(getParam(params, "label"));
7138 if(rdr)
7140 int32_t tcaid = dyn_word_atob(getParam(params, "emmcaid"));
7141 uint16_t caid = (-1 != tcaid) ? (uint16_t)tcaid : 0;
7142 char buff[7] = "";
7143 const struct s_cardsystem *csystem = NULL;
7144 int32_t proxy = is_cascading_reader(rdr);
7146 if((proxy || !rdr->csystem_active) && caid) // network reader (R_CAMD35 R_NEWCAMD R_CS378X R_CCCAM)
7148 if(proxy && !rdr->ph.c_send_emm)
7150 tpl_addMsg(vars, "The reader does not support EMM's!");
7151 return tpl_getTpl(vars, "EMM_RUNNING");
7154 csystem = get_cardsystem_by_caid(caid);
7155 if(!csystem)
7157 rdr_log_dbg(rdr, D_EMM, "unable to find cardsystem for caid %04X", caid);
7158 caid = 0;
7161 else if(!proxy && rdr->csystem_active) // local active reader
7163 csystem = rdr->csystem;
7165 if(rdr->typ != R_EMU)
7167 caid = rdr->caid;
7171 if(csystem)
7173 tpl_addVar(vars, TPLADD, "SYSTEM", csystem->desc);
7175 else
7177 tpl_addVar(vars, TPLADD, "SYSTEM", "unknown");
7179 if(caid)
7181 snprintf(buff, sizeof(buff), "0x%04X", caid);
7182 tpl_addVar(vars, TPLADD, "CAID", buff);
7184 else
7186 tpl_addVar(vars, TPLADD, "CAID", "unknown");
7189 process_single_emm(vars, rdr, caid, csystem, getParam(params, "ep"));
7190 process_emm_file(vars, rdr, caid, csystem, getParam(params, "emmfile"));
7192 else
7194 char sMessage[128] = {0};
7195 snprintf(sMessage, sizeof(sMessage), "READER \"%s\" not found!", getParam(params, "label"));
7196 tpl_addMsg(vars, sMessage);
7197 tpl_addVar(vars, TPLADD, "READER", "reader not found");
7200 return tpl_getTpl(vars, "EMM_RUNNING");
7203 static char *send_oscam_EMM(struct templatevars * vars, struct uriparams * params)
7206 setActiveMenu(vars, MNU_READERS);
7207 tpl_addVar(vars, TPLADD, "READER", getParam(params, "label"));
7209 struct s_reader *rdr = NULL;
7210 rdr = get_reader_by_label(getParam(params, "label"));
7211 if(rdr && rdr->caid)
7213 char buff[5] = "";
7214 snprintf(buff, sizeof(buff), "%04X", rdr->caid);
7215 tpl_addVar(vars, TPLADD, "CAID", buff);
7216 if(!is_cascading_reader(rdr))
7218 tpl_addVar(vars, TPLADD, "READONLY", "readonly=\"readonly\"");
7222 FILE *fp;
7223 struct stat sb;
7224 char buffer[1024];
7225 char emm_hex[1024];
7226 char filename[128];
7227 char targetfile[256];
7228 char tmpstr[20];
7229 char emm_txt[32];
7230 char emm_title[32];
7231 char *emm_path;
7232 char *emm_types[] = { "unique_emm", "shared_emm", "global_emm" };
7233 char *emm_names[] = { "RDREMMUNIQUE", "RDREMMSHARED", "RDREMMGLOBAL" };
7234 char *emm_cfg_names[] = { "httpemmuclean", "httpemmsclean", "httpemmgclean" };
7235 int32_t emm_max_size[] = { cfg.http_emmu_clean, cfg.http_emms_clean, cfg.http_emmg_clean };
7236 int num_emm_types = 3;
7237 int i;
7239 emm_path = cfg.emmlogdir ? cfg.emmlogdir : cs_confdir;
7241 for( i = 0 ; i < num_emm_types; i++ )
7243 snprintf(filename, sizeof(filename), "%s%s%s%s", getParam(params, "label"), "_", emm_types[i], ".log");
7244 snprintf(targetfile, sizeof(targetfile), "%s%s%s", emm_path, emm_path[strlen(emm_path) - 1] == '/' ? "" : "/", filename);
7245 snprintf(emm_txt, sizeof(emm_txt), "%s_TXT", emm_names[i]);
7246 tpl_addVar(vars, TPLADD, emm_txt, filename);
7248 if((fp = fopen(targetfile, "r")) != NULL)
7250 stat(targetfile, &sb);
7251 tpl_printf(vars, TPLAPPEND, emm_txt, " (Size: %'.2f kB)", (double)sb.st_size/1024);
7253 if(emm_max_size[i]>=0)
7255 snprintf(emm_title, sizeof(emm_title), "%s_TITLE", emm_names[i]);
7256 tpl_addVar(vars, TPLADD, emm_title, "title=\"Click Line to Copy EMM in Single EMM Write Field\"");
7259 if(emm_max_size[i]>0)
7261 uint32_t emms=0, emm_d, emmrs=0;
7262 char *ptr, *saveptr1 = NULL;
7264 while(fgets(buffer, sizeof(buffer), fp) != NULL)
7266 emms++;
7267 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emms);
7268 tpl_addVar(vars, TPLADD, tmpstr, buffer);
7271 for(emm_d=emms;emm_d>0;--emm_d)
7273 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emm_d);
7274 if(sscanf(tpl_getVar(vars, tmpstr), "%*s %*s %*s %s", &emm_hex[0])==1)
7276 if(strstr(tpl_getVar(vars, "EMM_TMP"),emm_hex)==0)
7277 { tpl_addVar(vars, TPLAPPEND, "EMM_TMP", tpl_getVar(vars, tmpstr)); }
7278 tpl_addVar(vars, TPLADD, tmpstr, "");
7282 for(ptr = strtok_r(tpl_getVar(vars, "EMM_TMP"),"\n", &saveptr1); ptr; ptr = strtok_r(NULL,"\n", &saveptr1))
7284 emmrs++;
7285 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emmrs);
7286 tpl_addVar(vars, TPLADD, tmpstr, ptr);
7288 tpl_addVar(vars, TPLADD, "EMM_TMP", "");
7290 tpl_printf(vars, TPLAPPEND, emm_txt, ": %'d different EMM's from a total off %'d Entrys", emmrs,emms);
7291 for(emm_d=emmrs;emm_d>0;--emm_d)
7293 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emm_d);
7294 tpl_printf(vars, TPLAPPEND, emm_names[i], "<a class=\"tosingleemm\" href=\"#\">%s</a>\n", tpl_getVar(vars, tmpstr));
7295 if(sb.st_size>emm_max_size[i]*1024) { tpl_printf(vars, TPLAPPEND, "EMM_TMP", "%s\n", tpl_getVar(vars, tmpstr)); }
7296 tpl_addVar(vars, TPLADD, tmpstr, "");
7299 if(sb.st_size>emm_max_size[i]*1024)
7301 char orgfile[268];
7302 int f=0;
7303 do {
7304 snprintf(orgfile, sizeof(orgfile), "%s.%d", targetfile, f);
7305 f++;
7306 } while(access(orgfile, 0|F_OK) != -1);
7308 if(rename(targetfile, orgfile) == 0)
7310 FILE *fs = fopen(targetfile, "w");
7311 fprintf(fs, "%s", tpl_getVar(vars, "EMM_TMP"));
7312 fclose(fs);
7313 tpl_printf(vars, TPLAPPEND, emm_txt, "<br><b>New reduced File created!</b> Size of Original File is higher as %d kB, saved to %s", emm_max_size[i], orgfile);
7316 tpl_addVar(vars, TPLADD, "EMM_TMP", "");
7318 else if (emm_max_size[i]==0)
7320 while(fgets(buffer, sizeof(buffer), fp) != NULL)
7322 tpl_printf(vars, TPLAPPEND, emm_names[i], "<a class=\"tosingleemm\" href=\"#\">%s</a>", buffer);
7325 else
7327 tpl_printf(vars, TPLADD, emm_names[i],"Viewing of EMM File deactivated.<br>Set %s in Config Webif to 0 or higher for viewing or filtering EMM File.", emm_cfg_names[i]);
7329 fclose(fp);
7331 if(strcmp(tpl_getVar(vars, emm_names[i]),"")==0) { tpl_addVar(vars, TPLADD, emm_names[i],"no saved EMM's"); }
7334 return tpl_getTpl(vars, "ASKEMM");
7337 #ifdef CS_CACHEEX
7338 static uint64_t get_cacheex_node(struct s_client * cl)
7340 uint64_t node = 0x00;
7341 #if defined(MODULE_CCCAM) || defined(MODULE_CAMD35) || defined(MODULE_CAMD35_TCP)
7342 struct s_module *module = (cl->reader ? &cl->reader->ph : get_module(cl));
7343 #endif
7344 #ifdef MODULE_CCCAM
7345 if(module->num == R_CCCAM && cl->cc)
7347 struct cc_data *cc = cl->cc;
7348 memcpy(&node, cc->peer_node_id, 8);
7350 else
7351 #endif
7352 #ifdef MODULE_CAMD35
7353 if(module->num == R_CAMD35)
7355 memcpy(&node, cl->ncd_skey, 8);
7357 else
7358 #endif
7359 #ifdef MODULE_CAMD35_TCP
7360 if(module->num == R_CS378X)
7362 memcpy(&node, cl->ncd_skey, 8);
7364 else
7365 #endif
7367 return node;
7371 static char *send_oscam_cacheex(struct templatevars * vars, struct uriparams * params, int8_t apicall)
7374 if(!apicall) { setActiveMenu(vars, MNU_CACHEEX); }
7376 if(strcmp(getParam(params, "x"), "x") == 0)
7378 // avoid compilerwarning unused vars
7380 char *level[] = {"NONE", "CACHE PULL", "CACHE PUSH", "REVERSE CACHE PUSH"};
7381 char *getting = "<IMG SRC=\"image?i=ICARRL\" ALT=\"Getting\">";
7382 char *pushing = "<IMG SRC=\"image?i=ICARRR\" ALT=\"Pushing\">";
7383 char *rowvariable = "";
7385 int16_t i, written = 0;
7386 struct s_client *cl;
7387 time_t now = time((time_t *)0);
7388 int delimiter=0;
7390 if(!apicall)
7392 if(strcmp(getParam(params, "action"), "resetallcacheexstats") == 0)
7394 cacheex_clear_all_stats();
7398 tpl_printf(vars, TPLADD, "OWN_CACHEEX_NODEID", "%" PRIu64 "X", cacheex_node_id(cacheex_peer_id));
7400 const char *cacheex_name_link_tpl = NULL;
7401 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
7403 for(i = 0, cl = first_client; cl ; cl = cl->next, i++)
7405 if(cl->typ == 'c' && cl->account && cl->account->cacheex.mode)
7407 cacheex_name_link_tpl = "SUSER";
7408 tpl_addVar(vars, TPLADD, "TYPE", "Client");
7409 if(!apicall)
7411 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, cl->account->usr));
7412 tpl_addVar(vars, TPLADD, "USERENC", urlencode(vars, cl->account->usr));
7414 if(cl->account->description)
7416 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->account->description));
7419 else
7421 tpl_addVar(vars, TPLADD, "NAME", cl->account->usr);
7423 if(cl->account->description)
7425 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", cl->account->description);
7429 tpl_addVar(vars, TPLADD, "IP", cs_inet_ntoa(cl->ip));
7430 tpl_printf(vars, TPLADD, "NODE", "%" PRIu64 "X", get_cacheex_node(cl));
7431 tpl_addVar(vars, TPLADD, "LEVEL", level[cl->account->cacheex.mode]);
7432 tpl_printf(vars, TPLADD, "PUSH", "%d", cl->account->cwcacheexpush);
7433 tpl_printf(vars, TPLADD, "GOT", "%d", cl->account->cwcacheexgot);
7434 tpl_printf(vars, TPLADD, "CWCINFO", "%d", cl->account->cwc_info);
7435 tpl_printf(vars, TPLADD, "HIT", "%d", cl->account->cwcacheexhit);
7436 tpl_printf(vars, TPLADD, "ERR", "%d", cl->account->cwcacheexerr);
7437 tpl_printf(vars, TPLADD, "ERRCW", "%d", cl->account->cwcacheexerrcw);
7438 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", (cl->account->cacheex.mode == 3) ? getting : pushing);
7439 rowvariable = "TABLECLIENTROWS";
7440 written = 1;
7442 else if((cl->typ == 'p' || cl->typ == 'r') && (cl->reader && cl->reader->cacheex.mode))
7444 cacheex_name_link_tpl = "SREADER";
7445 tpl_addVar(vars, TPLADD, "TYPE", "Reader");
7447 if(!apicall)
7449 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, cl->reader->label));
7450 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, cl->reader->label));
7452 if(cl->reader->description)
7454 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->reader->description));
7457 else
7459 tpl_addVar(vars, TPLADD, "NAME", cl->reader->label);
7461 if(cl->reader->description)
7463 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", cl->reader->description);
7467 tpl_addVar(vars, TPLADD, "IP", cs_inet_ntoa(cl->ip));
7468 tpl_printf(vars, TPLADD, "NODE", "%" PRIu64 "X", get_cacheex_node(cl));
7469 tpl_addVar(vars, TPLADD, "LEVEL", level[cl->reader->cacheex.mode]);
7470 tpl_printf(vars, TPLADD, "PUSH", "%d", cl->cwcacheexpush);
7471 tpl_printf(vars, TPLADD, "CWCINFO", "%d", cl->cwc_info);
7472 tpl_printf(vars, TPLADD, "GOT", "%d", cl->cwcacheexgot);
7473 tpl_printf(vars, TPLADD, "CWCINFO", "%d", cl->cwc_info);
7474 tpl_printf(vars, TPLADD, "HIT", "%d", cl->cwcacheexhit);
7475 tpl_printf(vars, TPLADD, "ERR", "%d", cl->cwcacheexerr);
7476 tpl_printf(vars, TPLADD, "ERRCW", "%d", cl->cwcacheexerrcw);
7477 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", (cl->reader->cacheex.mode == 3) ? pushing : getting);
7479 rowvariable = "TABLEREADERROWS";
7480 written = 1;
7482 else if(get_module(cl)->listenertype == LIS_CSPUDP)
7484 cacheex_name_link_tpl = "SREADER";
7485 tpl_addVar(vars, TPLADD, "TYPE", "csp");
7487 if(!apicall)
7489 tpl_addVar(vars, TPLADD, "READERNAME", "csp");
7490 tpl_addVar(vars, TPLADD, "READERNAMEENC", "csp");
7492 else
7494 tpl_addVar(vars, TPLADD, "NAME", "csp");
7497 tpl_addVar(vars, TPLADD, "IP", cs_inet_ntoa(cl->ip));
7498 tpl_addVar(vars, TPLADD, "NODE", "csp");
7500 if(cl->cwcacheexping)
7502 tpl_printf(vars, TPLADD, "LEVEL", "csp (%d ms)", cl->cwcacheexping);
7504 else
7506 tpl_addVar(vars, TPLADD, "LEVEL", "csp");
7509 tpl_printf(vars, TPLADD, "PUSH", "%d", cl->cwcacheexpush);
7510 tpl_printf(vars, TPLADD, "GOT", "%d", cl->cwcacheexgot);
7511 tpl_printf(vars, TPLADD, "HIT", "%d", cl->cwcacheexhit);
7512 tpl_printf(vars, TPLADD, "ERR", "%d", cl->cwcacheexerr);
7513 tpl_printf(vars, TPLADD, "ERRCW", "%d", cl->cwcacheexerrcw);
7514 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", getting);
7515 rowvariable = "TABLECLIENTROWS";
7516 written = 1;
7519 if(written)
7521 if(!apicall)
7523 tpl_addVar(vars, TPLADD, "NAME", tpl_getTpl(vars, cacheex_name_link_tpl));
7525 tpl_addVar(vars, TPLAPPEND, rowvariable, tpl_getTpl(vars, "CACHEEXTABLEROW"));
7527 if(cl->ll_cacheex_stats)
7529 LL_ITER itr = ll_iter_create(cl->ll_cacheex_stats);
7530 S_CACHEEX_STAT_ENTRY *cacheex_stats_entry;
7532 while((cacheex_stats_entry = ll_iter_next(&itr)))
7534 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", "");
7535 if(now - cacheex_stats_entry->cache_last < 20)
7536 { tpl_addVar(vars, TPLADD, "TYPE", cacheex_stats_entry->cache_direction == 0 ? pushing : getting); }
7537 else
7538 { tpl_addVar(vars, TPLADD, "TYPE", ""); }
7539 tpl_printf(vars, TPLADD, "NAME", "%04X@%06X:%04X", cacheex_stats_entry->cache_caid,
7540 cacheex_stats_entry->cache_prid,
7541 cacheex_stats_entry->cache_srvid);
7542 if(cacheex_stats_entry->cache_direction == 0)
7544 tpl_printf(vars, TPLADD, "PUSH", "%d", cacheex_stats_entry->cache_count);
7545 tpl_addVar(vars, TPLADD, "GOT", "");
7547 else
7549 tpl_printf(vars, TPLADD, "GOT", "%d", cacheex_stats_entry->cache_count);
7550 tpl_addVar(vars, TPLADD, "PUSH", "");
7552 tpl_addVar(vars, TPLADD, "HIT", "");
7553 char channame[CS_SERVICENAME_SIZE];
7554 char *lastchan = xml_encode(vars, get_servicename(cl, cacheex_stats_entry->cache_srvid, cacheex_stats_entry->cache_prid, cacheex_stats_entry->cache_caid, channame, sizeof(channame)));
7555 tpl_addVar(vars, TPLADD, "LEVEL", lastchan);
7556 if (apicall == 2)
7558 tpl_printf(vars, TPLADD, "JSONDELIMITER", "%s", (delimiter > 1)?",":"");
7559 tpl_addVar(vars, TPLAPPEND, "JSONCACHEEXBITS", tpl_getTpl(vars, "JSONCACHEEXBIT"));
7560 delimiter++;
7562 else
7564 tpl_addVar(vars, TPLAPPEND, rowvariable, tpl_getTpl(vars, "CACHEEXTABLEROW"));
7568 written = 0;
7572 float cachesum = first_client ? first_client->cwcacheexgot : 1;
7573 if(cachesum < 1)
7575 cachesum = 1;
7577 tpl_printf(vars, TPLADD, "TOTAL_CACHEXPUSH", PRINTF_LOCAL_D, first_client ? first_client->cwcacheexpush : 0);
7578 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXPUSH_IMG", pushing);
7579 tpl_printf(vars, TPLADD, "TOTAL_CACHEXGOT", PRINTF_LOCAL_D, first_client ? first_client->cwcacheexgot : 0);
7580 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXGOT_IMG", getting);
7581 tpl_printf(vars, TPLADD, "TOTAL_CACHEXHIT", PRINTF_LOCAL_D, first_client ? first_client->cwcacheexhit : 0);
7582 tpl_printf(vars, TPLADD, "TOTAL_CACHESIZE", "%d", cache_size());
7584 tpl_printf(vars, TPLADD, "REL_CACHEXHIT", "%.2f", (first_client ? first_client->cwcacheexhit : 0) * 100 / cachesum);
7586 if(!apicall)
7587 { return tpl_getTpl(vars, "CACHEEXPAGE"); }
7588 else
7590 return tpl_getTpl(vars, "JSONCACHEEX");
7593 #endif
7595 static char *send_oscam_api(struct templatevars * vars, FILE * f, struct uriparams * params, int8_t *keepalive, int8_t apicall, char *extraheader)
7597 if(strcmp(getParam(params, "part"), "status") == 0)
7599 return send_oscam_status(vars, params, apicall);
7601 else if(strcmp(getParam(params, "part"), "userstats") == 0)
7603 return send_oscam_user_config(vars, params, apicall);
7605 else if(strcmp(getParam(params, "part"), "failban") == 0)
7607 return send_oscam_failban(vars, params, apicall);
7609 #ifdef CS_CACHEEX
7610 else if(strcmp(getParam(params, "part"), "cacheex") == 0)
7612 return send_oscam_cacheex(vars, params, apicall);
7614 #endif
7615 else if(strcmp(getParam(params, "part"), "files") == 0)
7617 return send_oscam_files(vars, params, apicall);
7619 else if(strcmp(getParam(params, "part"), "readerlist") == 0)
7621 return send_oscam_reader(vars, params, apicall);
7623 else if(strcmp(getParam(params, "part"), "serverconfig") == 0)
7625 //Send Errormessage
7626 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "serverconfig not yet avail");
7627 return tpl_getTpl(vars, "APIERROR");
7629 else if(strcmp(getParam(params, "part"), "userconfig") == 0)
7631 if(((strcmp(getParam(params, "action"), "Save") == 0) ||
7632 (strcmp(getParam(params, "action"), "Save As") == 0)) && cfg.http_readonly == 1)
7634 //Send Errormessage
7635 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "API is in readonly mode");
7636 return tpl_getTpl(vars, "APIERROR");
7638 else
7640 struct s_auth *account = get_account_by_name(getParam(params, "user"));
7641 if(!account && strcmp(getParam(params, "action"), "Save"))
7643 //Send Errormessage
7644 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "user not exist");
7645 return tpl_getTpl(vars, "APIERROR");
7647 else
7649 return send_oscam_user_config_edit(vars, params, apicall);
7653 else if(strcmp(getParam(params, "part"), "entitlement") == 0)
7656 if(strcmp(getParam(params, "label"), ""))
7658 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
7659 if(rdr)
7661 if(rdr->enable == 1)
7663 return send_oscam_entitlement(vars, params, apicall);
7665 else
7667 //Send Errormessage
7668 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no cccam reader or disabled");
7669 return tpl_getTpl(vars, "APIERROR");
7672 else
7674 //Send Errormessage
7675 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "reader not exist");
7676 return tpl_getTpl(vars, "APIERROR");
7679 else
7681 //Send Errormessage
7682 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no reader selected");
7683 return tpl_getTpl(vars, "APIERROR");
7686 else if(strcmp(getParam(params, "part"), "ecmhistory") == 0)
7688 int32_t i;
7689 int32_t isec;
7690 int32_t shown;
7691 time_t now = time((time_t *)0);
7692 const char *usr;
7693 struct s_client *cl;
7694 for(i = 0, cl = first_client; cl ; cl = cl->next, i++)
7696 if(cl->wihidden != 1)
7698 isec = now - cl->lastecm;
7699 usr = username(cl);
7700 shown = 0;
7701 if(strcmp(getParam(params, "label"), "") == 0)
7703 if(strcmp(getParam(params, "type"), "servers") == 0)
7705 if(cl->typ == 'p' || cl->typ == 'r')
7706 { shown = 1; }
7708 else if(strcmp(getParam(params, "type"), "users") == 0)
7710 if(cl->typ == 'c')
7711 { shown = 1; }
7713 else
7715 shown = 1;
7718 else if(strcmp(getParam(params, "label"), usr) == 0)
7720 shown = 1;
7722 if(shown == 1)
7724 tpl_printf(vars, TPLADD, "CLIENTTYPE", "%c", cl->typ);
7725 tpl_addVar(vars, TPLADD, "CLIENTUSER", xml_encode(vars, usr));
7726 if(cl->typ == 'c' || cl->typ == 'm')
7728 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", xml_encode(vars, cl->account->description ? cl->account->description : ""));
7730 else if(cl->typ == 'p' || cl->typ == 'r')
7732 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", xml_encode(vars, cl->reader->description ? cl->reader->description : ""));
7734 tpl_printf(vars, TPLADD, "CLIENTLASTRESPONSETIME", "%d", cl->cwlastresptime ? cl->cwlastresptime : -1);
7735 tpl_printf(vars, TPLADD, "CLIENTIDLESECS", "%d", isec);
7737 //load historical values from ringbuffer
7738 char *value = get_ecm_fullhistorystring(cl);
7739 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIMEHIST", value);
7740 free_mk_t(value);
7742 tpl_addVar(vars, TPLAPPEND, "APISTATUSBITS", tpl_getTpl(vars, "APISTATUSBIT"));
7746 return tpl_getTpl(vars, "APISTATUS");
7748 else if(strcmp(getParam(params, "part"), "readerstats") == 0)
7750 if(strcmp(getParam(params, "label"), ""))
7752 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
7753 if(rdr)
7755 return send_oscam_reader_stats(vars, params, apicall);
7757 else
7759 //Send Errormessage
7760 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "reader not exist");
7761 return tpl_getTpl(vars, "APIERROR");
7764 else
7766 //Send Errormessage
7767 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no reader selected");
7768 return tpl_getTpl(vars, "APIERROR");
7771 else if(strcmp(getParam(params, "part"), "shutdown") == 0)
7773 if((strcmp(strtolower(getParam(params, "action")), "restart") == 0) ||
7774 (strcmp(strtolower(getParam(params, "action")), "shutdown") == 0))
7776 if(!cfg.http_readonly)
7778 return send_oscam_shutdown(vars, f, params, apicall, keepalive, extraheader);
7780 else
7782 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "webif readonly mode");
7783 return tpl_getTpl(vars, "APIERROR");
7786 else
7788 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "missing parameter action");
7789 return tpl_getTpl(vars, "APIERROR");
7793 else
7795 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "part not found");
7796 return tpl_getTpl(vars, "APIERROR");
7800 static char *send_oscam_image(struct templatevars * vars, FILE * f, struct uriparams * params, char *image, time_t modifiedheader, uint32_t etagheader, char *extraheader)
7802 char *wanted;
7803 if(image == NULL) { wanted = getParam(params, "i"); }
7804 else { wanted = image; }
7805 if(strlen(wanted) > 3 && wanted[0] == 'I' && wanted[1] == 'C')
7807 if(etagheader == 0)
7809 int8_t disktpl = 0;
7810 char *tpl_path;
7811 tpl_path = cfg.http_piconpath? cfg.http_piconpath : cfg.http_tpl;
7813 if(tpl_path)
7815 char path[255];
7816 if(strlen(tpl_getTplPath(wanted, tpl_path, path, 255)) > 0 && file_exists(path))
7818 struct stat st;
7819 disktpl = 1;
7820 stat(path, &st);
7821 if((time_t)st.st_mtime < modifiedheader)
7823 send_header304(f, extraheader);
7824 return "1";
7828 if(disktpl == 0 && first_client->login < modifiedheader)
7830 send_header304(f, extraheader);
7831 return "1";
7834 char *header = strstr(tpl_getTpl(vars, wanted), "data:");
7835 if(header != NULL)
7837 char *ptr = header + 5;
7838 while(ptr[0] != ';' && ptr[0] != '\0') { ++ptr; }
7839 if(ptr[0] != '\0' && ptr[1] != '\0') { ptr[0] = '\0'; }
7840 else { return "0"; }
7841 ptr = strstr(ptr + 1, "base64,");
7842 if(ptr != NULL)
7844 int32_t len = b64decode((uint8_t *)ptr + 7);
7845 if(len > 0)
7847 if((uint32_t)crc32(0L, (uint8_t *)ptr + 7, len) == etagheader)
7849 send_header304(f, extraheader);
7851 else
7853 send_headers(f, 200, "OK", extraheader, header + 5, 1, len, ptr + 7, 0);
7854 webif_write_raw(ptr + 7, f, len);
7856 return "1";
7861 // Return file not found
7862 const char *not_found = "File not found.\n";
7863 send_headers(f, 404, "Not Found", extraheader, "text/plain", 0, strlen(not_found), (char *)not_found, 0);
7864 webif_write_raw((char *)not_found, f, strlen(not_found));
7865 return "1";
7868 static char *send_oscam_robots_txt(FILE * f)
7870 const char *content = "User-agent: *\nDisallow: /\n";
7871 send_headers(f, 200, "OK", NULL, "text/plain", 0, strlen(content), (char *)content, 0);
7872 webif_write_raw((char *)content, f, strlen(content));
7873 return "1";
7876 static char *send_oscam_graph(struct templatevars * vars)
7878 return tpl_getTpl(vars, "GRAPH");
7881 #ifdef MODULE_GHTTP
7882 static bool ghttp_autoconf(struct templatevars * vars, struct uriparams * params)
7884 int8_t i = 0;
7885 struct s_reader *rdr;
7886 char *name = getParam(params, "gacname");
7887 if(strlen(name) < 3)
7889 tpl_addMsg(vars, "Invalid host name!");
7890 return false;
7893 LL_ITER itr = ll_iter_create(configured_readers);
7894 while((rdr = ll_iter_next(&itr)))
7895 if(rdr->ph.num == R_GHTTP) { i++; } // count existing ghttp readers
7897 while(i < 3) // if less than 3, add more
7899 char lbl[128];
7900 snprintf(lbl, sizeof(lbl), "%s%d", "ghttp", i + 1);
7901 cs_log("GHttp autoconf: adding reader %s", lbl);
7902 struct s_reader *newrdr;
7903 if(!cs_malloc(&newrdr, sizeof(struct s_reader)))
7905 tpl_addMsg(vars, "Create reader failed!");
7906 return false;
7908 newrdr->typ = R_GHTTP;
7909 cs_strncpy(newrdr->label, lbl, sizeof(newrdr->label));
7910 module_reader_set(newrdr);
7911 reader_set_defaults(newrdr);
7912 newrdr->enable = 0;
7913 newrdr->grp = 1;
7914 ll_append(configured_readers, newrdr);
7915 i++;
7918 uint16_t port = 0;
7919 char *str = strstr(name, ":");
7920 if(str)
7922 port = atoi(str + 1);
7923 str[0] = '\0';
7926 i = 0;
7927 itr = ll_iter_create(configured_readers);
7928 while((rdr = ll_iter_next(&itr)))
7930 if(rdr->ph.num == R_GHTTP)
7932 if(i > 2) // remove superflous
7934 cs_log("GHttp autoconf: removing reader %s", rdr->label);
7935 inactivate_reader(rdr);
7936 ll_iter_remove(&itr);
7937 free_reader(rdr);
7939 else // reconfigure the 3 first ghttp readers
7941 cs_log("GHttp autoconf: reconfiguring reader %s", rdr->label);
7942 snprintf(rdr->label, sizeof(rdr->label), "%s%d", "ghttp", i + 1);
7943 rdr->r_port = port;
7944 rdr->enable = 1;
7945 rdr->ghttp_use_ssl = 0;
7946 #ifdef WITH_SSL
7947 rdr->ghttp_use_ssl = 1;
7948 #endif
7949 if(rdr->grp < 1) { rdr->grp = 1; }
7950 cs_strncpy(rdr->r_usr, getParam(params, "gacuser"), sizeof(rdr->r_usr));
7951 cs_strncpy(rdr->r_pwd, getParam(params, "gacpasswd"), sizeof(rdr->r_pwd));
7952 if(i == 0) { cs_strncpy(rdr->device, name, sizeof(rdr->device)); }
7953 else
7955 if(!strstr(name, "."))
7956 { snprintf(rdr->device, sizeof(rdr->device), "%s%d", name, i); } // name, name1, name2
7957 else { cs_strncpy(rdr->device, name, sizeof(rdr->device)); }
7958 // . in the name = assume full hostname = use same for all 3 readers
7960 if(i == 2) { rdr->fallback = 1; }
7961 else { rdr->fallback = 0; }
7962 i++;
7966 cs_log("GHttp autoconf: Saving %d readers", i);
7967 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
7968 itr = ll_iter_create(configured_readers);
7969 while((rdr = ll_iter_next(&itr)))
7971 if(rdr->ph.num == R_GHTTP)
7972 { restart_cardreader(rdr, 1); }
7974 return true;
7977 static char *send_oscam_ghttp(struct templatevars * vars, struct uriparams * params, int8_t apicall)
7979 if(strcmp(strtolower(getParam(params, "action")), "autoconf") == 0)
7981 if(!apicall)
7983 bool missing = false;
7984 if(strlen(getParam(params, "gacuser")) == 0)
7986 tpl_addVar(vars, TPLADD, "USERREQ", "<FONT COLOR='red'>(Required)</FONT>");
7987 missing = true;
7989 else { tpl_addVar(vars, TPLADD, "GACUSER", getParam(params, "gacuser")); }
7990 if(strlen(getParam(params, "gacpasswd")) == 0)
7992 tpl_addVar(vars, TPLADD, "PWDREQ", "<FONT COLOR='red'>(Required)</FONT>");
7993 missing = true;
7995 else { tpl_addVar(vars, TPLADD, "GACPASSWD", getParam(params, "gacpasswd")); }
7996 if(strlen(getParam(params, "gacname")) == 0)
7998 tpl_addVar(vars, TPLADD, "NAMEREQ", "<FONT COLOR='red'>(Required)</FONT>");
7999 missing = true;
8001 else { tpl_addVar(vars, TPLADD, "GACNAME", getParam(params, "gacname")); }
8002 if(missing) { return tpl_getTpl(vars, "PREAUTOCONF"); }
8003 cs_log("GHttp autoconf requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
8005 else
8007 tpl_addVar(vars, TPLADD, "APICONFIRMMESSAGE", "autoconf");
8008 cs_log("GHttp autoconf requested by XMLApi from %s", cs_inet_ntoa(GET_IP()));
8011 if(ghttp_autoconf(vars, params))
8013 tpl_printf(vars, TPLADD, "REFRESHTIME", "%d", 3);
8014 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
8015 tpl_printf(vars, TPLADD, "SECONDS", "%d", 3);
8016 if(apicall) { return tpl_getTpl(vars, "APICONFIRMATION"); }
8017 else { return tpl_getTpl(vars, "AUTOCONF"); }
8019 else { return tpl_getTpl(vars, "PREAUTOCONF"); } // something failed
8022 else
8024 if(strlen(getParam(params, "token")) > 0) // parse autoconf token
8026 char *token = getParam(params, "token");
8027 int32_t len = b64decode((uint8_t *)token);
8028 if(len > 0)
8030 struct uriparams tokenprms;
8031 tokenprms.paramcount = 0;
8032 parseParams(&tokenprms, token);
8033 if(strlen(getParam(&tokenprms, "u")) > 0)
8035 tpl_addVar(vars, TPLADD, "GACUSER", getParam(&tokenprms, "u"));
8036 tpl_addVar(vars, TPLADD, "USERRDONLY", "readonly");
8038 if(strlen(getParam(&tokenprms, "p")) > 0)
8040 tpl_addVar(vars, TPLADD, "GACPASSWD", getParam(&tokenprms, "p"));
8041 tpl_addVar(vars, TPLADD, "PWDRDONLY", "readonly");
8043 if(strlen(getParam(&tokenprms, "n")) > 0)
8045 tpl_addVar(vars, TPLADD, "GACNAME", getParam(&tokenprms, "n"));
8046 tpl_addVar(vars, TPLADD, "NAMERDONLY", "readonly");
8050 return tpl_getTpl(vars, "PREAUTOCONF");
8053 #endif
8055 static int8_t check_httpip(IN_ADDR_T addr)
8057 int8_t i = 0;
8058 // check all previously dyndns resolved addresses
8059 for(i = 0; i < MAX_HTTP_DYNDNS; i++)
8061 if(IP_ISSET(cfg.http_dynip[i]) && IP_EQUAL(cfg.http_dynip[i], addr))
8062 { return 1; }
8064 return 0;
8067 static int8_t check_httpdyndns(IN_ADDR_T addr)
8070 // check all previously dyndns resolved addresses
8071 if(check_httpip(addr))
8072 { return 1; }
8074 // we are not ok, so resolve all dyndns entries into IP's - maybe outdated IP's
8076 if(cfg.http_dyndns[0][0])
8078 int8_t i = 0;
8079 for(i = 0; i < MAX_HTTP_DYNDNS; i++)
8081 if(cfg.http_dyndns[i][0])
8083 cs_resolve((const char *)cfg.http_dyndns[i], &cfg.http_dynip[i], NULL, NULL);
8084 cs_log_dbg(D_TRACE, "WebIf: httpdyndns [%d] resolved %s to %s ", i, (char *)cfg.http_dyndns[i], cs_inet_ntoa(cfg.http_dynip[i]));
8088 else
8090 cs_log_dbg(D_TRACE, "WebIf: No dyndns addresses found");
8091 return 0;
8094 // again check all dyndns resolved addresses
8095 if(check_httpip(addr))
8096 { return 1; }
8098 return 0;
8101 static int8_t check_valid_origin(IN_ADDR_T addr)
8104 // check whether requesting IP is in allowed IP ranges
8105 if(check_ip(cfg.http_allowed, addr))
8106 { return 1; }
8108 // we havn't found the requesting IP in allowed range. So we check for allowed httpdyndns as last chance
8109 if(cfg.http_dyndns[0][0])
8111 int8_t ok;
8112 ok = check_httpdyndns(addr);
8113 return ok;
8115 return 0;
8118 static int8_t check_request(char *result, int32_t readen)
8120 if(readen < 50) { return 0; }
8121 result[readen] = '\0';
8122 int8_t method;
8123 if(strncmp(result, "POST", 4) == 0) { method = 1; }
8124 else { method = 0; }
8125 char *headerEnd = strstr(result, "\r\n\r\n");
8126 if(headerEnd == NULL) { return 0; }
8127 else if(method == 0) { return 1; }
8128 else
8130 char *ptr = strstr(result, "Content-Length: ");
8131 if(ptr != NULL)
8133 ptr += 16;
8134 if(ptr < result + readen)
8136 uint32_t length = atoi(ptr);
8137 if(strlen(headerEnd + 4) >= length) { return 1; }
8141 return 0;
8144 static int32_t readRequest(FILE * f, IN_ADDR_T in, char **result, int8_t forcePlain)
8146 int32_t n, bufsize = 0, errcount = 0;
8147 char buf2[1024];
8148 struct pollfd pfd2[1];
8149 #ifdef WITH_SSL
8150 int8_t is_ssl = 0;
8151 if(ssl_active && !forcePlain)
8152 { is_ssl = 1; }
8153 #endif
8155 while(1)
8157 errno = 0;
8158 if(forcePlain)
8159 { n = read(fileno(f), buf2, sizeof(buf2)); }
8160 else
8161 { n = webif_read(buf2, sizeof(buf2), f); }
8162 if(n <= 0)
8164 if((errno == 0 || errno == EINTR))
8166 if(errcount++ < 10)
8168 cs_sleepms(5);
8169 continue;
8171 else { return -1; }
8173 #ifdef WITH_SSL
8174 if(is_ssl)
8176 if(errno != ECONNRESET)
8178 int32_t errcode = ERR_peek_error();
8179 char errstring[128];
8180 ERR_error_string_n(errcode, errstring, sizeof(errstring) - 1);
8181 cs_log_dbg(D_TRACE, "WebIf: read error ret=%d (%d%s%s)", n, SSL_get_error(cur_ssl(), n), errcode ? " " : "", errcode ? errstring : "");
8183 return -1;
8185 #else
8186 if(errno != ECONNRESET)
8187 { cs_log_dbg(D_TRACE, "WebIf: read error ret=%d (errno=%d %s)", n, errno, strerror(errno)); }
8188 #endif
8189 return -1;
8191 if(!cs_realloc(result, bufsize + n + 1))
8193 send_error500(f);
8194 NULLFREE(*result);
8195 return -1;
8198 memcpy(*result + bufsize, buf2, n);
8199 bufsize += n;
8201 #ifdef WITH_EMU
8202 if(bufsize > 204800) // max request size 200kb
8203 #else
8204 if(bufsize > 102400) // max request size 100kb
8205 #endif
8207 cs_log("error: too much data received from %s", cs_inet_ntoa(in));
8208 NULLFREE(*result);
8209 *result = NULL;
8210 return -1;
8213 #ifdef WITH_SSL
8214 if(ssl_active && !forcePlain)
8216 int32_t len = 0;
8217 len = SSL_pending((SSL *)f);
8219 if(len > 0)
8220 { continue; }
8222 pfd2[0].fd = SSL_get_fd((SSL *)f);
8225 else
8226 #endif
8227 pfd2[0].fd = fileno(f);
8229 pfd2[0].events = (POLLIN | POLLPRI);
8231 int32_t rc = poll(pfd2, 1, 100);
8232 if(rc > 0 || !check_request(*result, bufsize))
8233 { continue; }
8234 else
8235 { break; }
8237 return bufsize;
8239 static int32_t process_request(FILE * f, IN_ADDR_T in)
8241 int32_t ok = 0;
8242 int8_t *keepalive = (int8_t *)pthread_getspecific(getkeepalive);
8243 IN_ADDR_T addr = GET_IP();
8247 #ifdef WITH_SSL
8248 if(!ssl_active && *keepalive) { fflush(f); }
8249 #else
8250 if(*keepalive) { fflush(f); }
8251 #endif
8253 // at this point we do all checks related origin IP, ranges and dyndns stuff
8254 ok = check_valid_origin(addr);
8255 cs_log_dbg(D_TRACE, "WebIf: Origin checked. Result: access from %s => %s", cs_inet_ntoa(addr), (!ok) ? "forbidden" : "allowed");
8257 // based on the failed origin checks we send a 403 to calling browser
8258 if(!ok)
8260 send_error(f, 403, "Forbidden", NULL, "Access denied.", 0);
8261 cs_log("unauthorized access from %s - invalid ip or dyndns", cs_inet_ntoa(addr));
8262 return 0;
8264 int32_t authok = 0;
8265 char expectednonce[(MD5_DIGEST_LENGTH * 2) + 1], opaque[(MD5_DIGEST_LENGTH * 2) + 1];
8266 char authheadertmp[sizeof(AUTHREALM) + sizeof(expectednonce) + sizeof(opaque) + 100];
8268 char *method, *path, *protocol, *str1, *saveptr1 = NULL, *authheader = NULL, *extraheader = NULL, *filebuf = NULL;
8269 char *pch, *tmp, *buf, *nameInUrl, subdir[32];
8270 /* List of possible pages */
8271 char *pages[] =
8273 "/config.html",
8274 "/readers.html",
8275 "/entitlements.html",
8276 "/status.html",
8277 "/userconfig.html",
8278 "/readerconfig.html",
8279 "/services.html",
8280 "/user_edit.html",
8281 "/site.css",
8282 "/services_edit.html",
8283 "/savetemplates.html",
8284 "/shutdown.html",
8285 "/script.html",
8286 "/scanusb.html",
8287 "/files.html",
8288 "/readerstats.html",
8289 "/failban.html",
8290 "/oscam.js",
8291 "/oscamapi.html",
8292 "/image",
8293 "/favicon.ico",
8294 "/graph.svg",
8295 "/oscamapi.xml",
8296 "/cacheex.html",
8297 "/oscamapi.json",
8298 "/emm.html",
8299 "/emm_running.html",
8300 "/robots.txt",
8301 "/ghttp.html",
8302 "/logpoll.html",
8303 "/jquery.js",
8306 int32_t pagescnt = sizeof(pages) / sizeof(char *); // Calculate the amount of items in array
8307 int32_t i, bufsize, len, pgidx = -1;
8308 uint32_t etagheader = 0;
8309 struct uriparams params;
8310 params.paramcount = 0;
8311 time_t modifiedheader = 0;
8313 bufsize = readRequest(f, in, &filebuf, 0);
8315 if(!filebuf || bufsize < 1)
8317 if(!*keepalive) { cs_log_dbg(D_CLIENT, "WebIf: No data received from client %s. Closing connection.", cs_inet_ntoa(addr)); }
8318 return -1;
8321 buf = filebuf;
8323 if((method = strtok_r(buf, " ", &saveptr1)) != NULL)
8325 if((path = strtok_r(NULL, " ", &saveptr1)) != NULL)
8327 if((protocol = strtok_r(NULL, "\r", &saveptr1)) == NULL)
8329 NULLFREE(filebuf);
8330 return -1;
8333 else
8335 NULLFREE(filebuf);
8336 return -1;
8339 else
8341 NULLFREE(filebuf);
8342 return -1;
8344 tmp = protocol + strlen(protocol) + 2;
8346 pch = path;
8347 /* advance pointer to beginning of query string */
8348 while(pch[0] != '?' && pch[0] != '\0') { ++pch; }
8349 if(pch[0] == '?')
8351 pch[0] = '\0';
8352 ++pch;
8355 nameInUrl = pch - 1;
8356 while(nameInUrl != path && nameInUrl[0] != '/') { --nameInUrl; }
8358 /* allow only alphanumeric sub-folders */
8359 int32_t subdirLen = nameInUrl - path;
8360 subdir[0] = '\0';
8361 if(subdirLen > 0 && subdirLen < 32)
8363 cs_strncpy(subdir, path + 1, subdirLen);
8365 int32_t invalidSubdir = 0;
8366 for(i = 0; i < subdirLen - 1; i++)
8368 if(!((subdir[i] >= '0' && subdir[i] <= '9')
8369 || (subdir[i] >= 'a' && subdir[i] <= 'z')
8370 || (subdir[i] >= 'A' && subdir[i] <= 'Z')))
8373 invalidSubdir = 1;
8374 subdir[0] = '\0';
8375 break;
8379 if(!invalidSubdir)
8381 subdir[subdirLen] = '\0';
8382 #ifdef WIN32
8383 subdir[subdirLen - 1] = '\\';
8384 #else
8385 subdir[subdirLen - 1] = '/';
8386 #endif
8390 /* Map page to our static page definitions */
8391 for(i = 0; i < pagescnt; i++)
8393 if(!strcmp(nameInUrl, pages[i])) { pgidx = i; }
8396 parseParams(&params, pch);
8398 if(!cfg.http_user || !cfg.http_pwd)
8399 { authok = 1; }
8401 for(str1 = strtok_r(tmp, "\n", &saveptr1); str1; str1 = strtok_r(NULL, "\n", &saveptr1))
8403 len = strlen(str1);
8404 if(str1[len - 1] == '\r')
8406 str1[len - 1] = '\0';
8407 --len;
8409 if(len == 0)
8411 if(strcmp(method, "POST") == 0)
8413 parseParams(&params, str1 + 2);
8415 break;
8417 if(!authok && len > 50 && strncasecmp(str1, "Authorization:", 14) == 0 && strstr(str1, "Digest") != NULL)
8419 if(cs_dblevel & D_CLIENT)
8421 if(cs_realloc(&authheader, len + 1))
8422 { cs_strncpy(authheader, str1, len); }
8424 authok = check_auth(str1, method, path, addr, expectednonce, opaque);
8426 else if(len > 40 && strncasecmp(str1, "If-Modified-Since:", 18) == 0)
8428 modifiedheader = parse_modifiedsince(str1);
8430 else if(len > 20 && strncasecmp(str1, "If-None-Match:", 14) == 0)
8432 for(pch = str1 + 14; pch[0] != '"' && pch[0] != '\0'; ++pch) { ; }
8433 if(strlen(pch) > 5) { etagheader = (uint32_t)strtoul(++pch, NULL, 10); }
8435 else if(len > 12 && strncasecmp(str1, "Connection: Keep-Alive", 22) == 0 && strcmp(method, "POST"))
8437 *keepalive = 1;
8441 if(cfg.http_user && cfg.http_pwd)
8443 if(!authok || strlen(opaque) != MD5_DIGEST_LENGTH * 2) { calculate_opaque(addr, opaque); }
8444 if(authok != 2)
8446 if(!authok)
8448 if(authheader)
8450 cs_log_dbg(D_CLIENT, "WebIf: Received wrong auth header from %s:", cs_inet_ntoa(addr));
8451 cs_log_dbg(D_CLIENT, "%s", authheader);
8453 else
8454 { cs_log_dbg(D_CLIENT, "WebIf: Received no auth header from %s.", cs_inet_ntoa(addr)); }
8456 calculate_nonce(NULL, expectednonce, opaque);
8458 if(authok != 1)
8460 snprintf(authheadertmp, sizeof(authheadertmp), "WWW-Authenticate: Digest algorithm=\"MD5\", realm=\"%s\", qop=\"auth\", opaque=\"%s\", nonce=\"%s\"", AUTHREALM, opaque, expectednonce);
8461 if(authok == 2) { strncat(authheadertmp, ", stale=true", sizeof(authheadertmp) - strlen(authheadertmp) - 1); }
8463 else
8464 { snprintf(authheadertmp, sizeof(authheadertmp), "Authentication-Info: nextnonce=\"%s\"", expectednonce); }
8465 extraheader = authheadertmp;
8466 if(authok != 1)
8468 char *msg = "Access denied.\n";
8469 send_headers(f, 401, "Unauthorized", extraheader, "text/html", 0, strlen(msg), msg, 0);
8470 webif_write(msg, f);
8471 NULLFREE(authheader);
8472 NULLFREE(filebuf);
8473 if(*keepalive) { continue; }
8474 else { return 0; }
8477 else { NULLFREE(authheader); }
8479 /*build page*/
8480 if(pgidx == 8)
8482 send_file(f, "CSS", subdir, modifiedheader, etagheader, extraheader);
8484 else if(pgidx == 17)
8486 send_file(f, "JS", subdir, modifiedheader, etagheader, extraheader);
8488 else if(pgidx == 30)
8490 send_file(f, "JQ", subdir, modifiedheader, etagheader, extraheader);
8492 else
8494 time_t t;
8495 struct templatevars *vars = tpl_create();
8496 if(vars == NULL)
8498 send_error500(f);
8499 NULLFREE(filebuf);
8500 return 0;
8503 tpl_addVar(vars, TPLADD, "SUBDIR", subdir);
8505 struct tm lt, st;
8506 time(&t);
8508 localtime_r(&t, &lt);
8510 tpl_addVar(vars, TPLADD, "CS_VERSION", CS_VERSION);
8511 tpl_addVar(vars, TPLADD, "CS_SVN_VERSION", CS_SVN_VERSION);
8512 tpl_addVar(vars, TPLADD, "CS_TARGET", CS_TARGET);
8513 tpl_addVar(vars, TPLADD, "HTTPOSCAMLABEL", xml_encode(vars,cfg.http_oscam_label));
8514 if (!boxtype_is("generic"))
8516 if (!boxname_is("generic"))
8517 tpl_printf(vars, TPLADD, "DETECTED_BOXTYPE", "%s (%s)", boxtype_get(), boxname_get());
8518 else
8519 tpl_addVar(vars, TPLADD, "DETECTED_BOXTYPE", boxtype_get());
8522 if(cfg.http_locale){
8523 float decimal_point = 0.0;
8524 setlocale(LC_ALL, cfg.http_locale);
8525 tpl_printf(vars, TPLADD, "TMP_DECPOINT", "%.1f", decimal_point);
8526 tpl_addVar(vars, TPLADD, "LOCALE_DECPOINT", strstr(tpl_getVar(vars, "TMP_DECPOINT"), ",") ? ",": ".");
8529 tpl_addVar(vars, TPLADD, "HTTP_CHARSET", cs_http_use_utf8 ? "UTF-8" : "ISO-8859-1");
8530 if(cfg.http_picon_size > 0)
8532 tpl_printf(vars, TPLADD, "HTTPPICONSIZEINS", "img.statususericon, img.protoicon, img.usericon, img.readericon {height:%dpx !important;max-height:%dpx !important;}", cfg.http_picon_size, cfg.http_picon_size);
8534 if(cfg.poll_refresh > 0)
8536 tpl_printf(vars, TPLADD, "POLLREFRESHTIME", "%d", cfg.poll_refresh);
8538 if ( cfg.http_refresh > 0 &&
8539 ((( pgidx == 1 || pgidx == 4 ) && !cfg.poll_refresh ) ||
8540 ( pgidx == 3 && ( cfg.http_status_log || !cfg.poll_refresh )) ||
8541 pgidx == 15 || pgidx == 23 || pgidx == -1 )) // wenn polling bei cachex.html eingeführt wird muss die 23 => 2 zeilen höher
8543 tpl_printf(vars, TPLADD, "REFRESHTIME", "%d", cfg.http_refresh);
8544 tpl_addVar(vars, TPLADD, "WITHQUERY", pgidx == 15 ? "1" : "0");
8545 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
8547 #ifdef WEBIF_JQUERY
8548 tpl_printf(vars, TPLADD, "SRCJQUERY", "jquery.js?v=%s", CS_SVN_VERSION);
8549 #else
8550 tpl_addVar(vars, TPLADD, "SRCJQUERY", cfg.http_extern_jquery);
8551 #endif
8553 if(picon_exists("LOGO")||strlen(tpl_getTpl(vars, "IC_LOGO"))>3)
8555 tpl_addVar(vars, TPLADD, "LOGO_INS", tpl_getTpl(vars, "LOGOBITIMG"));
8557 else
8559 tpl_addVar(vars, TPLADD, "LOGO_INS", tpl_getTpl(vars, "LOGOBITSVG"));
8561 tpl_addVar(vars, TPLADD, "LOGO", tpl_getTpl(vars, "LOGOBIT"));
8562 tpl_printf(vars, TPLADD, "CURDATE", "%02d.%02d.%02d", lt.tm_mday, lt.tm_mon + 1, lt.tm_year % 100);
8563 tpl_printf(vars, TPLADD, "CURTIME", "%02d:%02d:%02d", lt.tm_hour, lt.tm_min, lt.tm_sec);
8564 localtime_r(&first_client->login, &st);
8565 tpl_printf(vars, TPLADD, "STARTDATE", "%02d.%02d.%02d", st.tm_mday, st.tm_mon + 1, st.tm_year % 100);
8566 tpl_printf(vars, TPLADD, "STARTTIME", "%02d:%02d:%02d", st.tm_hour, st.tm_min, st.tm_sec);
8567 tpl_printf(vars, TPLADD, "PROCESSID", "%d", getppid());
8568 tpl_addVar(vars, TPLADD, "RUNAS", urlencode(vars, username(first_client)));
8570 time_t now = time((time_t *)0);
8571 // XMLAPI
8572 if(pgidx == 18 || pgidx == 22 || pgidx == 24)
8574 char tbuffer [30];
8575 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &st);
8576 tpl_addVar(vars, TPLADD, "APISTARTTIME", tbuffer);
8577 tpl_printf(vars, TPLADD, "APIRUNTIME", "%ld", now - first_client->login);
8578 tpl_printf(vars, TPLADD, "APIREADONLY", "%d", cfg.http_readonly);
8579 if(strcmp(getParam(&params, "callback"), ""))
8581 tpl_printf(vars, TPLADD, "CALLBACK", "%s%s", getParam(&params, "callback"), "(");
8582 tpl_addVar(vars, TPLADD, "ENDBRACKET", ")");
8587 if (config_enabled(WITH_LB))
8588 tpl_addVar(vars, TPLADD, "LBISDEFINED", "1");
8590 // language code in helplink
8591 tpl_addVar(vars, TPLADD, "LANGUAGE", cfg.http_help_lang);
8592 tpl_addVar(vars, TPLADD, "RUNTIME", sec2timeformat(vars, (now - first_client->login)));
8593 time_t uptime = oscam_get_uptime();
8594 if(uptime > 0){
8595 tpl_printf(vars, TPLADD, "UPTIMETXT", "%s Up Time: ", strcmp(tpl_getVar(vars, "DETECTED_BOXTYPE"),"")==0 ? "System" : tpl_getVar(vars, "DETECTED_BOXTYPE"));
8596 tpl_addVar(vars, TPLADD, "UPTIME", sec2timeformat(vars, uptime));
8598 tpl_addVar(vars, TPLADD, "CURIP", cs_inet_ntoa(addr));
8599 if(cfg.http_readonly)
8600 { tpl_addVar(vars, TPLAPPEND, "BTNDISABLED", "DISABLED"); }
8602 i = ll_count(cfg.v_list);
8603 if(i > 0) { tpl_printf(vars, TPLADD, "FAILBANNOTIFIER", "<SPAN CLASS=\"span_notifier\">%d</SPAN>", i); }
8604 tpl_printf(vars, TPLADD, "FAILBANNOTIFIERPOLL", "%d", i);
8606 char *result = NULL;
8608 // WebIf allows modifying many things. Thus, all pages except images/css/static are expected to be non-threadsafe!
8609 if(pgidx != 19 && pgidx != 20 && pgidx != 21 && pgidx != 27) { cs_writelock(__func__, &http_lock); }
8610 switch(pgidx)
8612 case 0:
8613 tpl_addVar(vars, TPLADD, "CONFIG_CONTENT", send_oscam_config(vars, &params));
8614 result = tpl_getTpl(vars, "CONFIGCONTENT");
8615 break;
8616 case 1:
8617 result = send_oscam_reader(vars, &params, 0);
8618 break;
8619 case 2:
8620 result = send_oscam_entitlement(vars, &params, 0);
8621 break;
8622 case 3:
8623 result = send_oscam_status(vars, &params, 0);
8624 break;
8625 case 4:
8626 result = send_oscam_user_config(vars, &params, 0);
8627 break;
8628 case 5:
8629 result = send_oscam_reader_config(vars, &params);
8630 break;
8631 case 6:
8632 result = send_oscam_services(vars, &params);
8633 break;
8634 case 7:
8635 result = send_oscam_user_config_edit(vars, &params, 0);
8636 break;
8637 //case 8: css file
8638 case 9:
8639 result = send_oscam_services_edit(vars, &params);
8640 break;
8641 case 10:
8642 result = send_oscam_savetpls(vars);
8643 break;
8644 case 11:
8645 result = send_oscam_shutdown(vars, f, &params, 0, keepalive, extraheader);
8646 break;
8647 case 12:
8648 result = send_oscam_script(vars, &params);
8649 break;
8650 case 13:
8651 result = send_oscam_scanusb(vars);
8652 break;
8653 case 14:
8654 result = send_oscam_files(vars, &params, 0);
8655 break;
8656 case 15:
8657 result = send_oscam_reader_stats(vars, &params, 0);
8658 break;
8659 case 16:
8660 result = send_oscam_failban(vars, &params, 0);
8661 break;
8662 //case 17: js file
8663 case 18:
8664 result = send_oscam_api(vars, f, &params, keepalive, 1, extraheader);
8665 break; //oscamapi.html
8666 case 19:
8667 result = send_oscam_image(vars, f, &params, NULL, modifiedheader, etagheader, extraheader);
8668 break;
8669 case 20:
8670 result = send_oscam_image(vars, f, &params, "ICMAI", modifiedheader, etagheader, extraheader);
8671 break;
8672 case 21:
8673 result = send_oscam_graph(vars);
8674 break;
8675 case 22:
8676 result = send_oscam_api(vars, f, &params, keepalive, 1, extraheader);
8677 break; //oscamapi.xml
8678 #ifdef CS_CACHEEX
8679 case 23:
8680 result = send_oscam_cacheex(vars, &params, 0);
8681 break;
8682 #endif
8683 case 24:
8684 result = send_oscam_api(vars, f, &params, keepalive, 2, extraheader);
8685 break; //oscamapi.json
8686 case 25:
8687 result = send_oscam_EMM(vars, &params);
8688 break; //emm.html
8689 case 26:
8690 result = send_oscam_EMM_running(vars, &params);
8691 break; //emm_running.html
8692 case 27:
8693 result = send_oscam_robots_txt(f);
8694 break; //robots.txt
8695 #ifdef MODULE_GHTTP
8696 case 28:
8697 result = send_oscam_ghttp(vars, &params, 0);
8698 break;
8699 #endif
8700 #ifdef WEBIF_LIVELOG
8701 case 29:
8702 result = send_oscam_logpoll(vars, &params);
8703 break;
8704 //case 30: jquery.js
8705 #endif
8706 default:
8707 result = send_oscam_status(vars, &params, 0);
8708 break;
8710 if(pgidx != 19 && pgidx != 20 && pgidx != 21 && pgidx != 27) { cs_writeunlock(__func__, &http_lock); }
8712 if(result == NULL || !strcmp(result, "0") || strlen(result) == 0) { send_error500(f); }
8713 else if(strcmp(result, "1"))
8715 //it doesn't make sense to check for modified etagheader here as standard template has timestamp in output and so site changes on every request
8716 if(pgidx == 18)
8717 { send_headers(f, 200, "OK", extraheader, "text/xml", 0, strlen(result), NULL, 0); }
8718 else if(pgidx == 21)
8719 { send_headers(f, 200, "OK", extraheader, "image/svg+xml", 0, strlen(result), NULL, 0); }
8720 else if(pgidx == 24)
8721 { send_headers(f, 200, "OK", extraheader, "text/javascript", 0, strlen(result), NULL, 0); }
8722 else
8723 { send_headers(f, 200, "OK", extraheader, "text/html", 0, strlen(result), NULL, 0); }
8724 webif_write(result, f);
8726 tpl_clear(vars);
8728 NULLFREE(filebuf);
8730 while(*keepalive == 1 && !exit_oscam);
8731 return 0;
8734 static void *serve_process(void *conn)
8736 struct s_connection *myconn = (struct s_connection *)conn;
8737 int32_t s = myconn->socket;
8738 struct s_client *cl = myconn->cl;
8739 IN_ADDR_T in;
8740 IP_ASSIGN(in, myconn->remote);
8742 set_thread_name(__func__);
8744 #ifdef WITH_SSL
8745 SSL *ssl = myconn->ssl;
8746 SAFE_SETSPECIFIC(getssl, ssl);
8747 #endif
8748 NULLFREE(myconn);
8750 SAFE_SETSPECIFIC(getip, &in);
8751 SAFE_SETSPECIFIC(getclient, cl);
8753 int8_t keepalive = 0;
8754 SAFE_SETSPECIFIC(getkeepalive, &keepalive);
8756 #ifdef WITH_SSL
8757 if(ssl_active)
8759 if(SSL_set_fd(ssl, s))
8761 int32_t ok = (SSL_accept(ssl) != -1);
8762 if(!ok)
8764 int8_t tries = 100;
8765 while(!ok && tries--)
8767 int32_t err = SSL_get_error(ssl, -1);
8768 if(err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
8769 { break; }
8770 else
8772 struct pollfd pfd;
8773 pfd.fd = s;
8774 pfd.events = POLLIN | POLLPRI;
8775 int32_t rc = poll(&pfd, 1, -1);
8776 if(rc < 0)
8778 if(errno == EINTR || errno == EAGAIN) { continue; }
8779 break;
8781 if(rc == 1)
8782 { ok = (SSL_accept(ssl) != -1); }
8786 if(ok)
8788 process_request((FILE *)ssl, in);
8790 else
8792 FILE *f;
8793 f = fdopen(s, "r+");
8794 if(f != NULL)
8796 char *ptr, *filebuf = NULL, *host = NULL;
8797 int32_t bufsize = readRequest(f, in, &filebuf, 1);
8799 if(filebuf)
8801 filebuf[bufsize] = '\0';
8802 host = strstr(filebuf, "Host: ");
8803 if(host)
8805 host += 6;
8806 ptr = strchr(host, '\r');
8807 if(ptr) { ptr[0] = '\0'; }
8810 if(host)
8812 char extra[strlen(host) + 20];
8813 snprintf(extra, sizeof(extra), "Location: https://%s", host);
8814 send_error(f, 301, "Moved Permanently", extra, "This web server is running in SSL mode.", 1);
8816 else
8817 { send_error(f, 200, "Bad Request", NULL, "This web server is running in SSL mode.", 1); }
8818 fflush(f);
8819 fclose(f);
8820 NULLFREE(filebuf);
8822 else
8824 cs_log_dbg(D_TRACE, "WebIf: fdopen(%d) failed. (errno=%d %s)", s, errno, strerror(errno));
8828 else { cs_log("WebIf: Error calling SSL_set_fd()."); }
8829 SSL_shutdown(ssl);
8830 close(s);
8831 SSL_free(ssl);
8833 else
8834 #endif
8836 FILE *f;
8837 f = fdopen(s, "r+");
8838 if(f != NULL)
8840 process_request(f, in);
8841 fflush(f);
8842 fclose(f);
8844 else
8846 cs_log_dbg(D_TRACE, "WebIf: fdopen(%d) failed. (errno=%d %s)", s, errno, strerror(errno));
8848 shutdown(s, SHUT_WR);
8849 close(s);
8852 return NULL;
8855 /* Creates a random string with specified length. Note that dst must be one larger than size to hold the trailing \0*/
8856 static void create_rand_str(char *dst, int32_t size)
8858 int32_t i;
8859 for(i = 0; i < size; ++i)
8861 dst[i] = (rand() % 94) + 32;
8863 dst[i] = '\0';
8866 static void *http_server(void *UNUSED(d))
8868 struct s_client *cl = create_client(first_client->ip);
8869 if(cl == NULL) { return NULL; }
8870 SAFE_SETSPECIFIC(getclient, cl);
8871 cl->typ = 'h';
8872 int32_t s, reuse = 1;
8873 struct s_connection *conn;
8875 set_thread_name(__func__);
8877 /* Create random string for nonce value generation */
8878 create_rand_str(noncekey, 32);
8880 /* Prepare base64 decoding array */
8881 b64prepare();
8882 webif_tpls_prepare();
8884 tpl_checkDiskRevisions();
8886 cs_lock_create(__func__, &http_lock, "http_lock", 10000);
8887 init_noncelocks();
8889 memset(&p_stat_cur, 0x0, sizeof(p_stat_cur));
8891 if(pthread_key_create(&getip, NULL))
8893 cs_log("Could not create getip");
8894 return NULL;
8896 if(pthread_key_create(&getkeepalive, NULL))
8898 cs_log("Could not create getkeepalive");
8899 return NULL;
8902 struct SOCKADDR sin;
8903 socklen_t len = 0;
8904 memset(&sin, 0, sizeof(sin));
8906 bool do_ipv6 = config_enabled(IPV6SUPPORT);
8907 #ifdef IPV6SUPPORT
8908 if(do_ipv6)
8910 len = sizeof(struct sockaddr_in6);
8911 if((sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0)
8913 cs_log("HTTP Server: ERROR: Creating IPv6 socket failed! (errno=%d %s)", errno, strerror(errno));
8914 cs_log("HTTP Server: Falling back to IPv4.");
8915 do_ipv6 = false;
8917 else
8919 struct sockaddr_in6 *ia = (struct sockaddr_in6 *)&sin;
8920 ia->sin6_family = AF_INET6;
8921 ia->sin6_addr = in6addr_any;
8922 ia->sin6_port = htons(cfg.http_port);
8925 #endif
8926 if(!do_ipv6)
8928 len = sizeof(struct sockaddr_in);
8929 if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
8931 cs_log("HTTP Server: ERROR: Creating socket failed! (errno=%d %s)", errno, strerror(errno));
8932 return NULL;
8934 SIN_GET_FAMILY(sin) = AF_INET;
8935 if(IP_ISSET(cfg.http_srvip))
8936 { IP_ASSIGN(SIN_GET_ADDR(sin), cfg.http_srvip); }
8937 else if(IP_ISSET(cfg.srvip))
8938 { IP_ASSIGN(SIN_GET_ADDR(sin), cfg.srvip); }
8939 // The default is INADDR_ANY (0)
8940 SIN_GET_PORT(sin) = htons(cfg.http_port);
8943 if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
8945 cs_log("HTTP Server: Setting SO_REUSEADDR via setsockopt failed! (errno=%d %s)", errno, strerror(errno));
8948 if(bind(sock, (struct sockaddr *)&sin, len) < 0)
8950 cs_log("HTTP Server couldn't bind on port %d (errno=%d %s). Not starting HTTP!", cfg.http_port, errno, strerror(errno));
8951 close(sock);
8952 return NULL;
8955 if(listen(sock, SOMAXCONN) < 0)
8957 cs_log("HTTP Server: Call to listen() failed! (errno=%d %s)", errno, strerror(errno));
8958 close(sock);
8959 return NULL;
8962 #ifdef WITH_SSL
8963 if(pthread_key_create(&getssl, NULL))
8965 cs_log("Could not create getssl");
8968 SSL_CTX *ctx = NULL;
8969 if(cfg.http_use_ssl)
8971 ctx = SSL_Webif_Init();
8972 if(ctx == NULL)
8973 { cs_log("SSL could not be initialized. Starting WebIf in plain mode."); }
8974 else { ssl_active = 1; }
8976 else { ssl_active = 0; }
8977 cs_log("HTTP Server running. ip=%s port=%d%s", cs_inet_ntoa(SIN_GET_ADDR(sin)), cfg.http_port, ssl_active ? " (SSL)" : "");
8978 #else
8979 cs_log("HTTP Server running. ip=%s port=%d", cs_inet_ntoa(SIN_GET_ADDR(sin)), cfg.http_port);
8980 #endif
8982 struct SOCKADDR remote;
8983 memset(&remote, 0, sizeof(remote));
8985 while(!exit_oscam)
8987 if((s = accept(sock, (struct sockaddr *) &remote, &len)) < 0)
8989 if(exit_oscam)
8990 { break; }
8991 if(errno != EAGAIN && errno != EINTR)
8993 cs_log("HTTP Server: Error calling accept() (errno=%d %s)", errno, strerror(errno));
8994 cs_sleepms(100);
8996 else { cs_sleepms(5); }
8997 continue;
8999 else
9001 getpeername(s, (struct sockaddr *) &remote, &len);
9002 if(!cs_malloc(&conn, sizeof(struct s_connection)))
9004 close(s);
9005 continue;
9007 setTCPTimeouts(s);
9008 cur_client()->last = time((time_t *)0); //reset last busy time
9009 conn->cl = cur_client();
9010 #ifdef IPV6SUPPORT
9011 if(do_ipv6)
9013 struct sockaddr_in6 *ra = (struct sockaddr_in6 *)&remote;
9014 memcpy(&conn->remote, &ra->sin6_addr, sizeof(struct in6_addr));
9016 else
9018 struct sockaddr_in *fba = (struct sockaddr_in *)&remote;
9019 struct in6_addr taddr;
9020 memset(&taddr, 0, sizeof(taddr));
9021 taddr.s6_addr32[3] = fba->sin_addr.s_addr;
9022 memcpy(&conn->remote, &taddr, sizeof(struct in6_addr));
9024 #else
9025 memcpy(&conn->remote, &remote.sin_addr, sizeof(struct in_addr));
9026 #endif
9027 conn->socket = s;
9028 #ifdef WITH_SSL
9029 conn->ssl = NULL;
9030 if(ssl_active)
9032 conn->ssl = SSL_new(ctx);
9033 if(conn->ssl == NULL)
9035 close(s);
9036 cs_log("WebIf: Error calling SSL_new().");
9037 continue;
9040 #endif
9042 int32_t ret = start_thread("webif workthread", serve_process, (void *)conn, NULL, 1, 1);
9043 if(ret)
9045 NULLFREE(conn);
9049 // Wait a bit so that we don't close ressources while http threads are active
9050 cs_sleepms(300);
9051 #ifdef WITH_SSL
9052 SSL_CTX_free(ctx);
9053 CRYPTO_set_dynlock_create_callback(NULL);
9054 CRYPTO_set_dynlock_lock_callback(NULL);
9055 CRYPTO_set_dynlock_destroy_callback(NULL);
9056 CRYPTO_set_locking_callback(NULL);
9057 CRYPTO_set_id_callback(NULL);
9058 OPENSSL_free(lock_cs);
9059 lock_cs = NULL;
9060 #endif
9061 cs_log("HTTP Server stopped");
9062 free_client(cl);
9063 close(sock);
9064 return NULL;
9067 void webif_client_reset_lastresponsetime(struct s_client * cl)
9069 int32_t i;
9070 for(i = 0; i < CS_ECM_RINGBUFFER_MAX; i++)
9072 cl->cwlastresptimes[i].duration = 0;
9073 cl->cwlastresptimes[i].timestamp = time((time_t *)0);
9074 cl->cwlastresptimes[i].rc = 0;
9076 cl->cwlastresptimes_last = 0;
9079 void webif_client_add_lastresponsetime(struct s_client * cl, int32_t ltime, time_t timestamp, int32_t rc)
9081 int32_t last = cl->cwlastresptimes_last = (cl->cwlastresptimes_last + 1) & (CS_ECM_RINGBUFFER_MAX - 1);
9082 cl->cwlastresptimes[last].duration = ltime > 9999 ? 9999 : ltime;
9083 cl->cwlastresptimes[last].timestamp = timestamp;
9084 cl->cwlastresptimes[last].rc = rc;
9087 void webif_client_init_lastreader(struct s_client * client, ECM_REQUEST * er, struct s_reader * er_reader, const char *stxt[])
9089 if(er_reader)
9091 if(er->rc == E_FOUND)
9092 { cs_strncpy(client->lastreader, er_reader->label, sizeof(client->lastreader)); }
9093 else if(er->rc == E_CACHEEX)
9094 { cs_strncpy(client->lastreader, "cache3", sizeof(client->lastreader)); }
9095 else if(er->rc < E_NOTFOUND)
9096 { snprintf(client->lastreader, sizeof(client->lastreader) - 1, "%.54s (cache)", er_reader->label); }
9097 else
9098 { cs_strncpy(client->lastreader, stxt[er->rc], sizeof(client->lastreader)); }
9100 else
9102 cs_strncpy(client->lastreader, stxt[er->rc], sizeof(client->lastreader));
9106 void webif_init(void)
9108 char buf[8], fname[256];
9109 snprintf(buf, 8, "%'d", 7);
9110 if(strcmp(buf, "7"))
9112 useLocal = 0;
9115 if(cfg.http_port == 0)
9117 cs_log("http disabled");
9118 return;
9121 get_config_filename(fname, sizeof(fname), "oscam.srvid2");
9122 use_srvid2 = file_exists(fname);
9124 if(start_thread("http", http_server, NULL, &httpthread, 0, 1) == 0)
9126 httpthread_running = 1;
9130 void webif_close(void)
9132 if(!sock)
9133 { return; }
9135 shutdown(sock, 2);
9136 close(sock);
9138 if(httpthread_running)
9139 { SAFE_THREAD_JOIN(httpthread, NULL); }
9142 #endif