revert breaks some stupid old compilers
[oscam.git] / module-webif.c
blobfd3f816cc8157f6e1286e904fddbda25d9ddb3a0
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 #endif
37 extern const struct s_cardreader *cardreaders[];
38 extern char cs_confdir[];
39 extern uint32_t ecmcwcache_size;
40 extern uint8_t cs_http_use_utf8;
41 extern uint32_t cfg_sidtab_generation;
42 extern int32_t exit_oscam;
43 extern uint8_t cacheex_peer_id[8];
45 extern char *entitlement_type[];
46 extern char *RDR_CD_TXT[];
48 int32_t ssl_active = 0;
49 char noncekey[33];
50 pthread_key_t getkeepalive;
51 static pthread_key_t getip;
52 pthread_key_t getssl;
53 static CS_MUTEX_LOCK http_lock;
54 CS_MUTEX_LOCK *lock_cs;
56 static uint8_t useLocal = 1;
57 #define PRINTF_LOCAL_D useLocal ? "%'d" : "%d"
58 #define PRINTF_LOCAL_F useLocal ? "%'.0f" : "%.0f"
59 #define PRINTF_LOCAL_MB useLocal ? "%'.2f MB" : "%.2f MB"
61 static int8_t httpthread_running = 0;
62 static pthread_t httpthread;
63 static int32_t sock;
64 enum refreshtypes { REFR_ACCOUNTS, REFR_READERS, REFR_CLIENTS, REFR_SERVER, REFR_ANTICASC, REFR_SERVICES };
66 //initialize structs for calculating cpu-usage depending on time between refresh of status_page
67 static struct pstat p_stat_cur;
68 static struct pstat p_stat_old;
70 static bool use_srvid2 = false;
72 /* constants for menuactivating */
73 #define MNU_STATUS 0
74 #define MNU_LIVELOG 1
75 #define MNU_CONFIG 2
76 #define MNU_READERS 3
77 #define MNU_USERS 4
78 #define MNU_SERVICES 5
79 #define MNU_FILES 6
80 #define MNU_FAILBAN 7
81 #define MNU_CACHEEX 8
82 #define MNU_SCRIPT 9
83 #define MNU_SHUTDOWN 10
84 #define MNU_TOTAL_ITEMS 11 // sum of items above
86 /* constants for config.html submenuactivating */
87 #define MNU_CFG_GLOBAL 0
88 #define MNU_CFG_ANTICASC 1
89 #define MNU_CFG_CACHE 2
90 #define MNU_CFG_LOADBAL 3
91 #define MNU_CFG_CAMD33 4
92 #define MNU_CFG_CAMD35 5
93 #define MNU_CFG_CAMD35TCP 6
94 #define MNU_CFG_CCCAM 7
95 #define MNU_CFG_NEWCAMD 8
96 #define MNU_CFG_GBOX 9
97 #define MNU_CFG_RADEGAST 10
98 #define MNU_CFG_SCAM 11
99 #define MNU_CFG_SERIAL 12
100 #define MNU_CFG_DVBAPI 13
101 #define MNU_CFG_LCD 14
102 #define MNU_CFG_MONITOR 15
103 #define MNU_CFG_WEBIF 16
105 /* constants for files.html submenuactivating */
106 #define MNU_CFG_FVERSION 0
107 #define MNU_CFG_FCONF 1
108 #define MNU_CFG_FUSER 2
109 #define MNU_CFG_FSERVER 3
110 #define MNU_CFG_FSRVID 4
111 #define MNU_CFG_FDVBAPI 5
112 #define MNU_CFG_FACLOG 6
113 #define MNU_CFG_FLOGFILE 7
114 #define MNU_CFG_FUSERFILE 8
115 #define MNU_CFG_FSERVICES 9
116 #define MNU_CFG_FPROVID 10
117 #define MNU_CFG_FTIERS 11
118 #define MNU_CFG_FRATELIMIT 12
119 #define MNU_CFG_FWHITELIST 13
120 #define MNU_CFG_FSRVID2 14
121 #define MNU_CFG_FFAKECWS 15
122 #define MNU_CFG_FCSS 16
123 #define MNU_CFG_FTWIN 17
124 #define MNU_CFG_FKEYCW 18
125 /* constants for files.html for GBOX submenuactivating */
126 #define MNU_GBX_FSCINF 19
127 #define MNU_GBX_FSHRINF 20
128 #define MNU_GBX_FSHRONL 21
129 #define MNU_GBX_FVERS 22
130 #define MNU_GBX_FATTACK 23
131 #define MNU_GBX_FSMSLOG 24
132 #define MNU_GBX_FSMSACK 25
133 #define MNU_GBX_FSMSNACK 26
134 #define MNU_GBX_FSTAINF 27
135 #define MNU_GBX_FEXPINF 28
136 #define MNU_GBX_INFOLOG 29
138 #define MNU_CFG_TOTAL_ITEMS 30 // sum of items above. Use it for "All inactive" in function calls too.
140 static void set_status_info_var(struct templatevars *vars, char *varname, int no_data, char *fmt, double value) {
141 if (no_data)
142 tpl_addVar(vars, TPLADD, varname, "N/A");
143 else
144 tpl_printf(vars, TPLADD, varname, fmt, value);
148 * Creates vars Memory/CPU/OSCAM info in for status_page
149 * if check_available == 0 N/A will be displayed
150 * Bit mapping
151 * mem 0 total, 1 used & free, 2 buff, cached & free incl. buff, 3 share
152 * swap 4 total, 5 used & free,
153 * proc 6 count
154 * cpu 7 load
155 * oscam 8 vsize & rssize, 9 cpu user, 10 cpu sys, 11 cpu sum, 12 cpu refreshtime
156 * unused 13 - 15
158 static void set_status_info(struct templatevars *vars, struct pstat stats){
159 set_status_info_var(vars, "MEM_CUR_TOTAL", stats.check_available & (1 << 0), PRINTF_LOCAL_MB , (double)stats.mem_total/(1024.0*1024.0));
160 set_status_info_var(vars, "MEM_CUR_FREE", stats.check_available & (1 << 1), PRINTF_LOCAL_MB , (double)stats.mem_free/(1024.0*1024.0));
161 set_status_info_var(vars, "MEM_CUR_USED", stats.check_available & (1 << 1), PRINTF_LOCAL_MB , (double)stats.mem_used/(1024.0*1024.0));
162 set_status_info_var(vars, "MEM_CUR_BUFF", stats.check_available & (1 << 2), PRINTF_LOCAL_MB , (double)stats.mem_buff/(1024.0*1024.0));
163 set_status_info_var(vars, "MEM_CUR_CACHED", stats.check_available & (1 << 2), PRINTF_LOCAL_MB , (double)stats.mem_cached/(1024.0*1024.0));
164 set_status_info_var(vars, "MEM_CUR_FREEM", stats.check_available & (1 << 2), PRINTF_LOCAL_MB , (double)stats.mem_freem/(1024.0*1024.0));
165 set_status_info_var(vars, "MEM_CUR_SHARE", stats.check_available & (1 << 3), PRINTF_LOCAL_MB , (double)stats.mem_share/(1024.0*1024.0));
166 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));
167 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));
168 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));
170 set_status_info_var(vars, "SERVER_PROCS", stats.check_available & (1 << 6), PRINTF_LOCAL_F , stats.info_procs);
172 set_status_info_var(vars, "CPU_LOAD_0", stats.check_available & (1 << 7), "%.2f" , stats.cpu_avg[0]);
173 set_status_info_var(vars, "CPU_LOAD_1", stats.check_available & (1 << 7), "%.2f" , stats.cpu_avg[1]);
174 set_status_info_var(vars, "CPU_LOAD_2", stats.check_available & (1 << 7), "%.2f" , stats.cpu_avg[2]);
176 set_status_info_var(vars, "OSCAM_VMSIZE", stats.check_available & (1 << 8), PRINTF_LOCAL_MB , (double)stats.vsize/(1024.0*1024.0));
177 set_status_info_var(vars, "OSCAM_RSSSIZE", stats.check_available & (1 << 8), PRINTF_LOCAL_MB , (double)stats.rss/(1024.0*1024.0));
178 set_status_info_var(vars, "OSCAM_CPU_USER", stats.check_available & (1 << 9), "%.2f %%" , stats.cpu_usage_user);
179 set_status_info_var(vars, "OSCAM_CPU_SYS", stats.check_available & (1 << 10), "%.2f %%" , stats.cpu_usage_sys);
180 double sum_cpu = stats.cpu_usage_sys + stats.cpu_usage_user;
181 set_status_info_var(vars, "OSCAM_CPU_SUM", stats.check_available & (1 << 11), "%.2f %%" , sum_cpu);
183 if (stats.check_available & (1 << 12)) {
184 tpl_addVar(vars, TPLADD, "OSCAM_REFRESH" , "N/A");
185 } else {
186 tpl_printf(vars, TPLADD, "OSCAM_REFRESH" , "%02"PRId64":%02"PRId64":%02"PRId64"h",
187 stats.gone_refresh / 3600,
188 (stats.gone_refresh / 60) % 60,
189 stats.gone_refresh % 60);
193 static void clear_account_stats(struct s_auth *account)
195 account->cwfound = 0;
196 account->cwcache = 0;
197 account->cwnot = 0;
198 account->cwtun = 0;
199 account->cwignored = 0;
200 account->cwtout = 0;
201 account->emmok = 0;
202 account->emmnok = 0;
203 #ifdef CW_CYCLE_CHECK
204 account->cwcycledchecked = 0;
205 account->cwcycledok = 0;
206 account->cwcyclednok = 0;
207 account->cwcycledign = 0;
208 #endif
209 cacheex_clear_account_stats(account);
212 static void clear_all_account_stats(void)
214 struct s_auth *account = cfg.account;
215 while(account)
217 clear_account_stats(account);
218 account = account->next;
222 #ifdef CS_CACHEEX
223 static void cacheex_clear_all_stats(void)
225 struct s_auth *account = cfg.account;
226 while(account)
228 cacheex_clear_account_stats(account);
229 account = account->next;
231 struct s_client *cl;
232 for(cl = first_client->next; cl ; cl = cl->next)
234 cacheex_clear_client_stats(cl);
235 ll_clear_data(cl->ll_cacheex_stats);
237 cacheex_clear_client_stats(first_client);
239 #endif
241 static void clear_info_clients_stats(void)
243 first_client->cwfound = 0;
244 first_client->cwcache = 0;
245 first_client->cwnot = 0;
246 first_client->cwtun = 0;
247 first_client->cwignored = 0;
248 first_client->cwtout = 0;
249 first_client->emmok = 0;
250 first_client->emmnok = 0;
251 cacheex_clear_client_stats(first_client);
254 static void clear_info_readers_stats(void)
256 int8_t i;
257 cs_writelock(__func__, &readerlist_lock);
258 LL_ITER itr = ll_iter_create(configured_readers);
259 struct s_reader *rdr;
260 while((rdr = ll_iter_next(&itr)))
262 rdr->webif_ecmsok = 0;
263 rdr->webif_ecmsnok = 0;
264 rdr->webif_ecmstout = 0;
265 rdr->webif_ecmsfilteredhead = 0;
266 rdr->webif_ecmsfilteredlen = 0;
268 for(i = 0; i < 4; i++)
270 rdr->webif_emmerror[i] = 0;
271 rdr->webif_emmwritten[i] = 0;
272 rdr->webif_emmskipped[i] = 0;
273 rdr->webif_emmblocked[i] = 0;
276 cs_writeunlock(__func__, &readerlist_lock);
279 static void set_ecm_info(struct templatevars * vars)
281 //if one of the stats overloaded, reset all stats!
282 if(first_client->cwfound<0
283 || first_client->cwnot<0
284 || first_client->cwignored<0
285 || first_client->cwtout<0
286 || first_client->cwcache<0
287 || first_client->cwtun<0
288 || first_client->emmok<0
289 || first_client->emmnok<0
290 #ifdef CS_CACHEEX
291 || first_client->cwcacheexgot<0
292 || first_client->cwcacheexpush<0
293 || first_client->cwcacheexhit<0
294 #endif
296 clear_info_clients_stats();
298 //end reset stats
300 int ecm = 0, emm = 0;
301 double ecmsum = first_client->cwfound + first_client->cwcache + first_client->cwnot + first_client->cwtout; //dont count TUN its included
302 if(ecmsum < 1) {ecmsum = 1; ecm = 1;}
303 double ecmpos = first_client->cwfound + first_client->cwcache; // dont count TUN its included
304 if(ecmpos < 1) {ecmpos = 1;}
305 double ecmneg = first_client->cwnot + first_client->cwtout; //dont count IGN its not part of neagtiv
306 if(ecmneg < 1) {ecmneg = 1;}
307 double emmsum = first_client->emmok + first_client->emmnok;
308 if(emmsum < 1) {emmsum = 1; emm = 1;}
310 tpl_printf(vars, TPLADD, "TOTAL_ECM_MIN", "%d", first_client->n_request[0]);
311 tpl_printf(vars, TPLADD, "TOTAL_CW", PRINTF_LOCAL_F, !ecm ? ecmsum : 0);
312 tpl_printf(vars, TPLADD, "TOTAL_CWOK", PRINTF_LOCAL_F, (double)first_client->cwfound);
313 tpl_printf(vars, TPLADD, "TOTAL_CWNOK", PRINTF_LOCAL_F, (double)first_client->cwnot);
314 tpl_printf(vars, TPLADD, "TOTAL_CWIGN", PRINTF_LOCAL_F, (double)first_client->cwignored);
315 tpl_printf(vars, TPLADD, "TOTAL_CWTOUT", PRINTF_LOCAL_F, (double)first_client->cwtout);
316 tpl_printf(vars, TPLADD, "TOTAL_CWCACHE", PRINTF_LOCAL_F, (double)first_client->cwcache);
317 tpl_printf(vars, TPLADD, "TOTAL_CWTUN", PRINTF_LOCAL_F, (double)first_client->cwtun);
318 tpl_printf(vars, TPLADD, "TOTAL_CWPOS", PRINTF_LOCAL_F, (double)first_client->cwfound + (double)first_client->cwcache);
319 tpl_printf(vars, TPLADD, "TOTAL_CWNEG", PRINTF_LOCAL_F, (double)first_client->cwnot + (double)first_client->cwtout);
320 tpl_printf(vars, TPLADD, "TOTAL_EM", PRINTF_LOCAL_F, !emm ? emmsum : 0);
321 tpl_printf(vars, TPLADD, "TOTAL_EMOK", PRINTF_LOCAL_F, (double)first_client->emmok);
322 tpl_printf(vars, TPLADD, "TOTAL_EMNOK", PRINTF_LOCAL_F, (double)first_client->emmnok);
323 tpl_printf(vars, TPLADD, "REL_CWOK", "%.2f", (double)first_client->cwfound * 100 / ecmsum);
324 tpl_printf(vars, TPLADD, "REL_CWNOK", "%.2f", (double)first_client->cwnot * 100 / ecmsum);
325 //tpl_printf(vars, TPLADD, "REL_CWIGN", "%.2f", (double)first_client->cwignored * 100 / ecmsum);
326 tpl_printf(vars, TPLADD, "REL_CWTOUT", "%.2f", (double)first_client->cwtout * 100 / ecmsum);
327 tpl_printf(vars, TPLADD, "REL_CWCACHE", "%.2f", (double)first_client->cwcache * 100 / ecmsum);
328 tpl_printf(vars, TPLADD, "REL_CWTUN", "%.2f", (double)first_client->cwtun * 100 / ecmsum);
329 tpl_printf(vars, TPLADD, "REL_CWPOS", "%.2f", (double)(first_client->cwfound + first_client->cwcache) * 100 / ecmsum);
330 tpl_printf(vars, TPLADD, "REL_CWNEG", "%.2f", (double)(first_client->cwnot + first_client->cwtout) * 100 / ecmsum);
331 tpl_printf(vars, TPLADD, "REL_EMOK", "%.2f", (double)first_client->emmok * 100 / emmsum);
332 tpl_printf(vars, TPLADD, "REL_EMNOK", "%.2f", (double)first_client->emmnok * 100 / emmsum);
333 tpl_printf(vars, TPLADD, "REL_CWPOSOK", "%.2f", (double)first_client->cwfound * 100 / ecmpos);
334 tpl_printf(vars, TPLADD, "REL_CWPOSCACHE", "%.2f", (double)first_client->cwcache * 100 / ecmpos);
335 tpl_printf(vars, TPLADD, "REL_CWNEGNOK", "%.2f", (double)first_client->cwnot * 100 / ecmneg);
336 //tpl_printf(vars, TPLADD, "REL_CWNEGIGN", "%.2f", (double)first_client->cwignored * 100 / ecmneg);
337 tpl_printf(vars, TPLADD, "REL_CWNEGTOUT", "%.2f", (double)first_client->cwtout * 100 / ecmneg);
339 double totalrdrneg = 0, totalrdrpos = 0;
340 double totalrdrok = 0, totalrdrnok = 0, totalrdrtout = 0;
341 double flen = 0, fhead = 0;
342 double teruk = 0, terg = 0, ters = 0, teruq = 0;
343 double twruk = 0, twrg = 0, twrs = 0, twruq = 0;
344 double tskuk = 0, tskg = 0, tsks = 0, tskuq = 0;
345 double tbluk = 0, tblg = 0, tbls = 0, tbluq = 0;
347 ecmsum = 0;
348 emmsum = 0;
350 cs_readlock(__func__, &readerlist_lock);
351 LL_ITER itr = ll_iter_create(configured_readers);
352 struct s_reader *rdr;
353 while((rdr = ll_iter_next(&itr)))
355 if (rdr->webif_ecmsok) { totalrdrok += rdr->webif_ecmsok; }
356 if (rdr->webif_ecmsnok) { totalrdrnok += rdr->webif_ecmsnok; }
357 if (rdr->webif_ecmstout) { totalrdrtout += rdr->webif_ecmstout; }
359 if (rdr->webif_ecmsfilteredlen) { flen += rdr->webif_ecmsfilteredlen; }
360 if (rdr->webif_ecmsfilteredhead) { fhead += rdr->webif_ecmsfilteredhead; }
362 if (rdr->webif_emmerror[0]) { teruk += rdr->webif_emmerror[0]; }
363 if (rdr->webif_emmerror[1]) { teruq += rdr->webif_emmerror[1]; }
364 if (rdr->webif_emmerror[2]) { ters += rdr->webif_emmerror[2]; }
365 if (rdr->webif_emmerror[3]) { terg += rdr->webif_emmerror[3]; }
367 if (rdr->webif_emmwritten[0]) { twruk += rdr->webif_emmwritten[0]; }
368 if (rdr->webif_emmwritten[1]) { twruq += rdr->webif_emmwritten[1]; }
369 if (rdr->webif_emmwritten[2]) { twrs += rdr->webif_emmwritten[2]; }
370 if (rdr->webif_emmwritten[3]) { twrg += rdr->webif_emmwritten[3]; }
372 if (rdr->webif_emmskipped[0]) { tskuk += rdr->webif_emmskipped[0]; }
373 if (rdr->webif_emmskipped[1]) { tskuq += rdr->webif_emmskipped[1]; }
374 if (rdr->webif_emmskipped[2]) { tsks += rdr->webif_emmskipped[2]; }
375 if (rdr->webif_emmskipped[3]) { tskg += rdr->webif_emmskipped[3]; }
377 if (rdr->webif_emmblocked[0]) { tbluk += rdr->webif_emmblocked[0]; }
378 if (rdr->webif_emmblocked[1]) { tbluq += rdr->webif_emmblocked[1]; }
379 if (rdr->webif_emmblocked[2]) { tbls += rdr->webif_emmblocked[2]; }
380 if (rdr->webif_emmblocked[3]) { tblg += rdr->webif_emmblocked[3]; }
382 cs_readunlock(__func__, &readerlist_lock);
384 totalrdrneg = totalrdrnok + totalrdrtout;
385 totalrdrpos = totalrdrok;
386 ecmsum = totalrdrok + totalrdrnok + totalrdrtout;
388 tpl_printf(vars, TPLADD, "TOTAL_CWOK_READERS", PRINTF_LOCAL_F, totalrdrok);
389 tpl_printf(vars, TPLADD, "TOTAL_CWNOK_READERS", PRINTF_LOCAL_F, totalrdrnok);
390 tpl_printf(vars, TPLADD, "TOTAL_CWTOUT_READERS", PRINTF_LOCAL_F, totalrdrtout);
391 tpl_printf(vars, TPLADD, "REL_CWOK_READERS", "%.2f", totalrdrok * 100 / ecmsum);
392 tpl_printf(vars, TPLADD, "REL_CWNOK_READERS", "%.2f", totalrdrnok * 100 / ecmsum);
393 tpl_printf(vars, TPLADD, "REL_CWTOUT_READERS", "%.2f", totalrdrtout * 100 / ecmsum);
394 tpl_printf(vars, TPLADD, "TOTAL_CWPOS_READERS", PRINTF_LOCAL_F, totalrdrpos);
395 tpl_printf(vars, TPLADD, "TOTAL_CWNEG_READERS", PRINTF_LOCAL_F, totalrdrneg);
396 tpl_printf(vars, TPLADD, "REL_CWPOS_READERS", "%.2f", totalrdrpos * 100 / ecmsum);
397 tpl_printf(vars, TPLADD, "REL_CWNEG_READERS", "%.2f", totalrdrneg * 100 / ecmsum);
398 tpl_printf(vars, TPLADD, "TOTAL_ELENR", PRINTF_LOCAL_F, flen);
399 tpl_printf(vars, TPLADD, "TOTAL_EHEADR", PRINTF_LOCAL_F, fhead);
400 tpl_printf(vars, TPLADD, "TOTAL_SUM_ALL_READERS_ECM", PRINTF_LOCAL_F, ecmsum);
402 tpl_printf(vars, TPLADD, "TOTAL_EMMERRORUK_READERS", PRINTF_LOCAL_F, teruk);
403 tpl_printf(vars, TPLADD, "TOTAL_EMMERRORG_READERS", PRINTF_LOCAL_F, terg);
404 tpl_printf(vars, TPLADD, "TOTAL_EMMERRORS_READERS", PRINTF_LOCAL_F, ters);
405 tpl_printf(vars, TPLADD, "TOTAL_EMMERRORUQ_READERS", PRINTF_LOCAL_F, teruq);
406 tpl_printf(vars, TPLADD, "TOTAL_EMMWRITTENUK_READERS", PRINTF_LOCAL_F, twruk);
407 tpl_printf(vars, TPLADD, "TOTAL_EMMWRITTENG_READERS", PRINTF_LOCAL_F, twrg);
408 tpl_printf(vars, TPLADD, "TOTAL_EMMWRITTENS_READERS", PRINTF_LOCAL_F, twrs);
409 tpl_printf(vars, TPLADD, "TOTAL_EMMWRITTENUQ_READERS", PRINTF_LOCAL_F, twruq);
410 tpl_printf(vars, TPLADD, "TOTAL_EMMSKIPPEDUK_READERS", PRINTF_LOCAL_F, tskuk);
411 tpl_printf(vars, TPLADD, "TOTAL_EMMSKIPPEDG_READERS", PRINTF_LOCAL_F, tskg);
412 tpl_printf(vars, TPLADD, "TOTAL_EMMSKIPPEDS_READERS", PRINTF_LOCAL_F, tsks);
413 tpl_printf(vars, TPLADD, "TOTAL_EMMSKIPPEDUQ_READERS", PRINTF_LOCAL_F, tskuq);
414 tpl_printf(vars, TPLADD, "TOTAL_EMMBLOCKEDUK_READERS", PRINTF_LOCAL_F, tbluk);
415 tpl_printf(vars, TPLADD, "TOTAL_EMMBLOCKEDG_READERS", PRINTF_LOCAL_F, tblg);
416 tpl_printf(vars, TPLADD, "TOTAL_EMMBLOCKEDS_READERS", PRINTF_LOCAL_F, tbls);
417 tpl_printf(vars, TPLADD, "TOTAL_EMMBLOCKEDUQ_READERS", PRINTF_LOCAL_F, tbluq);
419 emmsum = teruk + terg + ters + teruq + twruk + twrg + twrs + twruq + tskuk + tskg + tsks + tskuq + tbluk + tblg + tbls + tbluq;
421 tpl_printf(vars, TPLADD, "TOTAL_SUM_ALL_READERS_EMM", PRINTF_LOCAL_F, emmsum);
424 static void refresh_oscam(enum refreshtypes refreshtype)
427 switch(refreshtype)
429 case REFR_ACCOUNTS:
430 cs_log("Refresh Accounts requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
431 cs_accounts_chk();
432 break;
434 case REFR_READERS:
435 cs_log("Refresh Readers requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
436 reload_readerdb();
437 break;
439 case REFR_CLIENTS:
440 cs_log("Refresh Clients requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
441 cs_reinit_clients(cfg.account);
442 break;
444 case REFR_SERVER:
445 cs_log("Refresh Server requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
446 //kill(first_client->pid, SIGHUP);
447 //todo how I can refresh the server after global settings
448 break;
450 case REFR_SERVICES:
451 cs_log("Refresh Services requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
452 //init_sidtab();
453 cs_accounts_chk();
454 break;
456 #ifdef CS_ANTICASC
457 case REFR_ANTICASC:
458 cs_log("Refresh Anticascading requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
459 ac_init_stat();
460 struct s_client *cl;
461 struct s_auth *account;
462 for(cl = first_client->next; cl ; cl = cl->next)
464 if(cl->typ == 'c' && (account = cl->account))
466 cl->ac_limit = (account->ac_users * 100 + 80) * cfg.ac_stime;
469 break;
470 #endif
471 default:
472 break;
476 * load historical values from ringbuffer and return it in the right order
477 * as string. Value should be freed with free_mk_t()
479 static char *get_ecm_historystring(struct s_client *cl)
482 if(cl)
484 int32_t k, i, pos = 0, needed = 1, v;
485 char *value, *dot = "";
486 int32_t ptr = cl->cwlastresptimes_last;
488 needed = CS_ECM_RINGBUFFER_MAX * 6; //5 digits + delimiter
489 if(!cs_malloc(&value, needed)) { return ""; }
491 k = ptr + 1;
492 for(i = 0; i < CS_ECM_RINGBUFFER_MAX; i++)
494 if(k >= CS_ECM_RINGBUFFER_MAX)
495 { k = 0; }
496 v = cl->cwlastresptimes[k].duration;
497 if(v > 0 && v < (int32_t)cfg.ctimeout * 5)
499 pos += snprintf(value + pos, needed - pos, "%s%d", dot, v);
500 dot = ",";
502 k++;
504 if(strlen(value) == 0)
506 NULLFREE(value);
507 return "";
509 else { return value; }
512 else
514 return "";
518 static char *get_ecm_fullhistorystring(struct s_client *cl)
521 if(cl)
523 int32_t k, i, pos = 0, needed = 1, v;
524 char *value, *dot = "";
525 int32_t ptr = cl->cwlastresptimes_last;
527 needed = CS_ECM_RINGBUFFER_MAX * 20; //5 digits + : + returncode(2) + : + time(10) + delimiter
528 if(!cs_malloc(&value, needed)) { return ""; }
530 k = ptr + 1;
531 for(i = 0; i < CS_ECM_RINGBUFFER_MAX; i++)
533 if(k >= CS_ECM_RINGBUFFER_MAX)
534 { k = 0; }
535 v = cl->cwlastresptimes[k].duration;
536 if(v > 0 && v < (int32_t)cfg.ctimeout * 5)
538 pos += snprintf(value + pos, needed - pos, "%s%d:%d:%ld", dot, cl->cwlastresptimes[k].duration, cl->cwlastresptimes[k].rc, cl->cwlastresptimes[k].timestamp);
539 dot = ",";
541 k++;
544 return (value);
547 else
549 return "";
554 * Set the active menu to a different CSS class
556 static void setActiveMenu(struct templatevars *vars, int8_t active)
558 int8_t i;
559 for(i = 0; i < MNU_TOTAL_ITEMS; i++)
561 tpl_printf(vars, TPLADD, "TMP", "MENUACTIVE%d", i);
562 if(i == active)
563 { tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "menu_selected"); }
564 else
565 { tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "menu"); }
567 #ifdef WEBIF_LIVELOG
568 tpl_addVar(vars, TPLADD, "LOGPAGEMENU", tpl_getTpl(vars, "LOGMENU"));
569 #endif
573 * Set the active submenu to a different CSS class
575 static void setActiveSubMenu(struct templatevars *vars, int8_t active)
577 int8_t i;
578 for(i = 0; i < MNU_CFG_TOTAL_ITEMS; i++)
580 tpl_printf(vars, TPLADD, "TMP", "CMENUACTIVE%d", i);
581 if(i == active)
582 { tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "configmenu_selected"); }
583 else
584 { tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "configmenu"); }
588 static void webif_save_config(char *section, struct templatevars *vars, struct uriparams *params)
590 if(!streq(getParam(params, "action"), "execute"))
591 { return; }
592 if(cfg.http_readonly)
594 tpl_addMsg(vars, "WebIf is in readonly mode. No changes are possible!");
595 return;
597 int i;
598 int cnt = (*params).paramcount;
599 for(i = 0; i < cnt; i++)
601 char *token = (*params).params[i];
602 char *value = (*params).values[i];
603 if(!streq(token, "part") && !streq(token, "action"))
604 { config_set(section, token, value); }
606 if(write_config() == 0)
608 tpl_addMsg(vars, "Configuration was saved.");
609 enum refreshtypes ref_type = REFR_SERVER;
610 if(streq(getParam(params, "part"), "anticasc"))
611 { ref_type = REFR_ANTICASC; }
612 refresh_oscam(ref_type);
614 else
616 tpl_addMsg(vars, "ERROR: Failed to write config file!!!");
620 static char *send_oscam_config_global(struct templatevars *vars, struct uriparams *params)
622 setActiveSubMenu(vars, MNU_CFG_GLOBAL);
624 webif_save_config("global", vars, params);
626 if(IP_ISSET(cfg.srvip))
627 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.srvip)); }
628 tpl_printf(vars, TPLADD, "NICE", "%d", cfg.nice);
629 tpl_printf(vars, TPLADD, "BINDWAIT", "%d", cfg.bindwait);
631 tpl_printf(vars, TPLADD, "TMP", "NETPRIO%d", cfg.netprio);
632 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
634 tpl_printf(vars, TPLADD, "PIDFILE", "%s", ESTR(cfg.pidfile));
637 if(cfg.usrfile != NULL) { tpl_addVar(vars, TPLADD, "USERFILE", cfg.usrfile); }
638 if(cfg.disableuserfile == 0) { tpl_addVar(vars, TPLADD, "DISABLEUSERFILECHECKED", "checked"); }
639 if(cfg.usrfileflag == 1) { tpl_addVar(vars, TPLADD, "USERFILEFLAGCHECKED", "selected"); }
640 if(cfg.mailfile != NULL) { tpl_addVar(vars, TPLADD, "MAILFILE", cfg.mailfile); }
641 if(cfg.disablemail == 0) { tpl_addVar(vars, TPLADD, "DISABLEMAILCHECKED", "checked"); }
643 char *value = mk_t_logfile();
644 tpl_addVar(vars, TPLADD, "LOGFILE", value);
645 free_mk_t(value);
646 if(cfg.disablelog == 0) { tpl_addVar(vars, TPLADD, "DISABLELOGCHECKED", "checked"); }
647 tpl_printf(vars, TPLADD, "MAXLOGSIZE", "%d", cfg.max_log_size);
649 tpl_addVar(vars, TPLADD, "LOGDUPSCHECKED", (cfg.logduplicatelines == 1) ? "checked" : "");
650 tpl_printf(vars, TPLADD, "INITIALDEBUGLEVEL", "%u", cfg.initial_debuglevel);
652 if(cfg.cwlogdir != NULL) { tpl_addVar(vars, TPLADD, "CWLOGDIR", cfg.cwlogdir); }
653 if(cfg.emmlogdir != NULL) { tpl_addVar(vars, TPLADD, "EMMLOGDIR", cfg.emmlogdir); }
654 tpl_addVar(vars, TPLADD, "ECMFMT", cfg.ecmfmt);
655 tpl_printf(vars, TPLADD, "LOGHISTORYLINES", "%u", cfg.loghistorylines);
656 if(cfg.sysloghost != NULL) { tpl_addVar(vars, TPLADD, "SYSLOGHOST", cfg.sysloghost); }
657 tpl_printf(vars, TPLADD, "SYSLOGPORT", "%u", cfg.syslogport);
660 tpl_printf(vars, TPLADD, "CLIENTTIMEOUT", "%u", cfg.ctimeout);
661 tpl_printf(vars, TPLADD, "FALLBACKTIMEOUT", "%u", cfg.ftimeout);
662 tpl_printf(vars, TPLADD, "CLIENTMAXIDLE", "%u", cfg.cmaxidle);
665 value = mk_t_caidvaluetab(&cfg.ftimeouttab);
666 tpl_addVar(vars, TPLADD, "FALLBACKTIMEOUT_PERCAID", value);
667 free_mk_t(value);
669 tpl_printf(vars, TPLADD, "SLEEP", "%d", cfg.tosleep);
670 tpl_addVar(vars, TPLADD, "UNLOCKPARENTALCHECKED", (cfg.ulparent == 1) ? "checked" : "");
672 if(cfg.reload_useraccounts) { tpl_addVar(vars, TPLADD, "RELOADUSERACCOUNTSCHECKED", "checked"); }
673 if(cfg.reload_readers) { tpl_addVar(vars, TPLADD, "RELOADREADERSCHECKED", "checked"); }
674 if(cfg.reload_provid) { tpl_addVar(vars, TPLADD, "RELOADPROVIDCHECKED", "checked"); }
675 if(cfg.reload_services_ids) { tpl_addVar(vars, TPLADD, "RELOADSERVICESIDSCHECKED", "checked"); }
676 if(cfg.reload_tier_ids) { tpl_addVar(vars, TPLADD, "RELOADTIERUDSCHECKED", "checked"); }
677 if(cfg.reload_fakecws) { tpl_addVar(vars, TPLADD, "RELOADFAKECWSCHECKED", "checked"); }
678 if(cfg.reload_ac_stat) { tpl_addVar(vars, TPLADD, "RELOADACSTATCHECKED", "checked"); }
679 if(cfg.reload_log) { tpl_addVar(vars, TPLADD, "RELOADLOGCHECKED", "checked"); }
681 if(cfg.block_same_ip) { tpl_addVar(vars, TPLADD, "BLOCKSAMEIPCHECKED", "checked"); }
682 if(cfg.block_same_name) { tpl_addVar(vars, TPLADD, "BLOCKSAMENAMECHECKED", "checked"); }
684 if(cfg.waitforcards == 1) { tpl_addVar(vars, TPLADD, "WAITFORCARDSCHECKED", "checked"); }
685 tpl_printf(vars, TPLADD, "EXTRADELAY", "%d", cfg.waitforcards_extra_delay);
686 if(cfg.preferlocalcards == 1)
688 tpl_addVar(vars, TPLADD, "PREFERCACHEEX", "selected");
690 else if(cfg.preferlocalcards == 2)
692 tpl_addVar(vars, TPLADD, "PREFERLOCALCARDS", "selected");
695 if(cfg.c35_suppresscmd08)
696 { tpl_addVar(vars, TPLADD, "SUPPRESSCMD08", "checked"); }
698 if(cfg.getblockemmauprovid > 0)
700 tpl_addVar(vars, TPLADD, "GETBLOCKEMMAUPROVID", "checked");
703 if(cfg.reader_restart_seconds)
704 { tpl_printf(vars, TPLADD, "READERRESTARTSECONDS", "%d", cfg.reader_restart_seconds); }
706 tpl_addVar(vars, TPLADD, "DROPDUPSCHECKED", (cfg.dropdups == 1) ? "checked" : "");
708 if(cfg.resolve_gethostbyname == 1)
709 { tpl_addVar(vars, TPLADD, "RESOLVER1", "selected"); }
710 else
711 { tpl_addVar(vars, TPLADD, "RESOLVER0", "selected"); }
713 tpl_printf(vars, TPLADD, "FAILBANTIME", "%d", cfg.failbantime);
714 tpl_printf(vars, TPLADD, "FAILBANCOUNT", "%d", cfg.failbancount);
716 tpl_addVar(vars, TPLADD, "DCHECKCSELECTED", (cfg.double_check == 1) ? "checked" : "");
718 value = mk_t_caidtab(&cfg.double_check_caid);
719 tpl_addVar(vars, TPLADD, "DOUBLECHECKCAID", value);
720 free_mk_t(value);
722 tpl_addVar(vars, TPLADD, "DISABLECRCCWSCHECKEDGLOBAL", (cfg.disablecrccws == 1) ? "checked" : "");
724 value = mk_t_ftab(&cfg.disablecrccws_only_for);
725 tpl_addVar(vars, TPLADD, "IGNCHKSUMONLYFORGLOBAL", value);
726 free_mk_t(value);
728 #ifdef LEDSUPPORT
729 if(cfg.enableled == 1)
730 { tpl_addVar(vars, TPLADD, "ENABLELEDSELECTED1", "selected"); }
731 else if(cfg.enableled == 2)
732 { tpl_addVar(vars, TPLADD, "ENABLELEDSELECTED2", "selected"); }
733 #endif
735 return tpl_getTpl(vars, "CONFIGGLOBAL");
738 #ifdef WITH_LB
739 static char *send_oscam_config_loadbalancer(struct templatevars *vars, struct uriparams *params)
741 setActiveSubMenu(vars, MNU_CFG_LOADBAL);
743 if(strlen(getParam(params, "button")) > 0)
745 if(cfg.http_readonly)
747 tpl_addMsg(vars, "WebIf is in readonly mode. No changes are possible!");
749 else
751 if(strcmp(getParam(params, "button"), "Load Stats") == 0)
753 clear_all_stat();
754 load_stat_from_file();
755 tpl_addMsg(vars, "Stats loaded from file");
758 if(strcmp(getParam(params, "button"), "Save Stats") == 0)
760 save_stat_to_file(1);
761 tpl_addMsg(vars, "Stats saved to file");
764 if(strcmp(getParam(params, "button"), "Clear Stats") == 0)
766 clear_all_stat();
767 tpl_addMsg(vars, "Stats cleared completly");
770 if(strcmp(getParam(params, "button"), "Clear Timeouts") == 0)
772 clean_all_stats_by_rc(E_TIMEOUT, 0);
773 tpl_addMsg(vars, "Timeout cleared from Stats");
776 if(strcmp(getParam(params, "button"), "Clear Not Found") == 0)
778 clean_all_stats_by_rc(E_NOTFOUND, 0);
779 tpl_addMsg(vars, "Not Found cleared from Stats");
782 if(strcmp(getParam(params, "button"), "Clear Invalid") == 0)
784 clean_all_stats_by_rc(E_INVALID, 0);
785 tpl_addMsg(vars, "Invalid cleared from Stats");
790 webif_save_config("global", vars, params);
792 tpl_printf(vars, TPLADD, "TMP", "LBMODE%d", cfg.lb_mode);
793 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
795 tpl_printf(vars, TPLADD, "LBSAVE", "%d", cfg.lb_save);
796 if(cfg.lb_savepath) { tpl_addVar(vars, TPLADD, "LBSAVEPATH", cfg.lb_savepath); }
798 tpl_printf(vars, TPLADD, "LBNBESTREADERS", "%d", cfg.lb_nbest_readers);
799 char *value = mk_t_caidvaluetab(&cfg.lb_nbest_readers_tab);
800 tpl_addVar(vars, TPLADD, "LBNBESTPERCAID", value);
801 free_mk_t(value);
802 tpl_printf(vars, TPLADD, "LBNFBREADERS", "%d", cfg.lb_nfb_readers);
803 tpl_printf(vars, TPLADD, "LBMAXREADERS", "%d", cfg.lb_max_readers);
804 tpl_printf(vars, TPLADD, "LBMINECMCOUNT", "%d", cfg.lb_min_ecmcount);
805 tpl_printf(vars, TPLADD, "LBMAXECEMCOUNT", "%d", cfg.lb_max_ecmcount);
806 tpl_printf(vars, TPLADD, "LBRETRYLIMIT", "%d", cfg.lb_retrylimit);
808 value = mk_t_caidvaluetab(&cfg.lb_retrylimittab);
809 tpl_addVar(vars, TPLADD, "LBRETRYLIMITS", value);
810 free_mk_t(value);
812 tpl_printf(vars, TPLADD, "LBREOPENSECONDS", "%d", cfg.lb_reopen_seconds);
813 tpl_printf(vars, TPLADD, "LBCLEANUP", "%d", cfg.lb_stat_cleanup);
815 tpl_addVar(vars, TPLADD, "LBREOPENINVALID", (cfg.lb_reopen_invalid == 1) ? "checked" : "");
816 tpl_addVar(vars, TPLADD, "LBFORCEALWAYS", (cfg.lb_force_reopen_always == 1) ? "checked" : "");
818 value = mk_t_caidtab(&cfg.lb_noproviderforcaid);
819 tpl_addVar(vars, TPLADD, "LBNOPROVIDERFORCAID", value);
820 free_mk_t(value);
822 tpl_addVar(vars, TPLADD, "LBAUTOBETATUNNEL", (cfg.lb_auto_betatunnel == 1) ? "checked" : "");
824 if(cfg.lb_auto_betatunnel_mode)
826 tpl_printf(vars, TPLADD, "TMP", "LBAUTOBETATUNNELMODE%d", cfg.lb_auto_betatunnel_mode);
827 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
830 tpl_printf(vars, TPLADD, "LBPREFERBETA", "%d", cfg.lb_auto_betatunnel_prefer_beta);
832 tpl_addVar(vars, TPLADD, "LBAUTOTIMEOUT", (cfg.lb_auto_timeout == 1) ? "checked" : "");
834 tpl_printf(vars, TPLADD, "LBAUTOTIMEOUTP", "%d", cfg.lb_auto_timeout_p);
835 tpl_printf(vars, TPLADD, "LBAUTOTIMEOUTT", "%d", cfg.lb_auto_timeout_t);
837 tpl_addVar(vars, TPLADDONCE, "CONFIG_CONTROL", tpl_getTpl(vars, "CONFIGLOADBALANCERCTRL"));
839 return tpl_getTpl(vars, "CONFIGLOADBALANCER");
841 #endif
843 #ifdef MODULE_CAMD33
844 static char *send_oscam_config_camd33(struct templatevars *vars, struct uriparams *params)
846 int32_t i;
848 setActiveSubMenu(vars, MNU_CFG_CAMD33);
850 webif_save_config("camd33", vars, params);
852 if(cfg.c33_port)
854 tpl_printf(vars, TPLADD, "PORT", "%d", cfg.c33_port);
855 if(IP_ISSET(cfg.c33_srvip)) { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.c33_srvip)); }
856 tpl_addVar(vars, TPLADD, "PASSIVECHECKED", (cfg.c33_passive == 1) ? "checked" : "");
858 for(i = 0; i < (int) sizeof(cfg.c33_key); ++i) { tpl_printf(vars, TPLAPPEND, "KEY", "%02X", cfg.c33_key[i]); }
859 char *value = mk_t_iprange(cfg.c33_plain);
860 tpl_addVar(vars, TPLADD, "NOCRYPT", value);
861 free_mk_t(value);
864 return tpl_getTpl(vars, "CONFIGCAMD33");
866 #endif
868 #ifdef MODULE_CAMD35
869 static char *send_oscam_config_camd35(struct templatevars *vars, struct uriparams *params)
871 setActiveSubMenu(vars, MNU_CFG_CAMD35);
873 webif_save_config("cs357x", vars, params);
875 if(cfg.c35_port)
877 tpl_printf(vars, TPLADD, "PORT", "%d", cfg.c35_port);
878 if(IP_ISSET(cfg.c35_srvip))
879 { tpl_addVar(vars, TPLAPPEND, "SERVERIP", cs_inet_ntoa(cfg.c35_srvip)); }
881 if(cfg.c35_udp_suppresscmd08)
882 { tpl_addVar(vars, TPLADD, "SUPPRESSCMD08UDP", "checked"); }
885 return tpl_getTpl(vars, "CONFIGCAMD35");
887 #endif
889 #ifdef MODULE_CAMD35_TCP
890 static char *send_oscam_config_camd35tcp(struct templatevars *vars, struct uriparams *params)
892 setActiveSubMenu(vars, MNU_CFG_CAMD35TCP);
894 webif_save_config("cs378x", vars, params);
896 if((cfg.c35_tcp_ptab.nports > 0) && (cfg.c35_tcp_ptab.ports[0].s_port > 0))
899 char *value = mk_t_camd35tcp_port();
900 tpl_addVar(vars, TPLADD, "PORT", value);
901 free_mk_t(value);
903 if(IP_ISSET(cfg.c35_tcp_srvip))
904 { tpl_addVar(vars, TPLAPPEND, "SERVERIP", cs_inet_ntoa(cfg.c35_tcp_srvip)); }
906 if(cfg.c35_tcp_suppresscmd08)
907 { tpl_addVar(vars, TPLADD, "SUPPRESSCMD08TCP", "checked"); }
909 return tpl_getTpl(vars, "CONFIGCAMD35TCP");
911 #endif
913 static char *send_oscam_config_cache(struct templatevars *vars, struct uriparams *params)
915 setActiveSubMenu(vars, MNU_CFG_CACHE);
917 webif_save_config("cache", vars, params);
919 tpl_printf(vars, TPLADD, "CACHEDELAY", "%u", cfg.delay);
921 tpl_printf(vars, TPLADD, "MAXCACHETIME", "%d", cfg.max_cache_time);
923 #ifdef CS_CACHEEX
924 char *value = NULL;
925 value = mk_t_cacheex_valuetab(&cfg.cacheex_wait_timetab);
926 tpl_addVar(vars, TPLADD, "WAIT_TIME", value);
927 free_mk_t(value);
929 value = mk_t_caidvaluetab(&cfg.cacheex_mode1_delay_tab);
930 tpl_addVar(vars, TPLADD, "CACHEEXMODE1DELAY", value);
931 free_mk_t(value);
933 tpl_printf(vars, TPLADD, "MAX_HIT_TIME", "%d", cfg.max_hitcache_time);
935 tpl_addVar(vars, TPLADD, "CACHEEXSTATSSELECTED", (cfg.cacheex_enable_stats == 1) ? "checked" : "");
937 tpl_addVar(vars, TPLADD, "WTTCHECKED", (cfg.wait_until_ctimeout == 1) ? "checked" : "");
939 if(cfg.csp_port)
940 { tpl_printf(vars, TPLADD, "PORT", "%d", cfg.csp_port); }
942 if(IP_ISSET(cfg.csp_srvip))
943 { tpl_addVar(vars, TPLAPPEND, "SERVERIP", cs_inet_ntoa(cfg.csp_srvip)); }
945 value = mk_t_cacheex_hitvaluetab(&cfg.csp.filter_caidtab);
946 tpl_addVar(vars, TPLADD, "CSP_ECM_FILTER", value);
947 free_mk_t(value);
949 value = mk_t_cacheex_cwcheck_valuetab(&cfg.cacheex_cwcheck_tab);
950 tpl_addVar(vars, TPLADD, "CACHEEXCWCHECK", value);
951 free_mk_t(value);
953 tpl_addVar(vars, TPLADD, "ARCHECKED", (cfg.csp.allow_request == 1) ? "checked" : "");
954 tpl_addVar(vars, TPLADD, "ARFCHECKED", (cfg.csp.allow_reforward == 1) ? "checked" : "");
955 tpl_addVar(vars, TPLADD, "BLOCKFAKECWSCHECKED", (cfg.csp.block_fakecws == 1) ? "checked" : "");
956 #endif
958 #ifdef CW_CYCLE_CHECK
959 #ifndef CS_CACHEEX
960 char *value = NULL;
961 #endif
963 tpl_addVar(vars, TPLADD, "CWCYCLECHECK", (cfg.cwcycle_check_enable == 1) ? "checked" : "");
965 value = mk_t_caidtab(&cfg.cwcycle_check_caidtab);
966 tpl_addVar(vars, TPLADD, "CWCYCLECHECKCAID", value);
967 free_mk_t(value);
969 tpl_printf(vars, TPLADD, "MAXCYCLELIST", "%d", cfg.maxcyclelist);
970 tpl_printf(vars, TPLADD, "KEEPCYCLETIME", "%d", cfg.keepcycletime);
972 if(cfg.onbadcycle)
974 tpl_printf(vars, TPLADD, "TMP", "ONBADCYCLE%d", cfg.onbadcycle);
975 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
978 tpl_addVar(vars, TPLADD, "DROPOLD", (cfg.cwcycle_dropold == 1) ? "checked" : "");
980 if(cfg.cwcycle_sensitive)
982 tpl_printf(vars, TPLADD, "TMP", "CWCSEN%d", cfg.cwcycle_sensitive);
983 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
986 tpl_addVar(vars, TPLADD, "ALLOWBADFROMFFB", (cfg.cwcycle_allowbadfromffb == 1) ? "checked" : "");
988 tpl_addVar(vars, TPLADD, "USECWCFROMCE", (cfg.cwcycle_usecwcfromce == 1) ? "checked" : "");
991 #endif
993 return tpl_getTpl(vars, "CONFIGCACHE");
996 #ifdef MODULE_NEWCAMD
997 static char *send_oscam_config_newcamd(struct templatevars *vars, struct uriparams *params)
999 int32_t i;
1001 setActiveSubMenu(vars, MNU_CFG_NEWCAMD);
1003 webif_save_config("newcamd", vars, params);
1005 if((cfg.ncd_ptab.nports > 0) && (cfg.ncd_ptab.ports[0].s_port > 0))
1008 char *value = mk_t_newcamd_port();
1009 tpl_addVar(vars, TPLADD, "PORT", value);
1010 free_mk_t(value);
1012 if(IP_ISSET(cfg.ncd_srvip))
1013 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.ncd_srvip)); }
1015 for(i = 0; i < (int32_t)sizeof(cfg.ncd_key); i++)
1016 { tpl_printf(vars, TPLAPPEND, "KEY", "%02X", cfg.ncd_key[i]); }
1018 value = mk_t_iprange(cfg.ncd_allowed);
1019 tpl_addVar(vars, TPLADD, "ALLOWED", value);
1020 free_mk_t(value);
1022 if(cfg.ncd_keepalive)
1023 { tpl_addVar(vars, TPLADD, "KEEPALIVE", "checked"); }
1024 if(cfg.ncd_mgclient)
1025 { tpl_addVar(vars, TPLADD, "MGCLIENTCHK", "checked"); }
1027 return tpl_getTpl(vars, "CONFIGNEWCAMD");
1029 #endif
1031 #ifdef MODULE_GBOX
1032 static char *send_oscam_config_gbox(struct templatevars *vars, struct uriparams *params)
1034 uint8_t i=0;
1035 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] ;
1036 int n=0, len_gbox_save_gsms=0, len_gbox_msg_type=0, len_gbox_dest_peers=0, len_gbox_msg_txt=0;
1037 char *ptr1, *saveptr1, *isbroadcast = NULL;
1038 const char *s;
1039 uint16_t gbox_dest_peers_tmp;
1041 setActiveSubMenu(vars, MNU_CFG_GBOX);
1042 webif_save_config("gbox", vars, params);
1044 * Action when GetOnlinePeers is pressed
1046 if(streq(getParam(params, "action"), "Online peers"))
1048 gbox_get_online_peers();
1049 // init var
1050 len_gbox_save_gsms=strlen(getParam(params, "gbox_msg_type"));
1051 len_gbox_msg_type=strlen(getParam(params, "gbox_msg_type"));
1052 len_gbox_msg_txt=strlen(getParam(params, "gbox_msg_txt"));
1053 if(len_gbox_msg_txt>GBOX_MAX_MSG_TXT) { len_gbox_msg_txt=GBOX_MAX_MSG_TXT; }
1054 // retrieve value from Webif
1055 cs_strncpy(local_gbox_save_gsms, getParam(params, "gbox_save_gsms"), len_gbox_save_gsms+1);
1056 cfg.gbox_save_gsms=atoi(local_gbox_save_gsms);
1057 cs_strncpy(local_gbox_msg_type, getParam(params, "gbox_msg_type"), len_gbox_msg_type+1);
1058 cfg.gbox_msg_type=atoi(local_gbox_msg_type);
1059 cs_strncpy(cfg.gbox_msg_txt,getParam(params, "gbox_msg_txt"), len_gbox_msg_txt+1);
1062 * Action when ResetGSMS button is pressed
1064 if(streq(getParam(params, "action"), "resetallgsms"))
1066 cfg.gbox_save_gsms = 0;
1067 cfg.gbox_msg_type = 0;
1068 for(i = 0; i < GBOX_MAX_DEST_PEERS; i++)
1070 cfg.gbox_dest_peers[i]='\0';
1072 cfg.gbox_dest_peers_num=0;
1073 for(i = 0; i < GBOX_MAX_MSG_TXT; i++)
1075 cfg.gbox_msg_txt[i]='\0';
1077 tpl_addMsg(vars, "GBOX: Reset GSMS datas done!");
1080 * Action when Send GSMS is pressed
1082 if(streq(getParam(params, "action"), "Send GSMS"))
1084 // init var
1085 len_gbox_msg_type=strlen(getParam(params, "gbox_msg_type"));
1086 len_gbox_dest_peers=strlen(trim(getParam(params, "gbox_dest_peers")));
1087 len_gbox_msg_txt=strlen(getParam(params, "gbox_msg_txt"));
1088 if(len_gbox_msg_txt>GBOX_MAX_MSG_TXT) { len_gbox_msg_txt=GBOX_MAX_MSG_TXT; }
1089 // retrieve value from Webif
1090 cs_strncpy(local_gbox_msg_type, getParam(params, "gbox_msg_type"), len_gbox_msg_type+1);
1091 cfg.gbox_msg_type=atoi(local_gbox_msg_type);
1092 cs_strncpy(local_gbox_dest_peers, strtoupper(trim(getParam(params, "gbox_dest_peers"))), len_gbox_dest_peers+1);
1093 cs_strncpy(tmp_gbox_dest_peers, strtoupper(trim(getParam(params, "gbox_dest_peers"))), len_gbox_dest_peers+1);
1094 cs_strncpy(cfg.gbox_msg_txt,getParam(params, "gbox_msg_txt"), len_gbox_msg_txt+1);
1095 n=0;
1096 for (ptr1 = strtok_r(tmp_gbox_dest_peers, ",", &saveptr1); (ptr1); ptr1 = strtok_r(NULL, ",", &saveptr1))
1098 s=trim(ptr1);
1099 if ((n < GBOX_MAX_DEST_PEERS) && (s[strspn(s, "0123456789abcdefABCDEF")] == 0))
1100 { cfg.gbox_dest_peers[n++] = a2i(trim(ptr1), strlen(trim(ptr1))); }
1102 cfg.gbox_dest_peers_num = n;
1104 Start sending GBox SMS
1106 if((strlen(cfg.gbox_msg_txt) > 5))
1108 isbroadcast=strstr(local_gbox_dest_peers, "FFFF");
1109 if(isbroadcast == NULL)
1111 n =0;
1112 for (i = 0, ptr1 = strtok_r(local_gbox_dest_peers, ",", &saveptr1); (i < 4) && (ptr1); ptr1 = strtok_r(NULL, ",", &saveptr1))
1114 s=ptr1;
1115 if ((n < GBOX_MAX_DEST_PEERS) && (s[strspn(s, "0123456789abcdefABCDEF")] == 0))
1117 gbox_dest_peers_tmp = a2i(ptr1, 4);
1118 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);}
1119 n++;
1122 tpl_addMsg(vars, "GBOX Send SMS: individual messages started.");
1124 else
1126 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);}
1127 tpl_addMsg(vars, "GBOX Send SMS: broadcast started.");
1130 else
1132 cs_log("GBox SMS: destination peers or message text not specified or too short");
1133 tpl_addMsg(vars, "GBOX: Send SMS failed - error in input fields: dest peers or text message.");
1137 tpl_addVar(vars, TPLADD, "HOSTNAME", xml_encode(vars, cfg.gbox_hostname));
1138 char *value0 = mk_t_gbox_port();
1139 tpl_addVar(vars, TPLAPPEND, "PORT", value0);
1140 free_mk_t(value0);
1141 tpl_printf(vars, TPLADD, "GBOXPASSWORD", "%08X", cfg.gbox_password);
1142 tpl_printf(vars, TPLADD, "GBOXRECONNECT", "%d", cfg.gbox_reconnect);
1143 tpl_printf(vars, TPLADD, "GBOXMYVERS", "%02X", cfg.gbox_my_vers);
1144 tpl_printf(vars, TPLAPPEND, "GBOXMYCPUAPI", "%02X", cfg.gbox_my_cpu_api);
1145 if(cfg.ccc_reshare == 1) { tpl_addVar(vars, TPLADD, "GBOXCCCRESHARE", "checked"); }
1146 if(cfg.log_hello == 1) { tpl_addVar(vars, TPLADD, "GBOXLOGHELLO", "checked"); }
1147 if(cfg.gsms_dis == 1) { tpl_addVar(vars, TPLADD, "GBOXGSMSDISABLE", "checked"); }
1148 if(cfg.dis_attack_txt == 1) { tpl_addVar(vars, TPLADD, "GBOXDISATTACKTXT", "checked"); }
1149 if(cfg.gbox_tmp_dir != NULL) { tpl_addVar(vars, TPLADD, "GBOXTMPDIR", cfg.gbox_tmp_dir); }
1150 char *value1 = mk_t_gbox_proxy_card();
1151 tpl_addVar(vars, TPLAPPEND, "GBOXPROXYCARD", value1);
1152 free_mk_t(value1);
1153 char *value2 = mk_t_gbox_ignored_peer();
1154 tpl_addVar(vars, TPLAPPEND, "GBOXIGNOREDPEER", value2);
1155 free_mk_t(value2);
1156 char *value3 = mk_t_gbox_block_ecm();
1157 tpl_addVar(vars, TPLAPPEND, "GBOXBLOCKECM", value3);
1158 free_mk_t(value3);
1159 char *value4 = mk_t_accept_remm_peer();
1160 tpl_addVar(vars, TPLAPPEND, "GBOXACCEPTREMM", value4);
1161 free_mk_t(value4);
1163 * GBOX SMS
1165 tpl_addVar(vars, TPLADD, "GBOXSAVEGSMS", (cfg.gbox_save_gsms == 1) ? "checked" : "");
1166 if(cfg.gbox_msg_type == 0)
1168 tpl_addVar(vars, TPLADD, "GBOXMSGTYPENORMAL", "selected");
1170 else if(cfg.gbox_msg_type == 1)
1172 tpl_addVar(vars, TPLADD, "GBOXMSGTYPEOSD", "selected");
1174 char *gmsg_dest_peers = mk_t_gbox_dest_peers();
1175 tpl_addVar(vars, TPLADD, "GBOXMSGDESTPEERS", gmsg_dest_peers);
1176 free_mk_t(gmsg_dest_peers);
1177 tpl_addVar(vars, TPLADD, "GBOXMSGTXT", cfg.gbox_msg_txt);
1179 return tpl_getTpl(vars, "CONFIGGBOX");
1181 #endif
1183 #ifdef MODULE_RADEGAST
1184 static char *send_oscam_config_radegast(struct templatevars *vars, struct uriparams *params)
1186 setActiveSubMenu(vars, MNU_CFG_RADEGAST);
1188 webif_save_config("radegast", vars, params);
1190 tpl_printf(vars, TPLADD, "PORT", "%d", cfg.rad_port);
1191 if(IP_ISSET(cfg.rad_srvip))
1192 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.rad_srvip)); }
1193 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, cfg.rad_usr));
1195 char *value = mk_t_iprange(cfg.rad_allowed);
1196 tpl_addVar(vars, TPLADD, "ALLOWED", value);
1197 free_mk_t(value);
1199 return tpl_getTpl(vars, "CONFIGRADEGAST");
1201 #endif
1203 #ifdef MODULE_SCAM
1204 static char *send_oscam_config_scam(struct templatevars *vars, struct uriparams *params)
1206 setActiveSubMenu(vars, MNU_CFG_SCAM);
1208 webif_save_config("scam", vars, params);
1210 tpl_printf(vars, TPLADD, "PORT", "%d", cfg.scam_port);
1211 if(IP_ISSET(cfg.scam_srvip))
1212 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.scam_srvip)); }
1214 char *value = mk_t_iprange(cfg.scam_allowed);
1215 tpl_addVar(vars, TPLADD, "ALLOWED", value);
1216 free_mk_t(value);
1218 return tpl_getTpl(vars, "CONFIGSCAM");
1220 #endif
1222 #ifdef MODULE_CCCAM
1223 static char *send_oscam_config_cccam(struct templatevars *vars, struct uriparams *params)
1226 setActiveSubMenu(vars, MNU_CFG_CCCAM);
1228 if(strcmp(getParam(params, "button"), "Refresh list") == 0)
1230 cs_log_dbg(D_TRACE, "Entitlements: Refresh Shares start");
1231 #ifdef MODULE_CCCSHARE
1232 refresh_shares();
1233 #endif
1234 cs_log_dbg(D_TRACE, "Entitlements: Refresh Shares finished");
1235 tpl_addMsg(vars, "Refresh Shares started");
1238 webif_save_config("cccam", vars, params);
1240 if(streq(getParam(params, "action"), "execute") && !cfg.http_readonly)
1241 { cc_update_nodeid(); }
1243 char *value = mk_t_cccam_port();
1244 tpl_addVar(vars, TPLAPPEND, "PORT", value);
1245 free_mk_t(value);
1247 if(IP_ISSET(cfg.cc_srvip))
1248 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.cc_srvip)); }
1250 tpl_printf(vars, TPLADD, "RESHARE", "%d", cfg.cc_reshare);
1252 if(!strcmp((char *)cfg.cc_version, "2.0.11"))
1254 tpl_addVar(vars, TPLADD, "VERSIONSELECTED0", "selected");
1256 else if(!strcmp((char *)cfg.cc_version, "2.1.1"))
1258 tpl_addVar(vars, TPLADD, "VERSIONSELECTED1", "selected");
1260 else if(!strcmp((char *)cfg.cc_version, "2.1.2"))
1262 tpl_addVar(vars, TPLADD, "VERSIONSELECTED2", "selected");
1264 else if(!strcmp((char *)cfg.cc_version, "2.1.3"))
1266 tpl_addVar(vars, TPLADD, "VERSIONSELECTED3", "selected");
1268 else if(!strcmp((char *)cfg.cc_version, "2.1.4"))
1270 tpl_addVar(vars, TPLADD, "VERSIONSELECTED4", "selected");
1272 else if(!strcmp((char *)cfg.cc_version, "2.2.0"))
1274 tpl_addVar(vars, TPLADD, "VERSIONSELECTED5", "selected");
1276 else if(!strcmp((char *)cfg.cc_version, "2.2.1"))
1278 tpl_addVar(vars, TPLADD, "VERSIONSELECTED6", "selected");
1280 else if(!strcmp((char *)cfg.cc_version, "2.3.0"))
1282 tpl_addVar(vars, TPLADD, "VERSIONSELECTED7", "selected");
1284 else if(!strcmp((char *)cfg.cc_version, "2.3.1"))
1286 tpl_addVar(vars, TPLADD, "VERSIONSELECTED8", "selected");
1288 else if(!strcmp((char *)cfg.cc_version, "2.3.2"))
1290 tpl_addVar(vars, TPLADD, "VERSIONSELECTED9", "selected");
1293 tpl_printf(vars, TPLADD, "UPDATEINTERVAL", "%d", cfg.cc_update_interval);
1294 tpl_printf(vars, TPLADD, "RECV_TIMEOUT", "%u", cfg.cc_recv_timeout);
1296 tpl_addVar(vars, TPLADD, "STEALTH", (cfg.cc_stealth == 1) ? "checked" : "");
1298 tpl_printf(vars, TPLADD, "NODEID", "%02X%02X%02X%02X%02X%02X%02X%02X",
1299 cfg.cc_fixed_nodeid[0], cfg.cc_fixed_nodeid[1], cfg.cc_fixed_nodeid[2], cfg.cc_fixed_nodeid[3],
1300 cfg.cc_fixed_nodeid[4], cfg.cc_fixed_nodeid[5], cfg.cc_fixed_nodeid[6], cfg.cc_fixed_nodeid[7]);
1302 tpl_printf(vars, TPLADD, "TMP", "MINIMIZECARDSELECTED%d", cfg.cc_minimize_cards);
1303 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1305 tpl_printf(vars, TPLADD, "TMP", "RESHAREMODE%d", cfg.cc_reshare_services);
1306 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1308 tpl_printf(vars, TPLADD, "TMP", "IGNRSHRSELECTED%d", cfg.cc_ignore_reshare);
1309 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1311 tpl_addVar(vars, TPLADD, "FORWARDORIGINCARD", (cfg.cc_forward_origin_card == 1) ? "checked" : "");
1313 tpl_addVar(vars, TPLADD, "KEEPCONNECTED", (cfg.cc_keep_connected == 1) ? "checked" : "");
1315 tpl_addVar(vars, TPLADDONCE, "CONFIG_CONTROL", tpl_getTpl(vars, "CONFIGCCCAMCTRL"));
1317 return tpl_getTpl(vars, "CONFIGCCCAM");
1319 #endif
1321 static bool is_ext(const char *path, const char *ext)
1323 size_t lenpath = strlen(path);
1324 size_t lenext = strlen(ext);
1325 if(lenext > lenpath)
1326 { return 0; }
1327 return memcmp(path + lenpath - lenext, ext, lenext) == 0;
1330 static char *send_oscam_config_webif(struct templatevars *vars, struct uriparams *params)
1332 int32_t i;
1334 setActiveSubMenu(vars, MNU_CFG_WEBIF);
1336 webif_save_config("webif", vars, params);
1338 tpl_printf(vars, TPLADD, "HTTPPORT", "%s%d", cfg.http_use_ssl ? "+" : "", cfg.http_port);
1339 if(IP_ISSET(cfg.http_srvip))
1340 { tpl_addVar(vars, TPLAPPEND, "SERVERIP", cs_inet_ntoa(cfg.http_srvip)); }
1342 tpl_addVar(vars, TPLADD, "HTTPUSER", cfg.http_user);
1343 tpl_addVar(vars, TPLADD, "HTTPPASSWORD", cfg.http_pwd);
1344 tpl_addVar(vars, TPLADD, "HTTPOSCAMLABEL", cfg.http_oscam_label);
1346 // css style selector
1347 tpl_printf(vars, TPLADD, "CSSOPTIONS", "\t\t\t\t\t\t<option value=\"\"%s>embedded</option>\n",
1348 !cfg.http_css ? " selected" : "");
1350 if(cfg.http_tpl)
1352 char path[255];
1353 tpl_getFilePathInSubdir(cfg.http_tpl, "", "style", ".css", path, 255);
1354 if(file_exists(path))
1355 tpl_printf(vars, TPLAPPEND, "CSSOPTIONS", "\t\t\t\t\t\t<option value=\"%s\"%s>%s (template)</option>\n",
1356 path,
1357 cfg.http_css && strstr(cfg.http_css, path) ? " selected" : "",
1358 path);
1361 struct dirent **namelist;
1362 int count;
1363 count = scandir(cs_confdir, &namelist, 0, alphasort );
1365 if( count >= 0 )
1367 for( i = 0 ; i < count; i++ )
1369 if(is_ext(namelist[i]->d_name, ".css"))
1371 tpl_printf(vars, TPLAPPEND, "CSSOPTIONS", "\t\t\t\t\t\t<option value=\"%s%s\"%s>%s%s</option>\n",
1372 cs_confdir,
1373 namelist[i]->d_name,
1374 cfg.http_css && strstr(cfg.http_css, namelist[i]->d_name) ? " selected" : "",
1375 cs_confdir, namelist[i]->d_name);
1377 free( namelist[i] );
1379 free(namelist);
1382 if(cfg.http_prepend_embedded_css)
1383 { tpl_addVar(vars, TPLADD, "HTTPPREPENDEMBEDDEDCSS", "checked"); }
1385 tpl_addVar(vars, TPLADD, "HTTPHELPLANG", cfg.http_help_lang);
1386 tpl_addVar(vars, TPLADD, "HTTPLOCALE", cfg.http_locale);
1387 tpl_printf(vars, TPLADD, "HTTPEMMUCLEAN", "%d", cfg.http_emmu_clean);
1388 tpl_printf(vars, TPLADD, "HTTPEMMSCLEAN", "%d", cfg.http_emms_clean);
1389 tpl_printf(vars, TPLADD, "HTTPEMMGCLEAN", "%d", cfg.http_emmg_clean);
1390 tpl_printf(vars, TPLADD, "HTTPREFRESH", "%d", cfg.http_refresh);
1391 tpl_printf(vars, TPLADD, "HTTPPOLLREFRESH", "%d", cfg.poll_refresh);
1392 tpl_addVar(vars, TPLADD, "HTTPTPL", cfg.http_tpl);
1393 tpl_addVar(vars, TPLADD, "HTTPPICONPATH", cfg.http_piconpath);
1394 tpl_addVar(vars, TPLADD, "HTTPSCRIPT", cfg.http_script);
1395 tpl_addVar(vars, TPLADD, "HTTPJSCRIPT", cfg.http_jscript);
1396 #ifndef WEBIF_JQUERY
1397 tpl_addVar(vars, TPLADD, "HTTPEXTERNJQUERY", cfg.http_extern_jquery);
1398 #endif
1399 tpl_printf(vars, TPLADD, "HTTPPICONSIZE", "%d", cfg.http_picon_size);
1401 if(cfg.http_hide_idle_clients > 0) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
1402 tpl_addVar(vars, TPLADD, "HTTPHIDETYPE", cfg.http_hide_type);
1403 if(cfg.http_status_log > 0) { tpl_addVar(vars, TPLADD, "SHOWLOGCHECKED", "checked"); }
1404 if(cfg.http_showpicons > 0) { tpl_addVar(vars, TPLADD, "SHOWPICONSCHECKED", "checked"); }
1405 if(cfg.http_showmeminfo > 0) { tpl_addVar(vars, TPLADD, "SHOWMEMINFOCHECKED", "checked"); }
1406 if(cfg.http_showuserinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWUSERINFOCHECKED", "checked"); }
1407 if(cfg.http_showreaderinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWREADERINFOCHECKED", "checked"); }
1408 if(cfg.http_showcacheexinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWCACHEEXINFOCHECKED", "checked"); }
1409 if(cfg.http_showloadinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWLOADINFOCHECKED", "checked"); }
1410 if(cfg.http_showecminfo > 0) { tpl_addVar(vars, TPLADD, "SHOWECMINFOCHECKED", "checked"); }
1412 char *value = mk_t_iprange(cfg.http_allowed);
1413 tpl_addVar(vars, TPLADD, "HTTPALLOW", value);
1414 free_mk_t(value);
1416 for(i = 0; i < MAX_HTTP_DYNDNS; i++)
1418 if(cfg.http_dyndns[i][0])
1420 tpl_addVar(vars, TPLAPPEND, "HTTPDYNDNS", i > 0 ? "," : "");
1421 tpl_addVar(vars, TPLAPPEND, "HTTPDYNDNS", (char *)cfg.http_dyndns[i]);
1425 tpl_addVar(vars, TPLADD, "HTTPSAVEFULLSELECT", (cfg.http_full_cfg == 1) ? "checked" : "");
1426 tpl_addVar(vars, TPLADD, "HTTPOVERWRITEBAKFILE", (cfg.http_overwrite_bak_file == 1) ? "checked" : "");
1427 tpl_addVar(vars, TPLADD, "HTTPREADONLY", (cfg.http_readonly == 1) ? "checked" : "");
1430 #ifdef WITH_SSL
1431 if(cfg.http_cert != NULL) { tpl_addVar(vars, TPLADD, "HTTPCERT", cfg.http_cert); }
1432 tpl_addVar(vars, TPLADD, "HTTPFORCESECUREMODESELECT", (cfg.https_force_secure_mode == 1) ? "checked" : "");
1433 #endif
1435 #ifndef WEBIF_JQUERY
1436 tpl_addVar(vars, TPLADDONCE, "CONFIGWEBIFJQUERY", tpl_getTpl(vars, "CONFIGWEBIFJQUERYBIT"));
1437 #endif
1439 tpl_printf(vars, TPLADD, "AULOW", "%d", cfg.aulow);
1440 tpl_printf(vars, TPLADD, "HIDECLIENTTO", "%d", cfg.hideclient_to);
1442 return tpl_getTpl(vars, "CONFIGWEBIF");
1445 #ifdef LCDSUPPORT
1446 static char *send_oscam_config_lcd(struct templatevars *vars, struct uriparams *params)
1448 setActiveSubMenu(vars, MNU_CFG_LCD);
1450 webif_save_config("lcd", vars, params);
1452 tpl_addVar(vars, TPLADD, "ENABLELCDSELECTED", (cfg.enablelcd == 1) ? "checked" : "");
1454 if(cfg.lcd_output_path != NULL)
1455 { tpl_addVar(vars, TPLADD, "LCDOUTPUTPATH", cfg.lcd_output_path); }
1457 tpl_addVar(vars, TPLADD, "LCDHIDEIDLE", (cfg.lcd_hide_idle == 1) ? "checked" : "");
1459 tpl_printf(vars, TPLADD, "LCDREFRESHINTERVAL", "%d", cfg.lcd_write_intervall);
1461 return tpl_getTpl(vars, "CONFIGLCD");
1463 #endif
1465 #ifdef MODULE_MONITOR
1466 static char *send_oscam_config_monitor(struct templatevars *vars, struct uriparams *params)
1468 setActiveSubMenu(vars, MNU_CFG_MONITOR);
1470 webif_save_config("monitor", vars, params);
1472 tpl_printf(vars, TPLADD, "MONPORT", "%d", cfg.mon_port);
1473 if(IP_ISSET(cfg.mon_srvip))
1474 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.mon_srvip)); }
1476 tpl_printf(vars, TPLADD, "AULOW", "%d", cfg.aulow);
1477 tpl_printf(vars, TPLADD, "HIDECLIENTTO", "%d", cfg.hideclient_to);
1479 char *value = mk_t_iprange(cfg.mon_allowed);
1480 tpl_addVar(vars, TPLADD, "NOCRYPT", value);
1481 free_mk_t(value);
1483 //Monlevel selector
1484 tpl_printf(vars, TPLADD, "TMP", "MONSELECTED%d", cfg.mon_level);
1485 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1487 return tpl_getTpl(vars, "CONFIGMONITOR");
1489 #endif
1491 #ifdef MODULE_SERIAL
1492 static char *send_oscam_config_serial(struct templatevars *vars, struct uriparams *params)
1494 setActiveSubMenu(vars, MNU_CFG_SERIAL);
1496 webif_save_config("serial", vars, params);
1498 if(cfg.ser_device)
1500 char sdevice[strlen(cfg.ser_device)];
1501 cs_strncpy(sdevice, cfg.ser_device, sizeof(sdevice));
1502 char *ptr, *saveptr1 = NULL;
1503 char delimiter[2];
1504 delimiter[0] = 1;
1505 delimiter[1] = '\0';
1506 for(ptr = strtok_r(sdevice, delimiter, &saveptr1); ptr; ptr = strtok_r(NULL, delimiter, &saveptr1))
1508 tpl_addVar(vars, TPLADD, "SERIALDEVICE", xml_encode(vars, ptr));
1509 tpl_addVar(vars, TPLAPPEND, "DEVICES", tpl_getTpl(vars, "CONFIGSERIALDEVICEBIT"));
1513 tpl_addVar(vars, TPLADD, "SERIALDEVICE", "");
1514 tpl_addVar(vars, TPLAPPEND, "DEVICES", tpl_getTpl(vars, "CONFIGSERIALDEVICEBIT"));
1516 return tpl_getTpl(vars, "CONFIGSERIAL");
1518 #endif
1520 #ifdef HAVE_DVBAPI
1521 extern const char *boxdesc[];
1523 static char *send_oscam_config_dvbapi(struct templatevars *vars, struct uriparams *params)
1525 int32_t i;
1527 setActiveSubMenu(vars, MNU_CFG_DVBAPI);
1529 webif_save_config("dvbapi", vars, params);
1531 if(cfg.dvbapi_enabled > 0)
1532 { tpl_addVar(vars, TPLADD, "ENABLEDCHECKED", "checked"); }
1534 if(cfg.dvbapi_au > 0)
1535 { tpl_addVar(vars, TPLADD, "AUCHECKED", "checked"); }
1537 if(cfg.dvbapi_delayer > 0)
1538 { tpl_printf(vars, TPLADD, "DELAYER", "%d", cfg.dvbapi_delayer); }
1540 tpl_printf(vars, TPLADD, "BOXTYPE", "<option value=\"\"%s>None</option>\n", cfg.dvbapi_boxtype == 0 ? " selected" : "");
1541 for(i = 1; i <= BOXTYPES; i++)
1543 tpl_printf(vars, TPLAPPEND, "BOXTYPE", "<option%s>%s</option>\n", cfg.dvbapi_boxtype == i ? " selected" : "", boxdesc[i]);
1546 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, cfg.dvbapi_usr));
1548 //PMT Mode
1549 tpl_printf(vars, TPLADD, "TMP", "PMTMODESELECTED%d", cfg.dvbapi_pmtmode);
1550 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1552 //Request Mode
1553 tpl_printf(vars, TPLADD, "TMP", "REQMODESELECTED%d", cfg.dvbapi_requestmode);
1554 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1556 //ecminfo_type
1557 tpl_printf(vars, TPLADD, "TMP", "ECMINFOTYPESELECTED%d", cfg.dvbapi_ecminfo_type);
1558 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1560 //read_sdt
1561 tpl_printf(vars, TPLADD, "TMP", "READSDTSELECTED%d", cfg.dvbapi_read_sdt);
1562 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1564 //extended_cw_api
1565 tpl_printf(vars, TPLADD, "TMP", "EXTENDEDCWAPISELECTED%d", cfg.dvbapi_extended_cw_api);
1566 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1568 //write_sdt_prov
1569 if(cfg.dvbapi_write_sdt_prov > 0)
1570 { tpl_addVar(vars, TPLADD, "WRITESDTPROVCHECKED", "checked"); }
1572 //TCP listen port
1573 if(cfg.dvbapi_listenport > 0)
1574 { tpl_printf(vars, TPLADD, "LISTENPORT", "%d", cfg.dvbapi_listenport); }
1576 return tpl_getTpl(vars, "CONFIGDVBAPI");
1578 #endif
1580 #ifdef CS_ANTICASC
1581 static char *send_oscam_config_anticasc(struct templatevars *vars, struct uriparams *params)
1583 setActiveSubMenu(vars, MNU_CFG_ANTICASC);
1585 webif_save_config("anticasc", vars, params);
1587 if(cfg.ac_enabled > 0) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
1588 tpl_printf(vars, TPLADD, "NUMUSERS", "%d", cfg.ac_users);
1589 tpl_printf(vars, TPLADD, "SAMPLETIME", "%d", cfg.ac_stime);
1590 tpl_printf(vars, TPLADD, "SAMPLES", "%d", cfg.ac_samples);
1592 tpl_printf(vars, TPLADD, "TMP", "PENALTY%d", cfg.ac_penalty);
1593 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1595 if(cfg.ac_logfile)
1596 { tpl_addVar(vars, TPLADD, "ACLOGFILE", cfg.ac_logfile); }
1597 tpl_printf(vars, TPLADD, "FAKEDELAY", "%d", cfg.ac_fakedelay);
1598 tpl_printf(vars, TPLADD, "DENYSAMPLES", "%d", cfg.ac_denysamples);
1600 if(cfg.acosc_enabled == 1)
1601 { tpl_addVar(vars, TPLADD, "ACOSC_CHECKED", "checked"); }
1602 tpl_printf(vars, TPLADD, "ACOSC_MAX_ACTIVE_SIDS", "%d", cfg.acosc_max_active_sids);
1603 tpl_printf(vars, TPLADD, "ACOSC_ZAP_LIMIT", "%d", cfg.acosc_zap_limit);
1604 tpl_printf(vars, TPLADD, "TMP", "ACOSC_PENALTY%d", cfg.acosc_penalty);
1605 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1606 tpl_printf(vars, TPLADD, "ACOSC_PENALTY_DURATION", "%d", cfg.acosc_penalty_duration);
1607 tpl_printf(vars, TPLADD, "ACOSC_DELAY", "%d", cfg.acosc_delay);
1609 return tpl_getTpl(vars, "CONFIGANTICASC");
1611 #endif
1613 static char *send_oscam_config(struct templatevars *vars, struct uriparams *params)
1616 setActiveMenu(vars, MNU_CONFIG);
1618 char *part = getParam(params, "part");
1619 if(!strcmp(part, "webif")) { return send_oscam_config_webif(vars, params); }
1620 #ifdef MODULE_MONITOR
1621 else if(!strcmp(part, "monitor")) { return send_oscam_config_monitor(vars, params); }
1622 #endif
1623 #ifdef LCDSUPPORT
1624 else if(!strcmp(part, "lcd")) { return send_oscam_config_lcd(vars, params); }
1625 #endif
1626 #ifdef MODULE_CAMD33
1627 else if(!strcmp(part, "camd33")) { return send_oscam_config_camd33(vars, params); }
1628 #endif
1629 #ifdef MODULE_CAMD35
1630 else if(!strcmp(part, "camd35")) { return send_oscam_config_camd35(vars, params); }
1631 #endif
1632 #ifdef MODULE_CAMD35_TCP
1633 else if(!strcmp(part, "camd35tcp")) { return send_oscam_config_camd35tcp(vars, params); }
1634 #endif
1635 else if(!strcmp(part, "cache")) { return send_oscam_config_cache(vars, params); }
1636 #ifdef MODULE_NEWCAMD
1637 else if(!strcmp(part, "newcamd")) { return send_oscam_config_newcamd(vars, params); }
1638 #endif
1639 #ifdef MODULE_RADEGAST
1640 else if(!strcmp(part, "radegast")) { return send_oscam_config_radegast(vars, params); }
1641 #endif
1642 #ifdef MODULE_SCAM
1643 else if(!strcmp(part, "scam")) { return send_oscam_config_scam(vars, params); }
1644 #endif
1645 #ifdef MODULE_CCCAM
1646 else if(!strcmp(part, "cccam")) { return send_oscam_config_cccam(vars, params); }
1647 #endif
1648 #ifdef MODULE_GBOX
1649 else if(!strcmp(part, "gbox")) { return send_oscam_config_gbox(vars, params); }
1650 #endif
1651 #ifdef HAVE_DVBAPI
1652 else if(!strcmp(part, "dvbapi")) { return send_oscam_config_dvbapi(vars, params); }
1653 #endif
1654 #ifdef CS_ANTICASC
1655 else if(!strcmp(part, "anticasc")) { return send_oscam_config_anticasc(vars, params); }
1656 #endif
1657 #ifdef MODULE_SERIAL
1658 else if(!strcmp(part, "serial")) { return send_oscam_config_serial(vars, params); }
1659 #endif
1660 #ifdef WITH_LB
1661 else if(!strcmp(part, "loadbalancer")) { return send_oscam_config_loadbalancer(vars, params); }
1662 #endif
1663 else { return send_oscam_config_global(vars, params); }
1666 static void inactivate_reader(struct s_reader *rdr)
1668 struct s_client *cl = rdr->client;
1669 if(cl)
1670 { kill_thread(cl); }
1673 static bool picon_exists(char *name)
1675 char picon_name[64], path[255];
1676 char *tpl_path;
1677 tpl_path = cfg.http_piconpath ? cfg.http_piconpath : cfg.http_tpl;
1678 if(!tpl_path)
1679 { return false; }
1680 snprintf(picon_name, sizeof(picon_name) - 1, "IC_%s", name);
1681 return strlen(tpl_getTplPath(picon_name, tpl_path, path, sizeof(path) - 1)) && file_exists(path);
1684 static void clear_rdr_stats(struct s_reader *rdr)
1686 int i;
1687 for(i = 0; i < 4; i++)
1689 rdr->emmerror[i] = 0;
1690 rdr->emmwritten[i] = 0;
1691 rdr->emmskipped[i] = 0;
1692 rdr->emmblocked[i] = 0;
1694 rdr->ecmsok = 0;
1695 rdr->ecmsnok = 0;
1696 rdr->ecmstout = 0;
1697 rdr->ecmshealthok = 0;
1698 rdr->ecmshealthnok = 0;
1699 rdr->ecmshealthtout = 0;
1700 rdr->ecmsfilteredhead = 0;
1701 rdr->ecmsfilteredlen = 0;
1704 static void clear_all_rdr_stats(void)
1706 struct s_reader *rdr;
1707 LL_ITER itr = ll_iter_create(configured_readers);
1708 while((rdr = ll_iter_next(&itr)))
1710 clear_rdr_stats(rdr);
1714 static char *send_oscam_reader(struct templatevars *vars, struct uriparams *params, int32_t apicall)
1716 struct s_reader *rdr;
1717 int32_t i;
1718 unsigned char md5tmp[MD5_DIGEST_LENGTH];
1720 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
1721 if(!apicall)
1723 if(strcmp(getParam(params, "action"), "resetallrdrstats") == 0)
1725 clear_all_rdr_stats();
1729 tpl_addVar(vars, TPLADD, "READERACTIONCOLS", config_enabled(WITH_LB) ? "6" : "5");
1731 if(strcmp(getParam(params, "action"), "resetuserstats") == 0)
1733 clear_info_clients_stats();
1735 if(strcmp(getParam(params, "action"), "resetreaderstats") == 0)
1737 clear_info_readers_stats();
1739 if(strcmp(getParam(params, "action"), "reloadreaders") == 0)
1741 if(!cfg.http_readonly)
1742 { refresh_oscam(REFR_READERS); }
1744 if((strcmp(getParam(params, "action"), "disable") == 0) || (strcmp(getParam(params, "action"), "enable") == 0))
1746 if(cfg.http_readonly)
1748 tpl_addMsg(vars, "WebIf is in readonly mode. Enabling or disabling readers is not possible!");
1750 else
1752 rdr = get_reader_by_label(getParam(params, "label"));
1753 if(rdr)
1755 if(strcmp(getParam(params, "action"), "enable") == 0)
1757 if(!rdr->enable)
1759 rdr->enable = 1;
1762 else
1764 if(rdr->enable)
1766 rdr->enable = 0;
1769 restart_cardreader(rdr, 1);
1770 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
1775 if(strcmp(getParam(params, "action"), "delete") == 0)
1777 if(cfg.http_readonly)
1779 tpl_addMsg(vars, "WebIf is in readonly mode. No deletion will be made!");
1781 else
1783 rdr = get_reader_by_label(getParam(params, "label"));
1784 if(rdr)
1786 inactivate_reader(rdr);
1787 ll_remove(configured_readers, rdr);
1789 free_reader(rdr);
1791 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
1796 if(strcmp(getParam(params, "action"), "reread") == 0)
1798 rdr = get_reader_by_label(getParam(params, "label"));
1799 if(rdr)
1801 struct s_client *cl = rdr->client;
1802 //reset the counters
1803 for(i = 0; i < 4; i++)
1805 rdr->emmerror[i] = 0;
1806 rdr->emmwritten[i] = 0;
1807 rdr->emmskipped[i] = 0;
1808 rdr->emmblocked[i] = 0;
1811 if(rdr->enable == 1 && cl && cl->typ == 'r')
1813 add_job(cl, ACTION_READER_CARDINFO, NULL, 0);
1818 LL_ITER itr = ll_iter_create(configured_readers);
1820 if(!apicall)
1822 for(i = 0, rdr = ll_iter_next(&itr); rdr && rdr->label[0]; rdr = ll_iter_next(&itr), i++) { ; }
1823 tpl_printf(vars, TPLADD, "NEXTREADER", "Reader-%d", i); //Next Readername
1826 int jsondelimiter = 0;
1827 int existing_insert = 0;
1829 int32_t total_readers = 0;
1830 int32_t disabled_readers = 0;
1831 int32_t active_readers = 0;
1832 int32_t connected_readers = 0;
1834 ll_iter_reset(&itr); //going to iterate all configured readers
1835 while((rdr = ll_iter_next(&itr)))
1837 struct s_client *cl = rdr->client;
1838 if(rdr->label[0] && rdr->typ)
1840 total_readers += 1;
1842 // used for API and WebIf
1843 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
1845 MD5((unsigned char *)rdr->label, strlen(rdr->label), md5tmp);
1846 int z;
1847 tpl_addVar(vars, TPLADD, "LABELMD5","id_");
1848 for (z = 0; z < MD5_DIGEST_LENGTH; z++){
1849 tpl_printf(vars, TPLAPPEND, "LABELMD5", "%02x", md5tmp[z]);
1851 #ifdef MODULE_GBOX
1852 if(apicall){
1853 tpl_addVar(vars, TPLADD, "LASTGSMS", "");
1854 tpl_addVar(vars, TPLADD, "LASTGSMS", rdr->last_gsms);
1856 #endif
1857 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, rdr->label));
1858 if(!existing_insert){
1859 tpl_printf(vars, TPLADD, "EXISTING_INS", "'%s'", urlencode(vars, rdr->label));
1860 existing_insert++;
1861 }else{
1862 tpl_printf(vars, TPLAPPEND, "EXISTING_INS", ",'%s'", urlencode(vars, rdr->label));
1864 tpl_addVar(vars, TPLADD, "CTYP", reader_get_type_desc(rdr, 0));
1865 tpl_addVar(vars, TPLADD, "CTYPSORT", reader_get_type_desc(rdr, 0));
1867 tpl_addVar(vars, TPLADD, "READERCLASS", rdr->enable ? "enabledreader" : "disabledreader");
1869 if(rdr->enable) { active_readers += 1; }
1870 else { disabled_readers += 1; }
1872 if(rdr->tcp_connected) { connected_readers += 1; }
1874 if(rdr->description)
1875 tpl_printf(vars, TPLADD, "DESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, rdr->description));
1876 else
1877 tpl_addVar(vars, TPLADD, "DESCRIPTION", "");
1879 if(cfg.http_showpicons && !apicall)
1881 tpl_addVar(vars, TPLADD, "READERBIT", tpl_getTpl(vars, picon_exists(xml_encode(vars, rdr->label)) ? "READERNAMEBIT" : "READERNOICON"));
1882 tpl_addVar(vars, TPLADD, "CTYP", picon_exists(xml_encode(vars, reader_get_type_desc(rdr, 0))) ? tpl_getTpl(vars, "READERCTYPBIT") : tpl_getTpl(vars, "READERCTYPNOICON"));
1884 else
1885 tpl_addVar(vars, TPLADD, "READERBIT", tpl_getTpl(vars, "READERLABEL"));
1887 char *value = mk_t_group(rdr->grp);
1888 tpl_addVar(vars, TPLADD, "GROUPS", value);
1889 free_mk_t(value);
1890 tpl_printf(vars, TPLADD, "EMMERRORUK", PRINTF_LOCAL_D, rdr->emmerror[UNKNOWN]);
1891 tpl_printf(vars, TPLADD, "EMMERRORG", PRINTF_LOCAL_D, rdr->emmerror[GLOBAL]);
1892 tpl_printf(vars, TPLADD, "EMMERRORS", PRINTF_LOCAL_D, rdr->emmerror[SHARED]);
1893 tpl_printf(vars, TPLADD, "EMMERRORUQ", PRINTF_LOCAL_D, rdr->emmerror[UNIQUE]);
1895 tpl_printf(vars, TPLADD, "EMMWRITTENUK", PRINTF_LOCAL_D, rdr->emmwritten[UNKNOWN]);
1896 tpl_printf(vars, TPLADD, "EMMWRITTENG", PRINTF_LOCAL_D, rdr->emmwritten[GLOBAL]);
1897 tpl_printf(vars, TPLADD, "EMMWRITTENS", PRINTF_LOCAL_D, rdr->emmwritten[SHARED]);
1898 tpl_printf(vars, TPLADD, "EMMWRITTENUQ", PRINTF_LOCAL_D, rdr->emmwritten[UNIQUE]);
1900 tpl_printf(vars, TPLADD, "EMMSKIPPEDUK", PRINTF_LOCAL_D, rdr->emmskipped[UNKNOWN]);
1901 tpl_printf(vars, TPLADD, "EMMSKIPPEDG", PRINTF_LOCAL_D, rdr->emmskipped[GLOBAL]);
1902 tpl_printf(vars, TPLADD, "EMMSKIPPEDS", PRINTF_LOCAL_D, rdr->emmskipped[SHARED]);
1903 tpl_printf(vars, TPLADD, "EMMSKIPPEDUQ", PRINTF_LOCAL_D, rdr->emmskipped[UNIQUE]);
1905 tpl_printf(vars, TPLADD, "EMMBLOCKEDUK", PRINTF_LOCAL_D, rdr->emmblocked[UNKNOWN]);
1906 tpl_printf(vars, TPLADD, "EMMBLOCKEDG", PRINTF_LOCAL_D, rdr->emmblocked[GLOBAL]);
1907 tpl_printf(vars, TPLADD, "EMMBLOCKEDS", PRINTF_LOCAL_D, rdr->emmblocked[SHARED]);
1908 tpl_printf(vars, TPLADD, "EMMBLOCKEDUQ", PRINTF_LOCAL_D, rdr->emmblocked[UNIQUE]);
1910 tpl_printf(vars, TPLADD, "ECMSOK", PRINTF_LOCAL_D, rdr->ecmsok);
1911 tpl_printf(vars, TPLADD, "ECMSOKREL", " (%.2f %%)", rdr->ecmshealthok);
1912 tpl_printf(vars, TPLADD, "ECMSNOK", PRINTF_LOCAL_D, rdr->ecmsnok);
1913 tpl_printf(vars, TPLADD, "ECMSNOKREL", " (%.2f %%)",rdr->ecmshealthnok);
1914 tpl_printf(vars, TPLADD, "ECMSTOUT", PRINTF_LOCAL_D, rdr->ecmstout);
1915 tpl_printf(vars, TPLADD, "ECMSTOUTREL", " (%.2f %%)",rdr->ecmshealthtout);
1916 tpl_printf(vars, TPLADD, "ECMSFILTEREDHEAD", PRINTF_LOCAL_D, rdr->ecmsfilteredhead);
1917 tpl_printf(vars, TPLADD, "ECMSFILTEREDLEN", PRINTF_LOCAL_D, rdr->ecmsfilteredlen);
1918 #ifdef WITH_LB
1919 tpl_printf(vars, TPLADD, "LBWEIGHT", "%d", rdr->lb_weight);
1920 #endif
1921 if(!is_network_reader(rdr)) //reader is physical
1923 tpl_addVar(vars, TPLADD, "REFRICO", "image?i=ICREF");
1924 tpl_addVar(vars, TPLADD, "READERREFRESH", tpl_getTpl(vars, "READERREFRESHBIT"));
1925 tpl_addVar(vars, TPLADD, "ENTICO", "image?i=ICENT");
1926 tpl_addVar(vars, TPLADD, "ENTITLEMENT", tpl_getTpl(vars, "READERENTITLEBIT"));
1928 else
1930 tpl_addVar(vars, TPLADD, "READERREFRESH", "");
1931 if(rdr->typ == R_CCCAM)
1933 tpl_addVar(vars, TPLADD, "ENTICO", "image?i=ICENT");
1934 tpl_addVar(vars, TPLADD, "ENTITLEMENT", tpl_getTpl(vars, "READERENTITLEBIT"));
1936 else
1938 tpl_addVar(vars, TPLADD, "ENTITLEMENT", "");
1942 if(rdr->enable == 0)
1944 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICENA");
1945 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Enable");
1946 tpl_addVar(vars, TPLADD, "SWITCH", "enable");
1947 tpl_addVar(vars, TPLADD, "WRITEEMM", "");
1949 else
1951 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICDIS");
1952 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Disable");
1953 tpl_addVar(vars, TPLADD, "SWITCH", "disable");
1955 tpl_addVar(vars, TPLADD, "EMMICO", "image?i=ICEMM");
1956 tpl_addVar(vars, TPLADD, "WRITEEMM", tpl_getTpl(vars, "READERWRITEEMMBIT"));
1959 if(!apicall)
1961 // Add to WebIf Template
1962 tpl_addVar(vars, TPLAPPEND, "READERLIST", tpl_getTpl(vars, "READERSBIT"));
1964 else
1967 // used only for API
1968 tpl_addVar(vars, TPLADD, "APIREADERENABLED", !rdr->enable ? "0" : "1");
1969 if(cl)
1971 tpl_printf(vars, TPLADD, "APIREADERTYPE", "%c", cl->typ ? cl->typ : 'x');
1974 if(apicall==1)
1976 // Add to API Template
1977 tpl_addVar(vars, TPLAPPEND, "APIREADERLIST", tpl_getTpl(vars, "APIREADERSBIT"));
1979 if(apicall==2)
1981 tpl_printf(vars, TPLAPPEND, "APIREADERLIST","%s%s",jsondelimiter?",":"", tpl_getTpl(vars, "JSONREADERBIT"));
1982 jsondelimiter++;
1989 tpl_printf(vars, TPLADD, "TOTAL_READERS", "%d", total_readers);
1990 tpl_printf(vars, TPLADD, "TOTAL_DISABLED_READERS", "%d", disabled_readers);
1991 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE_READERS", "%d", active_readers);
1992 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED_READERS", "%d", connected_readers);
1994 //CM info
1995 tpl_addVar(vars, TPLADD, "DISPLAYUSERINFO", "hidden"); // no userinfo in readers
1996 set_ecm_info(vars);
1998 if(!apicall)
2000 #ifdef MODULE_CAMD33
2001 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>camd33</option>\n");
2002 #endif
2003 #ifdef MODULE_CAMD35
2004 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>cs357x</option>\n");
2005 #endif
2006 #ifdef MODULE_CAMD35_TCP
2007 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>cs378x</option>\n");
2008 #endif
2009 #ifdef MODULE_NEWCAMD
2010 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>newcamd</option>\n");
2011 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>newcamd524</option>\n");
2012 #endif
2013 #ifdef MODULE_CCCAM
2014 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>cccam</option>\n");
2015 #endif
2016 #ifdef MODULE_GBOX
2017 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>gbox</option>\n");
2018 #endif
2019 #ifdef MODULE_RADEGAST
2020 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>radegast</option>\n");
2021 #endif
2022 #ifdef MODULE_SERIAL
2023 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>serial</option>\n");
2024 #endif
2025 #ifdef MODULE_CONSTCW
2026 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>constcw</option>\n");
2027 #endif
2028 #ifdef MODULE_SCAM
2029 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>scam</option>\n");
2030 #endif
2032 for(i = 0; cardreaders[i]; i++)
2034 tpl_printf(vars, TPLAPPEND, "ADDPROTOCOL", "<option>%s</option>\n", xml_encode(vars, cardreaders[i]->desc));
2036 return tpl_getTpl(vars, "READERS");
2038 else
2040 if(apicall == 1)
2042 return tpl_getTpl(vars, "APIREADERS");
2044 else
2046 return tpl_getTpl(vars, "JSONREADER");
2051 static char *send_oscam_reader_config(struct templatevars *vars, struct uriparams *params)
2053 int32_t i;
2054 int32_t apicall = 0;
2055 char *reader_ = getParam(params, "label");
2056 char *value;
2058 struct s_reader *rdr;
2060 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
2062 if(strcmp(getParam(params, "action"), "Add") == 0)
2064 // Add new reader
2065 struct s_reader *newrdr;
2066 if(!cs_malloc(&newrdr, sizeof(struct s_reader))) { return "0"; }
2067 for(i = 0; i < (*params).paramcount; ++i)
2069 if(strcmp((*params).params[i], "action"))
2070 { chk_reader((*params).params[i], (*params).values[i], newrdr); }
2072 module_reader_set(newrdr);
2073 reader_ = newrdr->label;
2074 reader_set_defaults(newrdr);
2075 newrdr->enable = 0; // do not start the reader because must configured before
2076 ll_append(configured_readers, newrdr);
2077 tpl_addMsg(vars, "New Reader has been added with default settings");
2079 else if(strcmp(getParam(params, "action"), "Save") == 0)
2082 rdr = get_reader_by_label(getParam(params, "label"));
2083 if(!rdr)
2084 { return NULL; }
2085 //if (is_network_reader(rdr))
2086 // inactivate_reader(rdr); //Stop reader before reinitialization
2087 char servicelabels[1024] = "";
2088 char servicelabelslb[1024] = "";
2090 for(i = 0; i < (*params).paramcount; ++i)
2092 if((strcmp((*params).params[i], "reader")) && (strcmp((*params).params[i], "action")))
2094 if(!strcmp((*params).params[i], "services"))
2095 { snprintf(servicelabels + strlen(servicelabels), sizeof(servicelabels) - strlen(servicelabels), "%s,", (*params).values[i]); }
2096 else if(!strcmp((*params).params[i], "lb_whitelist_services"))
2097 { snprintf(servicelabelslb + strlen(servicelabelslb), sizeof(servicelabelslb) - strlen(servicelabelslb), "%s,", (*params).values[i]); }
2098 else
2099 /*if(strlen((*params).values[i]) > 0)*/
2100 { chk_reader((*params).params[i], (*params).values[i], rdr); }
2102 //printf("param %s value %s\n",(*params).params[i], (*params).values[i]);
2104 chk_reader("services", servicelabels, rdr);
2105 chk_reader("lb_whitelist_services", servicelabelslb, rdr);
2107 if(is_network_reader(rdr)) //physical readers make trouble if re-started
2109 restart_cardreader(rdr, 1);
2112 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); } else { tpl_addMsg(vars, "Reader config updated and saved"); }
2116 rdr = get_reader_by_label(reader_);
2117 if(!rdr)
2118 { return NULL; }
2120 // Label, Description
2121 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
2122 tpl_addVar(vars, TPLADD, "DESCRIPTION", xml_encode(vars, rdr->description));
2124 // enabled
2125 if(!apicall)
2127 tpl_addVar(vars, TPLADD, "ENABLED", (rdr->enable == 1) ? "checked" : "");
2129 else
2131 tpl_addVar(vars, TPLADD, "ENABLEDVALUE", (rdr->enable == 1) ? "1" : "0");
2134 tpl_addVar(vars, TPLADD, "PASSWORD", xml_encode(vars, rdr->r_pwd));
2135 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, rdr->r_usr));
2136 tpl_addVar(vars, TPLADD, "PASS", xml_encode(vars, rdr->r_pwd));
2138 // Key Newcamd
2139 for(i = 0; i < (int32_t)sizeof(rdr->ncd_key); i++)
2140 { tpl_printf(vars, TPLAPPEND, "NCD_KEY", "%02X", rdr->ncd_key[i]); }
2142 // Pincode
2143 tpl_addVar(vars, TPLADD, "PINCODE", rdr->pincode);
2145 // Emmfile Path
2146 if(rdr->emmfile) { tpl_addVar(vars, TPLADD, "EMMFILE", (char *)rdr->emmfile); }
2148 // Inactivity timeout
2149 tpl_printf(vars, TPLADD, "INACTIVITYTIMEOUT", "%d", rdr->tcp_ito);
2151 // Receive timeout
2152 tpl_printf(vars, TPLADD, "RECEIVETIMEOUT", "%d", rdr->tcp_rto);
2154 // keepalive
2155 tpl_addVar(vars, TPLADD, "RDRKEEPALIVE", (rdr->keepalive == 1) ? "checked" : "");
2157 // Connect on init (newcamd)
2158 if(!apicall)
2160 tpl_addVar(vars, TPLADD, "CONNECTONINITCHECKED", (rdr->ncd_connect_on_init == 1) ? "checked" : "");
2162 else
2164 tpl_addVar(vars, TPLADD, "CONNECTONINITCHECKED", (rdr->ncd_connect_on_init == 1) ? "1" : "0");
2167 // Reset Cycle
2168 tpl_printf(vars, TPLADD, "RESETCYCLE", "%d", rdr->resetcycle);
2170 // Disable Serverfilter
2171 if(!apicall)
2173 tpl_addVar(vars, TPLADD, "DISABLESERVERFILTERCHECKED", (rdr->ncd_disable_server_filt == 1) ? "checked" : "");
2175 else
2177 tpl_addVar(vars, TPLADD, "DISABLESERVERFILTERVALUE", (rdr->ncd_disable_server_filt == 1) ? "1" : "0");
2180 #ifdef MODULE_GHTTP
2181 // Use SSL
2182 if(!apicall)
2184 tpl_addVar(vars, TPLADD, "USESSLCHECKED", (rdr->ghttp_use_ssl == 1) ? "checked" : "");
2186 else
2188 tpl_addVar(vars, TPLADD, "USESSLVALUE", (rdr->ghttp_use_ssl == 1) ? "1" : "0");
2190 #endif
2192 // Fallback
2193 if(!apicall)
2195 tpl_addVar(vars, TPLADD, "FALLBACKCHECKED", (rdr->fallback == 1) ? "checked" : "");
2197 else
2199 tpl_addVar(vars, TPLADD, "FALLBACKVALUE", (rdr->fallback == 1) ? "1" : "0");
2202 // Fallback per caid
2203 value = mk_t_ftab(&rdr->fallback_percaid);
2204 tpl_addVar(vars, TPLADD, "FALLBACK_PERCAID", value);
2205 free_mk_t(value);
2207 // disable checksum test only for selected caid/provid
2208 value = mk_t_ftab(&rdr->disablecrccws_only_for);
2209 tpl_addVar(vars, TPLADD, "IGN_CHKSUM_ONLYFOR", value);
2210 free_mk_t(value);
2212 #ifdef WITH_LB
2213 tpl_addVar(vars, TPLADD, "LBFORCEFALLBACK", (rdr->lb_force_fallback == 1) ? "checked" : "");
2214 #endif
2216 #ifdef CS_CACHEEX
2217 // Cacheex
2218 if(!apicall)
2220 tpl_printf(vars, TPLADD, "TMP", "CACHEEXSELECTED%d", rdr->cacheex.mode);
2221 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
2223 else
2225 tpl_printf(vars, TPLADD, "CACHEEX", "%d", rdr->cacheex.mode);
2227 tpl_printf(vars, TPLADD, "CACHEEX_MAXHOP", "%d", rdr->cacheex.maxhop);
2228 value = mk_t_cacheex_hitvaluetab(&rdr->cacheex.filter_caidtab);
2229 //if (strlen(value) > 0)
2230 tpl_printf(vars, TPLADD, "CACHEEX_ECM_FILTER", "%s", value);
2231 free_mk_t(value);
2233 tpl_addVar(vars, TPLADD, "DCCHECKED", (rdr->cacheex.drop_csp == 1) ? "checked" : "");
2234 tpl_addVar(vars, TPLADD, "ARCHECKED", (rdr->cacheex.allow_request == 1) ? "checked" : "");
2235 tpl_addVar(vars, TPLADD, "AFCHECKED", (rdr->cacheex.allow_filter == 1) ? "checked" : "");
2236 tpl_addVar(vars, TPLADD, "BLOCKFAKECWSCHECKED", (rdr->cacheex.block_fakecws == 1) ? "checked" : "");
2237 #endif
2239 // BoxID
2240 if(rdr->boxid)
2241 { tpl_printf(vars, TPLADD, "BOXID", "%08X", rdr->boxid); }
2243 // Filt 07
2244 if(!apicall)
2246 tpl_addVar(vars, TPLADD, "FIX07CHECKED", (rdr->fix_07 == 1) ? "checked" : "");
2248 else
2250 tpl_addVar(vars, TPLADD, "FIX07VALUE", (rdr->fix_07 == 1) ? "1" : "0");
2254 // Fix 9993
2255 if(!apicall)
2257 tpl_addVar(vars, TPLADD, "FIX9993CHECKED", (rdr->fix_9993 == 1) ? "checked" : "");
2259 else
2261 tpl_addVar(vars, TPLADD, "FIX9993VALUE", (rdr->fix_9993 == 1) ? "1" : "0");
2264 // Drop CWs with wrong checksum:
2265 if(!apicall)
2267 tpl_addVar(vars, TPLADD, "DROPBADCWSCHECKED", (rdr->dropbadcws == 1) ? "checked" : "");
2269 else
2271 tpl_addVar(vars, TPLADD, "DROPBADCWSVALUE", (rdr->dropbadcws == 1) ? "1" : "0");
2274 // Disable CWs checksum test:
2275 if(!apicall)
2277 tpl_addVar(vars, TPLADD, "DISABLECRCCWSCHECKED", (rdr->disablecrccws == 1) ? "checked" : "");
2279 else
2281 tpl_addVar(vars, TPLADD, "DISABLECRCCWSVALUE", (rdr->disablecrccws == 1) ? "1" : "0");
2284 // Set reader to use GPIO
2285 if(!apicall)
2287 tpl_addVar(vars, TPLADD, "USE_GPIOCHECKED", rdr->use_gpio ? "checked" : "");
2289 else
2291 tpl_addVar(vars, TPLADD, "USE_GPIOVALUE", rdr->use_gpio ? "1" : "0");
2294 // AUdisabled
2295 if(!apicall)
2297 tpl_addVar(vars, TPLADD, "AUDISABLED", (rdr->audisabled == 1) ? "checked" : "");
2299 else
2301 tpl_addVar(vars, TPLADD, "AUDISABLEDVALUE", (rdr->audisabled == 1) ? "1" : "0");
2304 // AUprovid
2305 if(rdr->auprovid)
2306 { tpl_printf(vars, TPLADD, "AUPROVID", "%06X", rdr->auprovid); }
2308 if(rdr->ecmnotfoundlimit)
2309 { tpl_printf(vars, TPLADD, "ECMNOTFOUNDLIMIT", "%u", rdr->ecmnotfoundlimit); }
2311 // Force Irdeto
2312 if(!apicall)
2314 tpl_addVar(vars, TPLADD, "FORCEIRDETOCHECKED", (rdr->force_irdeto == 1) ? "checked" : "");
2316 else
2318 tpl_addVar(vars, TPLADD, "FORCEIRDETOVALUE", (rdr->force_irdeto == 1) ? "1" : "0");
2321 // needsemmfirst
2323 if(!apicall)
2325 tpl_addVar(vars, TPLADD, "NEEDSEMMFIRST", (rdr->needsemmfirst == 1) ? "checked" : "");
2327 else
2329 tpl_addVar(vars, TPLADD, "NEEDSEMMFIRST", (rdr->needsemmfirst == 1) ? "1" : "0");
2332 // RSA Key
2333 int32_t len = rdr->rsa_mod_length;
2334 if(len > 0)
2336 for(i = 0; i < len; i++) { tpl_printf(vars, TPLAPPEND, "RSAKEY", "%02X", rdr->rsa_mod[i]); }
2339 // 3DES Key
2340 len = rdr->des_key_length;
2341 if(len > 0)
2343 for(i = 0; i < len; i++) { tpl_printf(vars, TPLAPPEND, "DESKEY", "%02X", rdr->des_key[i]); }
2346 // BoxKey
2347 len = rdr->boxkey_length;
2348 if(len > 0)
2350 for(i = 0; i < len ; i++)
2351 { tpl_printf(vars, TPLAPPEND, "BOXKEY", "%02X", rdr->boxkey[i]); }
2354 // ins7E
2355 if(rdr->ins7E[0x1A])
2357 for(i = 0; i < 26 ; i++) { tpl_printf(vars, TPLAPPEND, "INS7E", "%02X", rdr->ins7E[i]); }
2360 // ins7E11
2361 if(rdr->ins7E11[0x01])
2363 tpl_printf(vars, TPLAPPEND, "INS7E11", "%02X", rdr->ins7E11[0]);
2366 // ins2e06
2367 if(rdr->ins2e06[0x04])
2369 for(i = 0; i < 4 ; i++) { tpl_printf(vars, TPLAPPEND, "INS2E06", "%02X", rdr->ins2e06[i]); }
2372 // ATR
2373 if(rdr->atr[0])
2374 for(i = 0; i < rdr->atrlen / 2; i++)
2375 { tpl_printf(vars, TPLAPPEND, "ATR", "%02X", rdr->atr[i]); }
2377 // ECM Whitelist
2378 value = mk_t_ecm_whitelist(&rdr->ecm_whitelist);
2379 tpl_addVar(vars, TPLADD, "ECMWHITELIST", value);
2380 free_mk_t(value);
2382 // ECM Header Whitelist
2383 value = mk_t_ecm_hdr_whitelist(&rdr->ecm_hdr_whitelist);
2384 tpl_addVar(vars, TPLADD, "ECMHEADERWHITELIST", value);
2385 free_mk_t(value);
2387 // Deprecated
2388 if(!apicall)
2390 tpl_addVar(vars, TPLADD, "DEPRECATEDCHECKED", (rdr->deprecated == 1) ? "checked" : "");
2392 else
2394 tpl_addVar(vars, TPLADD, "DEPRECATEDVALUE", (rdr->deprecated == 1) ? "1" : "0");
2397 // Smargopatch
2398 if(!apicall)
2400 tpl_addVar(vars, TPLADD, "SMARGOPATCHCHECKED", (rdr->smargopatch == 1) ? "checked" : "");
2402 else
2404 tpl_addVar(vars, TPLADD, "SMARGOPATCHVALUE", (rdr->smargopatch == 1) ? "1" : "0");
2407 // Autospeed
2408 if(!apicall)
2410 tpl_addVar(vars, TPLADD, "AUTOSPEEDCHECKED", (rdr->autospeed == 1) ? "checked" : "");
2412 else
2414 tpl_addVar(vars, TPLADD, "AUTOSPEEDVALUE", (rdr->autospeed == 1) ? "1" : "0");
2416 // sc8in1 dtrrts patch
2417 if(!apicall)
2419 tpl_addVar(vars, TPLADD, "SC8IN1DTRRTSPATCHCHECKED", (rdr->sc8in1_dtrrts_patch == 1) ? "checked" : "");
2421 else
2423 tpl_addVar(vars, TPLADD, "SC8IN1DTRRTSPATCHVALUE", (rdr->sc8in1_dtrrts_patch == 1) ? "1" : "0");
2426 if(!apicall)
2428 tpl_addVar(vars, TPLADD, "READOLDCLASSES", (rdr->read_old_classes == 1) ? "checked" : "");
2430 else
2432 tpl_addVar(vars, TPLADD, "READOLDCLASSES", (rdr->read_old_classes == 1) ? "1" : "0");
2435 // Detect
2436 if(rdr->detect & 0x80)
2437 { tpl_printf(vars, TPLADD, "DETECT", "!%s", RDR_CD_TXT[rdr->detect & 0x7f]); }
2438 else
2439 { tpl_addVar(vars, TPLADD, "DETECT", RDR_CD_TXT[rdr->detect & 0x7f]); }
2441 // Ratelimit
2442 if(rdr->ratelimitecm)
2444 tpl_printf(vars, TPLADD, "RATELIMITECM", "%d", rdr->ratelimitecm);
2445 // ECMUNIQUE
2446 if(!apicall)
2448 tpl_addVar(vars, TPLADD, "ECMUNIQUECHECKED", (rdr->ecmunique == 1) ? "checked" : "");
2450 else
2452 tpl_addVar(vars, TPLADD, "ECMUNIQUE", (rdr->ecmunique == 1) ? "1" : "0");
2454 tpl_printf(vars, TPLADD, "RATELIMITTIME", "%d", rdr->ratelimittime);
2455 tpl_printf(vars, TPLADD, "SRVIDHOLDTIME", "%d", rdr->srvidholdtime);
2457 // Cooldown
2458 if(rdr->cooldown[0] && rdr->cooldown[1])
2460 tpl_printf(vars, TPLADD, "COOLDOWNDELAY", "%d", rdr->cooldown[0]);
2461 tpl_printf(vars, TPLADD, "COOLDOWNTIME", "%d", rdr->cooldown[1]);
2463 // Frequencies
2464 tpl_printf(vars, TPLADD, "MHZ", "%d", rdr->mhz);
2465 tpl_printf(vars, TPLADD, "CARDMHZ", "%d", rdr->cardmhz);
2467 // Device
2468 if(!apicall)
2470 tpl_addVar(vars, TPLADD, "DEVICE", xml_encode(vars, rdr->device));
2472 else
2474 tpl_addVar(vars, TPLADD, "DEVICE", rdr->device);
2477 if(rdr->r_port)
2478 { tpl_printf(vars, TPLAPPEND, "DEVICE", ",%d", rdr->r_port); }
2479 if(rdr->l_port)
2481 if(rdr->r_port)
2482 { tpl_printf(vars, TPLAPPEND, "DEVICE", ",%d", rdr->l_port); }
2483 else
2484 { tpl_printf(vars, TPLAPPEND, "DEVICE", ",,%d", rdr->l_port); }
2487 // Group
2488 value = mk_t_group(rdr->grp);
2489 tpl_addVar(vars, TPLADD, "GRP", value);
2490 free_mk_t(value);
2492 #ifdef WITH_LB
2493 if(rdr->lb_weight)
2494 { tpl_printf(vars, TPLADD, "LBWEIGHT", "%d", rdr->lb_weight); }
2495 #endif
2497 //services
2498 if(!apicall)
2500 struct s_sidtab *sidtab = cfg.sidtab;
2501 //build matrix
2502 i = 0;
2503 while(sidtab != NULL)
2505 tpl_addVar(vars, TPLADD, "SIDLABEL", xml_encode(vars, sidtab->label));
2506 if(rdr->sidtabs.ok & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
2507 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
2508 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "READERCONFIGSIDOKBIT"));
2509 if(rdr->sidtabs.no & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
2510 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
2511 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "READERCONFIGSIDNOBIT"));
2512 if(rdr->lb_sidtabs.ok & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
2513 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
2514 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "READERCONFIGSIDLBOKBIT"));
2515 sidtab = sidtab->next;
2516 i++;
2518 if(i){
2519 tpl_addVar(vars, TPLADD, "READERCONFIGSIDINS", tpl_getTpl(vars, "READERCONFIGSID"));
2522 else
2524 value = mk_t_service(&rdr->sidtabs);
2525 if(strlen(value) > 0)
2526 { tpl_addVar(vars, TPLADD, "SERVICES", value); }
2527 free_mk_t(value);
2530 // CAID
2531 value = mk_t_caidtab(&rdr->ctab);
2532 tpl_addVar(vars, TPLADD, "CAIDS", value);
2533 free_mk_t(value);
2535 // AESkeys
2536 value = mk_t_aeskeys(rdr);
2537 tpl_addVar(vars, TPLADD, "AESKEYS", value);
2538 free_mk_t(value);
2540 //ident
2541 value = mk_t_ftab(&rdr->ftab);
2542 tpl_addVar(vars, TPLADD, "IDENTS", value);
2543 free_mk_t(value);
2545 //CHID
2546 value = mk_t_ftab(&rdr->fchid);
2547 tpl_addVar(vars, TPLADD, "CHIDS", value);
2548 free_mk_t(value);
2550 //Local cards
2551 value = mk_t_ftab(&rdr->localcards);
2552 tpl_addVar(vars, TPLADD, "LOCALCARDS", value);
2553 free_mk_t(value);
2555 //class
2556 value = mk_t_cltab(&rdr->cltab);
2557 tpl_addVar(vars, TPLADD, "CLASS", value);
2558 free_mk_t(value);
2560 if(rdr->cachemm || rdr->logemm)
2561 { tpl_printf(vars, TPLADD, "EMMCACHE", "%d,%d,%d,%d", rdr->cachemm, rdr->rewritemm, rdr->logemm, rdr->deviceemm); }
2563 //savenano
2564 value = mk_t_nano(rdr->s_nano);
2565 tpl_addVar(vars, TPLADD, "SAVENANO", value);
2566 free_mk_t(value);
2568 //blocknano
2569 value = mk_t_nano(rdr->b_nano);
2570 tpl_addVar(vars, TPLADD, "BLOCKNANO", value);
2571 free_mk_t(value);
2573 // Blocke EMM
2574 if(!apicall)
2576 tpl_addVar(vars, TPLADD, "BLOCKEMMUNKNOWNCHK", (rdr->blockemm & EMM_UNKNOWN) ? "checked" : "");
2577 tpl_addVar(vars, TPLADD, "BLOCKEMMUNIQCHK", (rdr->blockemm & EMM_UNIQUE) ? "checked" : "");
2578 tpl_addVar(vars, TPLADD, "BLOCKEMMSHAREDCHK", (rdr->blockemm & EMM_SHARED) ? "checked" : "");
2579 tpl_addVar(vars, TPLADD, "BLOCKEMMGLOBALCHK", (rdr->blockemm & EMM_GLOBAL) ? "checked" : "");
2581 else
2583 tpl_addVar(vars, TPLADD, "BLOCKEMMUNKNOWNVALUE", (rdr->blockemm & EMM_UNKNOWN) ? "1" : "0");
2584 tpl_addVar(vars, TPLADD, "BLOCKEMMUNIQVALUE", (rdr->blockemm & EMM_UNIQUE) ? "1" : "0");
2585 tpl_addVar(vars, TPLADD, "BLOCKEMMSHAREDVALUE", (rdr->blockemm & EMM_SHARED) ? "1" : "0");
2586 tpl_addVar(vars, TPLADD, "BLOCKEMMGLOBALVALUE", (rdr->blockemm & EMM_GLOBAL) ? "1" : "0");
2589 // Save EMM
2590 if(!apicall)
2592 tpl_addVar(vars, TPLADD, "SAVEEMMUNKNOWNCHK", (rdr->saveemm & EMM_UNKNOWN) ? "checked" : "");
2593 tpl_addVar(vars, TPLADD, "SAVEEMMUNIQCHK", (rdr->saveemm & EMM_UNIQUE) ? "checked" : "");
2594 tpl_addVar(vars, TPLADD, "SAVEEMMSHAREDCHK", (rdr->saveemm & EMM_SHARED) ? "checked" : "");
2595 tpl_addVar(vars, TPLADD, "SAVEEMMGLOBALCHK", (rdr->saveemm & EMM_GLOBAL) ? "checked" : "");
2597 else
2599 tpl_addVar(vars, TPLADD, "SAVEEMMUNKNOWNVALUE", (rdr->saveemm & EMM_UNKNOWN) ? "1" : "0");
2600 tpl_addVar(vars, TPLADD, "SAVEEMMUNIQVALUE", (rdr->saveemm & EMM_UNIQUE) ? "1" : "0");
2601 tpl_addVar(vars, TPLADD, "SAVEEMMSHAREDVALUE", (rdr->saveemm & EMM_SHARED) ? "1" : "0");
2602 tpl_addVar(vars, TPLADD, "SAVEEMMGLOBALVALUE", (rdr->saveemm & EMM_GLOBAL) ? "1" : "0");
2605 value = mk_t_emmbylen(rdr);
2606 if(strlen(value) > 0)
2607 { tpl_addVar(vars, TPLADD, "BLOCKEMMBYLEN", value); }
2608 free_mk_t(value);
2610 #ifdef MODULE_CCCAM
2611 if(!strcmp(rdr->cc_version, "2.0.11"))
2613 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED0", "selected");
2615 else if(!strcmp(rdr->cc_version, "2.1.1"))
2617 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED1", "selected");
2619 else if(!strcmp(rdr->cc_version, "2.1.2"))
2621 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED2", "selected");
2623 else if(!strcmp(rdr->cc_version, "2.1.3"))
2625 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED3", "selected");
2627 else if(!strcmp(rdr->cc_version, "2.1.4"))
2629 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED4", "selected");
2631 else if(!strcmp(rdr->cc_version, "2.2.0"))
2633 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED5", "selected");
2635 else if(!strcmp(rdr->cc_version, "2.2.1"))
2637 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED6", "selected");
2639 else if(!strcmp(rdr->cc_version, "2.3.0"))
2641 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED7", "selected");
2643 else if(!strcmp(rdr->cc_version, "2.3.1"))
2645 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED8", "selected");
2647 else if(!strcmp(rdr->cc_version, "2.3.2"))
2649 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED9", "selected");
2651 #endif
2653 tpl_printf(vars, TPLADD, "TMP", "NDSVERSION%d", rdr->ndsversion);
2654 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
2656 tpl_printf(vars, TPLADD, "TMP", "NDSREADTIERS%d", rdr->readtiers);
2657 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
2659 tpl_printf(vars, TPLADD, "TMP", "NAGRAREAD%d", rdr->nagra_read);
2660 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
2662 if(rdr->detect_seca_nagra_tunneled_card)
2663 { tpl_addVar(vars, TPLADD, "NAGRADETECTSECACARDCHECKED", "checked"); }
2665 #ifdef MODULE_CCCAM
2666 tpl_printf(vars, TPLADD, "CCCMAXHOPS", "%d", rdr->cc_maxhops);
2667 tpl_printf(vars, TPLADD, "CCCMINDOWN", "%d", rdr->cc_mindown);
2668 tpl_printf(vars, TPLADD, "CCCRESHARE", "%d", rdr->cc_reshare);
2669 tpl_printf(vars, TPLADD, "RESHARE", "%d", cfg.cc_reshare);
2670 tpl_printf(vars, TPLADD, "CCCRECONNECT", "%d", rdr->cc_reconnect);
2672 if(rdr->cc_want_emu)
2673 { tpl_addVar(vars, TPLADD, "CCCWANTEMUCHECKED", "checked"); }
2674 if(rdr->cc_keepalive)
2675 { tpl_addVar(vars, TPLADD, "KEEPALIVECHECKED", "checked"); }
2676 #endif
2678 #ifdef MODULE_GBOX
2679 tpl_printf(vars, TPLADD, "GBOXMAXDISTANCE", "%d", rdr->gbox_maxdist);
2680 tpl_printf(vars, TPLADD, "GBOXMAXECMSEND", "%d", rdr->gbox_maxecmsend);
2681 tpl_printf(vars, TPLADD, "GBOXRESHARE", "%d", rdr->gbox_reshare);
2682 tpl_printf(vars, TPLADD, "GBOXCCCAMRESHARE", "%d", rdr->gbox_cccam_reshare);
2683 #endif
2685 #ifdef READER_DRECAS
2686 tpl_addVar(vars, TPLADD, "STMKEYS", rdr->stmkeys);
2687 #endif
2689 #if defined(READER_DRE) || defined(READER_DRECAS)
2690 tpl_addVar(vars, TPLADD, "USERSCRIPT", rdr->userscript);
2691 #endif
2693 tpl_addVar(vars, TPLADD, "PROTOCOL", reader_get_type_desc(rdr, 0));
2695 // Show only parameters which needed for the reader
2696 switch(rdr->typ)
2698 case R_CONSTCW:
2699 case R_DB2COM1:
2700 case R_DB2COM2:
2701 case R_MOUSE :
2702 case R_DRECAS :
2703 case R_MP35:
2704 case R_SC8in1 :
2705 case R_SMART :
2706 case R_INTERNAL:
2707 case R_SERIAL :
2708 case R_PCSC :
2709 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGSTDHWREADERBIT"));
2710 break;
2711 case R_CAMD35 :
2712 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGCAMD35BIT"));
2713 break;
2714 case R_CS378X :
2715 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGCS378XBIT"));
2716 break;
2717 case R_RADEGAST:
2718 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGRADEGASTBIT"));
2719 break;
2720 case R_SCAM:
2721 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGSCAMBIT"));
2722 break;
2723 case R_GHTTP:
2724 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGGHTTPBIT"));
2725 break;
2726 #ifdef MODULE_GBOX
2727 case R_GBOX:
2728 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGGBOXBIT"));
2729 break;
2730 #endif
2731 case R_NEWCAMD:
2732 if(rdr->ncd_proto == NCD_525)
2734 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGNCD525BIT"));
2736 else if(rdr->ncd_proto == NCD_524)
2738 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGNCD524BIT"));
2740 break;
2741 #ifdef MODULE_CCCAM
2742 case R_CCCAM :
2743 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGCCCAMBIT"));
2744 break;
2745 #endif
2746 default :
2747 tpl_addMsg(vars, "Error: protocol not resolvable");
2748 break;
2752 #ifdef MODULE_CCCAM
2753 if(rdr->typ != R_CCCAM)
2755 tpl_printf(vars, TPLADD, "CCCHOP", "%d", rdr->cc_hop);
2756 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGHOPBIT"));
2758 #endif
2760 return tpl_getTpl(vars, "READERCONFIG");
2763 static char *send_oscam_reader_stats(struct templatevars *vars, struct uriparams *params, int32_t apicall)
2766 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
2768 int8_t error;
2769 struct s_client *cl = NULL;
2770 struct s_reader *rdr;
2772 rdr = get_reader_by_label(getParam(params, "label"));
2773 error = (rdr ? 0 : 1);
2775 if(!error && rdr)
2777 cl = rdr->client;
2778 error = (cl ? 0 : 1);
2781 if(error)
2783 tpl_addVar(vars, TPLAPPEND, "READERSTATSROW", tpl_getTpl(vars, "READERSTATSROWBIT"));
2784 if(!apicall)
2785 { return tpl_getTpl(vars, "READERSTATS"); }
2786 else
2787 { return tpl_getTpl(vars, "APIREADERSTATS"); }
2790 #ifdef WITH_LB
2791 char *stxt[] = {"found", "cache1", "cache2", "cache3",
2792 "not found", "timeout", "sleeping",
2793 "fake", "invalid", "corrupt", "no card", "expdate",
2794 "disabled", "stopped"
2797 if(strcmp(getParam(params, "action"), "resetstat") == 0)
2799 char *rcs = getParam(params, "rc");
2800 int32_t retval = 0;
2801 if(strlen(rcs) > 0)
2803 int8_t rc;
2804 rc = atoi(rcs);
2805 retval = clean_stat_by_rc(rdr, rc, 0);
2806 cs_log("Reader %s stats %d %s entr%s deleted by WebIF from %s",
2807 rdr->label, retval, stxt[rc],
2808 retval == 1 ? "y" : "ies",
2809 cs_inet_ntoa(GET_IP()));
2811 else
2813 clear_reader_stat(rdr);
2814 cs_log("Reader %s stats resetted by WebIF from %s", rdr->label, cs_inet_ntoa(GET_IP()));
2819 if(strcmp(getParam(params, "action"), "deleterecord") == 0)
2821 char *record = getParam(params, "record");
2822 if(strlen(record) > 0)
2824 int32_t retval = 0;
2825 uint32_t caid, provid, sid, cid, len;
2826 sscanf(record, "%4x@%6x:%4x:%4x:%4x", &caid, &provid, &sid, &cid, &len);
2827 retval = clean_stat_by_id(rdr, caid, provid, sid, cid, len);
2828 cs_log("Reader %s stats %d entr%s deleted by WebIF from %s",
2829 rdr->label, retval,
2830 retval == 1 ? "y" : "ies",
2831 cs_inet_ntoa(GET_IP()));
2835 if(strcmp(getParam(params, "action"), "updateecmlen") == 0)
2837 update_ecmlen_from_stat(rdr);
2838 write_server();
2841 #endif
2843 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
2844 tpl_addVar(vars, TPLADD, "LABEL", xml_encode(vars, rdr->label));
2845 tpl_addVar(vars, TPLADD, "ENCODEDLABEL", urlencode(vars, rdr->label));
2847 if(apicall)
2849 int32_t i, emmcount = 0;
2850 char *ttxt[] = {"unknown", "unique", "shared", "global"};
2852 for(i = 0; i < 4; i++)
2854 tpl_addVar(vars, TPLADD, "EMMRESULT", "error");
2855 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
2856 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmerror[i]);
2857 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
2858 emmcount += rdr->emmerror[i];
2859 tpl_printf(vars, TPLADD, "TOTALERROR", "%d", emmcount);
2861 emmcount = 0;
2862 for(i = 0; i < 4; i++)
2864 tpl_addVar(vars, TPLADD, "EMMRESULT", "written");
2865 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
2866 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmwritten[i]);
2867 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
2868 emmcount += rdr->emmwritten[i];
2869 tpl_printf(vars, TPLADD, "TOTALWRITTEN", "%d", emmcount);
2871 emmcount = 0;
2872 for(i = 0; i < 4; i++)
2874 tpl_addVar(vars, TPLADD, "EMMRESULT", "skipped");
2875 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
2876 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmskipped[i]);
2877 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
2878 emmcount += rdr->emmskipped[i];
2879 tpl_printf(vars, TPLADD, "TOTALSKIPPED", "%d", emmcount);
2881 emmcount = 0;
2882 for(i = 0; i < 4; i++)
2884 tpl_addVar(vars, TPLADD, "EMMRESULT", "blocked");
2885 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
2886 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmblocked[i]);
2887 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
2888 emmcount += rdr->emmblocked[i];
2889 tpl_printf(vars, TPLADD, "TOTALBLOCKED", "%d", emmcount);
2893 if(apicall)
2895 char *txt = "UNDEF";
2896 switch(rdr->card_status)
2898 case NO_CARD:
2899 txt = "OFF";
2900 break;
2901 case UNKNOWN:
2902 txt = "UNKNOWN";
2903 break;
2904 case READER_DEVICE_ERROR:
2905 txt = "READER DEVICE ERROR";
2906 break;
2907 case CARD_NEED_INIT:
2908 txt = "NEEDINIT";
2909 break;
2910 case CARD_INSERTED:
2911 if(cl->typ == 'p')
2912 { txt = "CONNECTED"; }
2913 else
2914 { txt = "CARDOK"; }
2915 break;
2916 case CARD_FAILURE:
2917 txt = "ERROR";
2918 break;
2919 default:
2920 txt = "UNDEF";
2922 tpl_addVar(vars, TPLADD, "READERSTATUS", txt);
2923 tpl_printf(vars, TPLADD, "READERCAID", "%04X", rdr->caid);
2926 int32_t rowcount = 0;
2927 uint64_t ecmcount = 0;
2928 time_t lastaccess = 0;
2930 #ifdef WITH_LB
2931 int32_t rc2hide = (-1);
2932 if(strlen(getParam(params, "hide")) > 0)
2933 { rc2hide = atoi(getParam(params, "hide")); }
2935 int32_t rc2show = (-1);
2936 if(strlen(getParam(params, "show")) > 0)
2937 { rc2show = atoi(getParam(params, "show")); }
2939 if(rdr->lb_stat)
2941 int32_t statsize;
2942 // @todo alno: sort by click, 0=ascending, 1=descending (maybe two buttons or reverse on second click)
2943 READER_STAT **statarray = get_sorted_stat_copy(rdr, 0, &statsize);
2944 char channame[CS_SERVICENAME_SIZE];
2945 for(; rowcount < statsize; ++rowcount)
2947 READER_STAT *s = statarray[rowcount];
2948 if(!(s->rc == rc2hide) && ((rc2show == -1) || (s->rc == rc2show)))
2950 struct tm lt;
2951 localtime_r(&s->last_received.time, &lt); // fixme we need walltime!
2952 ecmcount += s->ecm_count;
2953 if(!apicall)
2955 tpl_printf(vars, TPLADD, "CHANNEL", "%04X@%06X:%04X:%04X", s->caid, s->prid, s->srvid, s->chid);
2956 tpl_addVar(vars, TPLADD, "CHANNELNAME", xml_encode(vars, get_servicename(cur_client(), s->srvid, s->prid, s->caid, channame, sizeof(channame))));
2957 tpl_printf(vars, TPLADD, "ECMLEN", "%04hX", s->ecmlen);
2958 tpl_addVar(vars, TPLADD, "RC", stxt[s->rc]);
2959 tpl_printf(vars, TPLADD, "TIME", PRINTF_LOCAL_D " ms", s->time_avg);
2960 if(s->time_stat[s->time_idx])
2961 { tpl_printf(vars, TPLADD, "TIMELAST", PRINTF_LOCAL_D " ms", s->time_stat[s->time_idx]); }
2962 else
2963 { tpl_addVar(vars, TPLADD, "TIMELAST", ""); }
2964 tpl_printf(vars, TPLADD, "COUNT", PRINTF_LOCAL_D, s->ecm_count);
2966 if(s->last_received.time)
2968 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);
2971 else
2973 tpl_addVar(vars, TPLADD, "LAST", "never");
2976 else
2978 tpl_printf(vars, TPLADD, "ECMCAID", "%04X", s->caid);
2979 tpl_printf(vars, TPLADD, "ECMPROVID", "%06X", s->prid);
2980 tpl_printf(vars, TPLADD, "ECMSRVID", "%04X", s->srvid);
2981 tpl_printf(vars, TPLADD, "ECMLEN", "%04hX", s->ecmlen);
2982 tpl_addVar(vars, TPLADD, "ECMCHANNELNAME", xml_encode(vars, get_servicename(cur_client(), s->srvid, s->prid, s->caid, channame, sizeof(channame))));
2983 tpl_printf(vars, TPLADD, "ECMTIME", PRINTF_LOCAL_D, s->time_avg);
2984 tpl_printf(vars, TPLADD, "ECMTIMELAST", PRINTF_LOCAL_D, s->time_stat[s->time_idx]);
2985 tpl_printf(vars, TPLADD, "ECMRC", "%d", s->rc);
2986 tpl_addVar(vars, TPLADD, "ECMRCS", stxt[s->rc]);
2987 if(s->last_received.time)
2989 char tbuffer [30];
2990 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &lt);
2991 tpl_addVar(vars, TPLADD, "ECMLAST", tbuffer);
2993 else
2995 tpl_addVar(vars, TPLADD, "ECMLAST", "");
2997 tpl_printf(vars, TPLADD, "ECMCOUNT", PRINTF_LOCAL_D, s->ecm_count);
2999 if(s->last_received.time > lastaccess)
3000 { lastaccess = s->last_received.time; }
3003 if(!apicall)
3005 if(s->rc == E_NOTFOUND)
3007 tpl_addVar(vars, TPLAPPEND, "READERSTATSROWNOTFOUND", tpl_getTpl(vars, "READERSTATSBIT"));
3008 tpl_addVar(vars, TPLADD, "RESETA", urlencode(vars, rdr->label));
3009 tpl_addVar(vars, TPLADD, "READERSTATSNFHEADLINE", tpl_getTpl(vars, "READERSTATSROWNOTFOUNDBIT"));
3011 else if(s->rc == E_TIMEOUT)
3013 tpl_addVar(vars, TPLAPPEND, "READERSTATSROWTIMEOUT", tpl_getTpl(vars, "READERSTATSBIT"));
3014 tpl_addVar(vars, TPLADD, "RESETB", urlencode(vars, rdr->label));
3015 tpl_addVar(vars, TPLADD, "READERSTATSTOHEADLINE", tpl_getTpl(vars, "READERSTATSROWTIMEOUTBIT"));
3017 else if(s->rc == E_INVALID)
3019 tpl_addVar(vars, TPLAPPEND, "READERSTATSROWINVALID", tpl_getTpl(vars, "READERSTATSBIT"));
3020 tpl_addVar(vars, TPLADD, "RESETC", urlencode(vars, rdr->label));
3021 tpl_addVar(vars, TPLADD, "READERSTATSIVHEADLINE", tpl_getTpl(vars, "READERSTATSROWINVALIDBIT"));
3023 else
3024 { tpl_addVar(vars, TPLAPPEND, "READERSTATSROWFOUND", tpl_getTpl(vars, "READERSTATSBIT")); }
3026 else
3029 tpl_addVar(vars, TPLAPPEND, "ECMSTATS", tpl_getTpl(vars, "APIREADERSTATSECMBIT"));
3033 NULLFREE(statarray);
3035 else
3036 #endif
3037 tpl_addVar(vars, TPLAPPEND, "READERSTATSROW", tpl_getTpl(vars, "READERSTATSNOSTATS"));
3039 tpl_printf(vars, TPLADD, "ROWCOUNT", "%d", rowcount);
3041 if(lastaccess > 0)
3043 char tbuffer [30];
3044 struct tm lt;
3045 localtime_r(&lastaccess, &lt);
3046 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &lt);
3047 tpl_addVar(vars, TPLADD, "LASTACCESS", tbuffer);
3049 else
3051 tpl_addVar(vars, TPLADD, "LASTACCESS", "");
3054 if(apicall)
3056 if(cl)
3058 char *value = get_ecm_historystring(cl);
3059 tpl_addVar(vars, TPLADD, "ECMHISTORY", value);
3060 free_mk_t(value);
3064 tpl_printf(vars, TPLADD, "TOTALECM", "%'" PRIu64, ecmcount);
3066 if(!apicall)
3067 { return tpl_getTpl(vars, "READERSTATS"); }
3068 else
3069 { return tpl_getTpl(vars, "APIREADERSTATS"); }
3072 static char *send_oscam_user_config_edit(struct templatevars *vars, struct uriparams *params, int32_t apicall)
3074 struct s_auth *account, *ptr, *chk;
3075 char user[sizeof(first_client->account->usr)];
3077 int32_t i;
3078 int existing_insert = 0;
3080 if(!apicall) { setActiveMenu(vars, MNU_USERS); }
3082 if(strcmp(getParam(params, "action"), "Save As") == 0) { cs_strncpy(user, getParam(params, "newuser"), sizeof(user) / sizeof(char)); }
3083 else { cs_strncpy(user, getParam(params, "user"), sizeof(user) / sizeof(char)); }
3085 account = NULL;
3086 for(chk = cfg.account; chk != NULL; chk = chk->next) {
3087 if(strcmp(user, chk->usr) == 0)
3088 { account = chk; }
3089 if(!existing_insert){
3090 tpl_printf(vars, TPLADD, "EXISTING_INS", "'%s'", urlencode(vars, chk->usr));
3091 existing_insert++;
3092 }else{
3093 tpl_printf(vars, TPLAPPEND, "EXISTING_INS", ",'%s'", urlencode(vars, chk->usr));
3097 // Create a new user if it doesn't yet
3098 if(account == NULL)
3100 i = 1;
3101 while(strlen(user) < 1)
3103 snprintf(user, sizeof(user) / sizeof(char) - 1, "NEWUSER%d", i);
3104 for(account = cfg.account; account != NULL && strcmp(user, account->usr) != 0; account = account->next) { ; }
3105 if(account != NULL) { user[0] = '\0'; }
3106 ++i;
3108 if(!cs_malloc(&account, sizeof(struct s_auth))) { return "0"; }
3109 if(cfg.account == NULL) { cfg.account = account; }
3110 else
3112 for(ptr = cfg.account; ptr != NULL && ptr->next != NULL; ptr = ptr->next) { ; }
3113 ptr->next = account;
3115 account_set_defaults(account);
3116 account->disabled = 1;
3117 cs_strncpy((char *)account->usr, user, sizeof(account->usr));
3118 if(!account->grp)
3119 { account->grp = 1; }
3120 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
3121 else if(strcmp(getParam(params, "action"), "Save As") == 0) { tpl_addMsg(vars, "New user has been added with cloned settings"); }
3122 else { tpl_addMsg(vars, "New user has been added with default settings"); }
3123 // no need to refresh anything here as the account is disabled by default and there's no client with this new account anyway!
3126 if((strcmp(getParam(params, "action"), "Save") == 0) || (strcmp(getParam(params, "action"), "Save As") == 0))
3128 char servicelabels[1024] = "";
3130 for(i = 0; i < (*params).paramcount; i++)
3132 if((strcmp((*params).params[i], "action")) &&
3133 (strcmp((*params).params[i], "user")) &&
3134 (strcmp((*params).params[i], "newuser")) &&
3135 (strcmp((*params).params[i], "part")))
3138 if(!strcmp((*params).params[i], "services"))
3139 { snprintf(servicelabels + strlen(servicelabels), sizeof(servicelabels) - strlen(servicelabels), "%s,", (*params).values[i]); }
3140 else
3141 { chk_account((*params).params[i], (*params).values[i], account); }
3144 chk_account("services", servicelabels, account);
3146 refresh_oscam(REFR_CLIENTS);
3148 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
3149 else if(strcmp(getParam(params, "action"), "Save As") != 0) { tpl_addMsg(vars, "User Account updated and saved"); }
3152 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, account->usr));
3153 tpl_addVar(vars, TPLADD, "PASSWORD", xml_encode(vars, account->pwd));
3154 tpl_addVar(vars, TPLADD, "DESCRIPTION", xml_encode(vars, account->description));
3156 //Disabled
3157 if(!apicall)
3159 if(account->disabled)
3160 { tpl_addVar(vars, TPLADD, "DISABLEDCHECKED", "checked"); }
3162 else
3164 tpl_printf(vars, TPLADD, "DISABLEDVALUE", "%d", account->disabled);
3167 //Expirationdate
3168 struct tm timeinfo;
3169 cs_gmtime_r(&account->expirationdate, &timeinfo);
3170 char buf [80];
3171 strftime(buf, 80, "%Y-%m-%d", &timeinfo);
3172 if(strcmp(buf, "1970-01-01")) { tpl_addVar(vars, TPLADD, "EXPDATE", buf); }
3174 //Allowed TimeFrame
3175 char *allowedtf = mk_t_allowedtimeframe(account);
3176 tpl_printf(vars, TPLADD, "ALLOWEDTIMEFRAME", "%s", allowedtf);
3177 free_mk_t(allowedtf);
3179 //Group
3180 char *value = mk_t_group(account->grp);
3181 tpl_addVar(vars, TPLADD, "GROUPS", value);
3182 free_mk_t(value);
3184 // allowed protocols
3185 value = mk_t_allowedprotocols(account);
3186 tpl_addVar(vars, TPLADD, "ALLOWEDPROTOCOLS", value);
3187 free_mk_t(value);
3189 //Hostname
3190 tpl_addVar(vars, TPLADD, "DYNDNS", xml_encode(vars, account->dyndns));
3192 //Uniq
3193 if(!apicall)
3195 tpl_printf(vars, TPLADD, "TMP", "UNIQSELECTED%d", account->uniq);
3196 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3198 else
3200 tpl_printf(vars, TPLADD, "UNIQVALUE", "%d", account->uniq);
3203 //Sleep
3204 if(!account->tosleep) { tpl_addVar(vars, TPLADD, "SLEEP", "0"); }
3205 else { tpl_printf(vars, TPLADD, "SLEEP", "%d", account->tosleep); }
3207 //Monlevel selector
3208 if(!apicall)
3210 tpl_printf(vars, TPLADD, "TMP", "MONSELECTED%d", account->monlvl);
3211 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3213 else
3215 tpl_printf(vars, TPLADD, "MONVALUE", "%d", account->monlvl);
3218 //Au
3219 if(account->autoau == 1)
3220 { tpl_addVar(vars, TPLADD, "AUREADER", "1"); }
3221 else if(account->aureader_list)
3223 value = mk_t_aureader(account);
3224 tpl_addVar(vars, TPLADD, "AUREADER", value);
3225 free_mk_t(value);
3228 if(!apicall)
3230 /* SERVICES */
3231 struct s_sidtab *sidtab = cfg.sidtab;
3232 //build matrix
3233 i = 0;
3234 while(sidtab != NULL)
3236 tpl_addVar(vars, TPLADD, "SIDLABEL", xml_encode(vars, sidtab->label));
3237 if(account->sidtabs.ok & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
3238 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
3239 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "USEREDITSIDOKBIT"));
3240 if(account->sidtabs.no & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
3241 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
3242 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "USEREDITSIDNOBIT"));
3243 sidtab = sidtab->next;
3244 i++;
3246 if(i){
3247 tpl_addVar(vars, TPLADD, "USEREDITSIDINS", tpl_getTpl(vars, "USEREDITSID"));
3250 else
3252 value = mk_t_service(&account->sidtabs);
3253 if(strlen(value) > 0)
3254 { tpl_addVar(vars, TPLADD, "SERVICES", value); }
3255 free_mk_t(value);
3258 // CAID
3259 value = mk_t_caidtab(&account->ctab);
3260 tpl_addVar(vars, TPLADD, "CAIDS", value);
3261 free_mk_t(value);
3263 //ident
3264 value = mk_t_ftab(&account->ftab);
3265 tpl_addVar(vars, TPLADD, "IDENTS", value);
3266 free_mk_t(value);
3268 //CHID
3269 value = mk_t_ftab(&account->fchid);
3270 tpl_addVar(vars, TPLADD, "CHIDS", value);
3271 free_mk_t(value);
3273 //class
3274 value = mk_t_cltab(&account->cltab);
3275 tpl_addVar(vars, TPLADD, "CLASS", value);
3276 free_mk_t(value);
3278 //Betatunnel
3279 value = mk_t_tuntab(&account->ttab);
3280 tpl_addVar(vars, TPLADD, "BETATUNNELS", value);
3281 free_mk_t(value);
3283 //SUPPRESSCMD08
3284 if(!apicall)
3286 if(account->c35_suppresscmd08)
3287 { tpl_addVar(vars, TPLADD, "SUPPRESSCMD08", "selected"); }
3289 else
3291 tpl_printf(vars, TPLADD, "SUPPRESSCMD08VALUE", "%d", account->c35_suppresscmd08);
3294 //Sleepsend
3295 if(account->c35_sleepsend)
3297 tpl_printf(vars, TPLADD, "SLEEPSEND", "selected");
3300 //max_connections
3301 tpl_printf(vars, TPLADD, "MAXCONNECTIONS", "%d", account->max_connections);
3303 //User Max Idle
3304 tpl_printf(vars, TPLADD, "UMAXIDLE", "%d", account->umaxidle);
3306 //EMM Reassembly selector
3307 if(!apicall)
3309 tpl_printf(vars, TPLADD, "TMP", "EMMRSELECTED%d", account->emm_reassembly);
3310 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3312 else
3314 tpl_printf(vars, TPLADD, "EMMRVALUE", "%d", account->emm_reassembly);
3317 //Prefer local cards
3318 if(!apicall)
3320 tpl_printf(vars, TPLADD, "TMP", "PREFERLOCALCARDS%d", account->preferlocalcards);
3321 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3322 char *tmp = NULL;
3323 switch(cfg.preferlocalcards)
3325 case -1:
3326 tmp = "-1 - Use Global prefer local cards";
3327 break;
3328 case 0:
3329 tmp = "0 - local cards like proxied";
3330 break;
3331 case 1:
3332 tmp = "1 - prefer cache-ex then local cards";
3333 break;
3334 case 2:
3335 tmp = "2 - prefer local cards above cache-ex";
3336 break;
3338 tpl_addVar(vars, TPLADD, "CFGPREFERLOCALCARDS", tmp);
3340 else
3342 tpl_printf(vars, TPLADD, "PREFERLOCALCARDSVALUE", "%d", account->preferlocalcards);
3345 #ifdef CS_CACHEEX
3346 // Cacheex
3347 if(!apicall)
3349 tpl_printf(vars, TPLADD, "TMP", "CACHEEXSELECTED%d", account->cacheex.mode);
3350 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3353 else
3355 tpl_printf(vars, TPLADD, "CACHEEX", "%d", account->cacheex.mode);
3357 tpl_printf(vars, TPLADD, "CACHEEX_MAXHOP", "%d", account->cacheex.maxhop);
3359 value = mk_t_cacheex_hitvaluetab(&account->cacheex.filter_caidtab);
3360 //if (strlen(value) > 0)
3361 tpl_printf(vars, TPLADD, "CACHEEX_ECM_FILTER", "%s", value);
3362 free_mk_t(value);
3364 tpl_addVar(vars, TPLADD, "DCCHECKED", (account->cacheex.drop_csp == 1) ? "checked" : "");
3365 tpl_addVar(vars, TPLADD, "ARCHECKED", (account->cacheex.allow_request == 1) ? "checked" : "");
3366 tpl_addVar(vars, TPLADD, "AFCHECKED", (account->cacheex.allow_filter == 1) ? "checked" : "");
3367 tpl_addVar(vars, TPLADD, "BLOCKFAKECWSCHECKED", (account->cacheex.block_fakecws == 1) ? "checked" : "");
3368 tpl_addVar(vars, TPLADD, "NWTCHECKED", (account->no_wait_time == 1) ? "checked" : "");
3369 tpl_addVar(vars, TPLADD, "DISABLECRCCEX4USER", (account->disablecrccacheex == 1) ? "checked" : "");
3370 value = mk_t_ftab(&account->disablecrccacheex_only_for);
3371 tpl_addVar(vars, TPLADD, "IGNCRCCEX4USERONLYFOR", value);
3372 free_mk_t(value);
3374 #endif
3376 #ifdef CW_CYCLE_CHECK
3377 tpl_addVar(vars, TPLADD, "USERCWCYCLEDISABLE", (account->cwc_disable == 1) ? "checked" : "");
3378 #endif
3380 //Keepalive
3381 if(!apicall)
3383 if(account->ncd_keepalive)
3384 { tpl_addVar(vars, TPLADD, "KEEPALIVE", "checked"); }
3386 else
3388 tpl_printf(vars, TPLADD, "KEEPALIVEVALUE", "%d", account->ncd_keepalive);
3391 #ifdef CS_ANTICASC
3392 tpl_printf(vars, TPLADD, "AC_USERS", "%d", account->ac_users);
3393 tpl_printf(vars, TPLADD, "CFGNUMUSERS", "%d", cfg.ac_users);
3394 if(!apicall)
3396 tpl_printf(vars, TPLADD, "TMP", "PENALTY%d", account->ac_penalty);
3397 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3398 char *tmp = NULL;
3399 switch(cfg.ac_penalty)
3401 case 0:
3402 tmp = "(0) Only write to log";
3403 break;
3404 case 1:
3405 tmp = "(1) NULL CW";
3406 break;
3407 case 2:
3408 tmp = "(2) Ban";
3409 break;
3410 case 3:
3411 tmp = "(3) Real CW delayed";
3412 break;
3414 tpl_addVar(vars, TPLADD, "CFGPENALTY", tmp);
3416 else
3418 tpl_printf(vars, TPLADD, "PENALTYVALUE", "%d", account->ac_penalty);
3420 tpl_printf(vars, TPLADD, "ACOSC_MAX_ACTIVE_SIDS", "%d", account->acosc_max_active_sids);
3421 tpl_printf(vars, TPLADD, "CFG_ACOSC_MAX_ACTIVE_SIDS", "%d", cfg.acosc_max_active_sids);
3422 tpl_printf(vars, TPLADD, "ACOSC_ZAP_LIMIT", "%d", account->acosc_zap_limit);
3423 tpl_printf(vars, TPLADD, "CFG_ACOSC_ZAP_LIMIT", "%d", cfg.acosc_zap_limit);
3424 if(!apicall)
3426 tpl_printf(vars, TPLADD, "TMP", "ACOSC_PENALTY%d", account->acosc_penalty);
3427 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3428 char *tmp = NULL;
3429 switch(cfg.acosc_penalty)
3431 case -1:
3432 tmp = "(-1) Use Global Value";
3433 break;
3434 case 0:
3435 tmp = "(0) Only write to log";
3436 break;
3437 case 1:
3438 tmp = "(1) NULL CW";
3439 break;
3440 case 2:
3441 tmp = "(2) Ban";
3442 break;
3443 case 3:
3444 tmp = "(3) CW delayed";
3445 break;
3447 tpl_addVar(vars, TPLADD, "CFG_ACOSC_PENALTY", tmp);
3448 } else
3450 tpl_printf(vars, TPLADD, "ACOSC_PENALTYVALUE", "%d", account->acosc_penalty);
3453 tpl_printf(vars, TPLADD, "ACOSC_PENALTY_DURATION", "%d", account->acosc_penalty_duration);
3454 tpl_printf(vars, TPLADD, "CFG_ACOSC_PENALTY_DURATION", "%d", cfg.acosc_penalty_duration);
3455 tpl_printf(vars, TPLADD, "ACOSC_DELAY", "%d", account->acosc_delay);
3456 tpl_printf(vars, TPLADD, "CFG_ACOSC_DELAY", "%d", cfg.acosc_delay);
3457 #endif
3459 #ifdef MODULE_CCCAM
3460 tpl_printf(vars, TPLADD, "CCCMAXHOPS", "%d", account->cccmaxhops);
3461 tpl_printf(vars, TPLADD, "CCCRESHARE", "%d", account->cccreshare);
3462 tpl_printf(vars, TPLADD, "RESHARE", "%d", cfg.cc_reshare);
3464 //CCcam Ignore Reshare
3465 tpl_printf(vars, TPLADD, "TMP", "CCCIGNRSHRSELECTED%d", account->cccignorereshare);
3466 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3467 tpl_addVar(vars, TPLADD, "CFGIGNORERESHARE",
3468 cfg.cc_ignore_reshare == 0 ?
3469 "0 - use reshare level of Server" : "1 - use reshare level of Reader or User");
3471 //CCcam Stealth Mode
3472 tpl_printf(vars, TPLADD, "TMP", "CCCSTEALTHSELECTED%d", account->cccstealth);
3473 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3475 tpl_addVar(vars, TPLADD, "STEALTH", cfg.cc_stealth ? "enable" : "disable");
3476 #endif
3478 //Failban
3479 tpl_printf(vars, TPLADD, "FAILBAN", "%d", account->failban);
3481 if(!apicall)
3482 { return tpl_getTpl(vars, "USEREDIT"); }
3483 else
3484 { return tpl_getTpl(vars, "APIUSEREDIT"); }
3488 static void webif_add_client_proto(struct templatevars *vars, struct s_client *cl, const char *proto, int8_t apicall)
3490 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTO", "");
3491 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOSORT", "");
3492 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOTITLE", "");
3493 tpl_addVar(vars, TPLADDONCE, "PROTOICON", "");
3494 if(!cl) { return; }
3495 #ifdef MODULE_NEWCAMD
3496 if(streq(proto, "newcamd") && cl->typ == 'c')
3498 tpl_printf(vars, TPLADD, "CLIENTPROTO", "%s (%s)", proto, newcamd_get_client_name(cl->ncd_client_id));
3499 tpl_printf(vars, TPLADD, "CLIENTPROTOSORT", "%s (%s)", proto, newcamd_get_client_name(cl->ncd_client_id));
3500 if(cfg.http_showpicons )
3502 char picon_name[32];
3503 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s_%s", (char *)proto, newcamd_get_client_name(cl->ncd_client_id));
3504 if(picon_exists(picon_name))
3506 if (!apicall) {
3507 tpl_addVar(vars, TPLADD, "NCMDA", (char *)proto);
3508 tpl_addVar(vars, TPLADD, "NCMDB", (char *)newcamd_get_client_name(cl->ncd_client_id));
3509 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTONEWCAMDPIC"));
3510 } else {
3511 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s_%s",(char *)proto, (char *)newcamd_get_client_name(cl->ncd_client_id));
3514 else
3516 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s_%s.tpl", proto, newcamd_get_client_name(cl->ncd_client_id));
3519 return;
3521 #endif
3522 #ifdef MODULE_CCCAM
3523 if(strncmp(proto, "cccam", 5) == 0)
3525 struct cc_data *cc = cl->cc;
3526 if(cc && *cc->remote_version && *cc->remote_build)
3528 tpl_printf(vars, TPLADD, "CLIENTPROTO", "%s (%s-%s)", proto, cc->remote_version, cc->remote_build);
3529 tpl_printf(vars, TPLADD, "CLIENTPROTOSORT", "%s (%s-%s)", proto, cc->remote_version, cc->remote_build);
3530 if(cccam_client_multics_mode(cl))
3532 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "Multics, revision r%d", cc->multics_version[0] | (cc->multics_version[1] << 8));
3534 else
3536 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", cc->extended_mode ? cc->remote_oscam : "");
3539 if(cfg.http_showpicons)
3541 char picon_name[32];
3543 int8_t is_other_proto = 0;
3544 if(cccam_client_multics_mode(cl)) { is_other_proto = 1; }
3546 switch(is_other_proto)
3548 case 1:
3549 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s_r_%d", proto, cc->multics_version[0] | (cc->multics_version[1] << 8));
3550 if(picon_exists(picon_name))
3552 if (!apicall) {
3553 tpl_addVar(vars, TPLADD, "CCA", (char *)proto);
3554 tpl_addVar(vars, TPLADD, "CCB", "r");
3555 tpl_printf(vars, TPLADD, "CCC", "%d", cc->multics_version[0] | (cc->multics_version[1] << 8));
3556 tpl_addVar(vars, TPLADD, "CCD", "");
3557 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTOCCCAMPIC"));
3558 } else {
3559 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s_r_%d",(char *)proto, cc->multics_version[0] | (cc->multics_version[1] << 8));
3562 else
3564 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "Multics, revision r%d missing icon: IC_%s_r_%d.tpl",
3565 cc->multics_version[0] | (cc->multics_version[1] << 8), proto, cc->multics_version[0] | (cc->multics_version[1] << 8));
3567 break;
3569 default:
3570 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s_%s_%s", proto, cc->remote_version, cc->remote_build);
3571 if(picon_exists(picon_name))
3573 if (!apicall) {
3574 tpl_addVar(vars, TPLADD, "CCA", (char *)proto);
3575 tpl_addVar(vars, TPLADD, "CCB", cc->remote_version);
3576 tpl_addVar(vars, TPLADD, "CCC", cc->remote_build);
3577 tpl_addVar(vars, TPLADD, "CCD", cc->extended_mode ? cc->remote_oscam : "");
3578 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTOCCCAMPIC"));
3579 } else {
3580 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s_%s_%s",(char *)proto, cc->remote_version, cc->remote_build);
3583 else
3585 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "%s missing icon: IC_%s_%s_%s.tpl",
3586 cc->extended_mode ? cc->remote_oscam : "", proto, cc->remote_version, cc->remote_build);
3588 break;
3592 return;
3594 #endif
3595 #ifdef HAVE_DVBAPI
3596 if(streq(proto, "dvbapi") && cl->typ == 'c' && strcmp(dvbapi_get_client_name(), ""))
3598 if (!apicall)
3599 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());
3600 else
3601 tpl_printf(vars, TPLADD, "CLIENTPROTO", "%s (client: %s, protocol version: %d)", proto, dvbapi_get_client_name(), dvbapi_get_client_proto_version());
3602 tpl_printf(vars, TPLADD, "CLIENTPROTOSORT", "%s", proto);
3603 return;
3605 #endif
3606 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTO", (char *)proto);
3607 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOSORT", (char *)proto);
3608 if(cfg.http_showpicons)
3610 char picon_name[32];
3611 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", proto);
3612 if(picon_exists(picon_name))
3614 if (!apicall) {
3615 tpl_addVar(vars, TPLADD, "OTHER", (char *)proto);
3616 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTOOTHERPIC"));
3617 } else {
3618 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s",(char *)proto);
3621 else
3623 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s.tpl", proto);
3628 static void kill_account_thread(struct s_auth *account)
3630 struct s_client *cl;
3631 for(cl = first_client->next; cl ; cl = cl->next)
3633 if(cl->account == account)
3635 if(get_module(cl)->type & MOD_CONN_NET)
3637 kill_thread(cl);
3639 else
3641 cl->account = first_client->account;
3647 static char *send_oscam_user_config(struct templatevars *vars, struct uriparams *params, int32_t apicall)
3649 struct s_auth *account;
3650 struct s_client *cl;
3651 char *user = getParam(params, "user");
3652 int32_t found = 0;
3653 unsigned char md5tmp[MD5_DIGEST_LENGTH];
3655 if(!apicall)
3657 setActiveMenu(vars, MNU_USERS);
3659 if(strcmp(getParam(params, "action"), "reinit") == 0)
3661 if(!cfg.http_readonly)
3662 { refresh_oscam(REFR_ACCOUNTS); }
3664 if(strcmp(getParam(params, "action"), "delete") == 0)
3666 if(cfg.http_readonly)
3668 tpl_addMsg(vars, "WebIf is in readonly mode. No deletion will be made!");
3670 else
3672 struct s_auth *account_prev = NULL;
3674 for(account = cfg.account; (account); account = account->next)
3676 if(strcmp(account->usr, user) == 0)
3678 if(account_prev == NULL)
3679 { cfg.account = account->next; }
3680 else
3681 { account_prev->next = account->next; }
3682 ll_clear(account->aureader_list);
3683 kill_account_thread(account);
3684 add_garbage(account);
3685 found = 1;
3686 break;
3688 account_prev = account;
3690 if(found > 0)
3692 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
3694 else { tpl_addMsg(vars, "Sorry but the specified user doesn't exist. No deletion will be made!"); }
3698 if((strcmp(getParam(params, "action"), "disable") == 0) || (strcmp(getParam(params, "action"), "enable") == 0))
3700 account = get_account_by_name(getParam(params, "user"));
3701 if(account)
3703 if(strcmp(getParam(params, "action"), "disable") == 0)
3705 account->disabled = 1;
3706 kill_account_thread(account);
3708 else
3709 { account->disabled = 0; }
3710 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
3712 else
3714 tpl_addMsg(vars, "Sorry but the specified user doesn't exist. No deletion will be made!");
3718 if(strcmp(getParam(params, "action"), "resetstats") == 0)
3720 account = get_account_by_name(getParam(params, "user"));
3721 if(account) { clear_account_stats(account); }
3724 if(strcmp(getParam(params, "action"), "resetuserstats") == 0)
3726 clear_info_clients_stats();
3729 if(strcmp(getParam(params, "action"), "resetreaderstats") == 0)
3731 clear_info_readers_stats();
3734 if(strcmp(getParam(params, "action"), "resetalluserstats") == 0)
3736 clear_all_account_stats();
3739 if((strcmp(getParam(params, "part"), "adduser") == 0) && (!cfg.http_readonly))
3741 tpl_addVar(vars, TPLAPPEND, "NEWUSERFORM", tpl_getTpl(vars, "ADDNEWUSER"));
3744 /* List accounts*/
3745 char *status, *expired, *classname, *lastchan;
3746 time_t now = time((time_t *)0);
3747 int32_t isec = 0, chsec = 0;
3749 char *filter = NULL;
3750 int32_t clientcount = 0;
3751 if(apicall)
3753 filter = getParam(params, "label");
3755 int8_t grp_set = 0;
3756 int8_t expdate_set = 0;
3757 int32_t total_users = 0;
3758 int32_t disabled_users = 0;
3759 int32_t expired_users = 0;
3760 int32_t expired_or_disabled_users = 0;
3761 int32_t connected_users = 0;
3762 int32_t online_users = 0;
3763 int8_t isactive;
3764 int32_t casc_users = 0;
3765 int32_t casc_users2 = 0;
3766 int32_t n_request = 0;
3767 int existing_insert = 0;
3769 for(account = cfg.account; (account); account = account->next)
3771 if(account->expirationdate){
3772 expdate_set = 1;
3775 if(account->next){
3776 if(account->grp != account->next->grp){
3777 grp_set = 1;
3780 if(expdate_set && grp_set)
3781 break;
3784 for(account = cfg.account; (account); account = account->next)
3786 //clear for next client
3787 total_users++;
3788 isactive = 1;
3790 status = "offline";
3791 expired = "";
3792 classname = "offline";
3793 isec = 0;
3794 chsec = 0;
3796 //reset caid/srevid template variables
3797 tpl_addVar(vars, TPLADD, "CLIENTCAID", "");
3798 tpl_addVar(vars, TPLADD, "CLIENTPROVID", "");
3799 tpl_addVar(vars, TPLADD, "CLIENTSRVID", "");
3800 tpl_addVar(vars, TPLADD, "LASTCHANNEL", "");
3801 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", "");
3802 tpl_addVar(vars, TPLADD, "USERMD5", "");
3803 tpl_addVar(vars, TPLADD, "CWLASTRESPONSET", "");
3804 tpl_addVar(vars, TPLADD, "CWLASTRESPONSETMS", "");
3805 tpl_addVar(vars, TPLADD, "CLIENTIP", "");
3806 tpl_addVar(vars, TPLADD, "LASTCHANNELTITLE", "");
3807 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", "");
3808 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNELAPI", "");
3809 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", "");
3810 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEP", "");
3811 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEPAPI", "");
3812 tpl_addVar(vars, TPLADD, "IDLESECS", "");
3813 tpl_addVar(vars, TPLADD, "UNOTIFY", "");
3815 if(account->expirationdate && account->expirationdate < now)
3817 expired = " (expired)";
3818 classname = "expired";
3819 expired_users++;
3820 isactive = 0;
3822 else
3824 expired = "";
3827 if(account->disabled != 0)
3829 expired = " (disabled)";
3830 classname = "disabled";
3831 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICENA");
3832 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Enable");
3833 tpl_addVar(vars, TPLADD, "SWITCH", "enable");
3834 disabled_users++;
3835 isactive = 0;
3837 else
3839 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICDIS");
3840 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Disable");
3841 tpl_addVar(vars, TPLADD, "SWITCH", "disable");
3843 if((account->expirationdate && account->expirationdate < now)||account->disabled != 0)
3845 expired_or_disabled_users++;
3848 int32_t lastresponsetm = 0, latestactivity = 0;
3849 const char *proto = "";
3850 double cwrate = 0.0, cwrate2 = 0.0;
3852 //search account in active clients
3853 isactive = 0;
3854 int16_t nrclients = 0;
3855 struct s_client *latestclient = NULL;
3856 for(cl = first_client->next; cl ; cl = cl->next)
3858 if(cl->account && !strcmp(cl->account->usr, account->usr))
3860 if(cl->lastecm > latestactivity || cl->login > latestactivity)
3862 if(cl->lastecm > cl->login) { latestactivity = cl->lastecm; }
3863 else { latestactivity = cl->login; }
3864 latestclient = cl;
3866 nrclients++;
3869 if(account->cwfound + account->cwnot + account->cwcache > 0)
3871 cwrate = now - account->firstlogin;
3872 cwrate /= (account->cwfound + account->cwnot + account->cwcache);
3875 casc_users = 0;
3876 casc_users2 = 0;
3877 int8_t conn = 0;
3878 if(latestclient != NULL)
3880 char channame[CS_SERVICENAME_SIZE];
3881 status = (!apicall) ? "<B>connected</B>" : "connected";
3882 if(account->expirationdate && account->expirationdate < now) { classname = "expired"; }
3883 else { classname = "connected";conn = 1; }
3885 proto = client_get_proto(latestclient);
3886 int clientcaid = latestclient->last_caid;
3887 int clientsrvid = latestclient->last_srvid;
3888 int clientprovid = latestclient->last_provid;
3889 tpl_printf(vars, TPLADD, "CLIENTCAID", "%04X", clientcaid);
3890 tpl_printf(vars, TPLADD, "CLIENTPROVID", "%06X", clientprovid);
3891 tpl_printf(vars, TPLADD, "CLIENTSRVID", "%04X", clientsrvid);
3893 if(clientsrvid != NO_SRVID_VALUE || clientcaid != NO_CAID_VALUE)
3895 lastchan = xml_encode(vars, get_servicename(latestclient, clientsrvid, clientprovid, clientcaid, channame, sizeof(channame)));
3896 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", lastchan);
3898 else
3900 lastchan = "";
3901 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", "~~~~~");
3904 tpl_addVar(vars, TPLADDONCE, "LASTCHANNEL", lastchan);
3905 tpl_addVar(vars, TPLADD, "LASTCHANNELTITLE", lastchan);
3907 if(cfg.http_showpicons )
3909 char picon_name[128];
3910 char picon_channame[128];
3911 int8_t picon_ok = 0;
3913 get_picon_servicename_or_null(latestclient, clientsrvid, clientprovid, clientcaid, picon_channame, sizeof(picon_channame));
3914 if(picon_channame[0])
3916 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", picon_channame);
3917 picon_ok = picon_exists(picon_name);
3919 if(!picon_ok && picon_servicename_remve_hd(picon_channame, sizeof(picon_channame)))
3921 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", picon_channame);
3922 picon_ok = picon_exists(picon_name);
3925 if(!picon_ok)
3927 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%04X_%06X_%04X", clientcaid, clientprovid, clientsrvid);
3928 picon_ok = picon_exists(picon_name);
3930 if(!picon_ok)
3932 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%04X_%04X", clientcaid, clientsrvid);
3933 picon_ok = picon_exists(picon_name);
3935 if(!picon_ok)
3937 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "0000_%04X", clientsrvid);
3938 picon_ok = picon_exists(picon_name);
3940 if(picon_ok)
3942 tpl_addVar(vars, TPLADDONCE, "LCA", picon_name);
3943 tpl_addVar(vars, TPLADDONCE, "LCB", lastchan);
3944 if(!apicall)
3946 tpl_addVar(vars, TPLADDONCE, "LASTCHANNEL", tpl_getTpl(vars, "USERCONFIGLASTCHANEL"));
3949 else
3951 tpl_printf(vars, TPLADD, "LASTCHANNELTITLE", "missing icon: IC_%s.tpl", picon_name);
3955 lastresponsetm = latestclient->cwlastresptime;
3956 tpl_addVar(vars, TPLADD, "CLIENTIP", cs_inet_ntoa(latestclient->ip));
3957 connected_users++;
3958 casc_users = ll_count(latestclient->cascadeusers);
3959 LL_ITER it = ll_iter_create(latestclient->cascadeusers);
3960 struct s_cascadeuser *cu;
3961 while((cu = ll_iter_next(&it)))
3963 if(cu->cwrate > 0)
3964 { casc_users2++; }
3966 if(latestactivity > 0)
3968 isec = now - latestactivity;
3969 chsec = latestclient->lastswitch ? now - latestclient->lastswitch : 0;
3970 if(isec < cfg.hideclient_to)
3972 isactive = 1;
3973 status = (!apicall) ? "<B>online</B>" : "online";
3974 if(account->expirationdate && account->expirationdate < now) { classname = "expired"; }
3975 else { classname = "online"; }
3976 if(latestclient->cwfound + latestclient->cwnot + latestclient->cwcache > 0)
3978 cwrate2 = now - latestclient->login;
3979 cwrate2 /= (latestclient->cwfound + latestclient->cwnot + latestclient->cwcache);
3980 tpl_printf(vars, TPLADDONCE, "CWRATE2", " (%.2f)", cwrate2);
3981 online_users++;
3987 n_request = 0;
3988 if(latestclient != NULL){
3989 n_request = latestclient->n_request[0];
3992 tpl_addVar(vars, TPLADD, "EXPIREVIEW", expdate_set ? "" : "exp");
3993 tpl_addVar(vars, TPLADD, "GRPVIEW", grp_set ? "" : "grp");
3994 #ifdef CS_ANTICASC
3995 tpl_addVar(vars, TPLADD, "ANTICASCVIEW", cfg.ac_enabled ? "" : "acas");
3996 #endif
3997 tpl_printf(vars, TPLADD, "CWOK", PRINTF_LOCAL_D, account->cwfound);
3998 tpl_printf(vars, TPLADD, "CWNOK", PRINTF_LOCAL_D, account->cwnot);
3999 tpl_printf(vars, TPLADD, "CWIGN", PRINTF_LOCAL_D, account->cwignored);
4000 tpl_printf(vars, TPLADD, "CWTOUT", PRINTF_LOCAL_D, account->cwtout);
4001 #ifdef CW_CYCLE_CHECK
4002 tpl_addVar(vars, TPLADD, "CWCCYCVIEW", cfg.cwcycle_check_enable ? "" : "cwc");
4003 tpl_printf(vars, TPLADD, "CWCYCLECHECKED", "%d", account->cwcycledchecked);
4004 tpl_printf(vars, TPLADD, "CWCYCLEOK", "%d", account->cwcycledok);
4005 tpl_printf(vars, TPLADD, "CWCYCLENOK", "%d", account->cwcyclednok);
4006 tpl_printf(vars, TPLADD, "CWCYCLEIGN", "%d", account->cwcycledign);
4007 #endif
4008 tpl_printf(vars, TPLADD, "CWCACHE", PRINTF_LOCAL_D, account->cwcache);
4009 tpl_printf(vars, TPLADD, "CWTUN", PRINTF_LOCAL_D, account->cwtun);
4010 tpl_printf(vars, TPLADD, "EMMOK", PRINTF_LOCAL_D, account->emmok);
4011 tpl_printf(vars, TPLADD, "EMMNOK", PRINTF_LOCAL_D, account->emmnok);
4012 tpl_printf(vars, TPLADD, "CWRATE", "%.2f", cwrate);
4013 tpl_printf(vars, TPLADD, "CASCUSERS", "%d", casc_users);
4014 tpl_printf(vars, TPLADD, "CASCUSERS2", "%d", casc_users2);
4015 tpl_printf(vars, TPLADD, "CASCUSERSCOMB", "%d/%d", casc_users, casc_users2);
4016 tpl_printf(vars, TPLADD, "N_REQUEST_MIN", "%d", n_request);
4018 if(isactive > 0 || conn > 0)
4020 if(casc_users+casc_users2>0)
4022 tpl_printf(vars, TPLADD, "CWLASTRESPONSET", "%d", lastresponsetm);
4023 tpl_printf(vars, TPLADD, "CWLASTRESPONSETMS", PRINTF_LOCAL_D " ms", lastresponsetm);
4025 tpl_addVar(vars, TPLADD, "IDLESECS", sec2timeformat(vars, isec));
4028 if(isactive > 0)
4030 tpl_printf(vars, TPLADD, "CLIENTTIMEONCHANNELAPI", "%d", chsec);
4031 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", sec2timeformat(vars, chsec));
4033 if(account->tosleep)
4035 if(account->tosleep >0){
4036 tpl_printf(vars, TPLADD, "CLIENTTIMETOSLEEP", "Sleeping in %d minutes", account->tosleep - (chsec / 60));
4037 } else {
4038 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEP", "Sleeping");
4040 tpl_printf(vars, TPLADD, "CLIENTTIMETOSLEEPAPI", "%d", account->tosleep - (chsec / 60));
4041 } else {
4042 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEPAPI", "undefined");
4046 webif_add_client_proto(vars, latestclient, proto, apicall);
4048 tpl_addVar(vars, TPLADD, "CLASSNAME", classname);
4049 MD5((unsigned char *)account->usr, strlen(account->usr), md5tmp);
4050 int z;
4051 tpl_addVar(vars, TPLADD, "USERMD5","id_");
4052 for (z = 0; z < MD5_DIGEST_LENGTH; z++){
4053 tpl_printf(vars, TPLAPPEND, "USERMD5", "%02x", md5tmp[z]);
4055 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, account->usr));
4056 tpl_addVar(vars, TPLADD, "USERNAMEENC", urlencode(vars, account->usr));
4057 if(!existing_insert){
4058 tpl_printf(vars, TPLADD, "EXISTING_INS", "'%s'", urlencode(vars, account->usr));
4059 existing_insert++;
4060 }else{
4061 tpl_printf(vars, TPLAPPEND, "EXISTING_INS", ",'%s'", urlencode(vars, account->usr));
4064 if(account->description)
4065 tpl_printf(vars, TPLADD, "DESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, account->description));
4066 else
4067 tpl_addVar(vars, TPLADD, "DESCRIPTION", "");
4069 if(cfg.http_showpicons && !apicall)
4070 tpl_addVar(vars, TPLADD, "USERBIT", tpl_getTpl(vars, picon_exists(xml_encode(vars, account->usr)) ? "USERICON" : "USERNOICON"));
4071 else
4072 tpl_addVar(vars, TPLADD, "USERBIT", tpl_getTpl(vars, "USERLABEL"));
4074 char *value = mk_t_group(account->grp);
4075 tpl_addVar(vars, TPLADD, "GROUPS", value);
4076 free_mk_t(value);
4077 tpl_addVar(vars, TPLADD, "STATUS", status);
4078 tpl_addVar(vars, TPLAPPEND, "STATUS", expired);
4080 if(nrclients > 1)
4082 tpl_printf(vars, TPLADD, "UNOTIFY", "%d", nrclients);
4083 tpl_addVar(vars, TPLADDONCE, "CLIENTCOUNTNOTIFIER", tpl_getTpl(vars, "CLIENTCOUNTNOTIFIERBIT"));
4086 //Expirationdate
4087 struct tm timeinfo;
4088 cs_gmtime_r(&account->expirationdate, &timeinfo);
4089 char buf [80];
4090 strftime(buf, 80, "%Y-%m-%d", &timeinfo);
4091 if(strcmp(buf, "1970-01-01")) { tpl_addVar(vars, TPLADD, "EXPDATE", buf); }
4092 else { tpl_addVar(vars, TPLADD, "EXPDATE", ""); }
4094 // append row to table template
4095 if(!apicall)
4096 { tpl_addVar(vars, TPLAPPEND, "USERCONFIGS", tpl_getTpl(vars, "USERCONFIGLISTBIT")); }
4097 else if(!filter || strcmp(filter, account->usr) == 0 || strcmp(filter, "all") == 0 || strlen(filter) == 0)
4099 if(apicall == 1){
4100 tpl_addVar(vars, TPLAPPEND, "APIUSERCONFIGS", tpl_getTpl(vars, "APIUSERCONFIGLISTBIT"));
4101 } else if (apicall == 2){
4102 tpl_printf(vars, TPLADD, "JSONDELIMITER", "%s", (total_users > 1)?",":"");
4103 tpl_addVar(vars, TPLAPPEND, "APIUSERCONFIGS", tpl_getTpl(vars, "JSONUSERBIT"));
4105 ++clientcount;
4109 tpl_printf(vars, TPLADD, "TOTAL_USERS", "%d", total_users);
4110 tpl_printf(vars, TPLADD, "TOTAL_DISABLED", "%d", disabled_users);
4111 tpl_printf(vars, TPLADD, "TOTAL_EXPIRED", "%d", expired_users);
4112 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE", "%d", total_users - expired_or_disabled_users);
4113 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED", "%d", connected_users);
4114 tpl_printf(vars, TPLADD, "TOTAL_ONLINE", "%d", online_users);
4116 //CM info
4117 tpl_addVar(vars, TPLADD, "DISPLAYREADERINFO", "hidden"); // no readerinfo in users
4118 set_ecm_info(vars);
4120 if(!apicall)
4121 { return tpl_getTpl(vars, "USERCONFIGLIST"); }
4122 else
4124 if(!filter || clientcount > 0)
4126 return tpl_getTpl(vars, (apicall==1)?"APIUSERCONFIGLIST":"JSONUSER");
4128 else
4130 tpl_printf(vars, TPLADD, "APIERRORMESSAGE", "Invalid client %s", xml_encode(vars, filter));
4131 return tpl_getTpl(vars, "APIERROR");
4137 #define ENTITLEMENT_PAGE_SIZE 500
4139 #ifdef MODULE_CCCSHARE
4140 static void print_cards(struct templatevars *vars, struct uriparams *params, struct cc_card **cardarray, int32_t cardsize,
4141 int8_t show_global_list, struct s_reader *rdr, int32_t offset, int32_t apicall)
4143 if(cardarray)
4145 uint8_t serbuf[8];
4146 int32_t i, count = 0;
4147 char provname[83];
4148 struct cc_card *card;
4149 int32_t cardcount = 0;
4150 int32_t providercount = 0;
4151 int32_t nodecount = 0;
4153 char *provider = "";
4155 // @todo alno: sort by click, 0=ascending, 1=descending (maybe two buttons or reverse on second click)
4156 for(i = offset; i < cardsize; ++i)
4158 card = cardarray[i];
4159 if(count == ENTITLEMENT_PAGE_SIZE)
4160 { break; }
4161 count++;
4163 if(!apicall)
4165 if(show_global_list)
4166 { rdr = card->origin_reader; }
4167 if(rdr)
4168 { tpl_printf(vars, TPLADD, "HOST", "%s:%d", xml_encode(vars, rdr->device), rdr->r_port); }
4169 tpl_printf(vars, TPLADD, "CAID", "%04X", card->caid);
4170 tpl_printf(vars, TPLADD, "CARDTYPE", "%02X", card->card_type);
4172 else
4174 tpl_printf(vars, TPLADD, "APICARDNUMBER", "%d", cardcount);
4175 tpl_printf(vars, TPLADD, "APICAID", "%04X", card->caid);
4176 tpl_printf(vars, TPLADD, "APICARDTYPE", "%02X", card->card_type);
4179 if(cc_UA_valid(card->hexserial)) //Add UA:
4181 cc_UA_cccam2oscam(card->hexserial, serbuf, card->caid);
4182 char tmp[20];
4183 tpl_printf(vars, TPLAPPEND, "HOST", "<BR>\nUA_OSCam:%s", cs_hexdump(0, serbuf, 8, tmp, 20));
4184 tpl_printf(vars, TPLAPPEND, "HOST", "<BR>\nUA_CCcam:%s", cs_hexdump(0, card->hexserial, 8, tmp, 20));
4186 if(!apicall)
4188 int32_t n;
4189 char channame[CS_SERVICENAME_SIZE];
4190 int8_t sidname = 0;
4191 LL_ITER its = ll_iter_create(card->goodsids);
4192 struct cc_srvid *srv;
4193 n = 0;
4194 if(strcmp(getParam(params, "button"), "Show detail list") == 0)
4195 { sidname = 1; }
4197 tpl_addVar(vars, TPLADD, "SERVICESGOOD", "");
4198 while((srv = ll_iter_next(&its)))
4200 if(sidname)
4202 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))));
4203 } else {
4204 tpl_printf(vars, TPLAPPEND, "SERVICESGOOD", "%04X%s", srv->sid, ++n % 10 == 0 ? "<BR>\n" : " ");
4208 its = ll_iter_create(card->badsids);
4209 n = 0;
4210 tpl_addVar(vars, TPLADD, "SERVICESBAD", "");
4211 while((srv = ll_iter_next(&its)))
4213 if(sidname)
4215 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))));
4216 } else {
4217 tpl_printf(vars, TPLAPPEND, "SERVICESBAD", "%04X%s", srv->sid, ++n % 10 == 0 ? "<BR>\n" : " ");
4222 tpl_addVar(vars, TPLADD, "SYSTEM", get_cardsystem_desc_by_caid(card->caid));
4224 tpl_printf(vars, TPLADD, "SHAREID", "%08X", card->id);
4225 tpl_printf(vars, TPLADD, "REMOTEID", "%08X", card->remote_id);
4226 tpl_printf(vars, TPLADD, "UPHOPS", "%d", card->hop);
4227 tpl_printf(vars, TPLADD, "MAXDOWN", "%d", card->reshare);
4229 LL_ITER pit = ll_iter_create(card->providers);
4230 struct cc_provider *prov;
4232 providercount = 0;
4234 if(!apicall)
4235 { tpl_addVar(vars, TPLADD, "PROVIDERS", ""); }
4236 else
4237 { tpl_addVar(vars, TPLADD, "PROVIDERLIST", ""); }
4239 while((prov = ll_iter_next(&pit)))
4241 provider = xml_encode(vars, get_provider(prov->prov, card->caid, provname, sizeof(provname)));
4243 if(!apicall)
4245 if(prov->sa[0] || prov->sa[1] || prov->sa[2] || prov->sa[3])
4247 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]);
4249 else
4251 tpl_printf(vars, TPLAPPEND, "PROVIDERS", "%s<BR>\n", provider);
4254 else
4256 if(prov->sa[0] || prov->sa[1] || prov->sa[2] || prov->sa[3])
4257 { tpl_printf(vars, TPLADD, "APIPROVIDERSA", "%02X%02X%02X%02X", prov->sa[0], prov->sa[1], prov->sa[2], prov->sa[3]); }
4258 else
4259 { tpl_addVar(vars, TPLADD, "APIPROVIDERSA", ""); }
4260 tpl_printf(vars, TPLADD, "APIPROVIDERCAID", "%04X", card->caid);
4261 tpl_printf(vars, TPLADD, "APIPROVIDERPROVID", "%06X", prov->prov);
4262 tpl_printf(vars, TPLADD, "APIPROVIDERNUMBER", "%d", providercount);
4263 tpl_addVar(vars, TPLADD, "APIPROVIDERNAME", xml_encode(vars, provider));
4264 tpl_addVar(vars, TPLAPPEND, "PROVIDERLIST", tpl_getTpl(vars, "APICCCAMCARDPROVIDERBIT"));
4267 providercount++;
4268 tpl_printf(vars, TPLADD, "APITOTALPROVIDERS", "%d", providercount);
4271 LL_ITER nit = ll_iter_create(card->remote_nodes);
4272 uint8_t *node;
4274 nodecount = 0;
4275 if(!apicall) { tpl_addVar(vars, TPLADD, "NODES", ""); }
4276 else { tpl_addVar(vars, TPLADD, "NODELIST", ""); }
4278 while((node = ll_iter_next(&nit)))
4281 if(!apicall)
4283 tpl_printf(vars, TPLAPPEND, "NODES", "%02X%02X%02X%02X%02X%02X%02X%02X<BR>\n",
4284 node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7]);
4286 else
4288 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]);
4289 tpl_printf(vars, TPLADD, "APINODENUMBER", "%d", nodecount);
4290 tpl_addVar(vars, TPLAPPEND, "NODELIST", tpl_getTpl(vars, "APICCCAMCARDNODEBIT"));
4292 nodecount++;
4293 tpl_printf(vars, TPLADD, "APITOTALNODES", "%d", nodecount);
4296 if(!apicall)
4297 { tpl_addVar(vars, TPLAPPEND, "CCCAMSTATSENTRY", tpl_getTpl(vars, "ENTITLEMENTCCCAMENTRYBIT")); }
4298 else
4299 { tpl_addVar(vars, TPLAPPEND, "CARDLIST", tpl_getTpl(vars, "APICCCAMCARDBIT")); }
4301 cardcount++;
4303 // set previous Link if needed
4304 if(offset >= ENTITLEMENT_PAGE_SIZE)
4306 tpl_printf(vars, TPLAPPEND, "CONTROLS", "<A HREF=\"entitlements.html?offset=%d&globallist=%s&amp;label=%s\"> << PREVIOUS < </A>",
4307 offset - ENTITLEMENT_PAGE_SIZE,
4308 getParam(params, "globallist"),
4309 urlencode(vars, getParam(params, "label")));
4312 // set next link if needed
4313 if(cardsize > count && offset < cardsize)
4315 tpl_printf(vars, TPLAPPEND, "CONTROLS", "<A HREF=\"entitlements.html?offset=%d&globallist=%s&amp;label=%s\"> > NEXT >> </A>",
4316 offset + ENTITLEMENT_PAGE_SIZE,
4317 getParam(params, "globallist"),
4318 urlencode(vars, getParam(params, "label")));
4321 if(!apicall)
4323 tpl_printf(vars, TPLADD, "TOTALS", "card count=%d", cardsize);
4324 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTCCCAMBIT"));
4326 else
4328 tpl_printf(vars, TPLADD, "APITOTALCARDS", "%d", cardsize);
4332 else
4334 if(!apicall)
4336 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTGENERICBIT"));
4337 tpl_addVar(vars, TPLADD, "LOGHISTORY", "no cards found<BR>\n");
4339 else
4341 tpl_printf(vars, TPLADD, "APITOTALCARDS", "%d", 0);
4346 #endif
4348 static char *send_oscam_entitlement(struct templatevars *vars, struct uriparams *params, int32_t apicall)
4350 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
4351 char *reader_ = getParam(params, "label");
4352 #ifdef MODULE_CCCAM
4353 char *sharelist_ = getParam(params, "globallist");
4354 int32_t show_global_list = sharelist_ && sharelist_[0] == '1';
4356 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
4357 if(show_global_list || strlen(reader_) || (rdr && rdr->typ == R_CCCAM))
4360 if(show_global_list || (rdr && rdr->typ == R_CCCAM && rdr->enable))
4363 if(show_global_list)
4365 tpl_addVar(vars, TPLADD, "READERNAME", "GLOBAL");
4366 tpl_addVar(vars, TPLADD, "APIHOST", "GLOBAL");
4367 tpl_addVar(vars, TPLADD, "APIHOSTPORT", "GLOBAL");
4369 else
4371 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
4372 tpl_addVar(vars, TPLADD, "APIHOST", xml_encode(vars, rdr->device));
4373 tpl_printf(vars, TPLADD, "APIHOSTPORT", "%d", rdr->r_port);
4376 #ifdef MODULE_CCCSHARE
4377 int32_t offset = atoi(getParam(params, "offset")); //should be 0 if parameter is missed on very first call
4378 int32_t cardsize;
4379 if(show_global_list)
4381 int32_t i;
4382 LLIST **sharelist = get_and_lock_sharelist();
4383 LLIST *sharelist2 = ll_create("web-sharelist");
4384 for(i = 0; i < CAID_KEY; i++)
4386 if(sharelist[i])
4387 { ll_putall(sharelist2, sharelist[i]); }
4389 unlock_sharelist();
4390 struct cc_card **cardarray = get_sorted_card_copy(sharelist2, 0, &cardsize);
4391 ll_destroy(&sharelist2);
4392 print_cards(vars, params, cardarray, cardsize, 1, NULL, offset, apicall);
4393 NULLFREE(cardarray);
4395 else
4397 struct s_client *rc = rdr->client;
4398 struct cc_data *rcc = (rc) ? rc->cc : NULL;
4399 if(rcc && rcc->cards)
4401 struct cc_card **cardarray = get_sorted_card_copy(rcc->cards, 0, &cardsize);
4402 print_cards(vars, params, cardarray, cardsize, 0, rdr, offset, apicall);
4403 NULLFREE(cardarray);
4406 #endif
4409 else
4411 #else
4412 if(strlen(reader_))
4415 struct s_reader *rdr;
4416 #endif
4417 tpl_addVar(vars, TPLADD, "LOGHISTORY", "->");
4418 // normal non-cccam reader
4420 rdr = get_reader_by_label(reader_);
4422 if(rdr)
4424 struct s_client *cl = rdr->client;
4425 if(rdr->ll_entitlements)
4428 time_t now = time((time_t *)0);
4430 struct tm start_t, end_t;
4431 LL_ITER itr = ll_iter_create(rdr->ll_entitlements);
4432 S_ENTITLEMENT *item;
4434 tpl_addVar(vars, TPLAPPEND, "LOGHISTORY", "<BR><BR>New Structure:<BR>");
4435 char tbuffer[83];
4436 int jsondelimiter = 0;
4437 while((item = ll_iter_next(&itr)))
4439 localtime_r(&item->start, &start_t);
4440 localtime_r(&item->end, &end_t);
4442 if(!apicall)
4443 { strftime(tbuffer, 30, "%Y-%m-%d", &start_t); }
4444 else
4445 { strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &start_t); }
4446 tpl_addVar(vars, TPLADD, "ENTSTARTDATE", tbuffer);
4448 if(!apicall)
4449 { strftime(tbuffer, 30, "%Y-%m-%d", &end_t); }
4450 else
4451 { strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &end_t); }
4452 tpl_addVar(vars, TPLADD, "ENTENDDATE", tbuffer);
4454 tpl_addVar(vars, TPLADD, "ENTEXPIERED", item->end > now ? "e_valid" : "e_expired");
4455 tpl_printf(vars, TPLADD, "ENTCAID", "%04X", item->caid);
4456 tpl_printf(vars, TPLADD, "ENTPROVID", "%06X", item->provid);
4457 tpl_printf(vars, TPLADD, "ENTID", "%08X%08X", (uint32_t)(item->id >> 32), (uint32_t)item->id);
4458 tpl_printf(vars, TPLADD, "ENTCLASS", "%08X", item->class);
4459 tpl_addVar(vars, TPLADD, "ENTTYPE", entitlement_type[item->type]);
4461 char *entresname;
4462 entresname = xml_encode(vars, get_tiername((uint16_t)(item->id & 0xFFFF), item->caid, tbuffer));
4463 if(!tbuffer[0])
4464 { entresname = xml_encode(vars, get_provider(item->provid, item->caid, tbuffer, sizeof(tbuffer))); }
4465 tpl_addVar(vars, TPLADD, "ENTRESNAME", entresname);
4467 if((strcmp(getParam(params, "hideexpired"), "1") != 0) || (item->end > now))
4468 { tpl_addVar(vars, TPLAPPEND, "READERENTENTRY", tpl_getTpl(vars, "ENTITLEMENTITEMBIT")); }
4470 if(apicall==2)
4472 tpl_printf(vars, TPLAPPEND, "APIENTITLEMENTLIST","%s%s",jsondelimiter?",":"", tpl_getTpl(vars, "JSONENTITLEMENTBIT"));
4473 jsondelimiter++;
4478 if(cl && cl->typ)
4479 { tpl_printf(vars, TPLADD, "READERTYPE", "%c", cl->typ); }
4480 else
4481 { tpl_addVar(vars, TPLADD, "READERTYPE", "null"); }
4482 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
4484 int8_t i, j;
4485 for(i = 0; i < 15; i++) { tpl_printf(vars, TPLAPPEND, "READERROM", "%c", rdr->rom[i]); }
4486 if(rdr->hexserial[0] || rdr->hexserial[1]) { i = 0; }
4487 else { i = 2; }
4488 if(rdr->hexserial[6] || rdr->hexserial[7]) { j = 8; }
4489 else { j = 6; }
4490 for(; i < j; i++) { tpl_printf(vars, TPLAPPEND, "READERSERIAL", "%02X%s", rdr->hexserial[i], i < j - 1 ? " " : ""); }
4491 for(i = 0; i < rdr->nprov; i++)
4493 for(j = 0; j < 4; j++) { tpl_printf(vars, TPLAPPEND, "READERPROVIDS", "%02X ", rdr->prid[i][j]); }
4494 tpl_addVar(vars, TPLAPPEND, "READERPROVIDS", i == 0 ? "(sysid)<BR>\n" : "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>\n");
4497 //CountryCode Vg card
4498 char add_nds_line = 0;
4499 if(rdr->VgCountryC[0])
4501 for(i = 0; i < 3; i++) { tpl_printf(vars, TPLAPPEND, "READERCOUNTRYC", "%c", rdr->VgCountryC[i]); }
4502 add_nds_line = 1;
4504 else
4506 tpl_addVar(vars, TPLADD, "READERCOUNTRYC", "n/a");
4509 //regional code for Vg card
4510 if(rdr->VgRegionC[0])
4512 for(i = 0; i < 8; i++) { tpl_printf(vars, TPLAPPEND, "READER_RCODE", "%c", rdr->VgRegionC[i]); }
4513 add_nds_line = 1;
4515 else
4517 tpl_addVar(vars, TPLADD, "READER_RCODE", "n/a");
4520 //Pin Vg card
4521 if(rdr->VgPin)
4523 tpl_printf(vars, TPLAPPEND, "READERPIN", "%04i", rdr->VgPin);
4524 add_nds_line = 1;
4526 else
4528 tpl_addVar(vars, TPLADD, "READERPIN", "n/a");
4531 //Fuse Vg card
4532 if(rdr->VgFuse)
4534 tpl_printf(vars, TPLAPPEND, "READERFUSE", "%02X", rdr->VgFuse);
4535 add_nds_line = 1;
4538 if(caid_is_videoguard(rdr->caid))
4540 tpl_printf(vars, TPLAPPEND, "READERPAYLOAD", "%02X %02X %02X %02X %02X %02X", rdr->VgLastPayload[0],
4541 rdr->VgLastPayload[1], rdr->VgLastPayload[2], rdr->VgLastPayload[3], rdr->VgLastPayload[4], rdr->VgLastPayload[5]);
4542 add_nds_line = 1;
4545 //credit on Vg card
4546 if(rdr->VgCredit)
4548 tpl_printf(vars, TPLAPPEND, "READERCREDIT", "%i", rdr->VgCredit);
4549 add_nds_line = 1;
4551 else
4553 tpl_addVar(vars, TPLADD, "READERCREDIT", "n/a");
4556 if(rdr->card_valid_to)
4558 struct tm vto_t;
4559 char vtobuffer[30];
4560 localtime_r(&rdr->card_valid_to, &vto_t);
4561 strftime(vtobuffer, 30, "%Y-%m-%d", &vto_t);
4562 tpl_addVar(vars, TPLADD, "READERCARDVALIDTO", vtobuffer);
4564 else
4566 tpl_addVar(vars, TPLADD, "READERCARDVALIDTO", "n/a");
4569 if(rdr->irdId[0])
4571 for(i = 0; i < 4; i++) { tpl_printf(vars, TPLAPPEND, "READERIRDID", "%02X ", rdr->irdId[i]); }
4573 else
4575 tpl_addVar(vars, TPLADD, "READERIRDID", "n/a");
4578 if(rdr->card_atr_length)
4579 for(i = 0; i < rdr->card_atr_length; i++) { tpl_printf(vars, TPLAPPEND, "READERATR", "%02X ", rdr->card_atr[i]); }
4581 if(caid_is_seca(rdr->caid) || caid_is_viaccess(rdr->caid))
4583 if(rdr->maturity==0xF)
4585 tpl_printf(vars, TPLAPPEND, "READERMATURITY", "%s ", "no limit");
4587 else
4589 tpl_printf(vars, TPLAPPEND, "READERMATURITY", "%d+", rdr->maturity);
4592 else
4594 tpl_printf(vars, TPLAPPEND, "READERMATURITY", "%s ", "n/a");
4597 if (rdr->csystem)
4598 tpl_addVar(vars, TPLADD, "READERCSYSTEM", rdr->csystem->desc);
4600 if(add_nds_line)
4602 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENTNDS", tpl_getTpl(vars, "ENTITLEMENTBITNDS"));
4604 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTBIT"));
4606 else
4608 tpl_addMsg(vars, "Reader does not exist or is not started!");
4613 else
4615 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTGENERICBIT"));
4618 if(!apicall)
4619 { return tpl_getTpl(vars, "ENTITLEMENTS"); }
4620 else
4622 if(apicall==1)
4623 { return tpl_getTpl(vars, "APICCCAMCARDLIST"); }
4624 else
4625 { return tpl_getTpl(vars, "JSONENTITLEMENTS"); }
4629 #ifdef WEBIF_LIVELOG
4630 static char *send_oscam_logpoll(struct templatevars * vars, struct uriparams * params)
4633 uint64_t lastid = 0;
4635 #ifdef WITH_DEBUG
4636 tpl_addVar(vars, TPLADD, "LOG_DEBUGMENU", tpl_getTpl(vars, "LOGDEBUGMENU"));
4637 #endif
4638 tpl_addVar(vars, TPLADD, "LOG_SIZEMENU", tpl_getTpl(vars, "LOGSIZEMENU"));
4639 tpl_addVar(vars, TPLADD, "TITLEADD1", "Move mouse over log-window to stop scroll");
4641 if(strcmp(getParam(params, "lastid"), "start") == 0){
4642 setActiveMenu(vars, MNU_LIVELOG);
4643 return tpl_getTpl(vars, "LOGPAGE");
4645 else
4647 lastid = strtoull(getParam(params, "lastid"), NULL, 10);
4650 char *dot = ""; //Delimiter
4652 #ifdef WITH_DEBUG
4653 char *debuglvl = getParam(params, "debug");
4654 if(strlen(debuglvl) > 0) {
4655 int32_t dblvl = atoi(debuglvl);
4656 if(cs_dblevel != dblvl) {
4657 if(dblvl >= 0 && dblvl <= 65535) { cs_dblevel = dblvl; }
4658 cs_log("%s debug_level=%d", "all", cs_dblevel);
4661 tpl_printf(vars, TPLAPPEND, "DATA","%s\"debug\":\"%d\"", dot, cs_dblevel);
4662 dot = ",";
4663 tpl_printf(vars, TPLAPPEND, "DATA","%s\"maxdebug\":\"%d\"",dot, MAX_DEBUG_LEVELS);
4664 #endif
4666 if(cfg.loghistorylines == 0){
4667 tpl_printf(vars, TPLAPPEND, "DATA","%s\"logdisabled\":\"1\"",dot);
4668 return tpl_getTpl(vars, "POLL");
4671 if(log_history)
4673 LL_ITER it = ll_iter_create(log_history);
4674 struct s_log_history *hist;
4676 tpl_printf(vars, TPLAPPEND, "DATA", "%s\"lines\":[", dot);
4678 dot = "";
4680 while((hist = (struct s_log_history*)ll_iter_next(&it)))
4682 char p_usr[32];
4683 size_t pos1 = strcspn(hist->txt, "\t") + 1;
4684 cs_strncpy(p_usr, hist->txt , pos1 > sizeof(p_usr) ? sizeof(p_usr) : pos1);
4686 char *p_txt = hist->txt + pos1;
4688 pos1 = strcspn(p_txt, "\n") + 1;
4689 char str_out[pos1];
4690 cs_strncpy(str_out, p_txt, pos1);
4691 uint64_t id = hist->counter;
4693 size_t b64_str_in = strlen(xml_encode(vars, str_out));
4694 size_t b64_str_out = 32 + BASE64_LENGTH(b64_str_in);
4695 char *b64_str_out_buf;
4696 if(!cs_malloc(&b64_str_out_buf, b64_str_out))
4697 { continue; }
4698 base64_encode(xml_encode(vars, str_out), b64_str_in, b64_str_out_buf, b64_str_out);
4700 if(id > lastid){
4701 tpl_printf(vars, TPLAPPEND, "DATA","%s{\"id\":\"%" PRIu64 "\",\"usr\":\"%s\",\"line\":\"%s\"}",
4702 dot,
4704 urlencode(vars, xml_encode(vars, p_usr)),
4705 b64_str_out_buf);
4706 dot = ","; // next in Array with leading delimiter
4708 NULLFREE(b64_str_out_buf);
4712 tpl_addVar(vars, TPLAPPEND, "DATA", "]");
4713 return tpl_getTpl(vars, "POLL");
4715 #endif
4717 static char *send_oscam_status(struct templatevars * vars, struct uriparams * params, int32_t apicall)
4719 int32_t i;
4720 const char *usr;
4721 int32_t lsec, isec, chsec, con, cau = 0;
4722 time_t now = time((time_t *)0);
4723 struct tm lt;
4724 int delimiter=0;
4726 if(!apicall)
4728 setActiveMenu(vars, MNU_STATUS);
4729 if (config_enabled(WITH_LB))
4730 tpl_addVar(vars, TPLADD, "STATUSCOL14HEAD","LB Value/");
4732 if(strcmp(getParam(params, "action"), "kill") == 0)
4734 char *cptr = getParam(params, "threadid");
4735 struct s_client *cl = NULL;
4736 if(strlen(cptr) > 1)
4737 { sscanf(cptr, "%p", (void **)(void *)&cl); }
4739 if(cl && is_valid_client(cl))
4741 if(is_dvbapi_usr(cl->account->usr))
4743 cs_log("WebIF from %s requests to kill dvbapi client %s -> ignoring!", cs_inet_ntoa(GET_IP()), cl->account->usr);
4745 else
4747 kill_thread(cl);
4748 cs_log("Client %s killed by WebIF from %s", cl->account->usr, cs_inet_ntoa(GET_IP()));
4753 if(strcmp(getParam(params, "action"), "resetuserstats") == 0)
4755 clear_info_clients_stats();
4757 if(strcmp(getParam(params, "action"), "resetreaderstats") == 0)
4759 clear_info_readers_stats();
4761 if(strcmp(getParam(params, "action"), "restart") == 0)
4763 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
4764 if(rdr)
4766 add_job(rdr->client, ACTION_READER_RESTART, NULL, 0);
4767 cs_log("Reader %s restarted by WebIF from %s", rdr->label, cs_inet_ntoa(GET_IP()));
4771 char *debuglvl = getParam(params, "debug");
4772 if(strlen(debuglvl) > 0)
4774 #ifndef WITH_DEBUG
4775 cs_log("*** Warning: Debug Support not compiled in ***");
4776 #else
4777 int32_t dblvl = atoi(debuglvl);
4778 if(dblvl >= 0 && dblvl <= 65535) { cs_dblevel = dblvl; }
4779 cs_log("%s debug_level=%d", "all", cs_dblevel);
4780 #endif
4783 char *hide = getParam(params, "hide");
4784 if(strlen(hide) > 0)
4786 struct s_client *hideidx = NULL;
4787 sscanf(hide, "%p", (void **)(void *)&hideidx);
4789 if(hideidx && is_valid_client(hideidx))
4790 { hideidx->wihidden = 1; }
4793 char *hideidle = getParam(params, "hideidle");
4794 if(strlen(hideidle) > 0)
4796 if(atoi(hideidle) == 2)
4798 struct s_client *cl;
4799 for(cl = first_client; cl ; cl = cl->next)
4801 if(cl->typ == 's' || cl->typ == 'h' || cl->typ == 'm'){
4802 cl->wihidden = 0;
4806 else if(atoi(hideidle) == 3)
4808 struct s_client *cl;
4809 for(cl = first_client; cl ; cl = cl->next)
4811 if(cl->typ == 'r'){
4812 cl->wihidden = 0;
4816 else if(atoi(hideidle) == 4)
4818 struct s_client *cl;
4819 for(cl = first_client; cl ; cl = cl->next)
4821 if(cl->typ == 'p'){
4822 cl->wihidden = 0;
4826 else if(atoi(hideidle) == 5)
4828 struct s_client *cl;
4829 for(cl = first_client; cl ; cl = cl->next)
4831 if(cl->typ == 'c'){
4832 cl->wihidden = 0;
4836 else
4838 int32_t oldval = cfg.http_hide_idle_clients;
4839 config_set("webif", "httphideidleclients", hideidle);
4840 if(oldval != cfg.http_hide_idle_clients)
4842 refresh_oscam(REFR_SERVER);
4847 if(cfg.http_hide_idle_clients > 0) { tpl_addVar(vars, TPLADD, "HIDEIDLECLIENTSSELECTED1", "selected"); }
4848 else { tpl_addVar(vars, TPLADD, "HIDEIDLECLIENTSSELECTED0", "selected"); }
4850 tpl_addVar(vars, TPLADD, "SRVIDFILE", use_srvid2 ? "oscam.srvid2" : "oscam.srvid");
4852 int32_t user_count_all = 0, user_count_shown = 0, user_count_active = 0;
4853 int32_t reader_count_all = 0, reader_count_conn = 0, reader_count_off = 0;
4854 int32_t proxy_count_all = 0, proxy_count_conn = 0, proxy_count_off = 0;
4855 int32_t server_count_all = 0, server_count_shown = 0, server_count_hidden = 0;
4856 int32_t monitor_count_all = 0, monitor_count_shown = 0;
4857 int32_t shown;
4859 int32_t total_readers = 0;
4860 int32_t active_readers = 0;
4861 int32_t disabled_readers = 0;
4862 int32_t connected_readers = 0;
4864 struct s_client *cl;
4865 int8_t filtered;
4867 cs_readlock(__func__, &readerlist_lock);
4868 cs_readlock(__func__, &clientlist_lock);
4869 for(i = 0, cl = first_client; cl ; cl = cl->next, i++)
4871 if(cl->kill) { continue; }
4872 #ifdef CS_CACHEEX
4873 if(get_module(cl)->listenertype != LIS_CSPUDP)
4875 #endif
4877 // Reset template variables
4878 tpl_addVar(vars, TPLADD, "LBLRPSTRVALUE", "");
4879 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", "");
4880 tpl_addVar(vars, TPLADD, "LASTREADER", "");
4881 tpl_addVar(vars, TPLADD, "CLIENTPROTO", "");
4882 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
4883 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIME", "");
4884 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIMEHIST", "");
4885 tpl_addVar(vars, TPLADD, "UPICMISSING" , "");
4886 tpl_addVar(vars, TPLADD, "ENTITLEMENTS", "");
4888 if(cl->typ == 'c')
4889 { user_count_all++; }
4890 else if(cl->typ == 'p')
4891 { proxy_count_all++; if(cl->reader->card_status != CARD_INSERTED) { proxy_count_off++; } }
4892 else if(cl->typ == 'r')
4893 { reader_count_all++; if(cl->reader->card_status != CARD_INSERTED) { reader_count_off++; } }
4894 else if(cl->typ == 's' || cl->typ == 'h')
4895 { server_count_all++; if(cl->wihidden) {server_count_hidden++;} }
4896 else if(cl->typ == 'm')
4897 { monitor_count_all++; }
4899 shown = 0;
4900 if(cl->wihidden != 1)
4902 filtered = !(cfg.http_hide_idle_clients != 1 || cl->typ != 'c' || (now - cl->lastecm) <= cfg.hideclient_to);
4903 if(!filtered && cfg.http_hide_type)
4905 char *p = cfg.http_hide_type;
4906 while(*p && !filtered)
4908 char type = *p++;
4909 #ifdef CS_CACHEEX
4910 filtered = (type == cl->typ) || (type == 'x' && (cl->typ == 'p' || cl->typ == 'r') && (cl->reader && cl->reader->cacheex.mode));
4911 #else
4912 filtered = (type == cl->typ);
4913 #endif
4917 if(!filtered)
4919 if(cl->typ == 'c')
4921 user_count_shown++;
4922 if(cfg.http_hide_idle_clients != 1 && cfg.hideclient_to > 0 && (now - cl->lastecm) <= cfg.hideclient_to)
4924 user_count_active++;
4927 else if(cl->typ == 's' || cl->typ == 'h')
4929 server_count_shown++;
4931 else if(cl->typ == 'm')
4933 monitor_count_shown++;
4935 else if(cl->typ == 'r')
4937 reader_count_conn++;
4939 else if(cl->typ == 'p')
4941 proxy_count_conn++;
4944 if(cl->typ == 'c' || cl->typ == 'r' || cl->typ == 'p')
4946 if(cl->lastecm >= cl->login && cl->lastecm >= cl->logout) { isec = now - cl->lastecm; }
4947 else if(cl->logout >= cl->login) { isec = now - cl->logout; }
4948 else { isec = now - cl->login; }
4950 else { isec = now - cl->last; }
4952 shown = 1;
4953 lsec = now - cl->login;
4954 chsec = now - cl->lastswitch;
4955 usr = username(cl);
4957 if((cl->typ == 'r') || (cl->typ == 'p')) { usr = cl->reader->label; }
4959 if(cl->dup) { con = 2; }
4960 else if((cl->tosleep) && (now - cl->lastswitch > cl->tosleep)) { con = 1; }
4961 else { con = 0; }
4963 // no AU reader == 0 / AU ok == 1 / Last EMM > aulow == -1
4964 if(cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r')
4966 if((cl->typ == 'c' && ll_count(cl->aureader_list) == 0) || ((cl->typ == 'p' || cl->typ == 'r') && cl->reader->audisabled)) { cau = 0; }
4967 else if((now - cl->lastemm) / 60 > cfg.aulow) { cau = -1; }
4968 else { cau = 1; }
4970 if(cau == 0)
4972 tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", "OFF");
4974 else
4976 if(cau == -1)
4977 { tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", !apicall?"<A HREF=\"#\" CLASS=\"tooltip\">ON":""); }
4978 else
4979 { tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", !apicall?"<A HREF=\"#\" CLASS=\"tooltip\">ACTIVE":""); }
4980 tpl_addVar(vars, TPLAPPEND, "CLIENTCAUHTTP", !apicall?"<SPAN>":"");
4981 if(cl->typ == 'c')
4983 struct s_reader *rdr;
4984 LL_ITER itr = ll_iter_create(cl->aureader_list);
4985 while((rdr = ll_iter_next(&itr)))
4987 if(rdr->audisabled)
4988 { tpl_printf(vars, TPLAPPEND, "CLIENTCAUHTTP", "(%s)<BR>", xml_encode(vars, rdr->label)); }
4989 else
4990 { tpl_printf(vars, TPLAPPEND, "CLIENTCAUHTTP", "%s<BR>", xml_encode(vars, rdr->label)); }
4993 else { tpl_addVar(vars, TPLAPPEND, "CLIENTCAUHTTP", xml_encode(vars, cl->reader->label)); }
4994 tpl_addVar(vars, TPLAPPEND, "CLIENTCAUHTTP", !apicall?"</SPAN></A>":"");
4997 else
4999 cau = 0;
5000 tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", "");
5002 localtime_r(&cl->login, &lt);
5004 if(cl->typ == 'c' || cl->typ == 'm')
5006 if(cl->account && cl->account->description)
5007 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->account->description));
5008 else
5009 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
5011 else if(cl->typ == 'p' || cl->typ == 'r')
5013 if(cl->reader && cl->reader->description)
5014 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->reader->description));
5015 else
5016 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
5018 if(!apicall)
5020 tpl_addVar(vars, TPLADD, "LBL", xml_encode(vars, usr));
5021 tpl_printf(vars, TPLADD, "CID", "%p", cl);
5022 if(cl->typ == 'c' || cl->typ == 'm')
5024 tpl_addVar(vars, TPLADD, "TARGET", "User");
5025 tpl_addVar(vars, TPLADD, "CSIDX", tpl_getTpl(vars, "STATUSKBUTTON"));
5027 else if(cl->typ == 'p')
5029 tpl_addVar(vars, TPLADD, "TARGET", "Proxy");
5030 tpl_addVar(vars, TPLADD, "LBLENC", urlencode(vars, usr));
5031 tpl_addVar(vars, TPLADD, "CSIDX", tpl_getTpl(vars, "STATUSRBUTTON"));
5033 else if(cl->typ == 'r')
5035 tpl_addVar(vars, TPLADD, "TARGET", "Reader");
5036 tpl_addVar(vars, TPLADD, "LBLENC", urlencode(vars, usr));
5037 tpl_addVar(vars, TPLADD, "CSIDX", tpl_getTpl(vars, "STATUSRBUTTON"));
5039 else if (cl->typ == 'h' || cl->typ == 's')
5041 tpl_addVar(vars, TPLADD, "TARGET", "Server");
5042 tpl_addVar(vars, TPLADD, "CSIDX", "");
5044 tpl_addVar(vars, TPLADD, "HIDEIDX", tpl_getTpl(vars, "STATUSHBUTTON"));
5045 tpl_printf(vars, TPLADD, "CSIDXPLAIN", "id_%p", cl);
5047 else
5049 tpl_printf(vars, TPLADD, "HIDEIDX", "%p", cl);
5050 tpl_printf(vars, TPLADD, "CSIDX", "id_%p", cl);
5052 tpl_printf(vars, TPLADD, "CLIENTTYPE", "%c", cl->typ);
5053 tpl_printf(vars, TPLADD, "CLIENTCNR", "%d", get_threadnum(cl));
5054 tpl_addVar(vars, TPLADD, "CLIENTUSER", xml_encode(vars, usr));
5056 tpl_addVar(vars, TPLADD, "STATUSUSERICON", xml_encode(vars, usr));
5057 if (cl->typ == 'c' || cl->typ == 'm') {
5058 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, usr));
5059 tpl_addVar(vars, TPLADD, "USERENC", urlencode(vars, usr));
5060 } else if (cl->typ == 'p' || cl->typ == 'r') {
5061 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, usr));
5062 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, usr));
5065 bool picon_shown = false;
5066 const char *status_user_icon_tpl = NULL;
5068 char picon_name[32];
5069 if(cfg.http_showpicons)
5071 if(picon_exists(xml_encode(vars, usr)))
5073 switch (cl->typ) {
5074 case 'm': // Fall through
5075 case 'c': status_user_icon_tpl = "SUSERICON"; picon_shown = true; break;
5076 case 'p': // Fall through
5077 case 'r': status_user_icon_tpl = "SREADERICON"; picon_shown = true; break;
5080 else
5081 tpl_printf(vars, TPLADD, "UPICMISSING", "%smissing icon: IC_%s.tpl",!apicall?"&#13;":"",xml_encode(vars, usr));
5084 if (!picon_shown) {
5085 switch (cl->typ) {
5086 case 'm': // Fall through
5087 case 'c': status_user_icon_tpl = "SUSER"; break;
5088 case 'p': // Fall through
5089 case 'r': status_user_icon_tpl = "SREADER"; break;
5093 if (status_user_icon_tpl)
5094 tpl_addVar(vars, TPLADD, "STATUSUSERICON", tpl_getTpl(vars, status_user_icon_tpl));
5096 tpl_printf(vars, TPLADD, "CLIENTCAU", "%d", cau);
5097 if(!apicall)
5099 if(cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r')
5101 if(cl->crypted) { tpl_addVar(vars, TPLADD, "CLIENTCRYPTED", "ON"); }
5102 else { tpl_addVar(vars, TPLADD, "CLIENTCRYPTED", "OFF"); }
5104 else { tpl_addVar(vars, TPLADD, "CLIENTCRYPTED", ""); }
5106 else { tpl_printf(vars, TPLADD, "CLIENTCRYPTED", "%d", cl->crypted); }
5107 tpl_addVar(vars, TPLADD, "CLIENTIP", cs_inet_ntoa(cl->ip));
5108 tpl_printf(vars, TPLADD, "CLIENTPORT", "%d", cl->port);
5109 const char *proto = client_get_proto(cl);
5110 webif_add_client_proto(vars, cl, proto, apicall);
5112 if(!apicall)
5114 if((cl->typ != 'p' && cl->typ != 'r') || cl->reader->card_status == CARD_INSERTED)
5116 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);
5117 tpl_addVar(vars, TPLADD, "CLIENTLOGINSECS", sec2timeformat(vars, lsec));
5119 else
5121 tpl_addVar(vars, TPLADD, "CLIENTLOGINDATE", "");
5122 tpl_addVar(vars, TPLADD, "CLIENTLOGINSECS", "");
5125 else
5127 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);
5128 char tbuffer [30];
5129 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &lt);
5130 tpl_addVar(vars, TPLADD, "CLIENTLOGINDATE", tbuffer);
5131 tpl_printf(vars, TPLADD, "CLIENTLOGINSECS", "%d", lsec);
5134 //load historical values from ringbuffer
5135 char *value = get_ecm_historystring(cl);
5136 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIMEHIST", value);
5137 free_mk_t(value);
5139 if((isec < cfg.hideclient_to || cfg.hideclient_to == 0 || is_dvbapi_usr(cl->account->usr)) && (cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r'))
5141 if(((cl->typ == 'c')) && (cl->lastreader[0]))
5143 tpl_printf(vars, TPLADD, "MSVALUE", PRINTF_LOCAL_D, cl->cwlastresptime);
5144 if(apicall)
5146 tpl_addVar(vars, TPLADD, "LASTREADER", (cl->last_caid == NO_CAID_VALUE || isec > cfg.hideclient_to ) ? "" : cl->lastreader);
5147 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, cl->lastreader));
5149 else
5151 #ifdef WITH_LB
5152 tpl_addVar(vars, TPLADD, "LBLVALUE", xml_encode(vars, cl->lastreader));
5153 if(strstr(cl->lastreader, " (cache)"))
5155 char lastreader_tmp[strlen(cl->lastreader)-8];
5156 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", tpl_getVar(vars, "LBLRPSTRVALUE"));
5157 strncpy(lastreader_tmp, cl->lastreader, strlen(cl->lastreader)-8);
5158 tpl_addVar(vars, TPLADD, "LBLVALUEENC", urlencode(vars, lastreader_tmp));
5159 tpl_addVar(vars, TPLADD, "LBLVALUETITLE", xml_encode(vars, lastreader_tmp));
5161 else
5163 tpl_addVar(vars, TPLADD, "LBLVALUEENC", urlencode(vars, cl->lastreader));
5164 tpl_addVar(vars, TPLADD, "LBLVALUETITLE", xml_encode(vars, cl->lastreader));
5166 tpl_addVar(vars, TPLAPPEND, "CLIENTLBVALUE", tpl_getTpl(vars, "CLIENTLBLVALUEBIT"));
5167 #else
5168 tpl_printf(vars, TPLAPPEND, "CLIENTLBVALUE", "%s (%'d ms)", xml_encode(vars, cl->lastreader), cl->cwlastresptime);
5169 #endif
5171 if(cl->last_caid == NO_CAID_VALUE || isec > cfg.hideclient_to) tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", "");
5173 if(cl->last_caid != NO_CAID_VALUE || cl->last_srvid != NO_SRVID_VALUE)
5175 char channame[CS_SERVICENAME_SIZE];
5176 const char *lastprovidername;
5178 get_servicename_or_null(cl, cl->last_srvid, cl->last_provid, cl->last_caid, channame, sizeof(channame));
5179 if(channame[0] == '\0')
5181 cs_strncpy(channame, "unknown", sizeof(channame));
5184 lastprovidername = get_cl_lastprovidername(cl);
5186 tpl_printf(vars, TPLADD, "CLIENTCAID", "%04X", cl->last_caid);
5187 tpl_printf(vars, TPLADD, "CLIENTPROVID", "%06X", cl->last_provid);
5188 tpl_printf(vars, TPLADD, "CLIENTSRVID", "%04X", cl->last_srvid);
5189 tpl_printf(vars, TPLADD, "CLIENTSRVPROVIDER", "%s%s%s", (lastprovidername[0] != '\0' && strcmp(lastprovidername, " ")) ? " [" : "", xml_encode(vars, lastprovidername), (lastprovidername[0] != '\0' && strcmp(lastprovidername, " ")) ? "]" : "");
5190 tpl_addVar(vars, TPLADD, "CLIENTSRVNAME", xml_encode(vars, channame));
5191 tpl_printf(vars, TPLADD, "CLIENTLASTRESPONSETIME", "%d", cl->cwlastresptime ? cl->cwlastresptime : 1);
5192 tpl_addVar(vars, TPLADD, "CLIENTSRVTYPE", cl->last_srvidptr && cl->last_srvidptr->type ? xml_encode(vars, cl->last_srvidptr->type) : "");
5193 tpl_addVar(vars, TPLADD, "CLIENTSRVDESCRIPTION", cl->last_srvidptr && cl->last_srvidptr->desc ? xml_encode(vars, cl->last_srvidptr->desc) : "");
5194 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", sec2timeformat(vars, chsec));
5195 if(cfg.http_showpicons && cl->last_srvid)
5197 char picon_channame[128];
5198 int8_t picon_ok = 0;
5200 get_picon_servicename_or_null(cl, cl->last_srvid, cl->last_provid, cl->last_caid, picon_channame, sizeof(picon_channame));
5201 if(picon_channame[0])
5203 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", picon_channame);
5204 picon_ok = picon_exists(picon_name);
5205 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
5207 if(!picon_ok && picon_servicename_remve_hd(picon_channame, sizeof(picon_channame)))
5209 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", picon_channame);
5210 picon_ok = picon_exists(picon_name);
5211 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
5214 if(!picon_ok)
5216 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%04X_%06X_%04X", cl->last_caid, cl->last_provid, cl->last_srvid);
5217 tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
5218 picon_ok = picon_exists(picon_name);
5220 if(!picon_ok)
5222 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%04X_%04X", cl->last_caid, cl->last_srvid);
5223 picon_ok = picon_exists(picon_name);
5224 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
5226 if(!picon_ok)
5228 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "0000_%04X", cl->last_srvid);
5229 picon_ok = picon_exists(picon_name);
5230 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
5232 if(picon_ok)
5234 tpl_addVar(vars, TPLADDONCE, "CURRENTPICON", tpl_getTpl(vars, "CLIENTCURRENTCHANNELPIC"));
5236 else
5238 tpl_addVar(vars, TPLADDONCE, "CURRENTPICON", tpl_getTpl(vars, "CLIENTCURRENTCHANNEL"));
5239 tpl_addVar(vars, TPLADD, "PICONNAME", "");
5242 else
5244 tpl_addVar(vars, TPLADDONCE, "CURRENTPICON", tpl_getTpl(vars, "CLIENTCURRENTCHANNELBIT"));
5245 tpl_addVar(vars, TPLADD, "PICONNAME", "0000_0000");
5248 else
5250 tpl_addVar(vars, TPLADD, "CLIENTCAID", "0000");
5251 tpl_addVar(vars, TPLADD, "CLIENTPROVID", "000000");
5252 tpl_printf(vars, TPLADD, "CLIENTSRVID", "0000");
5255 else
5257 tpl_addVar(vars, TPLADD, "CLIENTCAID", "0000");
5258 tpl_addVar(vars, TPLADD, "CLIENTPROVID", "000000");
5259 tpl_addVar(vars, TPLADD, "CLIENTSRVID", "0000");
5260 tpl_addVar(vars, TPLADD, "CURRENTPICON", "");
5261 tpl_addVar(vars, TPLADD, "CLIENTSRVPROVIDER", "");
5262 tpl_addVar(vars, TPLADD, "CLIENTSRVNAME", "");
5263 tpl_addVar(vars, TPLADD, "CLIENTSRVTYPE", "");
5264 tpl_addVar(vars, TPLADD, "CLIENTSRVDESCRIPTION", "");
5265 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", "");
5266 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", "");
5269 if(!apicall)
5271 tpl_addVar(vars, TPLADD, "CLIENTIDLESECS", sec2timeformat(vars, isec));
5273 if((cl->typ != 'p' && cl->typ != 'r') || cl->reader->card_status == CARD_INSERTED)
5274 { tpl_addVar(vars, TPLADD, "CLIENTIDLESECSCLASS", "idlesec_normal"); }
5275 else
5276 { tpl_addVar(vars, TPLADD, "CLIENTIDLESECSCLASS", "idlesec_alert"); }
5278 else
5280 tpl_printf(vars, TPLADD, "CLIENTIDLESECS", "%d", isec);
5283 if(con == 2) { tpl_addVar(vars, TPLADD, "CLIENTCON", "Duplicate"); }
5284 else if(con == 1) { tpl_addVar(vars, TPLADD, "CLIENTCON", "Sleep"); }
5285 else
5287 struct s_reader *rdr = cl->reader;
5288 char *txt = "OK";
5289 if(!rdr && (cl->typ == 'r' || cl->typ == 'p')) { txt = "UNKNOWN"; }
5290 else if(cl->typ == 'r' || cl->typ == 'p') //reader or proxy
5292 #ifdef WITH_LB
5293 if(rdr->lbvalue)
5295 tpl_printf(vars, TPLADD, "LBLRPSTRVALUE", "%d", rdr->lbvalue);
5297 else
5299 tpl_addVar(vars, TPLADD, "LBLRPSTRVALUE", "no data");
5301 tpl_addVar(vars, TPLADD, "LBLRPVALUE", rdr->label);
5302 tpl_addVar(vars, TPLADD, "LBLRPVALUEENC", urlencode(vars, rdr->label));
5303 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", tpl_getTpl(vars, "CLIENTLBLVALUERP"));
5304 #else
5305 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", tpl_getVar(vars, "LBLRPSTRVALUE"));
5306 #endif
5307 switch(rdr->card_status)
5309 case NO_CARD:
5310 txt = "OFF";
5311 break;
5312 case UNKNOWN:
5313 txt = "UNKNOWN";
5314 break;
5315 case READER_DEVICE_ERROR:
5316 txt = "READER DEVICE ERROR";
5317 break;
5318 case CARD_NEED_INIT:
5319 #ifdef CS_CACHEEX
5320 if (cl->reader->cacheex.mode > 0)
5322 txt = "CCcam CacheEX";
5324 else
5326 #endif
5327 txt = "NEEDINIT";
5328 #ifdef CS_CACHEEX
5330 #endif
5331 break;
5332 case CARD_INSERTED:
5333 if(cl->typ == 'p')
5334 { txt = "CONNECTED"; }
5335 else
5336 { txt = "CARDOK"; }
5337 break;
5338 case CARD_FAILURE:
5339 txt = "ERROR";
5340 break;
5341 default:
5342 txt = "UNDEF";
5345 tpl_addVar(vars, TPLADD, "CLIENTCON", txt);
5347 if(rdr && (cl->typ == 'r')) //reader
5349 if(rdr->ll_entitlements)
5351 LL_ITER itr = ll_iter_create(rdr->ll_entitlements);
5352 S_ENTITLEMENT *ent;
5353 uint16_t total_ent = 0;
5354 uint16_t active_ent = 0;
5355 struct tm end_t;
5356 tpl_addVar(vars, TPLADD, "TMPSPAN", "<SPAN>");
5357 while((ent = ll_iter_next(&itr)))
5359 total_ent++;
5360 if((ent->end > now) && (ent->type != 7))
5362 if(active_ent) {tpl_addVar(vars, TPLAPPEND, "TMPSPAN", "<BR><BR>");}
5363 active_ent++;
5364 localtime_r(&ent->end, &end_t);
5365 tpl_printf(vars, TPLAPPEND, "TMPSPAN", "%04X@%06X<BR>exp:%04d/%02d/%02d",
5366 ent->caid, ent->provid,
5367 end_t.tm_year + 1900, end_t.tm_mon + 1, end_t.tm_mday);
5368 tpl_printf(vars, TPLAPPEND, "ENTITLEMENTS", "%s{\"caid\":\"%04X\",\"provid\":\"%06X\",\"exp\":\"%04d/%02d/%02d\"}",
5369 active_ent > 1 ? ",": "",
5370 ent->caid, ent->provid,
5371 end_t.tm_year + 1900, end_t.tm_mon + 1, end_t.tm_mday);
5374 tpl_printf(vars, TPLADD, "TOTENTITLEMENTS", "%d", total_ent);
5375 if(((total_ent) && (active_ent == 0)) || (total_ent == 0))
5377 tpl_addVar(vars, TPLAPPEND, "TMPSPAN", "No active entitlements found");
5379 tpl_addVar(vars, TPLAPPEND, "TMPSPAN", "</SPAN>");
5380 if(active_ent)
5382 tpl_printf(vars, TPLADD, "TMP", "(%d entitlement%s)", active_ent, (active_ent != 1) ? "s" : "");
5384 else
5386 tpl_addVar(vars, TPLADD, "TMP", "(no entitlements)");
5388 tpl_addVar(vars, TPLADD, "ENTLABEL", urlencode(vars, cl->reader->label));
5389 tpl_addVar(vars, TPLADD, "ENTVALUE", active_ent > 0 ? "" : "1");
5390 if (!apicall) tpl_addVar(vars, TPLAPPEND, "CLIENTCON", tpl_getTpl(vars, "FOUNDENTITLEMENTS"));
5392 else
5394 tpl_addVar(vars, TPLADD, "ENTLABEL", urlencode(vars, cl->reader->label));
5395 if (!apicall) tpl_addVar(vars, TPLAPPEND, "CLIENTCON", tpl_getTpl(vars, "NOENTITLEMENTS"));
5398 #ifdef MODULE_CCCAM
5399 if(!apicall || apicall == 2)
5401 if(rdr && (cl->typ == 'r' || cl->typ == 'p') && strncmp(proto, "cccam", 5) == 0 && rdr->tcp_connected && rdr->card_status != CARD_FAILURE)
5403 struct cc_data *rcc = cl->cc;
5404 if(rcc)
5406 LLIST *cards = rcc->cards;
5407 if(cards)
5409 int32_t cnt = ll_count(cards);
5410 int32_t locals = rcc->num_hop1;
5411 if(!apicall)
5413 tpl_printf(vars, TPLADD, "TMP", "(%d of %d card%s)", locals, cnt, (cnt > 1) ? "s" : "");
5414 tpl_printf(vars, TPLADD, "CCCOUNT", "%d", cnt);
5415 tpl_printf(vars, TPLADD, "CCCHOP1", "%d", rcc->num_hop1);
5416 tpl_printf(vars, TPLADD, "CCCHOP2", "%d", rcc->num_hop2);
5417 tpl_printf(vars, TPLADD, "CCCHOPX", "%d", rcc->num_hopx);
5418 tpl_printf(vars, TPLADD, "CCCCURR", "%d", cl->reader->currenthops);
5419 tpl_printf(vars, TPLADD, "CCCRES0", "%d", rcc->num_reshare0);
5420 tpl_printf(vars, TPLADD, "CCCRES1", "%d", rcc->num_reshare1);
5421 tpl_printf(vars, TPLADD, "CCCRES2", "%d", rcc->num_reshare2);
5422 tpl_printf(vars, TPLADD, "CCCRESX", "%d", rcc->num_resharex);
5423 tpl_addVar(vars, TPLADD, "TMPSPAN", tpl_getTpl(vars, "CCENTITLEMENTS"));
5424 tpl_addVar(vars, TPLADD, "CCCLABEL", urlencode(vars, cl->reader->label));
5425 tpl_addVar(vars, TPLADD, "CCCRESHARE", rcc->num_reshare0 > 0 ? "1" : "");
5426 tpl_addVar(vars, TPLADD, "CCCTMP", tpl_getVar(vars, "TMP"));
5427 tpl_addVar(vars, TPLADD, "CCCTMPSPAN", tpl_getVar(vars, "TMPSPAN"));
5428 tpl_addVar(vars, TPLAPPEND, "CLIENTCON", tpl_getTpl(vars, "CCENTITLETOOLTIP"));
5430 if (apicall == 2)
5432 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, cl->reader->label));
5433 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\"}",
5434 locals, cnt, rcc->num_hop1, rcc->num_hop2, rcc->num_hopx, cl->reader->currenthops,
5435 rcc->num_reshare0, rcc->num_reshare1, rcc->num_reshare2, rcc->num_resharex,
5436 rcc->num_reshare0 > 0 ? "1" : "");
5442 #endif
5446 if(!apicall)
5448 // select right suborder
5449 if(cl->typ == 'c')
5451 if(shown) { tpl_addVar(vars, TPLAPPEND, "CLIENTSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT")); }
5452 if(cfg.http_hide_idle_clients != 1 && cfg.hideclient_to > 0)
5454 tpl_printf(vars, TPLADD, "UCAC", "%d", user_count_active);
5455 tpl_printf(vars, TPLADD, "CFGH", "%d", cfg.hideclient_to);
5456 tpl_addVar(vars, TPLADD, "CHEADADD", tpl_getTpl(vars, "CLIENTHEADLINEADD"));
5458 tpl_printf(vars, TPLADD, "UCS", "%d", user_count_shown);
5459 tpl_printf(vars, TPLADD, "UCA", "%d", user_count_all);
5460 tpl_addVar(vars, TPLADD, "HIDEIDLE", "5");
5461 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "User");
5462 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTHEADLINE"));
5463 tpl_addVar(vars, TPLADD, "CLIENTOPTIONADD", tpl_getTpl(vars, "CLIENTHEADLINEBIT"));
5464 tpl_addVar(vars, TPLADD, "CLIENTHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
5465 tpl_addVar(vars, TPLADD, "CLIENTOPTIONADD", "");
5467 else if(cl->typ == 'r')
5469 if(shown) { tpl_addVar(vars, TPLAPPEND, "READERSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT")); }
5470 tpl_printf(vars, TPLADD, "RCC", "%d", reader_count_conn);
5471 tpl_printf(vars, TPLADD, "RCA", "%d", reader_count_all);
5472 if(reader_count_off) {
5473 tpl_printf(vars, TPLADD, "RCO", "%d", reader_count_all-reader_count_off);
5474 tpl_addVar(vars, TPLADD, "RHEADADD", tpl_getTpl(vars, "CLIENTRHEADLINEADD"));
5476 tpl_addVar(vars, TPLADD, "HIDEIDLE", "3");
5477 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "Reader");
5478 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTRHEADLINE"));
5479 tpl_addVar(vars, TPLADD, "READERHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
5481 else if(cl->typ == 'p')
5483 if(shown) { tpl_addVar(vars, TPLAPPEND, "PROXYSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT")); }
5484 tpl_printf(vars, TPLADD, "PCC", "%d", proxy_count_conn);
5485 tpl_printf(vars, TPLADD, "PCA", "%d", proxy_count_all);
5486 if(proxy_count_off) {
5487 tpl_printf(vars, TPLADD, "PCO", "%d", proxy_count_all-proxy_count_off);
5488 tpl_addVar(vars, TPLADD, "PHEADADD", tpl_getTpl(vars, "CLIENTPHEADLINEADD"));
5490 tpl_addVar(vars, TPLADD, "HIDEIDLE", "4");
5491 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "Proxy");
5492 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTPHEADLINE"));
5493 tpl_addVar(vars, TPLADD, "PROXYHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
5495 else if(cl->typ == 'm' || cl->typ == 's' || cl->typ == 'h')
5497 if(shown) { tpl_addVar(vars, TPLAPPEND, "SERVERSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT")); }
5498 tpl_addVar(vars, TPLADD, "HIDEIDLE", "2");
5499 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "Server");
5500 if(cl->typ == 's' || cl->typ == 'h')
5502 tpl_printf(vars, TPLADD, "SCS", "%d", server_count_shown);
5503 tpl_printf(vars, TPLADD, "SCA", "%d", server_count_all);
5504 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTSHEADLINE"));
5505 if(shown || cl->wihidden)
5507 tpl_addVar(vars, TPLADD, "SERVERHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
5508 usr = username(cl);
5511 else
5513 tpl_addVar(vars, TPLADD, "SHOWHIDDENADD", " & Monitors");
5514 tpl_printf(vars, TPLADD, "MCS", "%d", monitor_count_shown);
5515 tpl_printf(vars, TPLADD, "MCA", "%d", monitor_count_all);
5516 tpl_addVar(vars, TPLADD, "MHEADADD", tpl_getTpl(vars, "CLIENTMHEADLINE"));
5517 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTSHEADLINE"));
5518 tpl_addVar(vars, TPLADD, "SERVERHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
5519 tpl_addVar(vars, TPLADD, "SHOWHIDDENADD", "");
5523 else
5525 if(shown)
5527 if(apicall == 1)
5528 { tpl_addVar(vars, TPLAPPEND, "APISTATUSBITS", tpl_getTpl(vars, "APISTATUSBIT")); }
5529 if(apicall == 2)
5531 tpl_addVar(vars, TPLADD, "JSONARRAYDELIMITER", delimiter?",":"");
5532 tpl_addVar(vars, TPLAPPEND, "JSONSTATUSBITS", tpl_getTpl(vars, "JSONSTATUSBIT"));
5533 delimiter++;
5538 #ifdef CS_CACHEEX
5540 #endif
5544 LL_ITER itr = ll_iter_create(configured_readers);
5545 struct s_reader *rdrr;
5546 while((rdrr = ll_iter_next(&itr)))
5548 if(rdrr->label[0] && rdrr->typ)
5550 total_readers += 1;
5552 if(rdrr->enable) { active_readers += 1; }
5553 else { disabled_readers += 1; }
5555 if(rdrr->tcp_connected) { connected_readers += 1; }
5559 cs_readunlock(__func__, &clientlist_lock);
5560 cs_readunlock(__func__, &readerlist_lock);
5562 uint8_t is_touch = 0;
5563 if(config_enabled(TOUCH) && streq(tpl_getVar(vars, "SUBDIR"), TOUCH_SUBDIR))
5564 {is_touch=1;}
5566 if(cfg.http_status_log || (apicall == 1 && strcmp(getParam(params, "appendlog"), "1") == 0) || is_touch)
5568 if(cfg.loghistorylines && log_history)
5570 LL_ITER it = ll_iter_create(log_history);
5571 struct s_log_history *hist;
5573 while((hist = (struct s_log_history*)ll_iter_next(&it)))
5575 char p_usr[32];
5576 size_t pos1 = strcspn(hist->txt, "\t") + 1;
5577 cs_strncpy(p_usr, hist->txt , pos1 > sizeof(p_usr) ? sizeof(p_usr) : pos1);
5579 char *p_txt = hist->txt + pos1;
5581 if(!apicall)
5583 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));
5585 else
5587 tpl_addVar(vars, TPLAPPEND, "LOGHISTORY", p_txt);
5591 else
5593 tpl_addVar(vars, TPLADD, "LOGHISTORY", "loghistorylines is set to 0 in your configuration");
5597 #ifdef CS_CACHEEX
5598 char *getting = "<IMG SRC=\"image?i=ICARRL\" ALT=\"Getting\">";
5599 char *pushing = "<IMG SRC=\"image?i=ICARRR\" ALT=\"Pushing\">";
5601 float cachesum = first_client ? first_client->cwcacheexgot : 1;
5602 if(cachesum < 1)
5604 cachesum = 1;
5606 tpl_printf(vars, TPLADD, "TOTAL_CACHEXPUSH", "%d", first_client ? first_client->cwcacheexpush : 0);
5607 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXPUSH_IMG", pushing);
5608 tpl_printf(vars, TPLADD, "TOTAL_CACHEXGOT", "%d", first_client ? first_client->cwcacheexgot : 0);
5609 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXGOT_IMG", getting);
5610 tpl_printf(vars, TPLADD, "TOTAL_CACHEXHIT", "%d", first_client ? first_client->cwcacheexhit : 0);
5611 tpl_printf(vars, TPLADD, "TOTAL_CACHESIZE", "%d", cache_size());
5612 tpl_printf(vars, TPLADD, "REL_CACHEXHIT", "%.2f", (first_client ? first_client->cwcacheexhit : 0) * 100 / cachesum);
5613 tpl_addVar(vars, TPLADD, "CACHEEXSTATS", tpl_getTpl(vars, "STATUSCACHEX"));
5614 #endif
5615 //User info
5616 struct s_auth *account;
5617 int32_t total_users = 0;
5618 int32_t disabled_users = 0;
5619 int32_t expired_users = 0;
5620 int32_t expired_or_disabled_users = 0;
5621 int32_t connected_users = 0;
5622 int32_t online_users = 0;
5624 for(account = cfg.account; (account); account = account->next)
5626 total_users++;
5627 if(account->expirationdate && account->expirationdate < now)
5629 expired_users++;
5631 if(account->disabled != 0)
5633 disabled_users++;
5635 if((account->expirationdate && account->expirationdate < now)||account->disabled != 0)
5637 expired_or_disabled_users++;
5639 int32_t latestactivity = 0;
5640 struct s_client *latestclient = NULL;
5641 for(cl = first_client->next; cl ; cl = cl->next)
5643 if(cl->account && !strcmp(cl->account->usr, account->usr))
5645 if(cl->lastecm > latestactivity || cl->login > latestactivity)
5647 if(cl->lastecm > cl->login) { latestactivity = cl->lastecm; }
5648 else { latestactivity = cl->login; }
5649 latestclient = cl;
5654 if(latestclient != NULL)
5656 connected_users++;
5658 if(latestactivity > 0)
5660 if((now - latestactivity) < cfg.hideclient_to)
5662 if(latestclient->cwfound + latestclient->cwnot + latestclient->cwcache > 0)
5664 online_users++;
5670 tpl_printf(vars, TPLADD, "TOTAL_USERS", "%d", total_users);
5671 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE", "%d", total_users - expired_or_disabled_users);
5672 tpl_printf(vars, TPLADD, "TOTAL_EXPIRED", "%d", expired_users);
5673 tpl_printf(vars, TPLADD, "TOTAL_DISABLED", "%d", disabled_users);
5674 tpl_printf(vars, TPLADD, "TOTAL_ONLINE", "%d", online_users);
5675 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED", "%d", connected_users);
5677 tpl_printf(vars, TPLADD, "TOTAL_READERS", "%d", total_readers);
5678 tpl_printf(vars, TPLADD, "TOTAL_DISABLED_READERS", "%d", disabled_readers);
5679 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE_READERS", "%d", active_readers);
5680 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED_READERS", "%d", connected_readers);
5682 //CM info
5683 set_ecm_info(vars);
5685 //copy struct to p_stat_old for cpu_usage calculation
5686 p_stat_old = p_stat_cur;
5689 * check_available Bit mapping
5690 * mem 0 total, 1 used & free, 2 buff, cached & free incl. buff, 3 share
5691 * swap 4 total, 5 used & free,
5692 * proc 6 count
5693 * cpu 7 load
5694 * oscam 8 vsize & rssize, 9 cpu user, 10 cpu sys, 11 cpu sum, 12 cpu refreshtime
5695 * unused 13 - 15
5697 //Memory-CPU Info for linux based systems
5698 #if defined(__linux__)
5699 //get actual stats
5700 if(!get_stats_linux(getpid(),&p_stat_cur)){
5701 if(p_stat_old.cpu_total_time != 0){
5702 calc_cpu_usage_pct(&p_stat_cur, &p_stat_old);
5705 else{
5706 //something went wrong, so fill with "N/A"
5707 p_stat_cur.check_available = 65535;
5709 #else // if not linux, fill with "N/A" but probably in future gets filled also for other platforms
5710 p_stat_cur.check_available = 65535;
5711 #endif
5712 set_status_info(vars, p_stat_cur);
5714 if(cfg.http_showmeminfo || cfg.http_showuserinfo || cfg.http_showreaderinfo || cfg.http_showloadinfo || cfg.http_showecminfo || (cfg.http_showcacheexinfo && config_enabled(CS_CACHEEX))){
5715 tpl_addVar(vars, TPLADD, "DISPLAYINFO", "visible");
5717 else{
5718 tpl_addVar(vars, TPLADD, "DISPLAYINFO", "hidden");
5721 tpl_addVar(vars, TPLADD, "DISPLAYSYSINFO", cfg.http_showmeminfo ? "visible" : "hidden");
5722 tpl_addVar(vars, TPLADD, "DISPLAYUSERINFO", cfg.http_showuserinfo ? "visible" : "hidden");
5723 tpl_addVar(vars, TPLADD, "DISPLAYREADERINFO", cfg.http_showreaderinfo ? "visible" : "hidden");
5724 tpl_addVar(vars, TPLADD, "DISPLAYLOADINFO", cfg.http_showloadinfo ?"visible" : "hidden");
5725 tpl_addVar(vars, TPLADD, "DISPLAYECMINFO", cfg.http_showecminfo ? "visible" : "hidden");
5726 tpl_addVar(vars, TPLADD, "DISPLAYECMINFO_READERS", cfg.http_showecminfo ? "visible" : "hidden");
5728 if(cfg.http_showcacheexinfo == 1 && config_enabled(CS_CACHEEX)){
5729 tpl_addVar(vars, TPLADD, "DISPLAYCACHEEXINFO", "visible");
5731 else{
5732 tpl_addVar(vars, TPLADD, "DISPLAYCACHEEXINFO", "hidden");
5735 #ifdef WITH_DEBUG
5736 if(cfg.http_status_log || is_touch)
5738 // Debuglevel Selector
5739 int32_t lvl;
5740 for(i = 0; i < MAX_DEBUG_LEVELS; i++)
5742 lvl = 1 << i;
5743 tpl_printf(vars, TPLADD, "TMPC", "DCLASS%d", lvl);
5744 tpl_printf(vars, TPLADD, "TMPV", "DEBUGVAL%d", lvl);
5745 if(cs_dblevel & lvl)
5747 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugls");
5748 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel - lvl);
5750 else
5752 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugl");
5753 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel + lvl);
5757 if(cs_dblevel == D_ALL_DUMP)
5758 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugls"); }
5759 else
5760 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugl"); }
5762 tpl_addVar(vars, TPLADD, "NEXTPAGE", "status.html");
5763 tpl_addVar(vars, TPLADD, "DCLASS", "debugl"); //default
5764 tpl_printf(vars, TPLADD, "ACTDEBUG", "%d", cs_dblevel);
5765 tpl_addVar(vars, TPLADD, "SDEBUG", tpl_getTpl(vars, "DEBUGSELECT"));
5767 #endif
5769 if(cfg.http_status_log || is_touch)
5770 tpl_addVar(vars, TPLADDONCE, "LOG_HISTORY", tpl_getTpl(vars, "LOGHISTORYBIT"));
5772 if(apicall)
5774 if(apicall == 1)
5775 { return tpl_getTpl(vars, "APISTATUS"); }
5776 if(apicall == 2)
5778 tpl_printf(vars, TPLADD, "UCS", "%d", user_count_shown);
5779 tpl_printf(vars, TPLADD, "UCA", "%d", user_count_all);
5780 if(cfg.http_hide_idle_clients != 1 && cfg.hideclient_to > 0){
5781 tpl_printf(vars, TPLADD, "UCAC", "%d", user_count_active);
5783 tpl_printf(vars, TPLADD, "CFGH", "%d", cfg.hideclient_to);
5784 tpl_printf(vars, TPLADD, "MCS", "%d", monitor_count_shown);
5785 tpl_printf(vars, TPLADD, "MCA", "%d", monitor_count_all);
5786 tpl_printf(vars, TPLADD, "SCS", "%d", server_count_shown);
5787 tpl_printf(vars, TPLADD, "SCH", "%d", server_count_hidden);
5788 tpl_printf(vars, TPLADD, "SCA", "%d", server_count_all);
5789 tpl_printf(vars, TPLADD, "RCC", "%d", reader_count_conn);
5790 tpl_printf(vars, TPLADD, "RCO", "%d", reader_count_off);
5791 tpl_printf(vars, TPLADD, "RCA", "%d", reader_count_all);
5792 tpl_printf(vars, TPLADD, "PCC", "%d", proxy_count_conn);
5793 tpl_printf(vars, TPLADD, "PCO", "%d", proxy_count_off);
5794 tpl_printf(vars, TPLADD, "PCA", "%d", proxy_count_all);
5795 tpl_printf(vars, TPLADD, "PICONENABLED", "%d", cfg.http_showpicons?1:0);
5796 tpl_printf(vars, TPLADD, "SRVIDFILE", "%s", use_srvid2 ? "oscam.srvid2" : "oscam.srvid");
5797 return tpl_getTpl(vars, "JSONSTATUS");
5801 if(is_touch)
5802 { return tpl_getTpl(vars, "TOUCH_STATUS"); }
5803 else
5804 { return tpl_getTpl(vars, "STATUS"); }
5807 static char *send_oscam_services_edit(struct templatevars * vars, struct uriparams * params)
5809 struct s_sidtab *sidtab, *ptr;
5810 char label[sizeof(cfg.sidtab->label)];
5811 int32_t i;
5813 setActiveMenu(vars, MNU_SERVICES);
5815 cs_strncpy(label, strtolower(getParam(params, "service")), sizeof(label));
5816 ++cfg_sidtab_generation;
5817 for(sidtab = cfg.sidtab; sidtab != NULL && strcmp(label, sidtab->label) != 0; sidtab = sidtab->next) { ; }
5819 if(sidtab == NULL)
5821 i = 1;
5822 while(strlen(label) < 1)
5824 snprintf(label, sizeof(label) / sizeof(char) - 1, "newservice%d", i);
5825 for(sidtab = cfg.sidtab; sidtab != NULL && strcmp(label, sidtab->label) != 0; sidtab = sidtab->next) { ; }
5826 if(sidtab != NULL) { label[0] = '\0'; }
5827 ++i;
5829 if(!cs_malloc(&sidtab, sizeof(struct s_sidtab))) { return "0"; }
5831 if(cfg.sidtab == NULL) { cfg.sidtab = sidtab; }
5832 else
5834 for(ptr = cfg.sidtab; ptr != NULL && ptr->next != NULL; ptr = ptr->next) { ; }
5835 ptr->next = sidtab;
5837 cs_strncpy((char *)sidtab->label, label, sizeof(sidtab->label));
5838 ++cfg_sidtab_generation;
5839 tpl_addMsg(vars, "New service has been added");
5840 // Adding is uncritical as the new service is appended to sidtabs.ok/sidtabs.no and accounts/clients/readers have zeros there
5841 if(write_services() != 0) { tpl_addMsg(vars, "Writing services to disk failed!"); }
5844 if(strcmp(getParam(params, "action"), "Save") == 0)
5846 for(i = 0; i < (*params).paramcount; i++)
5848 if((strcmp((*params).params[i], "action")) && (strcmp((*params).params[i], "service")))
5850 chk_sidtab((*params).params[i], (*params).values[i], sidtab);
5853 ++cfg_sidtab_generation;
5854 tpl_addMsg(vars, "Services updated");
5855 // We don't need any refresh here as accounts/clients/readers sidtabs.ok/sidtabs.no are unaffected!
5856 if(write_services() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
5858 for(sidtab = cfg.sidtab; sidtab != NULL && strcmp(label, sidtab->label) != 0; sidtab = sidtab->next) { ; }
5861 tpl_addVar(vars, TPLADD, "LABEL", xml_encode(vars, sidtab->label));
5862 tpl_addVar(vars, TPLADD, "LABELENC", urlencode(vars, sidtab->label));
5864 if(sidtab)
5866 for(i = 0; i < sidtab->num_caid; i++)
5868 if(i == 0) { tpl_printf(vars, TPLADD, "CAIDS", "%04X", sidtab->caid[i]); }
5869 else { tpl_printf(vars, TPLAPPEND, "CAIDS", ",%04X", sidtab->caid[i]); }
5871 for(i = 0; i < sidtab->num_provid; i++)
5873 if(i == 0) { tpl_printf(vars, TPLADD, "PROVIDS", "%06X", sidtab->provid[i]); }
5874 else { tpl_printf(vars, TPLAPPEND, "PROVIDS", ",%06X", sidtab->provid[i]); }
5876 for(i = 0; i < sidtab->num_srvid; i++)
5878 if(i == 0) { tpl_printf(vars, TPLADD, "SRVIDS", "%04X", sidtab->srvid[i]); }
5879 else { tpl_printf(vars, TPLAPPEND, "SRVIDS", ",%04X", sidtab->srvid[i]); }
5882 return tpl_getTpl(vars, "SERVICEEDIT");
5885 static void delete_from_SIDTABBITS(SIDTABBITS * orgsidtab, int32_t position, int32_t sidtablength)
5887 if(*orgsidtab)
5889 int32_t i;
5890 SIDTABBITS newsidtab = 0;
5891 for(i = 0; i < position; ++i)
5893 if(*orgsidtab & ((SIDTABBITS)1 << i))
5894 { newsidtab |= ((SIDTABBITS)1 << i); }
5896 for(; i < sidtablength; ++i)
5898 if(*orgsidtab & ((SIDTABBITS)1 << (i + 1)))
5899 { newsidtab |= ((SIDTABBITS)1 << i); }
5901 *orgsidtab = newsidtab;
5905 static char *send_oscam_services(struct templatevars * vars, struct uriparams * params)
5907 struct s_sidtab *sidtab;
5908 char *service = getParam(params, "service");
5909 char channame[CS_SERVICENAME_SIZE];
5910 int32_t i, counter = 0;
5912 setActiveMenu(vars, MNU_SERVICES);
5914 if(strcmp(getParam(params, "action"), "delete") == 0)
5916 if(cfg.http_readonly)
5918 tpl_addMsg(vars, "Sorry, Webif is in readonly mode. No deletion will be made!");
5920 else
5922 struct s_sidtab *sidtab_prev = NULL;
5923 int32_t sidtablength = -1;
5924 int32_t position = 0;
5926 // Calculate sidtablength before deletion so that updating sidtabs is faster
5927 for(sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next)
5928 { ++sidtablength; }
5930 for(sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next)
5932 if(strcmp(sidtab->label, service) == 0)
5934 struct s_auth *account;
5935 struct s_client *cl;
5936 struct s_reader *rdr;
5938 if(!sidtab_prev)
5939 { cfg.sidtab = sidtab->next; }
5940 else
5941 { sidtab_prev->next = sidtab->next; }
5943 for(account = cfg.account; (account); account = account->next)
5945 delete_from_SIDTABBITS(&account->sidtabs.ok, position, sidtablength);
5946 delete_from_SIDTABBITS(&account->sidtabs.no, position, sidtablength);
5948 for(cl = first_client->next; cl ; cl = cl->next)
5950 if(account == cl->account)
5952 cl->sidtabs.ok = account->sidtabs.ok;
5953 cl->sidtabs.no = account->sidtabs.no;
5958 LL_ITER itr = ll_iter_create(configured_readers);
5959 while((rdr = ll_iter_next(&itr)))
5961 delete_from_SIDTABBITS(&rdr->sidtabs.ok, position, sidtablength);
5962 delete_from_SIDTABBITS(&rdr->sidtabs.no, position, sidtablength);
5963 delete_from_SIDTABBITS(&rdr->lb_sidtabs.ok, position, sidtablength);
5965 free_sidtab(sidtab);
5966 ++counter;
5967 break;
5969 sidtab_prev = sidtab;
5970 position++;
5972 if(counter > 0)
5974 ++cfg_sidtab_generation;
5975 tpl_addMsg(vars, "Service has been deleted!");
5976 if(write_services() != 0) { tpl_addMsg(vars, "Writing services to disk failed!"); }
5978 else { tpl_addMsg(vars, "Sorry but the specified service doesn't exist. No deletion will be made!"); }
5982 sidtab = cfg.sidtab;
5983 // Show List
5984 counter = 0;
5985 while(sidtab != NULL)
5987 tpl_addVar(vars, TPLADD, "SID", "");
5988 if((strcmp(getParam(params, "service"), sidtab->label) == 0) && (strcmp(getParam(params, "action"), "list") == 0))
5990 tpl_addVar(vars, TPLADD, "SIDCLASS", "sidlist");
5991 tpl_addVar(vars, TPLAPPEND, "SID", "<DIV CLASS=\"sidlistclose\"><A HREF=\"services.html\">X</A></DIV>");
5992 for(i = 0; i < sidtab->num_srvid; i++)
5994 tpl_printf(vars, TPLAPPEND, "SID", "%04X : %s<BR>", sidtab->srvid[i],
5995 xml_encode(vars, get_servicename(cur_client(), sidtab->srvid[i], sidtab->num_provid ? sidtab->provid[0] : 0,
5996 sidtab->num_caid ? sidtab->caid[0] : 0, channame, sizeof(channame))));
5999 else
6001 tpl_addVar(vars, TPLADD, "SIDCLASS", "");
6002 tpl_printf(vars, TPLADD, "SID", "<A HREF=\"services.html?service=%s&amp;action=list\">Show Services</A>", urlencode(vars, sidtab->label));
6004 tpl_addVar(vars, TPLADD, "LABELENC", urlencode(vars, sidtab->label));
6005 tpl_addVar(vars, TPLADD, "LABEL", xml_encode(vars, sidtab->label));
6006 tpl_addVar(vars, TPLADD, "SIDLIST", tpl_getTpl(vars, "SERVICECONFIGSIDBIT"));
6008 tpl_addVar(vars, TPLAPPEND, "SERVICETABS", tpl_getTpl(vars, "SERVICECONFIGLISTBIT"));
6009 sidtab = sidtab->next;
6010 counter++;
6012 if(counter >= MAX_SIDBITS)
6014 tpl_addVar(vars, TPLADD, "BTNDISABLED", "DISABLED");
6015 tpl_addMsg(vars, "Maximum Number of Services is reached");
6017 return tpl_getTpl(vars, "SERVICECONFIGLIST");
6020 static char *send_oscam_savetpls(struct templatevars * vars)
6022 if(cfg.http_tpl)
6024 tpl_printf(vars, TPLADD, "CNT", "%d", tpl_saveIncludedTpls(cfg.http_tpl));
6025 tpl_addVar(vars, TPLADD, "PATH", cfg.http_tpl);
6027 else { tpl_addVar(vars, TPLADD, "CNT", "0"); }
6028 return tpl_getTpl(vars, "SAVETEMPLATES");
6031 static char *send_oscam_shutdown(struct templatevars * vars, FILE * f, struct uriparams * params, int8_t apicall, int8_t *keepalive, char *extraheader)
6033 if(!apicall) { setActiveMenu(vars, MNU_SHUTDOWN); }
6034 if(strcmp(strtolower(getParam(params, "action")), "shutdown") == 0)
6036 *keepalive = 0;
6037 if(!apicall)
6039 char *CSS = tpl_getUnparsedTpl("CSS", 1, "");
6040 tpl_addVar(vars, TPLADD, "STYLESHEET", CSS);
6041 NULLFREE(CSS);
6042 tpl_printf(vars, TPLADD, "REFRESHTIME", "%d", SHUTDOWNREFRESH);
6043 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
6044 tpl_printf(vars, TPLADD, "SECONDS", "%d", SHUTDOWNREFRESH);
6045 char *result = tpl_getTpl(vars, "SHUTDOWN");
6046 send_headers(f, 200, "OK", extraheader, "text/html", 0, strlen(result), NULL, 0);
6047 webif_write(result, f);
6048 cs_log("Shutdown requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
6050 else
6052 tpl_addVar(vars, TPLADD, "APICONFIRMMESSAGE", "shutdown");
6053 cs_log("Shutdown requested by XMLApi from %s", cs_inet_ntoa(GET_IP()));
6055 cs_exit_oscam();
6057 if(!apicall)
6058 { return "1"; }
6059 else
6060 { return tpl_getTpl(vars, "APICONFIRMATION"); }
6063 else if(strcmp(strtolower(getParam(params, "action")), "restart") == 0)
6065 *keepalive = 0;
6066 if(!apicall)
6068 char *CSS = tpl_getUnparsedTpl("CSS", 1, "");
6069 tpl_addVar(vars, TPLADD, "STYLESHEET", CSS);
6070 NULLFREE(CSS);
6071 tpl_addVar(vars, TPLADD, "REFRESHTIME", "5");
6072 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
6073 tpl_addVar(vars, TPLADD, "SECONDS", "5");
6074 char *result = tpl_getTpl(vars, "SHUTDOWN");
6075 send_headers(f, 200, "OK", extraheader, "text/html", 0, strlen(result), NULL, 0);
6076 webif_write(result, f);
6077 cs_log("Restart requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
6079 else
6081 tpl_addVar(vars, TPLADD, "APICONFIRMMESSAGE", "restart");
6082 cs_log("Restart requested by XMLApi from %s", cs_inet_ntoa(GET_IP()));
6084 cs_restart_oscam();
6086 if(!apicall)
6087 { return "1"; }
6088 else
6089 { return tpl_getTpl(vars, "APICONFIRMATION"); }
6092 else
6094 return tpl_getTpl(vars, "PRESHUTDOWN");
6098 static char *send_oscam_script(struct templatevars * vars, struct uriparams * params)
6100 setActiveMenu(vars, MNU_SCRIPT);
6101 tpl_printf(vars, TPLADD, "SCRIPTOPTIONS", "<option value=\"\">----select script----</option>\n");
6103 if(!cfg.http_readonly && cfg.http_script)
6105 struct dirent **namelist;
6106 int count, i;
6107 count = scandir(cfg.http_script, &namelist, 0, alphasort );
6108 if( count >= 0 )
6110 for( i = 0 ; i < count; i++ )
6112 if(is_ext(namelist[i]->d_name, ".script") || is_ext(namelist[i]->d_name, ".sh"))
6114 tpl_printf(vars, TPLAPPEND, "SCRIPTOPTIONS", "<option value=\"script.html?scriptname=%s\">%s</option>\n",namelist[i]->d_name,namelist[i]->d_name);
6116 free( namelist[i] );
6118 free(namelist);
6121 char *scriptname = getParam(params, "scriptname");
6122 char *scriptparam = getParam(params, "scriptparam");
6123 char system_str[256];
6124 struct stat s;
6125 snprintf(system_str, sizeof(system_str), "%s/%s", cfg.http_script, scriptname);
6127 if(!stat(system_str,&s))
6129 if(s.st_mode & S_IFREG)
6131 if(s.st_mode & S_IXUSR)
6133 int32_t rc;
6134 FILE *fp;
6135 char buf[256];
6137 if((scriptparam != NULL) && (sizeof(scriptparam) > 0))
6139 strcat(system_str, " ");
6140 strcat(system_str, scriptparam);
6143 fp = popen(system_str,"r");
6145 while (fgets(buf, sizeof(buf), fp) != NULL) {
6146 tpl_addVar(vars, TPLAPPEND, "SCRIPTRESULTOUT", buf);
6149 rc = pclose(fp)/256;
6151 tpl_printf(vars, TPLAPPEND, "CODE", "returncode: %d", rc);
6152 tpl_printf(vars, TPLADD, "SCRIPTNAME", "scriptname: %s", scriptname);
6154 else
6156 tpl_printf(vars, TPLADD, "SCRIPTRESULTOUT", "[Error]: Script \"%s\" not executable!", scriptname);
6160 else
6162 tpl_printf(vars, TPLADD, "SCRIPTRESULTOUT", "[Error]: Script \"%s\" not found!", scriptname);
6166 return tpl_getTpl(vars, "SCRIPT");
6169 static char *send_oscam_scanusb(struct templatevars * vars)
6171 setActiveMenu(vars, MNU_READERS);
6172 #if !defined(__CYGWIN__)
6173 FILE *fp;
6174 char path[1035];
6176 fp = popen("lsusb -v | egrep '^Bus|^ *iSerial|^ *iProduct'", "r");
6177 if(!fgets(path, sizeof(path) - 1, fp) || !fp)
6179 tpl_addVar(vars, TPLADD, "USBENTRY", "<b>lsusb:</b> Failed to run or not installed!");
6180 tpl_addVar(vars, TPLADD, "USBBIT", tpl_getTpl(vars, "SCANUSBBIT"));
6182 else
6185 tpl_addVar(vars, TPLADD, "USBENTRYCLASS", "");
6186 if(strstr(path, "Bus "))
6188 tpl_addVar(vars, TPLADD, "USBENTRY", path);
6189 tpl_addVar(vars, TPLADD, "USBENTRYCLASS", "CLASS=\"scanusbsubhead\"");
6191 else
6193 tpl_printf(vars, TPLADD, "USBENTRY", "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%s", path);
6195 tpl_addVar(vars, TPLAPPEND, "USBBIT", tpl_getTpl(vars, "SCANUSBBIT"));
6197 while(fgets(path, sizeof(path) - 1, fp) != NULL);
6199 pclose(fp);
6200 #else
6201 tpl_addMsg(vars, "Function not supported in CYGWIN environment");
6202 #endif
6203 return tpl_getTpl(vars, "SCANUSB");
6206 static void webif_process_logfile(struct templatevars * vars, struct uriparams * params, char *targetfile, size_t targetfile_len)
6208 snprintf(targetfile, targetfile_len, "%s", cfg.logfile);
6209 if(strcmp(getParam(params, "clear"), "logfile") == 0)
6211 if(strlen(targetfile) > 0)
6213 FILE *file = fopen(targetfile, "w");
6214 fclose(file);
6217 #ifdef WITH_DEBUG
6218 // Debuglevel Selector
6219 int32_t i, lvl;
6220 for(i = 0; i < MAX_DEBUG_LEVELS; i++)
6222 lvl = 1 << i;
6223 tpl_printf(vars, TPLADD, "TMPC", "DCLASS%d", lvl);
6224 tpl_printf(vars, TPLADD, "TMPV", "DEBUGVAL%d", lvl);
6225 if(cs_dblevel & lvl)
6227 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugls");
6228 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel - lvl);
6230 else
6232 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugl");
6233 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel + lvl);
6236 if(cs_dblevel == D_ALL_DUMP)
6237 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugls"); }
6238 else
6239 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugl"); }
6240 tpl_addVar(vars, TPLADD, "CUSTOMPARAM", "&file=logfile");
6241 tpl_printf(vars, TPLADD, "ACTDEBUG", "%d", cs_dblevel);
6242 tpl_addVar(vars, TPLADD, "SDEBUG", tpl_getTpl(vars, "DEBUGSELECT"));
6243 tpl_addVar(vars, TPLADD, "NEXTPAGE", "files.html");
6244 #endif
6245 if(!cfg.disablelog)
6247 tpl_printf(vars, TPLADD, "SWITCH", "%d", 1);
6248 tpl_addVar(vars, TPLADD, "TEXT", "Stop Log");
6249 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUDISABLELOG"));
6252 else
6254 tpl_printf(vars, TPLADD, "SWITCH", "%d", 0);
6255 tpl_addVar(vars, TPLADD, "TEXT", "Start Log");
6256 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUDISABLELOG"));
6258 tpl_addVar(vars, TPLAPPEND, "LOGMENU", tpl_getTpl(vars, "CLEARLOG"));
6259 return;
6262 static void webif_process_userfile(struct templatevars * vars, struct uriparams * params, char *targetfile, size_t targetfile_len)
6264 snprintf(targetfile, targetfile_len, "%s", cfg.usrfile);
6265 if(strcmp(getParam(params, "clear"), "usrfile") == 0)
6267 if(strlen(targetfile) > 0)
6269 FILE *file = fopen(targetfile, "w");
6270 fclose(file);
6273 if(!cfg.disableuserfile)
6275 tpl_printf(vars, TPLADD, "SWITCH", "%d", 1);
6276 tpl_addVar(vars, TPLADD, "TEXT", "Stop Log");
6277 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUONOFF"));
6279 else
6281 tpl_printf(vars, TPLADD, "SWITCH", "%d", 0);
6282 tpl_addVar(vars, TPLADD, "TEXT", "Start Log");
6283 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUONOFF"));
6285 tpl_addVar(vars, TPLAPPEND, "LOGMENU", tpl_getTpl(vars, "CLEARUSERLOG"));
6286 tpl_addVar(vars, TPLADD, "FFVAL", "all");
6287 tpl_addVar(vars, TPLADD, "FILTERFORMOPTIONS", tpl_getTpl(vars, "LOGMENUFILTERFORM"));
6288 struct s_auth *account;
6289 for(account = cfg.account; account; account = account->next)
6291 tpl_addVar(vars, TPLADD, "FFVAL", xml_encode(vars, account->usr));
6292 tpl_addVar(vars, TPLADD, "FFSEL", strcmp(getParam(params, "filter"), account->usr) ? "" : "selected");
6293 tpl_addVar(vars, TPLAPPEND, "FILTERFORMOPTIONS", tpl_getTpl(vars, "LOGMENUFILTERFORM"));
6295 tpl_addVar(vars, TPLADD, "FILTERFORM", tpl_getTpl(vars, "FILTERFORM"));
6298 enum file_types { FTYPE_CONFIG, FTYPE_VERSION, FTYPE_ANTICASC, FTYPE_LOGFILE, FTYPE_USERFILE , FTYPE_GBOX };
6300 struct files
6302 char *file;
6303 int menu_id;
6304 enum file_types type;
6307 static char *send_oscam_files(struct templatevars * vars, struct uriparams * params, int8_t apicall)
6309 bool writable = false;
6310 const struct files *entry;
6311 static struct files config_files[] =
6313 // id are used
6314 // new entry after last entry before first ifdef entry
6315 // ifdef must be add to end
6316 { "oscam.version", MNU_CFG_FVERSION, FTYPE_VERSION }, // id 0
6317 { "oscam.conf", MNU_CFG_FCONF, FTYPE_CONFIG }, // id 1
6318 { "oscam.user", MNU_CFG_FUSER, FTYPE_CONFIG }, // id 2
6319 { "oscam.server", MNU_CFG_FSERVER, FTYPE_CONFIG }, // id 3
6320 { "oscam.srvid", MNU_CFG_FSRVID, FTYPE_CONFIG }, // id 4
6321 { "oscam.srvid2", MNU_CFG_FSRVID2, FTYPE_CONFIG }, // id 5
6322 { "logfile", MNU_CFG_FLOGFILE, FTYPE_LOGFILE }, // id 6
6323 { "userfile", MNU_CFG_FUSERFILE, FTYPE_USERFILE }, // id 7
6324 { "css_file_name", MNU_CFG_FCSS, FTYPE_CONFIG }, // id 8
6325 { "oscam.services", MNU_CFG_FSERVICES, FTYPE_CONFIG }, // id 9
6326 { "oscam.provid", MNU_CFG_FPROVID, FTYPE_CONFIG }, // id 10
6327 { "oscam.tiers", MNU_CFG_FTIERS, FTYPE_CONFIG }, // id 11
6328 { "oscam.ratelimit", MNU_CFG_FRATELIMIT,FTYPE_CONFIG }, // id 12
6329 { "oscam.whitelist", MNU_CFG_FWHITELIST,FTYPE_CONFIG }, // id 13
6330 #ifdef HAVE_DVBAPI
6331 { "oscam.dvbapi", MNU_CFG_FDVBAPI, FTYPE_CONFIG }, // id 14
6332 #endif
6333 #ifdef CS_CACHEEX
6334 { "oscam.fakecws", MNU_CFG_FFAKECWS, FTYPE_CONFIG }, // id 15
6335 #endif
6336 #ifdef CS_ANTICASC
6337 { "anticasc", MNU_CFG_FACLOG, FTYPE_ANTICASC }, // id 16
6338 #endif
6339 #ifdef MODULE_SERIAL
6340 { "oscam.twin", MNU_CFG_FTWIN, FTYPE_CONFIG }, // id 17
6341 #endif
6342 #ifdef MODULE_CONSTCW
6343 { "constant.cw", MNU_CFG_FKEYCW, FTYPE_CONFIG }, // id 18
6344 #endif
6345 #ifdef MODULE_GBOX
6346 { "sc.info", MNU_GBX_FSCINF, FTYPE_GBOX }, // id 19
6347 { "share.info", MNU_GBX_FSHRINF, FTYPE_GBOX }, // id 20
6348 { "share.onl", MNU_GBX_FSHRONL, FTYPE_GBOX }, // id 21
6349 { "gbox.ver", MNU_GBX_FVERS, FTYPE_GBOX }, // id 22
6350 { "attack.txt", MNU_GBX_FATTACK, FTYPE_GBOX }, // id 23
6351 { "gsms.log", MNU_GBX_FSMSLOG, FTYPE_GBOX }, // id 24
6352 { "gsms.ack", MNU_GBX_FSMSACK, FTYPE_GBOX }, // id 25
6353 { "gsms.nack", MNU_GBX_FSMSNACK, FTYPE_GBOX }, // id 26
6354 { "stats.info", MNU_GBX_FSTAINF, FTYPE_GBOX }, // id 27
6355 { "expired.info", MNU_GBX_FEXPINF, FTYPE_GBOX }, // id 28
6356 { "info.log", MNU_GBX_INFOLOG, FTYPE_GBOX }, // id 29
6357 #endif
6358 { NULL, 0, 0 },
6361 if(use_srvid2)
6363 config_files[4].menu_id = MNU_CFG_FSRVID2;
6364 config_files[5].menu_id = MNU_CFG_FSRVID;
6367 if(cfg.http_css)
6369 if(strchr(cfg.http_css,'/'))
6370 config_files[8].file = strrchr(cfg.http_css, '/')+1;
6371 else if(strchr(cfg.http_css,'\\'))
6372 config_files[8].file = strrchr(cfg.http_css, '\\')+1;
6373 else
6374 config_files[8].file = cfg.http_css;
6375 tpl_addVar(vars, TPLADD, "FILE_USER_CSS", xml_encode(vars, config_files[8].file));
6378 if(!apicall) { setActiveMenu(vars, MNU_FILES); }
6380 tpl_addVar(vars, TPLADD, "APIFILENAME", "null");
6381 tpl_addVar(vars, TPLADD, "APIWRITABLE", "0");
6383 if(use_srvid2)
6385 tpl_printf(vars, TPLADD, "SRVID", "%s", "oscam.srvid2");
6386 tpl_printf(vars, TPLADD, "SRVIDSUB", "%s", "oscam.srvid");
6388 else
6390 tpl_printf(vars, TPLADD, "SRVID", "%s", "oscam.srvid");
6391 tpl_printf(vars, TPLADD, "SRVIDSUB", "%s", "oscam.srvid2");
6394 char *stoplog = getParam(params, "stoplog");
6395 if(strlen(stoplog) > 0)
6396 { cs_disable_log(atoi(stoplog)); }
6398 char *stopusrlog = getParam(params, "stopusrlog");
6399 if(strlen(stopusrlog) > 0)
6400 { cfg.disableuserfile = atoi(stopusrlog); }
6402 char *debuglvl = getParam(params, "debug");
6403 if(strlen(debuglvl) > 0)
6405 #ifndef WITH_DEBUG
6406 cs_log("*** Warning: Debug Support not compiled in ***");
6407 #else
6408 int32_t dblvl = atoi(debuglvl);
6409 if(dblvl >= 0 && dblvl <= 65535) { cs_dblevel = dblvl; }
6410 cs_log("%s debug_level=%d", "all", cs_dblevel);
6411 #endif
6413 // Process config files
6414 char *file = getParam(params, "file");
6415 char targetfile[256] = { 0 };
6416 int menu_id = 0;
6417 for(entry = config_files; entry->file; entry++)
6419 if(streq(file, entry->file))
6421 if(!apicall) { setActiveSubMenu(vars, entry->menu_id); }
6422 menu_id = entry->menu_id;
6423 tpl_addVar(vars, TPLADD, "APIWRITABLE", writable ? "1" : "0");
6424 switch(entry->type)
6426 case FTYPE_CONFIG:
6427 writable = 1;
6428 get_config_filename(targetfile, sizeof(targetfile), entry->file);
6429 break;
6430 case FTYPE_VERSION:
6431 get_tmp_dir_filename(targetfile, sizeof(targetfile), entry->file);
6432 break;
6433 case FTYPE_ANTICASC:
6434 #ifdef CS_ANTICASC
6435 if(!apicall) { snprintf(targetfile, sizeof(targetfile), "%s", ESTR(cfg.ac_logfile)); }
6436 #endif
6437 break;
6438 case FTYPE_LOGFILE:
6439 if(!apicall) { webif_process_logfile(vars, params, targetfile, sizeof(targetfile)); }
6440 break;
6441 case FTYPE_USERFILE:
6442 if(!apicall) { webif_process_userfile(vars, params, targetfile, sizeof(targetfile)); }
6443 break;
6444 case FTYPE_GBOX:
6445 #ifdef MODULE_GBOX
6446 get_gbox_filename(targetfile, sizeof(targetfile), entry->file);
6447 #endif
6448 break;
6450 tpl_addVar(vars, TPLADD, "APIFILENAME", entry->file);
6451 break;
6455 if(cfg.http_css)
6457 tpl_addVar(vars, TPLADD, "VIEW_FILEMENUCSS", tpl_getTpl(vars, "FILEMENUCSS"));
6460 if(!strstr(targetfile, "/dev/"))
6462 if(strcmp(getParam(params, "action"), "Save") == 0)
6464 if((strlen(targetfile) > 0) /*&& (file_exists(targetfile) == 1)*/)
6466 FILE *fpsave;
6467 char *fcontent = getParam(params, "filecontent");
6468 if((fpsave = fopen(targetfile, "w")))
6470 int32_t i, lastpos = 0, len = strlen(fcontent) + 1;
6471 //write submitted file line by line to disk and remove windows linebreaks
6472 for(i = 0; i < len; ++i)
6474 char tmp = fcontent[i];
6475 if(tmp == '\r' || tmp == '\n' || tmp == 0)
6477 fcontent[i] = 0;
6478 fprintf(fpsave, "%s%s", fcontent + lastpos, tmp == 0 ? "" : "\n");
6479 if(tmp == '\r' && fcontent[i + 1] == '\n') { ++i; }
6480 lastpos = i + 1;
6483 fclose(fpsave);
6484 tpl_addVar(vars, TPLAPPEND, "APIFILENAME", " saved!");
6485 // Reinit on save
6486 switch(menu_id)
6488 case MNU_CFG_FSRVID:
6489 case MNU_CFG_FSRVID2:
6490 init_srvid();
6491 break;
6492 case MNU_CFG_FPROVID:
6493 init_provid();
6494 break;
6495 case MNU_CFG_FUSER:
6496 cs_accounts_chk();
6497 break;
6498 case MNU_CFG_FDVBAPI:
6499 dvbapi_read_priority();
6500 break;
6501 case MNU_CFG_FWHITELIST:
6502 global_whitelist_read();
6503 break;
6504 case MNU_CFG_FFAKECWS:
6505 init_fakecws();
6506 break;
6507 default:
6508 break;
6514 if((strlen(targetfile) > 0) && (file_exists(targetfile) == 1))
6516 FILE *fp;
6517 char buffer[256];
6519 if((fp = fopen(targetfile, "r")) == NULL) { return "0"; }
6520 while(fgets(buffer, sizeof(buffer), fp) != NULL)
6521 if(!strcmp(getParam(params, "filter"), "all"))
6522 { tpl_addVar(vars, TPLAPPEND, "FILECONTENT", buffer); }
6523 else if(strstr(buffer, getParam(params, "filter")))
6524 { tpl_addVar(vars, TPLAPPEND, "FILECONTENT", buffer); }
6525 fclose(fp);
6527 else
6529 tpl_addVar(vars, TPLAPPEND, "FILECONTENT", "File does not exist or no file selected!");
6532 else
6534 tpl_addVar(vars, TPLAPPEND, "FILECONTENT", "File not valid!");
6537 tpl_addVar(vars, TPLADD, "PART", file);
6539 if(!writable)
6541 tpl_addVar(vars, TPLADD, "WRITEPROTECTION", tpl_getTpl(vars, "WRITEPROTECTION"));
6542 tpl_addVar(vars, TPLADD, "BTNDISABLED", "DISABLED");
6545 if(!apicall)
6546 { return tpl_getTpl(vars, "FILE"); }
6547 else
6548 { return tpl_getTpl(vars, "APIFILE"); }
6551 static char *send_oscam_failban(struct templatevars * vars, struct uriparams * params, int8_t apicall)
6553 IN_ADDR_T ip2delete;
6554 set_null_ip(&ip2delete);
6555 LL_ITER itr = ll_iter_create(cfg.v_list);
6556 V_BAN *v_ban_entry;
6557 //int8_t apicall = 0; //remove before flight
6559 if(!apicall) { setActiveMenu(vars, MNU_FAILBAN); }
6561 if(strcmp(getParam(params, "action"), "delete") == 0)
6564 if(strcmp(getParam(params, "intip"), "all") == 0)
6566 // clear whole list
6567 while((v_ban_entry = ll_iter_next(&itr)))
6569 ll_iter_remove_data(&itr);
6573 else
6575 //we have a single IP
6576 cs_inet_addr(getParam(params, "intip"), &ip2delete);
6577 while((v_ban_entry = ll_iter_next(&itr)))
6579 if(IP_EQUAL(v_ban_entry->v_ip, ip2delete))
6581 ll_iter_remove_data(&itr);
6582 break;
6587 ll_iter_reset(&itr);
6589 struct timeb now;
6590 cs_ftime(&now);
6592 while((v_ban_entry = ll_iter_next(&itr)))
6595 tpl_printf(vars, TPLADD, "IPADDRESS", "%s@%d", cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port);
6596 tpl_addVar(vars, TPLADD, "VIOLATIONUSER", v_ban_entry->info ? v_ban_entry->info : "unknown");
6597 struct tm st ;
6598 localtime_r(&v_ban_entry->v_time.time, &st); // fix me, we need walltime!
6599 if(!apicall)
6601 tpl_printf(vars, TPLADD, "VIOLATIONDATE", "%02d.%02d.%02d %02d:%02d:%02d",
6602 st.tm_mday, st.tm_mon + 1,
6603 st.tm_year % 100, st.tm_hour,
6604 st.tm_min, st.tm_sec);
6606 else
6608 char tbuffer [30];
6609 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &st);
6610 tpl_addVar(vars, TPLADD, "VIOLATIONDATE", tbuffer);
6613 tpl_printf(vars, TPLADD, "VIOLATIONCOUNT", "%d", v_ban_entry->v_count);
6615 int64_t gone = comp_timeb(&now, &v_ban_entry->v_time);
6616 if(!apicall)
6618 if(!v_ban_entry->acosc_entry)
6619 { tpl_addVar(vars, TPLADD, "LEFTTIME", sec2timeformat(vars, (cfg.failbantime * 60) - (gone / 1000))); }
6620 else
6621 { tpl_addVar(vars, TPLADD, "LEFTTIME", sec2timeformat(vars, v_ban_entry->acosc_penalty_dur - (gone / 1000))); }
6623 else
6625 if(!v_ban_entry->acosc_entry)
6626 { tpl_printf(vars, TPLADD, "LEFTTIME", "%"PRId64"", (cfg.failbantime * 60) - (gone / 1000)); }
6627 else
6628 { tpl_printf(vars, TPLADD, "LEFTTIME", "%"PRId64"", v_ban_entry->acosc_penalty_dur - (gone / 1000)); }
6631 tpl_addVar(vars, TPLADD, "INTIP", cs_inet_ntoa(v_ban_entry->v_ip));
6633 if(!apicall)
6634 { tpl_addVar(vars, TPLAPPEND, "FAILBANROW", tpl_getTpl(vars, "FAILBANBIT")); }
6635 else
6636 { tpl_addVar(vars, TPLAPPEND, "APIFAILBANROW", tpl_getTpl(vars, "APIFAILBANBIT")); }
6638 if(!apicall)
6639 { return tpl_getTpl(vars, "FAILBAN"); }
6640 else
6641 { return tpl_getTpl(vars, "APIFAILBAN"); }
6644 static bool send_EMM(struct s_reader * rdr, uint16_t caid, const struct s_cardsystem *csystem, const unsigned char *emmhex, uint32_t len)
6647 if(NULL != rdr && NULL != emmhex && 0 != len)
6649 EMM_PACKET *emm_pack = NULL;
6651 if(cs_malloc(&emm_pack, sizeof(EMM_PACKET)))
6653 struct s_client *webif_client = cur_client();
6654 webif_client->grp = 0xFF; /* to access to all readers */
6656 memset(emm_pack, '\0', sizeof(EMM_PACKET));
6657 emm_pack->client = webif_client;
6658 emm_pack->emmlen = len;
6659 memcpy(emm_pack->emm, emmhex, len);
6661 emm_pack->caid[0] = (caid >> 8) & 0xFF;
6662 emm_pack->caid[1] = caid & 0xFF;
6664 if(csystem && csystem->get_emm_type)
6666 if(!csystem->get_emm_type(emm_pack, rdr))
6668 rdr_log_dbg(rdr, D_EMM, "get_emm_type() returns error");
6672 cs_log_dbg(D_EMM, "emm is being sent to reader %s.", rdr->label);
6673 add_job(rdr->client, ACTION_READER_EMM, emm_pack, sizeof(EMM_PACKET));
6674 return true;
6678 return false;
6681 static bool process_single_emm(struct templatevars * vars, struct s_reader * rdr, uint16_t caid, const struct s_cardsystem *csystem, const char *ep)
6684 if(NULL != vars && NULL != rdr && NULL != ep)
6686 char emmdata[1025] = {'\0'}; /*1024 + '\0'*/
6687 unsigned char emmhex[513] = {'\0'};
6688 char buff[5] = {'\0'};
6689 uint32_t len = 0;
6690 cs_strncpy(emmdata, ep, sizeof(emmdata));
6691 remove_white_chars(emmdata);
6693 if('\0' != emmdata[0])
6695 len = strlen(emmdata);
6696 tpl_addVar(vars, TPLADD, "EP", strtoupper(emmdata));
6697 if(key_atob_l(emmdata, emmhex, len))
6699 tpl_addMsg(vars, "Single EMM has not been sent due to wrong value!");
6701 else
6703 len /= 2;
6704 snprintf(buff, sizeof(buff), "0x%02X", len);
6705 tpl_addVar(vars, TPLADD, "EP", strtoupper(emmdata));
6706 tpl_addVar(vars, TPLADD, "SIZE", buff);
6708 if(send_EMM(rdr, caid, csystem, emmhex, len))
6710 tpl_addMsg(vars, "Single EMM has been sent.");
6711 return true;
6716 tpl_addVar(vars, TPLADD, "SIZE", "0x00");
6717 return false;
6720 static bool process_emm_file(struct templatevars * vars, struct s_reader * rdr, uint16_t caid, const struct s_cardsystem *csystem, const char *sFilePath)
6723 bool bret = false;
6724 uint32_t fsize = 0;
6725 uint32_t rlines = 0;
6726 uint32_t wemms = 0;
6727 uint32_t errsize = 0;
6728 char numerrl[256] = {'\0'};
6729 char buff[20] = {'\0'};
6731 if(NULL != rdr && NULL != sFilePath && '\0' != sFilePath[0])
6733 char sMessage[128] = {0};
6734 if(true == file_exists(sFilePath))
6736 FILE *fp;
6737 if((fp = fopen(sFilePath, "r")))
6739 char line[2048] = {'\0'};
6740 unsigned char emmhex[513] = {'\0'};
6741 uint32_t len = 0;
6743 tpl_addMsg(vars, "EMM file has been processed.");
6744 while(fgets(line, sizeof(line), fp))
6746 ++rlines;
6747 len = strlen(remove_white_chars(line));
6749 // wrong emm
6750 if(len > (sizeof(emmhex) * 2) ||
6751 key_atob_l(line, emmhex, len))
6753 errsize += snprintf(numerrl + errsize, sizeof(numerrl) - errsize, "%d, ", rlines);
6754 continue;
6756 len /= 2;
6757 if(send_EMM(rdr, caid, csystem, emmhex, len))
6759 ++wemms;
6760 /* Give time to process EMM, otherwise, too many jobs can be added*/
6761 cs_sleepms(1000); //TODO: use oscam signal to catch reader answer
6764 fsize = ftell(fp);
6765 fclose(fp);
6767 else
6769 snprintf(sMessage, sizeof(sMessage), "Cannot open file '%s' (errno=%d: %s)\n", sFilePath, errno, strerror(errno));
6770 tpl_addMsg(vars, sMessage);
6773 else
6775 snprintf(sMessage, sizeof(sMessage), "FILE \"%s\" not found!", sFilePath);
6776 tpl_addMsg(vars, sMessage);
6778 bret = true;
6781 snprintf(buff, sizeof(buff), "%d bytes", fsize);
6782 tpl_addVar(vars, TPLADD, "FSIZE", buff);
6783 snprintf(buff, sizeof(buff), "%d", rlines);
6784 tpl_addVar(vars, TPLADD, "NUMRLINE", buff);
6785 snprintf(buff, sizeof(buff), "%d", wemms);
6786 tpl_addVar(vars, TPLADD, "NUMWEMM", buff);
6787 tpl_addVar(vars, TPLADD, "ERRLINE", numerrl);
6789 return bret;
6792 static char *send_oscam_EMM_running(struct templatevars * vars, struct uriparams * params)
6795 struct s_reader *rdr = NULL;
6797 setActiveMenu(vars, MNU_READERS);
6798 tpl_addVar(vars, TPLADD, "READER", getParam(params, "label"));
6799 tpl_addVar(vars, TPLADD, "FNAME", getParam(params, "emmfile"));
6801 rdr = get_reader_by_label(getParam(params, "label"));
6802 if(rdr)
6804 int32_t tcaid = dyn_word_atob(getParam(params, "emmcaid"));
6805 uint16_t caid = (-1 != tcaid) ? (uint16_t)tcaid : 0;
6806 char buff[7] = "";
6807 const struct s_cardsystem *csystem = NULL;
6808 int32_t proxy = is_cascading_reader(rdr);
6810 if((proxy || !rdr->csystem_active) && caid) // network reader (R_CAMD35 R_NEWCAMD R_CS378X R_CCCAM)
6812 if(proxy && !rdr->ph.c_send_emm)
6814 tpl_addMsg(vars, "The reader does not support EMM's!");
6815 return tpl_getTpl(vars, "EMM_RUNNING");
6818 csystem = get_cardsystem_by_caid(caid);
6819 if(!csystem)
6821 rdr_log_dbg(rdr, D_EMM, "unable to find cardsystem for caid %04X", caid);
6822 caid = 0;
6825 else if(!proxy && rdr->csystem_active) // local active reader
6827 csystem = rdr->csystem;
6828 caid = rdr->caid;
6831 if(csystem)
6833 tpl_addVar(vars, TPLADD, "SYSTEM", csystem->desc);
6835 else
6837 tpl_addVar(vars, TPLADD, "SYSTEM", "unknown");
6839 if(caid)
6841 snprintf(buff, sizeof(buff), "0x%04X", caid);
6842 tpl_addVar(vars, TPLADD, "CAID", buff);
6844 else
6846 tpl_addVar(vars, TPLADD, "CAID", "unknown");
6849 process_single_emm(vars, rdr, caid, csystem, getParam(params, "ep"));
6850 process_emm_file(vars, rdr, caid, csystem, getParam(params, "emmfile"));
6852 else
6854 char sMessage[128] = {0};
6855 snprintf(sMessage, sizeof(sMessage), "READER \"%s\" not found!", getParam(params, "label"));
6856 tpl_addMsg(vars, sMessage);
6857 tpl_addVar(vars, TPLADD, "READER", "reader not found");
6860 return tpl_getTpl(vars, "EMM_RUNNING");
6863 static char *send_oscam_EMM(struct templatevars * vars, struct uriparams * params)
6866 setActiveMenu(vars, MNU_READERS);
6867 tpl_addVar(vars, TPLADD, "READER", getParam(params, "label"));
6869 struct s_reader *rdr = NULL;
6870 rdr = get_reader_by_label(getParam(params, "label"));
6871 if(rdr && rdr->caid)
6873 char buff[5] = "";
6874 snprintf(buff, sizeof(buff), "%04X", rdr->caid);
6875 tpl_addVar(vars, TPLADD, "CAID", buff);
6876 if(!is_cascading_reader(rdr))
6878 tpl_addVar(vars, TPLADD, "READONLY", "readonly=\"readonly\"");
6882 FILE *fp;
6883 struct stat sb;
6884 char buffer[1024];
6885 char emm_hex[1024];
6886 char filename[128];
6887 char targetfile[256];
6888 char tmpstr[20];
6889 char emm_txt[32];
6890 char emm_title[32];
6891 char *emm_path;
6892 char *emm_types[] = { "unique_emm", "shared_emm", "global_emm" };
6893 char *emm_names[] = { "RDREMMUNIQUE", "RDREMMSHARED", "RDREMMGLOBAL" };
6894 char *emm_cfg_names[] = { "httpemmuclean", "httpemmsclean", "httpemmgclean" };
6895 int32_t emm_max_size[] = { cfg.http_emmu_clean, cfg.http_emms_clean, cfg.http_emmg_clean };
6896 int num_emm_types = 3;
6897 int i;
6899 emm_path = cfg.emmlogdir ? cfg.emmlogdir : cs_confdir;
6901 for( i = 0 ; i < num_emm_types; i++ )
6903 snprintf(filename, sizeof(filename), "%s%s%s%s", getParam(params, "label"), "_", emm_types[i], ".log");
6904 snprintf(targetfile, sizeof(targetfile), "%s%s%s", emm_path, emm_path[strlen(emm_path) - 1] == '/' ? "" : "/", filename);
6905 snprintf(emm_txt, sizeof(emm_txt), "%s_TXT", emm_names[i]);
6906 tpl_addVar(vars, TPLADD, emm_txt, filename);
6908 if((fp = fopen(targetfile, "r")) != NULL)
6910 stat(targetfile, &sb);
6911 tpl_printf(vars, TPLAPPEND, emm_txt, " (Size: %'.2f kB)", (double)sb.st_size/1024);
6913 if(emm_max_size[i]>=0)
6915 snprintf(emm_title, sizeof(emm_title), "%s_TITLE", emm_names[i]);
6916 tpl_addVar(vars, TPLADD, emm_title, "title=\"Click Line to Copy EMM in Single EMM Write Field\"");
6919 if(emm_max_size[i]>0)
6921 uint32_t emms=0, emm_d, emmrs=0;
6922 char *ptr, *saveptr1 = NULL;
6924 while(fgets(buffer, sizeof(buffer), fp) != NULL)
6926 emms++;
6927 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emms);
6928 tpl_addVar(vars, TPLADD, tmpstr, buffer);
6931 for(emm_d=emms;emm_d>0;--emm_d)
6933 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emm_d);
6934 if(sscanf(tpl_getVar(vars, tmpstr), "%*s %*s %*s %s", &emm_hex[0])==1)
6936 if(strstr(tpl_getVar(vars, "EMM_TMP"),emm_hex)==0)
6937 { tpl_addVar(vars, TPLAPPEND, "EMM_TMP", tpl_getVar(vars, tmpstr)); }
6938 tpl_addVar(vars, TPLADD, tmpstr, "");
6942 for(ptr = strtok_r(tpl_getVar(vars, "EMM_TMP"),"\n", &saveptr1); ptr; ptr = strtok_r(NULL,"\n", &saveptr1))
6944 emmrs++;
6945 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emmrs);
6946 tpl_addVar(vars, TPLADD, tmpstr, ptr);
6948 tpl_addVar(vars, TPLADD, "EMM_TMP", "");
6950 tpl_printf(vars, TPLAPPEND, emm_txt, ": %'d different EMM's from a total off %'d Entrys", emmrs,emms);
6951 for(emm_d=emmrs;emm_d>0;--emm_d)
6953 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emm_d);
6954 tpl_printf(vars, TPLAPPEND, emm_names[i], "<a class=\"tosingleemm\" href=\"#\">%s</a>\n", tpl_getVar(vars, tmpstr));
6955 if(sb.st_size>emm_max_size[i]*1024) { tpl_printf(vars, TPLAPPEND, "EMM_TMP", "%s\n", tpl_getVar(vars, tmpstr)); }
6956 tpl_addVar(vars, TPLADD, tmpstr, "");
6959 if(sb.st_size>emm_max_size[i]*1024)
6961 char orgfile[256];
6962 int f=0;
6963 do {
6964 snprintf(orgfile, sizeof(orgfile), "%s.%d", targetfile, f);
6965 f++;
6966 } while(access(orgfile, 0|F_OK) != -1);
6968 if(rename(targetfile, orgfile) == 0)
6970 FILE *fs = fopen(targetfile, "w");
6971 fprintf(fs, "%s", tpl_getVar(vars, "EMM_TMP"));
6972 fclose(fs);
6973 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);
6976 tpl_addVar(vars, TPLADD, "EMM_TMP", "");
6978 else if (emm_max_size[i]==0)
6980 while(fgets(buffer, sizeof(buffer), fp) != NULL)
6982 tpl_printf(vars, TPLAPPEND, emm_names[i], "<a class=\"tosingleemm\" href=\"#\">%s</a>", buffer);
6985 else
6987 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]);
6989 fclose(fp);
6991 if(strcmp(tpl_getVar(vars, emm_names[i]),"")==0) { tpl_addVar(vars, TPLADD, emm_names[i],"no saved EMM's"); }
6994 return tpl_getTpl(vars, "ASKEMM");
6997 #ifdef CS_CACHEEX
6998 static uint64_t get_cacheex_node(struct s_client * cl)
7000 uint64_t node = 0x00;
7001 #if defined(MODULE_CCCAM) || defined(MODULE_CAMD35) || defined(MODULE_CAMD35_TCP)
7002 struct s_module *module = (cl->reader ? &cl->reader->ph : get_module(cl));
7003 #endif
7004 #ifdef MODULE_CCCAM
7005 if(module->num == R_CCCAM && cl->cc)
7007 struct cc_data *cc = cl->cc;
7008 memcpy(&node, cc->peer_node_id, 8);
7010 else
7011 #endif
7012 #ifdef MODULE_CAMD35
7013 if(module->num == R_CAMD35)
7015 memcpy(&node, cl->ncd_skey, 8);
7017 else
7018 #endif
7019 #ifdef MODULE_CAMD35_TCP
7020 if(module->num == R_CS378X)
7022 memcpy(&node, cl->ncd_skey, 8);
7024 else
7025 #endif
7027 return node;
7031 static char *send_oscam_cacheex(struct templatevars * vars, struct uriparams * params, int8_t apicall)
7034 if(!apicall) { setActiveMenu(vars, MNU_CACHEEX); }
7036 if(strcmp(getParam(params, "x"), "x") == 0)
7038 // avoid compilerwarning unused vars
7040 char *level[] = {"NONE", "CACHE PULL", "CACHE PUSH", "REVERSE CACHE PUSH"};
7041 char *getting = "<IMG SRC=\"image?i=ICARRL\" ALT=\"Getting\">";
7042 char *pushing = "<IMG SRC=\"image?i=ICARRR\" ALT=\"Pushing\">";
7043 char *rowvariable = "";
7045 int16_t i, written = 0;
7046 struct s_client *cl;
7047 time_t now = time((time_t *)0);
7048 int delimiter=0;
7050 if(!apicall)
7052 if(strcmp(getParam(params, "action"), "resetallcacheexstats") == 0)
7054 cacheex_clear_all_stats();
7058 tpl_printf(vars, TPLADD, "OWN_CACHEEX_NODEID", "%" PRIu64 "X", cacheex_node_id(cacheex_peer_id));
7060 const char *cacheex_name_link_tpl = NULL;
7061 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
7063 for(i = 0, cl = first_client; cl ; cl = cl->next, i++)
7065 if(cl->typ == 'c' && cl->account && cl->account->cacheex.mode)
7067 cacheex_name_link_tpl = "SUSER";
7068 tpl_addVar(vars, TPLADD, "TYPE", "Client");
7069 if(!apicall) {
7070 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, cl->account->usr));
7071 tpl_addVar(vars, TPLADD, "USERENC", urlencode(vars, cl->account->usr));
7072 if(cl->account->description) {
7073 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->account->description));
7075 } else {
7076 tpl_addVar(vars, TPLADD, "NAME", cl->account->usr);
7077 if(cl->account->description) {
7078 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", cl->account->description);
7081 tpl_addVar(vars, TPLADD, "IP", cs_inet_ntoa(cl->ip));
7082 tpl_printf(vars, TPLADD, "NODE", "%" PRIu64 "X", get_cacheex_node(cl));
7083 tpl_addVar(vars, TPLADD, "LEVEL", level[cl->account->cacheex.mode]);
7084 tpl_printf(vars, TPLADD, "PUSH", "%d", cl->account->cwcacheexpush);
7085 tpl_printf(vars, TPLADD, "GOT", "%d", cl->account->cwcacheexgot);
7086 tpl_printf(vars, TPLADD, "CWCINFO", "%d", cl->account->cwc_info);
7087 tpl_printf(vars, TPLADD, "HIT", "%d", cl->account->cwcacheexhit);
7088 tpl_printf(vars, TPLADD, "ERR", "%d", cl->account->cwcacheexerr);
7089 tpl_printf(vars, TPLADD, "ERRCW", "%d", cl->account->cwcacheexerrcw);
7090 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", (cl->account->cacheex.mode == 3) ? getting : pushing);
7091 rowvariable = "TABLECLIENTROWS";
7092 written = 1;
7094 else if((cl->typ == 'p' || cl->typ == 'r') && (cl->reader && cl->reader->cacheex.mode))
7096 cacheex_name_link_tpl = "SREADER";
7097 tpl_addVar(vars, TPLADD, "TYPE", "Reader");
7098 if(!apicall) {
7099 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, cl->reader->label));
7100 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, cl->reader->label));
7101 if(cl->reader->description) {
7102 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->reader->description));
7104 } else {
7105 tpl_addVar(vars, TPLADD, "NAME", cl->reader->label);
7106 if(cl->reader->description) {
7107 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", cl->reader->description);
7110 tpl_addVar(vars, TPLADD, "IP", cs_inet_ntoa(cl->ip));
7111 tpl_printf(vars, TPLADD, "NODE", "%" PRIu64 "X", get_cacheex_node(cl));
7112 tpl_addVar(vars, TPLADD, "LEVEL", level[cl->reader->cacheex.mode]);
7113 tpl_printf(vars, TPLADD, "PUSH", "%d", cl->cwcacheexpush);
7114 tpl_printf(vars, TPLADD, "CWCINFO", "%d", cl->cwc_info);
7115 tpl_printf(vars, TPLADD, "GOT", "%d", cl->cwcacheexgot);
7116 tpl_printf(vars, TPLADD, "CWCINFO", "%d", cl->cwc_info);
7117 tpl_printf(vars, TPLADD, "HIT", "%d", cl->cwcacheexhit);
7118 tpl_printf(vars, TPLADD, "ERR", "%d", cl->cwcacheexerr);
7119 tpl_printf(vars, TPLADD, "ERRCW", "%d", cl->cwcacheexerrcw);
7120 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", (cl->reader->cacheex.mode == 3) ? pushing : getting);
7121 rowvariable = "TABLEREADERROWS";
7122 written = 1;
7124 else if(get_module(cl)->listenertype == LIS_CSPUDP)
7126 cacheex_name_link_tpl = "SREADER";
7127 tpl_addVar(vars, TPLADD, "TYPE", "csp");
7128 if(!apicall) {
7129 tpl_addVar(vars, TPLADD, "READERNAME", "csp");
7130 tpl_addVar(vars, TPLADD, "READERNAMEENC", "csp");
7131 } else {
7132 tpl_addVar(vars, TPLADD, "NAME", "csp");
7134 tpl_addVar(vars, TPLADD, "IP", cs_inet_ntoa(cl->ip));
7135 tpl_addVar(vars, TPLADD, "NODE", "csp");
7136 if(cl->cwcacheexping)
7138 tpl_printf(vars, TPLADD, "LEVEL", "csp (%d ms)", cl->cwcacheexping);
7140 else
7142 tpl_addVar(vars, TPLADD, "LEVEL", "csp");
7144 tpl_printf(vars, TPLADD, "PUSH", "%d", cl->cwcacheexpush);
7145 tpl_printf(vars, TPLADD, "GOT", "%d", cl->cwcacheexgot);
7146 tpl_printf(vars, TPLADD, "HIT", "%d", cl->cwcacheexhit);
7147 tpl_printf(vars, TPLADD, "ERR", "%d", cl->cwcacheexerr);
7148 tpl_printf(vars, TPLADD, "ERRCW", "%d", cl->cwcacheexerrcw);
7149 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", getting);
7150 rowvariable = "TABLECLIENTROWS";
7151 written = 1;
7154 if(written)
7156 if(!apicall) {
7157 tpl_addVar(vars, TPLADD, "NAME", tpl_getTpl(vars, cacheex_name_link_tpl));
7159 tpl_addVar(vars, TPLAPPEND, rowvariable, tpl_getTpl(vars, "CACHEEXTABLEROW"));
7161 if(cl->ll_cacheex_stats)
7163 LL_ITER itr = ll_iter_create(cl->ll_cacheex_stats);
7164 S_CACHEEX_STAT_ENTRY *cacheex_stats_entry;
7166 while((cacheex_stats_entry = ll_iter_next(&itr)))
7169 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", "");
7170 if(now - cacheex_stats_entry->cache_last < 20)
7171 { tpl_addVar(vars, TPLADD, "TYPE", cacheex_stats_entry->cache_direction == 0 ? pushing : getting); }
7172 else
7173 { tpl_addVar(vars, TPLADD, "TYPE", ""); }
7174 tpl_printf(vars, TPLADD, "NAME", "%04X@%06X:%04X", cacheex_stats_entry->cache_caid,
7175 cacheex_stats_entry->cache_prid,
7176 cacheex_stats_entry->cache_srvid);
7177 if(cacheex_stats_entry->cache_direction == 0)
7179 tpl_printf(vars, TPLADD, "PUSH", "%d", cacheex_stats_entry->cache_count);
7180 tpl_addVar(vars, TPLADD, "GOT", "");
7182 else
7184 tpl_printf(vars, TPLADD, "GOT", "%d", cacheex_stats_entry->cache_count);
7185 tpl_addVar(vars, TPLADD, "PUSH", "");
7187 tpl_addVar(vars, TPLADD, "HIT", "");
7188 char channame[CS_SERVICENAME_SIZE];
7189 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)));
7190 tpl_addVar(vars, TPLADD, "LEVEL", lastchan);
7191 if (apicall == 2){
7192 tpl_printf(vars, TPLADD, "JSONDELIMITER", "%s", (delimiter > 1)?",":"");
7193 tpl_addVar(vars, TPLAPPEND, "JSONCACHEEXBITS", tpl_getTpl(vars, "JSONCACHEEXBIT"));
7194 delimiter++;
7196 else{
7197 tpl_addVar(vars, TPLAPPEND, rowvariable, tpl_getTpl(vars, "CACHEEXTABLEROW"));
7202 written = 0;
7206 float cachesum = first_client ? first_client->cwcacheexgot : 1;
7207 if(cachesum < 1)
7209 cachesum = 1;
7211 tpl_printf(vars, TPLADD, "TOTAL_CACHEXPUSH", PRINTF_LOCAL_D, first_client ? first_client->cwcacheexpush : 0);
7212 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXPUSH_IMG", pushing);
7213 tpl_printf(vars, TPLADD, "TOTAL_CACHEXGOT", PRINTF_LOCAL_D, first_client ? first_client->cwcacheexgot : 0);
7214 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXGOT_IMG", getting);
7215 tpl_printf(vars, TPLADD, "TOTAL_CACHEXHIT", PRINTF_LOCAL_D, first_client ? first_client->cwcacheexhit : 0);
7216 tpl_printf(vars, TPLADD, "TOTAL_CACHESIZE", "%d", cache_size());
7218 tpl_printf(vars, TPLADD, "REL_CACHEXHIT", "%.2f", (first_client ? first_client->cwcacheexhit : 0) * 100 / cachesum);
7220 if(!apicall)
7221 { return tpl_getTpl(vars, "CACHEEXPAGE"); }
7222 else
7224 return tpl_getTpl(vars, "JSONCACHEEX");
7227 #endif
7229 static char *send_oscam_api(struct templatevars * vars, FILE * f, struct uriparams * params, int8_t *keepalive, int8_t apicall, char *extraheader)
7231 if(strcmp(getParam(params, "part"), "status") == 0)
7233 return send_oscam_status(vars, params, apicall);
7235 else if(strcmp(getParam(params, "part"), "userstats") == 0)
7237 return send_oscam_user_config(vars, params, apicall);
7239 else if(strcmp(getParam(params, "part"), "failban") == 0)
7241 return send_oscam_failban(vars, params, apicall);
7243 #ifdef CS_CACHEEX
7244 else if(strcmp(getParam(params, "part"), "cacheex") == 0)
7246 return send_oscam_cacheex(vars, params, apicall);
7248 #endif
7249 else if(strcmp(getParam(params, "part"), "files") == 0)
7251 return send_oscam_files(vars, params, apicall);
7253 else if(strcmp(getParam(params, "part"), "readerlist") == 0)
7255 return send_oscam_reader(vars, params, apicall);
7257 else if(strcmp(getParam(params, "part"), "serverconfig") == 0)
7259 //Send Errormessage
7260 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "serverconfig not yet avail");
7261 return tpl_getTpl(vars, "APIERROR");
7263 else if(strcmp(getParam(params, "part"), "userconfig") == 0)
7265 if(((strcmp(getParam(params, "action"), "Save") == 0) ||
7266 (strcmp(getParam(params, "action"), "Save As") == 0)) && cfg.http_readonly == 1)
7268 //Send Errormessage
7269 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "API is in readonly mode");
7270 return tpl_getTpl(vars, "APIERROR");
7272 else
7274 struct s_auth *account = get_account_by_name(getParam(params, "user"));
7275 if(!account && strcmp(getParam(params, "action"), "Save"))
7277 //Send Errormessage
7278 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "user not exist");
7279 return tpl_getTpl(vars, "APIERROR");
7281 else
7283 return send_oscam_user_config_edit(vars, params, apicall);
7287 else if(strcmp(getParam(params, "part"), "entitlement") == 0)
7290 if(strcmp(getParam(params, "label"), ""))
7292 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
7293 if(rdr)
7295 if(rdr->enable == 1)
7297 return send_oscam_entitlement(vars, params, apicall);
7299 else
7301 //Send Errormessage
7302 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no cccam reader or disabled");
7303 return tpl_getTpl(vars, "APIERROR");
7306 else
7308 //Send Errormessage
7309 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "reader not exist");
7310 return tpl_getTpl(vars, "APIERROR");
7313 else
7315 //Send Errormessage
7316 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no reader selected");
7317 return tpl_getTpl(vars, "APIERROR");
7320 else if(strcmp(getParam(params, "part"), "ecmhistory") == 0)
7322 int32_t i;
7323 int32_t isec;
7324 int32_t shown;
7325 time_t now = time((time_t *)0);
7326 const char *usr;
7327 struct s_client *cl;
7328 for(i = 0, cl = first_client; cl ; cl = cl->next, i++)
7330 if(cl->wihidden != 1)
7332 isec = now - cl->lastecm;
7333 usr = username(cl);
7334 shown = 0;
7335 if(strcmp(getParam(params, "label"), "") == 0)
7337 if(strcmp(getParam(params, "type"), "servers") == 0)
7339 if(cl->typ == 'p' || cl->typ == 'r')
7340 { shown = 1; }
7342 else if(strcmp(getParam(params, "type"), "users") == 0)
7344 if(cl->typ == 'c')
7345 { shown = 1; }
7347 else
7349 shown = 1;
7352 else if(strcmp(getParam(params, "label"), usr) == 0)
7354 shown = 1;
7356 if(shown == 1)
7358 tpl_printf(vars, TPLADD, "CLIENTTYPE", "%c", cl->typ);
7359 tpl_addVar(vars, TPLADD, "CLIENTUSER", xml_encode(vars, usr));
7360 if(cl->typ == 'c' || cl->typ == 'm')
7362 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", xml_encode(vars, cl->account->description ? cl->account->description : ""));
7364 else if(cl->typ == 'p' || cl->typ == 'r')
7366 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", xml_encode(vars, cl->reader->description ? cl->reader->description : ""));
7368 tpl_printf(vars, TPLADD, "CLIENTLASTRESPONSETIME", "%d", cl->cwlastresptime ? cl->cwlastresptime : -1);
7369 tpl_printf(vars, TPLADD, "CLIENTIDLESECS", "%d", isec);
7371 //load historical values from ringbuffer
7372 char *value = get_ecm_fullhistorystring(cl);
7373 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIMEHIST", value);
7374 free_mk_t(value);
7376 tpl_addVar(vars, TPLAPPEND, "APISTATUSBITS", tpl_getTpl(vars, "APISTATUSBIT"));
7380 return tpl_getTpl(vars, "APISTATUS");
7382 else if(strcmp(getParam(params, "part"), "readerstats") == 0)
7384 if(strcmp(getParam(params, "label"), ""))
7386 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
7387 if(rdr)
7389 return send_oscam_reader_stats(vars, params, apicall);
7391 else
7393 //Send Errormessage
7394 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "reader not exist");
7395 return tpl_getTpl(vars, "APIERROR");
7398 else
7400 //Send Errormessage
7401 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no reader selected");
7402 return tpl_getTpl(vars, "APIERROR");
7405 else if(strcmp(getParam(params, "part"), "shutdown") == 0)
7407 if((strcmp(strtolower(getParam(params, "action")), "restart") == 0) ||
7408 (strcmp(strtolower(getParam(params, "action")), "shutdown") == 0))
7410 if(!cfg.http_readonly)
7412 return send_oscam_shutdown(vars, f, params, apicall, keepalive, extraheader);
7414 else
7416 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "webif readonly mode");
7417 return tpl_getTpl(vars, "APIERROR");
7420 else
7422 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "missing parameter action");
7423 return tpl_getTpl(vars, "APIERROR");
7427 else
7429 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "part not found");
7430 return tpl_getTpl(vars, "APIERROR");
7434 static char *send_oscam_image(struct templatevars * vars, FILE * f, struct uriparams * params, char *image, time_t modifiedheader, uint32_t etagheader, char *extraheader)
7436 char *wanted;
7437 if(image == NULL) { wanted = getParam(params, "i"); }
7438 else { wanted = image; }
7439 if(strlen(wanted) > 3 && wanted[0] == 'I' && wanted[1] == 'C')
7441 if(etagheader == 0)
7443 int8_t disktpl = 0;
7444 char *tpl_path;
7445 tpl_path = cfg.http_piconpath? cfg.http_piconpath : cfg.http_tpl;
7447 if(tpl_path)
7449 char path[255];
7450 if(strlen(tpl_getTplPath(wanted, tpl_path, path, 255)) > 0 && file_exists(path))
7452 struct stat st;
7453 disktpl = 1;
7454 stat(path, &st);
7455 if((time_t)st.st_mtime < modifiedheader)
7457 send_header304(f, extraheader);
7458 return "1";
7462 if(disktpl == 0 && first_client->login < modifiedheader)
7464 send_header304(f, extraheader);
7465 return "1";
7468 char *header = strstr(tpl_getTpl(vars, wanted), "data:");
7469 if(header != NULL)
7471 char *ptr = header + 5;
7472 while(ptr[0] != ';' && ptr[0] != '\0') { ++ptr; }
7473 if(ptr[0] != '\0' && ptr[1] != '\0') { ptr[0] = '\0'; }
7474 else { return "0"; }
7475 ptr = strstr(ptr + 1, "base64,");
7476 if(ptr != NULL)
7478 int32_t len = b64decode((uchar *)ptr + 7);
7479 if(len > 0)
7481 if((uint32_t)crc32(0L, (uchar *)ptr + 7, len) == etagheader)
7483 send_header304(f, extraheader);
7485 else
7487 send_headers(f, 200, "OK", extraheader, header + 5, 1, len, ptr + 7, 0);
7488 webif_write_raw(ptr + 7, f, len);
7490 return "1";
7495 // Return file not found
7496 const char *not_found = "File not found.\n";
7497 send_headers(f, 404, "Not Found", extraheader, "text/plain", 0, strlen(not_found), (char *)not_found, 0);
7498 webif_write_raw((char *)not_found, f, strlen(not_found));
7499 return "1";
7502 static char *send_oscam_robots_txt(FILE * f)
7504 const char *content = "User-agent: *\nDisallow: /\n";
7505 send_headers(f, 200, "OK", NULL, "text/plain", 0, strlen(content), (char *)content, 0);
7506 webif_write_raw((char *)content, f, strlen(content));
7507 return "1";
7510 static char *send_oscam_graph(struct templatevars * vars)
7512 return tpl_getTpl(vars, "GRAPH");
7515 #ifdef MODULE_GHTTP
7516 static bool ghttp_autoconf(struct templatevars * vars, struct uriparams * params)
7518 int8_t i = 0;
7519 struct s_reader *rdr;
7520 char *name = getParam(params, "gacname");
7521 if(strlen(name) < 3)
7523 tpl_addMsg(vars, "Invalid host name!");
7524 return false;
7527 LL_ITER itr = ll_iter_create(configured_readers);
7528 while((rdr = ll_iter_next(&itr)))
7529 if(rdr->ph.num == R_GHTTP) { i++; } // count existing ghttp readers
7531 while(i < 3) // if less than 3, add more
7533 char lbl[128];
7534 snprintf(lbl, sizeof(lbl), "%s%d", "ghttp", i + 1);
7535 cs_log("GHttp autoconf: adding reader %s", lbl);
7536 struct s_reader *newrdr;
7537 if(!cs_malloc(&newrdr, sizeof(struct s_reader)))
7539 tpl_addMsg(vars, "Create reader failed!");
7540 return false;
7542 newrdr->typ = R_GHTTP;
7543 cs_strncpy(newrdr->label, lbl, sizeof(newrdr->label));
7544 module_reader_set(newrdr);
7545 reader_set_defaults(newrdr);
7546 newrdr->enable = 0;
7547 newrdr->grp = 1;
7548 ll_append(configured_readers, newrdr);
7549 i++;
7552 uint16_t port = 0;
7553 char *str = strstr(name, ":");
7554 if(str)
7556 port = atoi(str + 1);
7557 str[0] = '\0';
7560 i = 0;
7561 itr = ll_iter_create(configured_readers);
7562 while((rdr = ll_iter_next(&itr)))
7564 if(rdr->ph.num == R_GHTTP)
7566 if(i > 2) // remove superflous
7568 cs_log("GHttp autoconf: removing reader %s", rdr->label);
7569 inactivate_reader(rdr);
7570 ll_iter_remove(&itr);
7571 free_reader(rdr);
7573 else // reconfigure the 3 first ghttp readers
7575 cs_log("GHttp autoconf: reconfiguring reader %s", rdr->label);
7576 snprintf(rdr->label, sizeof(rdr->label), "%s%d", "ghttp", i + 1);
7577 rdr->r_port = port;
7578 rdr->enable = 1;
7579 rdr->ghttp_use_ssl = 0;
7580 #ifdef WITH_SSL
7581 rdr->ghttp_use_ssl = 1;
7582 #endif
7583 if(rdr->grp < 1) { rdr->grp = 1; }
7584 cs_strncpy(rdr->r_usr, getParam(params, "gacuser"), sizeof(rdr->r_usr));
7585 cs_strncpy(rdr->r_pwd, getParam(params, "gacpasswd"), sizeof(rdr->r_pwd));
7586 if(i == 0) { cs_strncpy(rdr->device, name, sizeof(rdr->device)); }
7587 else
7589 if(!strstr(name, "."))
7590 { snprintf(rdr->device, sizeof(rdr->device), "%s%d", name, i); } // name, name1, name2
7591 else { cs_strncpy(rdr->device, name, sizeof(rdr->device)); }
7592 // . in the name = assume full hostname = use same for all 3 readers
7594 if(i == 2) { rdr->fallback = 1; }
7595 else { rdr->fallback = 0; }
7596 i++;
7600 cs_log("GHttp autoconf: Saving %d readers", i);
7601 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
7602 itr = ll_iter_create(configured_readers);
7603 while((rdr = ll_iter_next(&itr)))
7605 if(rdr->ph.num == R_GHTTP)
7606 { restart_cardreader(rdr, 1); }
7608 return true;
7611 static char *send_oscam_ghttp(struct templatevars * vars, struct uriparams * params, int8_t apicall)
7613 if(strcmp(strtolower(getParam(params, "action")), "autoconf") == 0)
7615 if(!apicall)
7617 bool missing = false;
7618 if(strlen(getParam(params, "gacuser")) == 0)
7620 tpl_addVar(vars, TPLADD, "USERREQ", "<FONT COLOR='red'>(Required)</FONT>");
7621 missing = true;
7623 else { tpl_addVar(vars, TPLADD, "GACUSER", getParam(params, "gacuser")); }
7624 if(strlen(getParam(params, "gacpasswd")) == 0)
7626 tpl_addVar(vars, TPLADD, "PWDREQ", "<FONT COLOR='red'>(Required)</FONT>");
7627 missing = true;
7629 else { tpl_addVar(vars, TPLADD, "GACPASSWD", getParam(params, "gacpasswd")); }
7630 if(strlen(getParam(params, "gacname")) == 0)
7632 tpl_addVar(vars, TPLADD, "NAMEREQ", "<FONT COLOR='red'>(Required)</FONT>");
7633 missing = true;
7635 else { tpl_addVar(vars, TPLADD, "GACNAME", getParam(params, "gacname")); }
7636 if(missing) { return tpl_getTpl(vars, "PREAUTOCONF"); }
7637 cs_log("GHttp autoconf requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
7639 else
7641 tpl_addVar(vars, TPLADD, "APICONFIRMMESSAGE", "autoconf");
7642 cs_log("GHttp autoconf requested by XMLApi from %s", cs_inet_ntoa(GET_IP()));
7645 if(ghttp_autoconf(vars, params))
7647 tpl_printf(vars, TPLADD, "REFRESHTIME", "%d", 3);
7648 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
7649 tpl_printf(vars, TPLADD, "SECONDS", "%d", 3);
7650 if(apicall) { return tpl_getTpl(vars, "APICONFIRMATION"); }
7651 else { return tpl_getTpl(vars, "AUTOCONF"); }
7653 else { return tpl_getTpl(vars, "PREAUTOCONF"); } // something failed
7656 else
7658 if(strlen(getParam(params, "token")) > 0) // parse autoconf token
7660 char *token = getParam(params, "token");
7661 int32_t len = b64decode((uchar *)token);
7662 if(len > 0)
7664 struct uriparams tokenprms;
7665 tokenprms.paramcount = 0;
7666 parseParams(&tokenprms, token);
7667 if(strlen(getParam(&tokenprms, "u")) > 0)
7669 tpl_addVar(vars, TPLADD, "GACUSER", getParam(&tokenprms, "u"));
7670 tpl_addVar(vars, TPLADD, "USERRDONLY", "readonly");
7672 if(strlen(getParam(&tokenprms, "p")) > 0)
7674 tpl_addVar(vars, TPLADD, "GACPASSWD", getParam(&tokenprms, "p"));
7675 tpl_addVar(vars, TPLADD, "PWDRDONLY", "readonly");
7677 if(strlen(getParam(&tokenprms, "n")) > 0)
7679 tpl_addVar(vars, TPLADD, "GACNAME", getParam(&tokenprms, "n"));
7680 tpl_addVar(vars, TPLADD, "NAMERDONLY", "readonly");
7684 return tpl_getTpl(vars, "PREAUTOCONF");
7687 #endif
7689 static int8_t check_httpip(IN_ADDR_T addr)
7691 int8_t i = 0;
7692 // check all previously dyndns resolved addresses
7693 for(i = 0; i < MAX_HTTP_DYNDNS; i++)
7695 if(IP_ISSET(cfg.http_dynip[i]) && IP_EQUAL(cfg.http_dynip[i], addr))
7696 { return 1; }
7698 return 0;
7701 static int8_t check_httpdyndns(IN_ADDR_T addr)
7704 // check all previously dyndns resolved addresses
7705 if(check_httpip(addr))
7706 { return 1; }
7708 // we are not ok, so resolve all dyndns entries into IP's - maybe outdated IP's
7710 if(cfg.http_dyndns[0][0])
7712 int8_t i = 0;
7713 for(i = 0; i < MAX_HTTP_DYNDNS; i++)
7715 if(cfg.http_dyndns[i][0])
7717 cs_resolve((const char *)cfg.http_dyndns[i], &cfg.http_dynip[i], NULL, NULL);
7718 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]));
7722 else
7724 cs_log_dbg(D_TRACE, "WebIf: No dyndns addresses found");
7725 return 0;
7728 // again check all dyndns resolved addresses
7729 if(check_httpip(addr))
7730 { return 1; }
7732 return 0;
7735 static int8_t check_valid_origin(IN_ADDR_T addr)
7738 // check whether requesting IP is in allowed IP ranges
7739 if(check_ip(cfg.http_allowed, addr))
7740 { return 1; }
7742 // we havn't found the requesting IP in allowed range. So we check for allowed httpdyndns as last chance
7743 if(cfg.http_dyndns[0][0])
7745 int8_t ok;
7746 ok = check_httpdyndns(addr);
7747 return ok;
7749 return 0;
7752 static int8_t check_request(char *result, int32_t readen)
7754 if(readen < 50) { return 0; }
7755 result[readen] = '\0';
7756 int8_t method;
7757 if(strncmp(result, "POST", 4) == 0) { method = 1; }
7758 else { method = 0; }
7759 char *headerEnd = strstr(result, "\r\n\r\n");
7760 if(headerEnd == NULL) { return 0; }
7761 else if(method == 0) { return 1; }
7762 else
7764 char *ptr = strstr(result, "Content-Length: ");
7765 if(ptr != NULL)
7767 ptr += 16;
7768 if(ptr < result + readen)
7770 uint32_t length = atoi(ptr);
7771 if(strlen(headerEnd + 4) >= length) { return 1; }
7775 return 0;
7778 static int32_t readRequest(FILE * f, IN_ADDR_T in, char **result, int8_t forcePlain)
7780 int32_t n, bufsize = 0, errcount = 0;
7781 char buf2[1024];
7782 struct pollfd pfd2[1];
7783 #ifdef WITH_SSL
7784 int8_t is_ssl = 0;
7785 if(ssl_active && !forcePlain)
7786 { is_ssl = 1; }
7787 #endif
7789 while(1)
7791 errno = 0;
7792 if(forcePlain)
7793 { n = read(fileno(f), buf2, sizeof(buf2)); }
7794 else
7795 { n = webif_read(buf2, sizeof(buf2), f); }
7796 if(n <= 0)
7798 if((errno == 0 || errno == EINTR))
7800 if(errcount++ < 10)
7802 cs_sleepms(5);
7803 continue;
7805 else { return -1; }
7807 #ifdef WITH_SSL
7808 if(is_ssl)
7810 if(errno != ECONNRESET)
7812 int32_t errcode = ERR_peek_error();
7813 char errstring[128];
7814 ERR_error_string_n(errcode, errstring, sizeof(errstring) - 1);
7815 cs_log_dbg(D_TRACE, "WebIf: read error ret=%d (%d%s%s)", n, SSL_get_error(cur_ssl(), n), errcode ? " " : "", errcode ? errstring : "");
7817 return -1;
7819 #else
7820 if(errno != ECONNRESET)
7821 { cs_log_dbg(D_TRACE, "WebIf: read error ret=%d (errno=%d %s)", n, errno, strerror(errno)); }
7822 #endif
7823 return -1;
7825 if(!cs_realloc(result, bufsize + n + 1))
7827 send_error500(f);
7828 NULLFREE(*result);
7829 return -1;
7832 memcpy(*result + bufsize, buf2, n);
7833 bufsize += n;
7835 //max request size 100kb
7836 if(bufsize > 102400)
7838 cs_log("error: too much data received from %s", cs_inet_ntoa(in));
7839 NULLFREE(*result);
7840 *result = NULL;
7841 return -1;
7844 #ifdef WITH_SSL
7845 if(ssl_active && !forcePlain)
7847 int32_t len = 0;
7848 len = SSL_pending((SSL *)f);
7850 if(len > 0)
7851 { continue; }
7853 pfd2[0].fd = SSL_get_fd((SSL *)f);
7856 else
7857 #endif
7858 pfd2[0].fd = fileno(f);
7860 pfd2[0].events = (POLLIN | POLLPRI);
7862 int32_t rc = poll(pfd2, 1, 100);
7863 if(rc > 0 || !check_request(*result, bufsize))
7864 { continue; }
7865 else
7866 { break; }
7868 return bufsize;
7870 static int32_t process_request(FILE * f, IN_ADDR_T in)
7872 int32_t ok = 0;
7873 int8_t *keepalive = (int8_t *)pthread_getspecific(getkeepalive);
7874 IN_ADDR_T addr = GET_IP();
7878 #ifdef WITH_SSL
7879 if(!ssl_active && *keepalive) { fflush(f); }
7880 #else
7881 if(*keepalive) { fflush(f); }
7882 #endif
7884 // at this point we do all checks related origin IP, ranges and dyndns stuff
7885 ok = check_valid_origin(addr);
7886 cs_log_dbg(D_TRACE, "WebIf: Origin checked. Result: access from %s => %s", cs_inet_ntoa(addr), (!ok) ? "forbidden" : "allowed");
7888 // based on the failed origin checks we send a 403 to calling browser
7889 if(!ok)
7891 send_error(f, 403, "Forbidden", NULL, "Access denied.", 0);
7892 cs_log("unauthorized access from %s - invalid ip or dyndns", cs_inet_ntoa(addr));
7893 return 0;
7895 int32_t authok = 0;
7896 char expectednonce[(MD5_DIGEST_LENGTH * 2) + 1], opaque[(MD5_DIGEST_LENGTH * 2) + 1];
7897 char authheadertmp[sizeof(AUTHREALM) + sizeof(expectednonce) + sizeof(opaque) + 100];
7899 char *method, *path, *protocol, *str1, *saveptr1 = NULL, *authheader = NULL, *extraheader = NULL, *filebuf = NULL;
7900 char *pch, *tmp, *buf, *nameInUrl, subdir[32];
7901 /* List of possible pages */
7902 char *pages[] =
7904 "/config.html",
7905 "/readers.html",
7906 "/entitlements.html",
7907 "/status.html",
7908 "/userconfig.html",
7909 "/readerconfig.html",
7910 "/services.html",
7911 "/user_edit.html",
7912 "/site.css",
7913 "/services_edit.html",
7914 "/savetemplates.html",
7915 "/shutdown.html",
7916 "/script.html",
7917 "/scanusb.html",
7918 "/files.html",
7919 "/readerstats.html",
7920 "/failban.html",
7921 "/oscam.js",
7922 "/oscamapi.html",
7923 "/image",
7924 "/favicon.ico",
7925 "/graph.svg",
7926 "/oscamapi.xml",
7927 "/cacheex.html",
7928 "/oscamapi.json",
7929 "/emm.html",
7930 "/emm_running.html",
7931 "/robots.txt",
7932 "/ghttp.html",
7933 "/logpoll.html",
7934 "/jquery.js",
7937 int32_t pagescnt = sizeof(pages) / sizeof(char *); // Calculate the amount of items in array
7938 int32_t i, bufsize, len, pgidx = -1;
7939 uint32_t etagheader = 0;
7940 struct uriparams params;
7941 params.paramcount = 0;
7942 time_t modifiedheader = 0;
7944 bufsize = readRequest(f, in, &filebuf, 0);
7946 if(!filebuf || bufsize < 1)
7948 if(!*keepalive) { cs_log_dbg(D_CLIENT, "WebIf: No data received from client %s. Closing connection.", cs_inet_ntoa(addr)); }
7949 return -1;
7952 buf = filebuf;
7954 if((method = strtok_r(buf, " ", &saveptr1)) != NULL)
7956 if((path = strtok_r(NULL, " ", &saveptr1)) != NULL)
7958 if((protocol = strtok_r(NULL, "\r", &saveptr1)) == NULL)
7960 NULLFREE(filebuf);
7961 return -1;
7964 else
7966 NULLFREE(filebuf);
7967 return -1;
7970 else
7972 NULLFREE(filebuf);
7973 return -1;
7975 tmp = protocol + strlen(protocol) + 2;
7977 pch = path;
7978 /* advance pointer to beginning of query string */
7979 while(pch[0] != '?' && pch[0] != '\0') { ++pch; }
7980 if(pch[0] == '?')
7982 pch[0] = '\0';
7983 ++pch;
7986 nameInUrl = pch - 1;
7987 while(nameInUrl != path && nameInUrl[0] != '/') { --nameInUrl; }
7989 /* allow only alphanumeric sub-folders */
7990 int32_t subdirLen = nameInUrl - path;
7991 subdir[0] = '\0';
7992 if(subdirLen > 0 && subdirLen < 32)
7994 cs_strncpy(subdir, path + 1, subdirLen);
7996 int32_t invalidSubdir = 0;
7997 for(i = 0; i < subdirLen - 1; i++)
7999 if(!((subdir[i] >= '0' && subdir[i] <= '9')
8000 || (subdir[i] >= 'a' && subdir[i] <= 'z')
8001 || (subdir[i] >= 'A' && subdir[i] <= 'Z')))
8004 invalidSubdir = 1;
8005 subdir[0] = '\0';
8006 break;
8010 if(!invalidSubdir)
8012 subdir[subdirLen] = '\0';
8013 #ifdef WIN32
8014 subdir[subdirLen - 1] = '\\';
8015 #else
8016 subdir[subdirLen - 1] = '/';
8017 #endif
8021 /* Map page to our static page definitions */
8022 for(i = 0; i < pagescnt; i++)
8024 if(!strcmp(nameInUrl, pages[i])) { pgidx = i; }
8027 parseParams(&params, pch);
8029 if(!cfg.http_user || !cfg.http_pwd)
8030 { authok = 1; }
8032 for(str1 = strtok_r(tmp, "\n", &saveptr1); str1; str1 = strtok_r(NULL, "\n", &saveptr1))
8034 len = strlen(str1);
8035 if(str1[len - 1] == '\r')
8037 str1[len - 1] = '\0';
8038 --len;
8040 if(len == 0)
8042 if(strcmp(method, "POST") == 0)
8044 parseParams(&params, str1 + 2);
8046 break;
8048 if(!authok && len > 50 && strncasecmp(str1, "Authorization:", 14) == 0 && strstr(str1, "Digest") != NULL)
8050 if(cs_dblevel & D_CLIENT)
8052 if(cs_realloc(&authheader, len + 1))
8053 { cs_strncpy(authheader, str1, len); }
8055 authok = check_auth(str1, method, path, addr, expectednonce, opaque);
8057 else if(len > 40 && strncasecmp(str1, "If-Modified-Since:", 18) == 0)
8059 modifiedheader = parse_modifiedsince(str1);
8061 else if(len > 20 && strncasecmp(str1, "If-None-Match:", 14) == 0)
8063 for(pch = str1 + 14; pch[0] != '"' && pch[0] != '\0'; ++pch) { ; }
8064 if(strlen(pch) > 5) { etagheader = (uint32_t)strtoul(++pch, NULL, 10); }
8066 else if(len > 12 && strncasecmp(str1, "Connection: Keep-Alive", 22) == 0 && strcmp(method, "POST"))
8068 *keepalive = 1;
8072 if(cfg.http_user && cfg.http_pwd)
8074 if(!authok || strlen(opaque) != MD5_DIGEST_LENGTH * 2) { calculate_opaque(addr, opaque); }
8075 if(authok != 2)
8077 if(!authok)
8079 if(authheader)
8081 cs_log_dbg(D_CLIENT, "WebIf: Received wrong auth header from %s:", cs_inet_ntoa(addr));
8082 cs_log_dbg(D_CLIENT, "%s", authheader);
8084 else
8085 { cs_log_dbg(D_CLIENT, "WebIf: Received no auth header from %s.", cs_inet_ntoa(addr)); }
8087 calculate_nonce(NULL, expectednonce, opaque);
8089 if(authok != 1)
8091 snprintf(authheadertmp, sizeof(authheadertmp), "WWW-Authenticate: Digest algorithm=\"MD5\", realm=\"%s\", qop=\"auth\", opaque=\"%s\", nonce=\"%s\"", AUTHREALM, opaque, expectednonce);
8092 if(authok == 2) { strncat(authheadertmp, ", stale=true", sizeof(authheadertmp) - strlen(authheadertmp) - 1); }
8094 else
8095 { snprintf(authheadertmp, sizeof(authheadertmp), "Authentication-Info: nextnonce=\"%s\"", expectednonce); }
8096 extraheader = authheadertmp;
8097 if(authok != 1)
8099 char *msg = "Access denied.\n";
8100 send_headers(f, 401, "Unauthorized", extraheader, "text/html", 0, strlen(msg), msg, 0);
8101 webif_write(msg, f);
8102 NULLFREE(authheader);
8103 NULLFREE(filebuf);
8104 if(*keepalive) { continue; }
8105 else { return 0; }
8108 else { NULLFREE(authheader); }
8110 /*build page*/
8111 if(pgidx == 8)
8113 send_file(f, "CSS", subdir, modifiedheader, etagheader, extraheader);
8115 else if(pgidx == 17)
8117 send_file(f, "JS", subdir, modifiedheader, etagheader, extraheader);
8119 else if(pgidx == 30)
8121 send_file(f, "JQ", subdir, modifiedheader, etagheader, extraheader);
8123 else
8125 time_t t;
8126 struct templatevars *vars = tpl_create();
8127 if(vars == NULL)
8129 send_error500(f);
8130 NULLFREE(filebuf);
8131 return 0;
8134 tpl_addVar(vars, TPLADD, "SUBDIR", subdir);
8136 struct tm lt, st;
8137 time(&t);
8139 localtime_r(&t, &lt);
8141 tpl_addVar(vars, TPLADD, "CS_VERSION", CS_VERSION);
8142 tpl_addVar(vars, TPLADD, "CS_SVN_VERSION", CS_SVN_VERSION);
8143 tpl_addVar(vars, TPLADD, "CS_TARGET", CS_TARGET);
8144 tpl_addVar(vars, TPLADD, "HTTPOSCAMLABEL", xml_encode(vars,cfg.http_oscam_label));
8145 if (!boxtype_is("generic"))
8147 if (!boxname_is("generic"))
8148 tpl_printf(vars, TPLADD, "DETECTED_BOXTYPE", "%s (%s)", boxtype_get(), boxname_get());
8149 else
8150 tpl_addVar(vars, TPLADD, "DETECTED_BOXTYPE", boxtype_get());
8153 if(cfg.http_locale){
8154 float decimal_point = 0.0;
8155 setlocale(LC_ALL, cfg.http_locale);
8156 tpl_printf(vars, TPLADD, "TMP_DECPOINT", "%.1f", decimal_point);
8157 tpl_addVar(vars, TPLADD, "LOCALE_DECPOINT", strstr(tpl_getVar(vars, "TMP_DECPOINT"), ",") ? ",": ".");
8160 tpl_addVar(vars, TPLADD, "HTTP_CHARSET", cs_http_use_utf8 ? "UTF-8" : "ISO-8859-1");
8161 if(cfg.http_picon_size > 0)
8163 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);
8165 if(cfg.poll_refresh > 0)
8167 tpl_printf(vars, TPLADD, "POLLREFRESHTIME", "%d", cfg.poll_refresh);
8169 if ( cfg.http_refresh > 0 &&
8170 ((( pgidx == 1 || pgidx == 4 ) && !cfg.poll_refresh ) ||
8171 ( pgidx == 3 && ( cfg.http_status_log || !cfg.poll_refresh )) ||
8172 pgidx == 15 || pgidx == 23 || pgidx == -1 )) // wenn polling bei cachex.html eingeführt wird muss die 23 => 2 zeilen höher
8174 tpl_printf(vars, TPLADD, "REFRESHTIME", "%d", cfg.http_refresh);
8175 tpl_addVar(vars, TPLADD, "WITHQUERY", pgidx == 15 ? "1" : "0");
8176 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
8178 #ifdef WEBIF_JQUERY
8179 tpl_printf(vars, TPLADD, "SRCJQUERY", "jquery.js?v=%s", CS_SVN_VERSION);
8180 #else
8181 tpl_addVar(vars, TPLADD, "SRCJQUERY", cfg.http_extern_jquery);
8182 #endif
8184 if(picon_exists("LOGO")||strlen(tpl_getTpl(vars, "IC_LOGO"))>3)
8186 tpl_addVar(vars, TPLADD, "LOGO_INS", tpl_getTpl(vars, "LOGOBITIMG"));
8188 else
8190 tpl_addVar(vars, TPLADD, "LOGO_INS", tpl_getTpl(vars, "LOGOBITSVG"));
8192 tpl_addVar(vars, TPLADD, "LOGO", tpl_getTpl(vars, "LOGOBIT"));
8193 tpl_printf(vars, TPLADD, "CURDATE", "%02d.%02d.%02d", lt.tm_mday, lt.tm_mon + 1, lt.tm_year % 100);
8194 tpl_printf(vars, TPLADD, "CURTIME", "%02d:%02d:%02d", lt.tm_hour, lt.tm_min, lt.tm_sec);
8195 localtime_r(&first_client->login, &st);
8196 tpl_printf(vars, TPLADD, "STARTDATE", "%02d.%02d.%02d", st.tm_mday, st.tm_mon + 1, st.tm_year % 100);
8197 tpl_printf(vars, TPLADD, "STARTTIME", "%02d:%02d:%02d", st.tm_hour, st.tm_min, st.tm_sec);
8198 tpl_printf(vars, TPLADD, "PROCESSID", "%d", getppid());
8199 tpl_addVar(vars, TPLADD, "RUNAS", urlencode(vars, username(first_client)));
8201 time_t now = time((time_t *)0);
8202 // XMLAPI
8203 if(pgidx == 18 || pgidx == 22 || pgidx == 24)
8205 char tbuffer [30];
8206 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &st);
8207 tpl_addVar(vars, TPLADD, "APISTARTTIME", tbuffer);
8208 tpl_printf(vars, TPLADD, "APIRUNTIME", "%ld", now - first_client->login);
8209 tpl_printf(vars, TPLADD, "APIREADONLY", "%d", cfg.http_readonly);
8210 if(strcmp(getParam(&params, "callback"), ""))
8212 tpl_printf(vars, TPLADD, "CALLBACK", "%s%s", getParam(&params, "callback"), "(");
8213 tpl_addVar(vars, TPLADD, "ENDBRACKET", ")");
8218 if (config_enabled(WITH_LB))
8219 tpl_addVar(vars, TPLADD, "LBISDEFINED", "1");
8221 // language code in helplink
8222 tpl_addVar(vars, TPLADD, "LANGUAGE", cfg.http_help_lang);
8223 tpl_addVar(vars, TPLADD, "RUNTIME", sec2timeformat(vars, (now - first_client->login)));
8224 time_t uptime = oscam_get_uptime();
8225 if(uptime > 0){
8226 tpl_printf(vars, TPLADD, "UPTIMETXT", "%s Up Time: ", strcmp(tpl_getVar(vars, "DETECTED_BOXTYPE"),"")==0 ? "System" : tpl_getVar(vars, "DETECTED_BOXTYPE"));
8227 tpl_addVar(vars, TPLADD, "UPTIME", sec2timeformat(vars, uptime));
8229 tpl_addVar(vars, TPLADD, "CURIP", cs_inet_ntoa(addr));
8230 if(cfg.http_readonly)
8231 { tpl_addVar(vars, TPLAPPEND, "BTNDISABLED", "DISABLED"); }
8233 i = ll_count(cfg.v_list);
8234 if(i > 0) { tpl_printf(vars, TPLADD, "FAILBANNOTIFIER", "<SPAN CLASS=\"span_notifier\">%d</SPAN>", i); }
8235 tpl_printf(vars, TPLADD, "FAILBANNOTIFIERPOLL", "%d", i);
8237 char *result = NULL;
8239 // WebIf allows modifying many things. Thus, all pages except images/css/static are expected to be non-threadsafe!
8240 if(pgidx != 19 && pgidx != 20 && pgidx != 21 && pgidx != 27) { cs_writelock(__func__, &http_lock); }
8241 switch(pgidx)
8243 case 0:
8244 tpl_addVar(vars, TPLADD, "CONFIG_CONTENT", send_oscam_config(vars, &params));
8245 result = tpl_getTpl(vars, "CONFIGCONTENT");
8246 break;
8247 case 1:
8248 result = send_oscam_reader(vars, &params, 0);
8249 break;
8250 case 2:
8251 result = send_oscam_entitlement(vars, &params, 0);
8252 break;
8253 case 3:
8254 result = send_oscam_status(vars, &params, 0);
8255 break;
8256 case 4:
8257 result = send_oscam_user_config(vars, &params, 0);
8258 break;
8259 case 5:
8260 result = send_oscam_reader_config(vars, &params);
8261 break;
8262 case 6:
8263 result = send_oscam_services(vars, &params);
8264 break;
8265 case 7:
8266 result = send_oscam_user_config_edit(vars, &params, 0);
8267 break;
8268 //case 8: css file
8269 case 9:
8270 result = send_oscam_services_edit(vars, &params);
8271 break;
8272 case 10:
8273 result = send_oscam_savetpls(vars);
8274 break;
8275 case 11:
8276 result = send_oscam_shutdown(vars, f, &params, 0, keepalive, extraheader);
8277 break;
8278 case 12:
8279 result = send_oscam_script(vars, &params);
8280 break;
8281 case 13:
8282 result = send_oscam_scanusb(vars);
8283 break;
8284 case 14:
8285 result = send_oscam_files(vars, &params, 0);
8286 break;
8287 case 15:
8288 result = send_oscam_reader_stats(vars, &params, 0);
8289 break;
8290 case 16:
8291 result = send_oscam_failban(vars, &params, 0);
8292 break;
8293 //case 17: js file
8294 case 18:
8295 result = send_oscam_api(vars, f, &params, keepalive, 1, extraheader);
8296 break; //oscamapi.html
8297 case 19:
8298 result = send_oscam_image(vars, f, &params, NULL, modifiedheader, etagheader, extraheader);
8299 break;
8300 case 20:
8301 result = send_oscam_image(vars, f, &params, "ICMAI", modifiedheader, etagheader, extraheader);
8302 break;
8303 case 21:
8304 result = send_oscam_graph(vars);
8305 break;
8306 case 22:
8307 result = send_oscam_api(vars, f, &params, keepalive, 1, extraheader);
8308 break; //oscamapi.xml
8309 #ifdef CS_CACHEEX
8310 case 23:
8311 result = send_oscam_cacheex(vars, &params, 0);
8312 break;
8313 #endif
8314 case 24:
8315 result = send_oscam_api(vars, f, &params, keepalive, 2, extraheader);
8316 break; //oscamapi.json
8317 case 25:
8318 result = send_oscam_EMM(vars, &params);
8319 break; //emm.html
8320 case 26:
8321 result = send_oscam_EMM_running(vars, &params);
8322 break; //emm_running.html
8323 case 27:
8324 result = send_oscam_robots_txt(f);
8325 break; //robots.txt
8326 #ifdef MODULE_GHTTP
8327 case 28:
8328 result = send_oscam_ghttp(vars, &params, 0);
8329 break;
8330 #endif
8331 #ifdef WEBIF_LIVELOG
8332 case 29:
8333 result = send_oscam_logpoll(vars, &params);
8334 break;
8335 //case 30: jquery.js
8336 #endif
8337 default:
8338 result = send_oscam_status(vars, &params, 0);
8339 break;
8341 if(pgidx != 19 && pgidx != 20 && pgidx != 21 && pgidx != 27) { cs_writeunlock(__func__, &http_lock); }
8343 if(result == NULL || !strcmp(result, "0") || strlen(result) == 0) { send_error500(f); }
8344 else if(strcmp(result, "1"))
8346 //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
8347 if(pgidx == 18)
8348 { send_headers(f, 200, "OK", extraheader, "text/xml", 0, strlen(result), NULL, 0); }
8349 else if(pgidx == 21)
8350 { send_headers(f, 200, "OK", extraheader, "image/svg+xml", 0, strlen(result), NULL, 0); }
8351 else if(pgidx == 24)
8352 { send_headers(f, 200, "OK", extraheader, "text/javascript", 0, strlen(result), NULL, 0); }
8353 else
8354 { send_headers(f, 200, "OK", extraheader, "text/html", 0, strlen(result), NULL, 0); }
8355 webif_write(result, f);
8357 tpl_clear(vars);
8359 NULLFREE(filebuf);
8361 while(*keepalive == 1 && !exit_oscam);
8362 return 0;
8365 static void *serve_process(void *conn)
8367 struct s_connection *myconn = (struct s_connection *)conn;
8368 int32_t s = myconn->socket;
8369 struct s_client *cl = myconn->cl;
8370 IN_ADDR_T in;
8371 IP_ASSIGN(in, myconn->remote);
8373 set_thread_name(__func__);
8375 #ifdef WITH_SSL
8376 SSL *ssl = myconn->ssl;
8377 SAFE_SETSPECIFIC(getssl, ssl);
8378 #endif
8379 NULLFREE(myconn);
8381 SAFE_SETSPECIFIC(getip, &in);
8382 SAFE_SETSPECIFIC(getclient, cl);
8384 int8_t keepalive = 0;
8385 SAFE_SETSPECIFIC(getkeepalive, &keepalive);
8387 #ifdef WITH_SSL
8388 if(ssl_active)
8390 if(SSL_set_fd(ssl, s))
8392 int32_t ok = (SSL_accept(ssl) != -1);
8393 if(!ok)
8395 int8_t tries = 100;
8396 while(!ok && tries--)
8398 int32_t err = SSL_get_error(ssl, -1);
8399 if(err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
8400 { break; }
8401 else
8403 struct pollfd pfd;
8404 pfd.fd = s;
8405 pfd.events = POLLIN | POLLPRI;
8406 int32_t rc = poll(&pfd, 1, -1);
8407 if(rc < 0)
8409 if(errno == EINTR || errno == EAGAIN) { continue; }
8410 break;
8412 if(rc == 1)
8413 { ok = (SSL_accept(ssl) != -1); }
8417 if(ok)
8419 process_request((FILE *)ssl, in);
8421 else
8423 FILE *f;
8424 f = fdopen(s, "r+");
8425 if(f != NULL)
8427 char *ptr, *filebuf = NULL, *host = NULL;
8428 int32_t bufsize = readRequest(f, in, &filebuf, 1);
8430 if(filebuf)
8432 filebuf[bufsize] = '\0';
8433 host = strstr(filebuf, "Host: ");
8434 if(host)
8436 host += 6;
8437 ptr = strchr(host, '\r');
8438 if(ptr) { ptr[0] = '\0'; }
8441 if(host)
8443 char extra[strlen(host) + 20];
8444 snprintf(extra, sizeof(extra), "Location: https://%s", host);
8445 send_error(f, 301, "Moved Permanently", extra, "This web server is running in SSL mode.", 1);
8447 else
8448 { send_error(f, 200, "Bad Request", NULL, "This web server is running in SSL mode.", 1); }
8449 fflush(f);
8450 fclose(f);
8451 NULLFREE(filebuf);
8453 else
8455 cs_log_dbg(D_TRACE, "WebIf: fdopen(%d) failed. (errno=%d %s)", s, errno, strerror(errno));
8459 else { cs_log("WebIf: Error calling SSL_set_fd()."); }
8460 SSL_shutdown(ssl);
8461 close(s);
8462 SSL_free(ssl);
8464 else
8465 #endif
8467 FILE *f;
8468 f = fdopen(s, "r+");
8469 if(f != NULL)
8471 process_request(f, in);
8472 fflush(f);
8473 fclose(f);
8475 else
8477 cs_log_dbg(D_TRACE, "WebIf: fdopen(%d) failed. (errno=%d %s)", s, errno, strerror(errno));
8479 shutdown(s, SHUT_WR);
8480 close(s);
8483 return NULL;
8486 /* Creates a random string with specified length. Note that dst must be one larger than size to hold the trailing \0*/
8487 static void create_rand_str(char *dst, int32_t size)
8489 int32_t i;
8490 for(i = 0; i < size; ++i)
8492 dst[i] = (rand() % 94) + 32;
8494 dst[i] = '\0';
8497 static void *http_server(void *UNUSED(d))
8499 struct s_client *cl = create_client(first_client->ip);
8500 if(cl == NULL) { return NULL; }
8501 SAFE_SETSPECIFIC(getclient, cl);
8502 cl->typ = 'h';
8503 int32_t s, reuse = 1;
8504 struct s_connection *conn;
8506 set_thread_name(__func__);
8508 /* Create random string for nonce value generation */
8509 create_rand_str(noncekey, 32);
8511 /* Prepare base64 decoding array */
8512 b64prepare();
8513 webif_tpls_prepare();
8515 tpl_checkDiskRevisions();
8517 cs_lock_create(__func__, &http_lock, "http_lock", 10000);
8518 init_noncelocks();
8520 memset(&p_stat_cur, 0x0, sizeof(p_stat_cur));
8522 if(pthread_key_create(&getip, NULL))
8524 cs_log("Could not create getip");
8525 return NULL;
8527 if(pthread_key_create(&getkeepalive, NULL))
8529 cs_log("Could not create getkeepalive");
8530 return NULL;
8533 struct SOCKADDR sin;
8534 socklen_t len = 0;
8535 memset(&sin, 0, sizeof(sin));
8537 bool do_ipv6 = config_enabled(IPV6SUPPORT);
8538 #ifdef IPV6SUPPORT
8539 if(do_ipv6)
8541 len = sizeof(struct sockaddr_in6);
8542 if((sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0)
8544 cs_log("HTTP Server: ERROR: Creating IPv6 socket failed! (errno=%d %s)", errno, strerror(errno));
8545 cs_log("HTTP Server: Falling back to IPv4.");
8546 do_ipv6 = false;
8548 else
8550 struct sockaddr_in6 *ia = (struct sockaddr_in6 *)&sin;
8551 ia->sin6_family = AF_INET6;
8552 ia->sin6_addr = in6addr_any;
8553 ia->sin6_port = htons(cfg.http_port);
8556 #endif
8557 if(!do_ipv6)
8559 len = sizeof(struct sockaddr_in);
8560 if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
8562 cs_log("HTTP Server: ERROR: Creating socket failed! (errno=%d %s)", errno, strerror(errno));
8563 return NULL;
8565 SIN_GET_FAMILY(sin) = AF_INET;
8566 if(IP_ISSET(cfg.http_srvip))
8567 { IP_ASSIGN(SIN_GET_ADDR(sin), cfg.http_srvip); }
8568 else if(IP_ISSET(cfg.srvip))
8569 { IP_ASSIGN(SIN_GET_ADDR(sin), cfg.srvip); }
8570 // The default is INADDR_ANY (0)
8571 SIN_GET_PORT(sin) = htons(cfg.http_port);
8574 if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
8576 cs_log("HTTP Server: Setting SO_REUSEADDR via setsockopt failed! (errno=%d %s)", errno, strerror(errno));
8579 if(bind(sock, (struct sockaddr *)&sin, len) < 0)
8581 cs_log("HTTP Server couldn't bind on port %d (errno=%d %s). Not starting HTTP!", cfg.http_port, errno, strerror(errno));
8582 close(sock);
8583 return NULL;
8586 if(listen(sock, SOMAXCONN) < 0)
8588 cs_log("HTTP Server: Call to listen() failed! (errno=%d %s)", errno, strerror(errno));
8589 close(sock);
8590 return NULL;
8593 #ifdef WITH_SSL
8594 if(pthread_key_create(&getssl, NULL))
8596 cs_log("Could not create getssl");
8599 SSL_CTX *ctx = NULL;
8600 if(cfg.http_use_ssl)
8602 ctx = SSL_Webif_Init();
8603 if(ctx == NULL)
8604 { cs_log("SSL could not be initialized. Starting WebIf in plain mode."); }
8605 else { ssl_active = 1; }
8607 else { ssl_active = 0; }
8608 cs_log("HTTP Server running. ip=%s port=%d%s", cs_inet_ntoa(SIN_GET_ADDR(sin)), cfg.http_port, ssl_active ? " (SSL)" : "");
8609 #else
8610 cs_log("HTTP Server running. ip=%s port=%d", cs_inet_ntoa(SIN_GET_ADDR(sin)), cfg.http_port);
8611 #endif
8613 struct SOCKADDR remote;
8614 memset(&remote, 0, sizeof(remote));
8616 while(!exit_oscam)
8618 if((s = accept(sock, (struct sockaddr *) &remote, &len)) < 0)
8620 if(exit_oscam)
8621 { break; }
8622 if(errno != EAGAIN && errno != EINTR)
8624 cs_log("HTTP Server: Error calling accept() (errno=%d %s)", errno, strerror(errno));
8625 cs_sleepms(100);
8627 else { cs_sleepms(5); }
8628 continue;
8630 else
8632 getpeername(s, (struct sockaddr *) &remote, &len);
8633 if(!cs_malloc(&conn, sizeof(struct s_connection)))
8635 close(s);
8636 continue;
8638 setTCPTimeouts(s);
8639 cur_client()->last = time((time_t *)0); //reset last busy time
8640 conn->cl = cur_client();
8641 #ifdef IPV6SUPPORT
8642 if(do_ipv6)
8644 struct sockaddr_in6 *ra = (struct sockaddr_in6 *)&remote;
8645 memcpy(&conn->remote, &ra->sin6_addr, sizeof(struct in6_addr));
8647 else
8649 struct sockaddr_in *fba = (struct sockaddr_in *)&remote;
8650 struct in6_addr taddr;
8651 memset(&taddr, 0, sizeof(taddr));
8652 taddr.s6_addr32[3] = fba->sin_addr.s_addr;
8653 memcpy(&conn->remote, &taddr, sizeof(struct in6_addr));
8655 #else
8656 memcpy(&conn->remote, &remote.sin_addr, sizeof(struct in_addr));
8657 #endif
8658 conn->socket = s;
8659 #ifdef WITH_SSL
8660 conn->ssl = NULL;
8661 if(ssl_active)
8663 conn->ssl = SSL_new(ctx);
8664 if(conn->ssl == NULL)
8666 close(s);
8667 cs_log("WebIf: Error calling SSL_new().");
8668 continue;
8671 #endif
8673 int32_t ret = start_thread("webif workthread", serve_process, (void *)conn, NULL, 1, 1);
8674 if(ret)
8676 NULLFREE(conn);
8680 // Wait a bit so that we don't close ressources while http threads are active
8681 cs_sleepms(300);
8682 #ifdef WITH_SSL
8683 SSL_CTX_free(ctx);
8684 CRYPTO_set_dynlock_create_callback(NULL);
8685 CRYPTO_set_dynlock_lock_callback(NULL);
8686 CRYPTO_set_dynlock_destroy_callback(NULL);
8687 CRYPTO_set_locking_callback(NULL);
8688 CRYPTO_set_id_callback(NULL);
8689 OPENSSL_free(lock_cs);
8690 lock_cs = NULL;
8691 #endif
8692 cs_log("HTTP Server stopped");
8693 free_client(cl);
8694 close(sock);
8695 return NULL;
8698 void webif_client_reset_lastresponsetime(struct s_client * cl)
8700 int32_t i;
8701 for(i = 0; i < CS_ECM_RINGBUFFER_MAX; i++)
8703 cl->cwlastresptimes[i].duration = 0;
8704 cl->cwlastresptimes[i].timestamp = time((time_t *)0);
8705 cl->cwlastresptimes[i].rc = 0;
8707 cl->cwlastresptimes_last = 0;
8710 void webif_client_add_lastresponsetime(struct s_client * cl, int32_t ltime, time_t timestamp, int32_t rc)
8712 int32_t last = cl->cwlastresptimes_last = (cl->cwlastresptimes_last + 1) & (CS_ECM_RINGBUFFER_MAX - 1);
8713 cl->cwlastresptimes[last].duration = ltime > 9999 ? 9999 : ltime;
8714 cl->cwlastresptimes[last].timestamp = timestamp;
8715 cl->cwlastresptimes[last].rc = rc;
8718 void webif_client_init_lastreader(struct s_client * client, ECM_REQUEST * er, struct s_reader * er_reader, const char *stxt[])
8720 if(er_reader)
8722 if(er->rc == E_FOUND)
8723 { cs_strncpy(client->lastreader, er_reader->label, sizeof(client->lastreader)); }
8724 else if(er->rc == E_CACHEEX)
8725 { cs_strncpy(client->lastreader, "cache3", sizeof(client->lastreader)); }
8726 else if(er->rc < E_NOTFOUND)
8727 { snprintf(client->lastreader, sizeof(client->lastreader) - 1, "%s (cache)", er_reader->label); }
8728 else
8729 { cs_strncpy(client->lastreader, stxt[er->rc], sizeof(client->lastreader)); }
8731 else
8733 cs_strncpy(client->lastreader, stxt[er->rc], sizeof(client->lastreader));
8737 void webif_init(void)
8739 char buf[8], fname[256];
8740 snprintf(buf, 8, "%'d", 7);
8741 if(strcmp(buf, "7"))
8743 useLocal = 0;
8746 if(cfg.http_port == 0)
8748 cs_log("http disabled");
8749 return;
8752 get_config_filename(fname, sizeof(fname), "oscam.srvid2");
8753 use_srvid2 = file_exists(fname);
8755 if(start_thread("http", http_server, NULL, &httpthread, 0, 1) == 0)
8757 httpthread_running = 1;
8761 void webif_close(void)
8763 if(!sock)
8764 { return; }
8766 shutdown(sock, 2);
8767 close(sock);
8769 if(httpthread_running)
8770 { SAFE_THREAD_JOIN(httpthread, NULL); }
8773 #endif