fix whitespaces thanks to Optimum Power
[oscam.git] / module-webif.c
blob66d2371979b1fb81839608f3a6a07849653908ba
1 #define MODULE_LOG_PREFIX "webif"
3 #include "globals.h"
5 #ifdef WEBIF
6 //
7 // OSCam HTTP server module
8 //
9 #include <locale.h>
10 #include "cscrypt/md5.h"
11 #include "module-anticasc.h"
12 #include "module-cacheex.h"
13 #include "module-cccam.h"
14 #include "module-cccam-data.h"
15 #include "module-dvbapi.h"
16 #include "module-newcamd.h"
17 #include "module-stat.h"
18 #include "module-webif.h"
19 #include "module-webif-lib.h"
20 #include "module-webif-tpl.h"
21 #include "oscam-conf-mk.h"
22 #include "oscam-config.h"
23 #include "oscam-files.h"
24 #include "oscam-garbage.h"
25 #include "oscam-cache.h"
26 #include "oscam-client.h"
27 #include "oscam-lock.h"
28 #include "oscam-net.h"
29 #include "oscam-reader.h"
30 #include "oscam-string.h"
31 #include "oscam-time.h"
32 #include "oscam-work.h"
33 #ifdef MODULE_GBOX
34 #include "module-gbox-sms.h"
35 #include "module-gbox.h"
36 #include "module-gbox-cards.h"
37 #endif
39 extern const struct s_cardreader *cardreaders[];
40 extern char cs_confdir[];
41 extern uint32_t ecmcwcache_size;
42 extern uint8_t cs_http_use_utf8;
43 extern uint32_t cfg_sidtab_generation;
44 extern int32_t exit_oscam;
45 extern uint8_t cacheex_peer_id[8];
47 extern char *entitlement_type[];
48 extern char *RDR_CD_TXT[];
49 int8_t isactive;
50 int32_t ssl_active = 0;
51 char noncekey[33];
52 pthread_key_t getkeepalive;
53 static pthread_key_t getip;
54 pthread_key_t getssl;
55 static CS_MUTEX_LOCK http_lock;
56 CS_MUTEX_LOCK *lock_cs;
58 static uint8_t useLocal = 1;
59 #define PRINTF_LOCAL_D useLocal ? "%'d" : "%d"
60 #define PRINTF_LOCAL_F useLocal ? "%'.0f" : "%.0f"
61 #define PRINTF_LOCAL_MB useLocal ? "%'.2f MB" : "%.2f MB"
63 static int8_t httpthread_running = 0;
64 static pthread_t httpthread;
65 static int32_t sock;
66 enum refreshtypes { REFR_ACCOUNTS, REFR_READERS, REFR_CLIENTS, REFR_SERVER, REFR_ANTICASC, REFR_SERVICES };
68 //initialize structs for calculating cpu-usage depending on time between refresh of status_page
69 static struct pstat p_stat_cur;
70 static struct pstat p_stat_old;
72 static bool use_srvid2 = false;
74 /* constants for menuactivating */
75 #define MNU_STATUS 0
76 #define MNU_LIVELOG 1
77 #define MNU_CONFIG 2
78 #define MNU_READERS 3
79 #define MNU_USERS 4
80 #define MNU_SERVICES 5
81 #define MNU_FILES 6
82 #define MNU_FAILBAN 7
83 #define MNU_CACHEEX 8
84 #define MNU_SCRIPT 9
85 #define MNU_SHUTDOWN 10
86 #define MNU_TOTAL_ITEMS 11 // sum of items above
88 /* constants for config.html submenuactivating */
89 #define MNU_CFG_GLOBAL 0
90 #define MNU_CFG_ANTICASC 1
91 #define MNU_CFG_CACHE 2
92 #define MNU_CFG_LOADBAL 3
93 #define MNU_CFG_CAMD33 4
94 #define MNU_CFG_CAMD35 5
95 #define MNU_CFG_CAMD35TCP 6
96 #define MNU_CFG_CCCAM 7
97 #define MNU_CFG_NEWCAMD 8
98 #define MNU_CFG_GBOX 9
99 #define MNU_CFG_RADEGAST 10
100 #define MNU_CFG_SCAM 11
101 #define MNU_CFG_SERIAL 12
102 #define MNU_CFG_DVBAPI 13
103 #define MNU_CFG_LCD 14
104 #define MNU_CFG_MONITOR 15
105 #define MNU_CFG_WEBIF 16
106 #define MNU_CFG_STREAMRELAY 17
108 /* constants for files.html submenuactivating */
109 #define MNU_CFG_FVERSION 0
110 #define MNU_CFG_FCONF 1
111 #define MNU_CFG_FUSER 2
112 #define MNU_CFG_FSERVER 3
113 #define MNU_CFG_FSRVID 4
114 #define MNU_CFG_FDVBAPI 5
115 #define MNU_CFG_FACLOG 6
116 #define MNU_CFG_FLOGFILE 7
117 #define MNU_CFG_FUSERFILE 8
118 #define MNU_CFG_FSERVICES 9
119 #define MNU_CFG_FPROVID 10
120 #define MNU_CFG_FTIERS 11
121 #define MNU_CFG_FRATELIMIT 12
122 #define MNU_CFG_FWHITELIST 13
123 #define MNU_CFG_FSRVID2 14
124 #define MNU_CFG_FFAKECWS 15
125 #define MNU_CFG_FCSS 16
126 #define MNU_CFG_FTWIN 17
127 #define MNU_CFG_FKEYCW 18
129 /* constants for files.html for GBOX submenuactivating */
130 #define MNU_GBX_FSCINF 19
131 #define MNU_GBX_FSHRINF 20
132 #define MNU_GBX_FSHRONL 21
133 #define MNU_GBX_FVERS 22
134 #define MNU_GBX_FATTACK 23
135 #define MNU_GBX_FSMSLOG 24
136 #define MNU_GBX_FSMSACK 25
137 #define MNU_GBX_FSMSNACK 26
138 #define MNU_GBX_FSTAINF 27
139 #define MNU_GBX_FEXPINF 28
140 #define MNU_GBX_INFOLOG 29
141 #define MNU_CFG_FSOFTCAMKEY 30
143 #define MNU_CFG_TOTAL_ITEMS 31 // sum of items above. Use it for "All inactive" in function calls too.
145 static void set_status_info_var(struct templatevars *vars, char *varname, int no_data, char *fmt, double value)
147 if (no_data)
148 tpl_addVar(vars, TPLADD, varname, "N/A");
149 else
150 tpl_printf(vars, TPLADD, varname, fmt, value);
154 * Creates vars Memory/CPU/OSCAM info in for status_page
155 * if check_available == 0 N/A will be displayed
156 * Bit mapping
157 * mem 0 total, 1 used & free, 2 buff, cached & free incl. buff, 3 share
158 * swap 4 total, 5 used & free,
159 * proc 6 count
160 * cpu 7 load
161 * oscam 8 vsize & rssize, 9 cpu user, 10 cpu sys, 11 cpu sum, 12 cpu refreshtime
162 * unused 13 - 15
164 static void set_status_info(struct templatevars *vars, struct pstat stats){
165 set_status_info_var(vars, "MEM_CUR_TOTAL", stats.check_available & (1 << 0), PRINTF_LOCAL_MB , (double)stats.mem_total/(1024.0*1024.0));
166 set_status_info_var(vars, "MEM_CUR_FREE", stats.check_available & (1 << 1), PRINTF_LOCAL_MB , (double)stats.mem_free/(1024.0*1024.0));
167 set_status_info_var(vars, "MEM_CUR_USED", stats.check_available & (1 << 1), PRINTF_LOCAL_MB , (double)stats.mem_used/(1024.0*1024.0));
168 set_status_info_var(vars, "MEM_CUR_BUFF", stats.check_available & (1 << 2), PRINTF_LOCAL_MB , (double)stats.mem_buff/(1024.0*1024.0));
169 set_status_info_var(vars, "MEM_CUR_CACHED", stats.check_available & (1 << 2), PRINTF_LOCAL_MB , (double)stats.mem_cached/(1024.0*1024.0));
170 set_status_info_var(vars, "MEM_CUR_FREEM", stats.check_available & (1 << 2), PRINTF_LOCAL_MB , (double)stats.mem_freem/(1024.0*1024.0));
171 set_status_info_var(vars, "MEM_CUR_SHARE", stats.check_available & (1 << 3), PRINTF_LOCAL_MB , (double)stats.mem_share/(1024.0*1024.0));
172 set_status_info_var(vars, "MEM_CUR_TOTSW", stats.check_available & (1 << 4), PRINTF_LOCAL_MB , (double)stats.mem_total_swap/(1024.0*1024.0));
173 set_status_info_var(vars, "MEM_CUR_FRESW", stats.check_available & (1 << 5), PRINTF_LOCAL_MB , (double)stats.mem_free_swap/(1024.0*1024.0));
174 set_status_info_var(vars, "MEM_CUR_USESW", stats.check_available & (1 << 5), PRINTF_LOCAL_MB , (double)stats.mem_used_swap/(1024.0*1024.0));
176 set_status_info_var(vars, "SERVER_PROCS", stats.check_available & (1 << 6), PRINTF_LOCAL_F , stats.info_procs);
178 set_status_info_var(vars, "CPU_LOAD_0", stats.check_available & (1 << 7), "%.2f" , stats.cpu_avg[0]);
179 set_status_info_var(vars, "CPU_LOAD_1", stats.check_available & (1 << 7), "%.2f" , stats.cpu_avg[1]);
180 set_status_info_var(vars, "CPU_LOAD_2", stats.check_available & (1 << 7), "%.2f" , stats.cpu_avg[2]);
182 set_status_info_var(vars, "OSCAM_VMSIZE", stats.check_available & (1 << 8), PRINTF_LOCAL_MB , (double)stats.vsize/(1024.0*1024.0));
183 set_status_info_var(vars, "OSCAM_RSSSIZE", stats.check_available & (1 << 8), PRINTF_LOCAL_MB , (double)stats.rss/(1024.0*1024.0));
184 set_status_info_var(vars, "OSCAM_CPU_USER", stats.check_available & (1 << 9), "%.2f %%" , stats.cpu_usage_user);
185 set_status_info_var(vars, "OSCAM_CPU_SYS", stats.check_available & (1 << 10), "%.2f %%" , stats.cpu_usage_sys);
186 double sum_cpu = stats.cpu_usage_sys + stats.cpu_usage_user;
187 set_status_info_var(vars, "OSCAM_CPU_SUM", stats.check_available & (1 << 11), "%.2f %%" , sum_cpu);
189 if (stats.check_available & (1 << 12))
191 tpl_addVar(vars, TPLADD, "OSCAM_REFRESH" , "N/A");
193 else
195 tpl_printf(vars, TPLADD, "OSCAM_REFRESH" , "%02"PRId64":%02"PRId64":%02"PRId64"h",
196 stats.gone_refresh / 3600,
197 (stats.gone_refresh / 60) % 60,
198 stats.gone_refresh % 60);
202 static void clear_account_stats(struct s_auth *account)
204 account->cwfound = 0;
205 account->cwcache = 0;
206 account->cwnot = 0;
207 account->cwtun = 0;
208 account->cwignored = 0;
209 account->cwtout = 0;
210 account->emmok = 0;
211 account->emmnok = 0;
212 #ifdef CW_CYCLE_CHECK
213 account->cwcycledchecked = 0;
214 account->cwcycledok = 0;
215 account->cwcyclednok = 0;
216 account->cwcycledign = 0;
217 #endif
218 cacheex_clear_account_stats(account);
221 static void clear_all_account_stats(void)
223 struct s_auth *account = cfg.account;
224 while(account)
226 clear_account_stats(account);
227 account = account->next;
231 #ifdef CS_CACHEEX
232 static void cacheex_clear_all_stats(void)
234 struct s_auth *account = cfg.account;
235 while(account)
237 cacheex_clear_account_stats(account);
238 account = account->next;
240 struct s_client *cl;
241 for(cl = first_client->next; cl ; cl = cl->next)
243 cacheex_clear_client_stats(cl);
244 ll_clear_data(cl->ll_cacheex_stats);
246 cacheex_clear_client_stats(first_client);
248 #endif
250 static void clear_info_clients_stats(void)
252 first_client->cwfound = 0;
253 first_client->cwcache = 0;
254 first_client->cwnot = 0;
255 first_client->cwtun = 0;
256 first_client->cwignored = 0;
257 first_client->cwtout = 0;
258 first_client->emmok = 0;
259 first_client->emmnok = 0;
260 cacheex_clear_client_stats(first_client);
263 static void clear_info_readers_stats(void)
265 int8_t i;
266 cs_writelock(__func__, &readerlist_lock);
267 LL_ITER itr = ll_iter_create(configured_readers);
268 struct s_reader *rdr;
269 while((rdr = ll_iter_next(&itr)))
271 rdr->webif_ecmsok = 0;
272 rdr->webif_ecmsnok = 0;
273 rdr->webif_ecmstout = 0;
274 rdr->webif_ecmsfilteredhead = 0;
275 rdr->webif_ecmsfilteredlen = 0;
277 for(i = 0; i < 4; i++)
279 rdr->webif_emmerror[i] = 0;
280 rdr->webif_emmwritten[i] = 0;
281 rdr->webif_emmskipped[i] = 0;
282 rdr->webif_emmblocked[i] = 0;
285 cs_writeunlock(__func__, &readerlist_lock);
288 static void set_ecm_info(struct templatevars * vars)
290 //if one of the stats overloaded, reset all stats!
291 if(first_client->cwfound<0
292 || first_client->cwnot<0
293 || first_client->cwignored<0
294 || first_client->cwtout<0
295 || first_client->cwcache<0
296 || first_client->cwtun<0
297 || first_client->emmok<0
298 || first_client->emmnok<0
299 #ifdef CS_CACHEEX
300 || first_client->cwcacheexgot<0
301 || first_client->cwcacheexpush<0
302 || first_client->cwcacheexhit<0
303 #ifdef CS_CACHEEX_AIO
304 || first_client->cwcacheexgotlg<0
305 || first_client->cwcacheexpushlg<0
306 #endif
307 #endif
309 clear_info_clients_stats();
311 //end reset stats
313 int ecm = 0, emm = 0;
314 double ecmsum = first_client->cwfound + first_client->cwcache + first_client->cwnot + first_client->cwtout; //dont count TUN its included
315 if(ecmsum < 1) {ecmsum = 1; ecm = 1;}
316 double ecmpos = first_client->cwfound + first_client->cwcache; // dont count TUN its included
317 if(ecmpos < 1) {ecmpos = 1;}
318 double ecmneg = first_client->cwnot + first_client->cwtout; //dont count IGN its not part of neagtiv
319 if(ecmneg < 1) {ecmneg = 1;}
320 double emmsum = first_client->emmok + first_client->emmnok;
321 if(emmsum < 1) {emmsum = 1; emm = 1;}
323 tpl_printf(vars, TPLADD, "TOTAL_ECM_MIN", "%d", first_client->n_request[0]);
324 tpl_printf(vars, TPLADD, "TOTAL_CW", PRINTF_LOCAL_F, !ecm ? ecmsum : 0);
325 tpl_printf(vars, TPLADD, "TOTAL_CWOK", PRINTF_LOCAL_F, (double)first_client->cwfound);
326 tpl_printf(vars, TPLADD, "TOTAL_CWNOK", PRINTF_LOCAL_F, (double)first_client->cwnot);
327 tpl_printf(vars, TPLADD, "TOTAL_CWIGN", PRINTF_LOCAL_F, (double)first_client->cwignored);
328 tpl_printf(vars, TPLADD, "TOTAL_CWTOUT", PRINTF_LOCAL_F, (double)first_client->cwtout);
329 tpl_printf(vars, TPLADD, "TOTAL_CWCACHE", PRINTF_LOCAL_F, (double)first_client->cwcache);
330 tpl_printf(vars, TPLADD, "TOTAL_CWTUN", PRINTF_LOCAL_F, (double)first_client->cwtun);
331 tpl_printf(vars, TPLADD, "TOTAL_CWPOS", PRINTF_LOCAL_F, (double)first_client->cwfound + (double)first_client->cwcache);
332 tpl_printf(vars, TPLADD, "TOTAL_CWNEG", PRINTF_LOCAL_F, (double)first_client->cwnot + (double)first_client->cwtout);
333 tpl_printf(vars, TPLADD, "TOTAL_EM", PRINTF_LOCAL_F, !emm ? emmsum : 0);
334 tpl_printf(vars, TPLADD, "TOTAL_EMOK", PRINTF_LOCAL_F, (double)first_client->emmok);
335 tpl_printf(vars, TPLADD, "TOTAL_EMNOK", PRINTF_LOCAL_F, (double)first_client->emmnok);
336 tpl_printf(vars, TPLADD, "REL_CWOK", "%.2f", (double)first_client->cwfound * 100 / ecmsum);
337 tpl_printf(vars, TPLADD, "REL_CWNOK", "%.2f", (double)first_client->cwnot * 100 / ecmsum);
338 //tpl_printf(vars, TPLADD, "REL_CWIGN", "%.2f", (double)first_client->cwignored * 100 / ecmsum);
339 tpl_printf(vars, TPLADD, "REL_CWTOUT", "%.2f", (double)first_client->cwtout * 100 / ecmsum);
340 tpl_printf(vars, TPLADD, "REL_CWCACHE", "%.2f", (double)first_client->cwcache * 100 / ecmsum);
341 tpl_printf(vars, TPLADD, "REL_CWTUN", "%.2f", (double)first_client->cwtun * 100 / ecmsum);
342 tpl_printf(vars, TPLADD, "REL_CWPOS", "%.2f", (double)(first_client->cwfound + first_client->cwcache) * 100 / ecmsum);
343 tpl_printf(vars, TPLADD, "REL_CWNEG", "%.2f", (double)(first_client->cwnot + first_client->cwtout) * 100 / ecmsum);
344 tpl_printf(vars, TPLADD, "REL_EMOK", "%.2f", (double)first_client->emmok * 100 / emmsum);
345 tpl_printf(vars, TPLADD, "REL_EMNOK", "%.2f", (double)first_client->emmnok * 100 / emmsum);
346 tpl_printf(vars, TPLADD, "REL_CWPOSOK", "%.2f", (double)first_client->cwfound * 100 / ecmpos);
347 tpl_printf(vars, TPLADD, "REL_CWPOSCACHE", "%.2f", (double)first_client->cwcache * 100 / ecmpos);
348 tpl_printf(vars, TPLADD, "REL_CWNEGNOK", "%.2f", (double)first_client->cwnot * 100 / ecmneg);
349 //tpl_printf(vars, TPLADD, "REL_CWNEGIGN", "%.2f", (double)first_client->cwignored * 100 / ecmneg);
350 tpl_printf(vars, TPLADD, "REL_CWNEGTOUT", "%.2f", (double)first_client->cwtout * 100 / ecmneg);
352 double totalrdrneg = 0, totalrdrpos = 0;
353 double totalrdrok = 0, totalrdrnok = 0, totalrdrtout = 0;
354 double flen = 0, fhead = 0;
355 double teruk = 0, terg = 0, ters = 0, teruq = 0;
356 double twruk = 0, twrg = 0, twrs = 0, twruq = 0;
357 double tskuk = 0, tskg = 0, tsks = 0, tskuq = 0;
358 double tbluk = 0, tblg = 0, tbls = 0, tbluq = 0;
360 cs_readlock(__func__, &readerlist_lock);
361 LL_ITER itr = ll_iter_create(configured_readers);
362 struct s_reader *rdr;
363 while((rdr = ll_iter_next(&itr)))
365 if (rdr->webif_ecmsok) { totalrdrok += rdr->webif_ecmsok; }
366 if (rdr->webif_ecmsnok) { totalrdrnok += rdr->webif_ecmsnok; }
367 if (rdr->webif_ecmstout) { totalrdrtout += rdr->webif_ecmstout; }
369 if (rdr->webif_ecmsfilteredlen) { flen += rdr->webif_ecmsfilteredlen; }
370 if (rdr->webif_ecmsfilteredhead) { fhead += rdr->webif_ecmsfilteredhead; }
372 if (rdr->webif_emmerror[0]) { teruk += rdr->webif_emmerror[0]; }
373 if (rdr->webif_emmerror[1]) { teruq += rdr->webif_emmerror[1]; }
374 if (rdr->webif_emmerror[2]) { ters += rdr->webif_emmerror[2]; }
375 if (rdr->webif_emmerror[3]) { terg += rdr->webif_emmerror[3]; }
377 if (rdr->webif_emmwritten[0]) { twruk += rdr->webif_emmwritten[0]; }
378 if (rdr->webif_emmwritten[1]) { twruq += rdr->webif_emmwritten[1]; }
379 if (rdr->webif_emmwritten[2]) { twrs += rdr->webif_emmwritten[2]; }
380 if (rdr->webif_emmwritten[3]) { twrg += rdr->webif_emmwritten[3]; }
382 if (rdr->webif_emmskipped[0]) { tskuk += rdr->webif_emmskipped[0]; }
383 if (rdr->webif_emmskipped[1]) { tskuq += rdr->webif_emmskipped[1]; }
384 if (rdr->webif_emmskipped[2]) { tsks += rdr->webif_emmskipped[2]; }
385 if (rdr->webif_emmskipped[3]) { tskg += rdr->webif_emmskipped[3]; }
387 if (rdr->webif_emmblocked[0]) { tbluk += rdr->webif_emmblocked[0]; }
388 if (rdr->webif_emmblocked[1]) { tbluq += rdr->webif_emmblocked[1]; }
389 if (rdr->webif_emmblocked[2]) { tbls += rdr->webif_emmblocked[2]; }
390 if (rdr->webif_emmblocked[3]) { tblg += rdr->webif_emmblocked[3]; }
392 cs_readunlock(__func__, &readerlist_lock);
394 totalrdrneg = totalrdrnok + totalrdrtout;
395 totalrdrpos = totalrdrok;
396 ecmsum = totalrdrok + totalrdrnok + totalrdrtout;
398 tpl_printf(vars, TPLADD, "TOTAL_CWOK_READERS", PRINTF_LOCAL_F, totalrdrok);
399 tpl_printf(vars, TPLADD, "TOTAL_CWNOK_READERS", PRINTF_LOCAL_F, totalrdrnok);
400 tpl_printf(vars, TPLADD, "TOTAL_CWTOUT_READERS", PRINTF_LOCAL_F, totalrdrtout);
401 tpl_printf(vars, TPLADD, "REL_CWOK_READERS", "%.2f", ecmsum ? totalrdrok * 100 / ecmsum : 0);
402 tpl_printf(vars, TPLADD, "REL_CWNOK_READERS", "%.2f", ecmsum ? totalrdrnok * 100 / ecmsum : 0);
403 tpl_printf(vars, TPLADD, "REL_CWTOUT_READERS", "%.2f", ecmsum ? totalrdrtout * 100 / ecmsum : 0);
404 tpl_printf(vars, TPLADD, "TOTAL_CWPOS_READERS", PRINTF_LOCAL_F, totalrdrpos);
405 tpl_printf(vars, TPLADD, "TOTAL_CWNEG_READERS", PRINTF_LOCAL_F, totalrdrneg);
406 tpl_printf(vars, TPLADD, "REL_CWPOS_READERS", "%.2f", ecmsum ? totalrdrpos * 100 / ecmsum : 0);
407 tpl_printf(vars, TPLADD, "REL_CWNEG_READERS", "%.2f", ecmsum ? totalrdrneg * 100 / ecmsum : 0);
408 tpl_printf(vars, TPLADD, "TOTAL_ELENR", PRINTF_LOCAL_F, flen);
409 tpl_printf(vars, TPLADD, "TOTAL_EHEADR", PRINTF_LOCAL_F, fhead);
410 tpl_printf(vars, TPLADD, "TOTAL_SUM_ALL_READERS_ECM", PRINTF_LOCAL_F, ecmsum);
412 tpl_printf(vars, TPLADD, "TOTAL_EMMERRORUK_READERS", PRINTF_LOCAL_F, teruk);
413 tpl_printf(vars, TPLADD, "TOTAL_EMMERRORG_READERS", PRINTF_LOCAL_F, terg);
414 tpl_printf(vars, TPLADD, "TOTAL_EMMERRORS_READERS", PRINTF_LOCAL_F, ters);
415 tpl_printf(vars, TPLADD, "TOTAL_EMMERRORUQ_READERS", PRINTF_LOCAL_F, teruq);
416 tpl_printf(vars, TPLADD, "TOTAL_EMMWRITTENUK_READERS", PRINTF_LOCAL_F, twruk);
417 tpl_printf(vars, TPLADD, "TOTAL_EMMWRITTENG_READERS", PRINTF_LOCAL_F, twrg);
418 tpl_printf(vars, TPLADD, "TOTAL_EMMWRITTENS_READERS", PRINTF_LOCAL_F, twrs);
419 tpl_printf(vars, TPLADD, "TOTAL_EMMWRITTENUQ_READERS", PRINTF_LOCAL_F, twruq);
420 tpl_printf(vars, TPLADD, "TOTAL_EMMSKIPPEDUK_READERS", PRINTF_LOCAL_F, tskuk);
421 tpl_printf(vars, TPLADD, "TOTAL_EMMSKIPPEDG_READERS", PRINTF_LOCAL_F, tskg);
422 tpl_printf(vars, TPLADD, "TOTAL_EMMSKIPPEDS_READERS", PRINTF_LOCAL_F, tsks);
423 tpl_printf(vars, TPLADD, "TOTAL_EMMSKIPPEDUQ_READERS", PRINTF_LOCAL_F, tskuq);
424 tpl_printf(vars, TPLADD, "TOTAL_EMMBLOCKEDUK_READERS", PRINTF_LOCAL_F, tbluk);
425 tpl_printf(vars, TPLADD, "TOTAL_EMMBLOCKEDG_READERS", PRINTF_LOCAL_F, tblg);
426 tpl_printf(vars, TPLADD, "TOTAL_EMMBLOCKEDS_READERS", PRINTF_LOCAL_F, tbls);
427 tpl_printf(vars, TPLADD, "TOTAL_EMMBLOCKEDUQ_READERS", PRINTF_LOCAL_F, tbluq);
429 emmsum = teruk + terg + ters + teruq + twruk + twrg + twrs + twruq + tskuk + tskg + tsks + tskuq + tbluk + tblg + tbls + tbluq;
431 tpl_printf(vars, TPLADD, "TOTAL_SUM_ALL_READERS_EMM", PRINTF_LOCAL_F, emmsum);
434 static void refresh_oscam(enum refreshtypes refreshtype)
437 switch(refreshtype)
439 case REFR_ACCOUNTS:
440 cs_log("Refresh Accounts requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
441 cs_accounts_chk();
442 break;
444 case REFR_READERS:
445 cs_log("Refresh Readers requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
446 reload_readerdb();
447 break;
449 case REFR_CLIENTS:
450 cs_log("Refresh Clients requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
451 cs_reinit_clients(cfg.account);
452 break;
454 case REFR_SERVER:
455 cs_log("Refresh Server requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
456 //kill(first_client->pid, SIGHUP);
457 //todo how I can refresh the server after global settings
458 break;
460 case REFR_SERVICES:
461 cs_log("Refresh Services requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
462 //init_sidtab();
463 cs_accounts_chk();
464 break;
466 #ifdef CS_ANTICASC
467 case REFR_ANTICASC:
468 cs_log("Refresh Anticascading requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
469 ac_init_stat();
470 struct s_client *cl;
471 struct s_auth *account;
472 for(cl = first_client->next; cl ; cl = cl->next)
474 if(cl->typ == 'c' && (account = cl->account))
476 cl->ac_limit = (account->ac_users * 100 + 80) * cfg.ac_stime;
479 break;
480 #endif
481 default:
482 break;
486 * load historical values from ringbuffer and return it in the right order
487 * as string. Value should be freed with free_mk_t()
489 static char *get_ecm_historystring(struct s_client *cl)
492 if(cl)
494 int32_t k, i, pos = 0, needed = 1, v;
495 char *value, *dot = "";
496 int32_t ptr = cl->cwlastresptimes_last;
498 needed = CS_ECM_RINGBUFFER_MAX * 6; //5 digits + delimiter
499 if(!cs_malloc(&value, needed)) { return ""; }
501 k = ptr + 1;
502 for(i = 0; i < CS_ECM_RINGBUFFER_MAX; i++)
504 if(k >= CS_ECM_RINGBUFFER_MAX)
505 { k = 0; }
506 v = cl->cwlastresptimes[k].duration;
507 if(v > 0 && v < (int32_t)cfg.ctimeout * 5)
509 pos += snprintf(value + pos, needed - pos, "%s%d", dot, v);
510 dot = ",";
512 k++;
514 if(cs_strlen(value) == 0)
516 NULLFREE(value);
517 return "";
519 else { return value; }
522 else
524 return "";
528 static char *get_ecm_fullhistorystring(struct s_client *cl)
531 if(cl)
533 int32_t k, i, pos = 0, needed = 1, v;
534 char *value, *dot = "";
535 int32_t ptr = cl->cwlastresptimes_last;
537 needed = CS_ECM_RINGBUFFER_MAX * 20; //5 digits + : + returncode(2) + : + time(10) + delimiter
538 if(!cs_malloc(&value, needed)) { return ""; }
540 k = ptr + 1;
541 for(i = 0; i < CS_ECM_RINGBUFFER_MAX; i++)
543 if(k >= CS_ECM_RINGBUFFER_MAX)
544 { k = 0; }
545 v = cl->cwlastresptimes[k].duration;
546 if(v > 0 && v < (int32_t)cfg.ctimeout * 5)
548 pos += snprintf(value + pos, needed - pos, "%s%d:%d:%ld", dot, cl->cwlastresptimes[k].duration, cl->cwlastresptimes[k].rc, cl->cwlastresptimes[k].timestamp);
549 dot = ",";
551 k++;
554 return (value);
557 else
559 return "";
564 * Set the active menu to a different CSS class
566 static void setActiveMenu(struct templatevars *vars, int8_t active)
568 int8_t i;
569 for(i = 0; i < MNU_TOTAL_ITEMS; i++)
571 tpl_printf(vars, TPLADD, "TMP", "MENUACTIVE%d", i);
572 if(i == active)
573 { tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "menu_selected"); }
574 else
575 { tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "menu"); }
577 #ifdef WEBIF_LIVELOG
578 tpl_addVar(vars, TPLADD, "LOGPAGEMENU", tpl_getTpl(vars, "LOGMENU"));
579 #endif
583 * Set the active submenu to a different CSS class
585 static void setActiveSubMenu(struct templatevars *vars, int8_t active)
587 int8_t i;
588 for(i = 0; i < MNU_CFG_TOTAL_ITEMS; i++)
590 tpl_printf(vars, TPLADD, "TMP", "CMENUACTIVE%d", i);
591 if(i == active)
592 { tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "configmenu_selected"); }
593 else
594 { tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "configmenu"); }
598 static void webif_save_config(char *section, struct templatevars *vars, struct uriparams *params)
600 if(!streq(getParam(params, "action"), "execute"))
601 { return; }
602 if(cfg.http_readonly)
604 tpl_addMsg(vars, "WebIf is in readonly mode. No changes are possible!");
605 return;
607 int i;
608 int cnt = (*params).paramcount;
609 for(i = 0; i < cnt; i++)
611 char *token = (*params).params[i];
612 char *value = (*params).values[i];
613 if(!streq(token, "part") && !streq(token, "action"))
614 { config_set(section, token, value); }
616 if(write_config() == 0)
618 tpl_addMsg(vars, "Configuration was saved.");
619 enum refreshtypes ref_type = REFR_SERVER;
620 if(streq(getParam(params, "part"), "anticasc"))
621 { ref_type = REFR_ANTICASC; }
622 refresh_oscam(ref_type);
624 else
626 tpl_addMsg(vars, "ERROR: Failed to write config file!!!");
630 static char *send_oscam_config_global(struct templatevars *vars, struct uriparams *params)
632 setActiveSubMenu(vars, MNU_CFG_GLOBAL);
634 webif_save_config("global", vars, params);
636 if(IP_ISSET(cfg.srvip))
637 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.srvip)); }
638 tpl_printf(vars, TPLADD, "NICE", "%d", cfg.nice);
639 tpl_printf(vars, TPLADD, "BINDWAIT", "%d", cfg.bindwait);
641 tpl_printf(vars, TPLADD, "TMP", "NETPRIO%d", cfg.netprio);
642 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
644 tpl_printf(vars, TPLADD, "PIDFILE", "%s", ESTR(cfg.pidfile));
647 if(cfg.usrfile != NULL) { tpl_addVar(vars, TPLADD, "USERFILE", cfg.usrfile); }
648 if(cfg.disableuserfile == 0) { tpl_addVar(vars, TPLADD, "DISABLEUSERFILECHECKED", "checked"); }
649 if(cfg.usrfileflag == 1) { tpl_addVar(vars, TPLADD, "USERFILEFLAGCHECKED", "selected"); }
650 if(cfg.mailfile != NULL) { tpl_addVar(vars, TPLADD, "MAILFILE", cfg.mailfile); }
651 if(cfg.disablemail == 0) { tpl_addVar(vars, TPLADD, "DISABLEMAILCHECKED", "checked"); }
653 char *value = mk_t_logfile();
654 tpl_addVar(vars, TPLADD, "LOGFILE", value);
655 free_mk_t(value);
656 if(cfg.disablelog == 0) { tpl_addVar(vars, TPLADD, "DISABLELOGCHECKED", "checked"); }
657 tpl_printf(vars, TPLADD, "MAXLOGSIZE", "%d", cfg.max_log_size);
659 tpl_addVar(vars, TPLADD, "LOGDUPSCHECKED", (cfg.logduplicatelines == 1) ? "checked" : "");
660 tpl_printf(vars, TPLADD, "INITIALDEBUGLEVEL", "%u", cfg.initial_debuglevel);
662 if(cfg.cwlogdir != NULL) { tpl_addVar(vars, TPLADD, "CWLOGDIR", cfg.cwlogdir); }
663 if(cfg.emmlogdir != NULL) { tpl_addVar(vars, TPLADD, "EMMLOGDIR", cfg.emmlogdir); }
664 tpl_addVar(vars, TPLADD, "ECMFMT", cfg.ecmfmt);
665 tpl_printf(vars, TPLADD, "LOGHISTORYLINES", "%u", cfg.loghistorylines);
666 if(cfg.sysloghost != NULL) { tpl_addVar(vars, TPLADD, "SYSLOGHOST", cfg.sysloghost); }
667 tpl_printf(vars, TPLADD, "SYSLOGPORT", "%u", cfg.syslogport);
670 tpl_printf(vars, TPLADD, "CLIENTTIMEOUT", "%u", cfg.ctimeout);
671 tpl_printf(vars, TPLADD, "FALLBACKTIMEOUT", "%u", cfg.ftimeout);
672 tpl_printf(vars, TPLADD, "CLIENTMAXIDLE", "%u", cfg.cmaxidle);
675 value = mk_t_caidvaluetab(&cfg.ftimeouttab);
676 tpl_addVar(vars, TPLADD, "FALLBACKTIMEOUT_PERCAID", value);
677 free_mk_t(value);
679 tpl_printf(vars, TPLADD, "SLEEP", "%d", cfg.tosleep);
680 tpl_addVar(vars, TPLADD, "UNLOCKPARENTALCHECKED", (cfg.ulparent == 1) ? "checked" : "");
682 if(cfg.reload_useraccounts) { tpl_addVar(vars, TPLADD, "RELOADUSERACCOUNTSCHECKED", "checked"); }
683 if(cfg.reload_readers) { tpl_addVar(vars, TPLADD, "RELOADREADERSCHECKED", "checked"); }
684 if(cfg.reload_provid) { tpl_addVar(vars, TPLADD, "RELOADPROVIDCHECKED", "checked"); }
685 if(cfg.reload_services_ids) { tpl_addVar(vars, TPLADD, "RELOADSERVICESIDSCHECKED", "checked"); }
686 if(cfg.reload_tier_ids) { tpl_addVar(vars, TPLADD, "RELOADTIERUDSCHECKED", "checked"); }
687 if(cfg.reload_fakecws) { tpl_addVar(vars, TPLADD, "RELOADFAKECWSCHECKED", "checked"); }
688 if(cfg.reload_ac_stat) { tpl_addVar(vars, TPLADD, "RELOADACSTATCHECKED", "checked"); }
689 if(cfg.reload_log) { tpl_addVar(vars, TPLADD, "RELOADLOGCHECKED", "checked"); }
691 if(cfg.block_same_ip) { tpl_addVar(vars, TPLADD, "BLOCKSAMEIPCHECKED", "checked"); }
692 if(cfg.block_same_name) { tpl_addVar(vars, TPLADD, "BLOCKSAMENAMECHECKED", "checked"); }
694 if(cfg.waitforcards == 1) { tpl_addVar(vars, TPLADD, "WAITFORCARDSCHECKED", "checked"); }
695 tpl_printf(vars, TPLADD, "EXTRADELAY", "%d", cfg.waitforcards_extra_delay);
696 if(cfg.preferlocalcards == 1)
698 tpl_addVar(vars, TPLADD, "PREFERCACHEEX", "selected");
700 else if(cfg.preferlocalcards == 2)
702 tpl_addVar(vars, TPLADD, "PREFERLOCALCARDS", "selected");
705 if(cfg.c35_suppresscmd08)
706 { tpl_addVar(vars, TPLADD, "SUPPRESSCMD08", "checked"); }
708 if(cfg.getblockemmauprovid > 0)
710 tpl_addVar(vars, TPLADD, "GETBLOCKEMMAUPROVID", "checked");
713 if(cfg.reader_restart_seconds)
714 { tpl_printf(vars, TPLADD, "READERRESTARTSECONDS", "%d", cfg.reader_restart_seconds); }
716 tpl_addVar(vars, TPLADD, "DROPDUPSCHECKED", (cfg.dropdups == 1) ? "checked" : "");
718 if(cfg.resolve_gethostbyname == 1)
719 { tpl_addVar(vars, TPLADD, "RESOLVER1", "selected"); }
720 else
721 { tpl_addVar(vars, TPLADD, "RESOLVER0", "selected"); }
723 tpl_printf(vars, TPLADD, "FAILBANTIME", "%d", cfg.failbantime);
724 tpl_printf(vars, TPLADD, "FAILBANCOUNT", "%d", cfg.failbancount);
726 tpl_addVar(vars, TPLADD, "DCHECKCSELECTED", (cfg.double_check == 1) ? "checked" : "");
728 value = mk_t_ftab(&cfg.double_check_caid);
729 tpl_addVar(vars, TPLADD, "DOUBLECHECKCAID", value);
730 free_mk_t(value);
732 tpl_addVar(vars, TPLADD, "DISABLECRCCWSCHECKEDGLOBAL", (cfg.disablecrccws == 1) ? "checked" : "");
734 value = mk_t_ftab(&cfg.disablecrccws_only_for);
735 tpl_addVar(vars, TPLADD, "IGNCHKSUMONLYFORGLOBAL", value);
736 free_mk_t(value);
738 #ifdef LEDSUPPORT
739 if(cfg.enableled == 1)
740 { tpl_addVar(vars, TPLADD, "ENABLELEDSELECTED1", "selected"); }
741 else if(cfg.enableled == 2)
742 { tpl_addVar(vars, TPLADD, "ENABLELEDSELECTED2", "selected"); }
743 #endif
745 return tpl_getTpl(vars, "CONFIGGLOBAL");
748 #ifdef WITH_LB
749 static char *send_oscam_config_loadbalancer(struct templatevars *vars, struct uriparams *params)
751 setActiveSubMenu(vars, MNU_CFG_LOADBAL);
753 if(cs_strlen(getParam(params, "button")) > 0)
755 if(cfg.http_readonly)
757 tpl_addMsg(vars, "WebIf is in readonly mode. No changes are possible!");
759 else
761 if(strcmp(getParam(params, "button"), "Load Stats") == 0)
763 clear_all_stat();
764 load_stat_from_file();
765 tpl_addMsg(vars, "Stats loaded from file");
768 if(strcmp(getParam(params, "button"), "Save Stats") == 0)
770 save_stat_to_file(1);
771 tpl_addMsg(vars, "Stats saved to file");
774 if(strcmp(getParam(params, "button"), "Clear Stats") == 0)
776 clear_all_stat();
777 tpl_addMsg(vars, "Stats cleared completly");
780 if(strcmp(getParam(params, "button"), "Clear Timeouts") == 0)
782 clean_all_stats_by_rc(E_TIMEOUT, 0);
783 tpl_addMsg(vars, "Timeout cleared from Stats");
786 if(strcmp(getParam(params, "button"), "Clear Not Found") == 0)
788 clean_all_stats_by_rc(E_NOTFOUND, 0);
789 tpl_addMsg(vars, "Not Found cleared from Stats");
792 if(strcmp(getParam(params, "button"), "Clear Invalid") == 0)
794 clean_all_stats_by_rc(E_INVALID, 0);
795 tpl_addMsg(vars, "Invalid cleared from Stats");
800 webif_save_config("global", vars, params);
802 tpl_printf(vars, TPLADD, "TMP", "LBMODE%d", cfg.lb_mode);
803 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
805 tpl_printf(vars, TPLADD, "LBSAVE", "%d", cfg.lb_save);
806 if(cfg.lb_savepath) { tpl_addVar(vars, TPLADD, "LBSAVEPATH", cfg.lb_savepath); }
808 tpl_printf(vars, TPLADD, "LBNBESTREADERS", "%d", cfg.lb_nbest_readers);
809 char *value = mk_t_caidvaluetab(&cfg.lb_nbest_readers_tab);
810 tpl_addVar(vars, TPLADD, "LBNBESTPERCAID", value);
811 free_mk_t(value);
812 tpl_printf(vars, TPLADD, "LBNFBREADERS", "%d", cfg.lb_nfb_readers);
813 tpl_printf(vars, TPLADD, "LBMAXREADERS", "%d", cfg.lb_max_readers);
814 tpl_printf(vars, TPLADD, "LBMINECMCOUNT", "%d", cfg.lb_min_ecmcount);
815 tpl_printf(vars, TPLADD, "LBMAXECEMCOUNT", "%d", cfg.lb_max_ecmcount);
816 tpl_printf(vars, TPLADD, "LBRETRYLIMIT", "%d", cfg.lb_retrylimit);
818 value = mk_t_caidvaluetab(&cfg.lb_retrylimittab);
819 tpl_addVar(vars, TPLADD, "LBRETRYLIMITS", value);
820 free_mk_t(value);
822 tpl_printf(vars, TPLADD, "LBREOPENSECONDS", "%d", cfg.lb_reopen_seconds);
823 tpl_printf(vars, TPLADD, "LBCLEANUP", "%d", cfg.lb_stat_cleanup);
825 tpl_addVar(vars, TPLADD, "LBREOPENINVALID", (cfg.lb_reopen_invalid == 1) ? "checked" : "");
826 tpl_addVar(vars, TPLADD, "LBFORCEALWAYS", (cfg.lb_force_reopen_always == 1) ? "checked" : "");
828 value = mk_t_caidtab(&cfg.lb_noproviderforcaid);
829 tpl_addVar(vars, TPLADD, "LBNOPROVIDERFORCAID", value);
830 free_mk_t(value);
832 tpl_addVar(vars, TPLADD, "LBAUTOBETATUNNEL", (cfg.lb_auto_betatunnel == 1) ? "checked" : "");
834 if(cfg.lb_auto_betatunnel_mode)
836 tpl_printf(vars, TPLADD, "TMP", "LBAUTOBETATUNNELMODE%d", cfg.lb_auto_betatunnel_mode);
837 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
840 tpl_printf(vars, TPLADD, "LBPREFERBETA", "%d", cfg.lb_auto_betatunnel_prefer_beta);
842 tpl_addVar(vars, TPLADD, "LBAUTOTIMEOUT", (cfg.lb_auto_timeout == 1) ? "checked" : "");
844 tpl_printf(vars, TPLADD, "LBAUTOTIMEOUTP", "%d", cfg.lb_auto_timeout_p);
845 tpl_printf(vars, TPLADD, "LBAUTOTIMEOUTT", "%d", cfg.lb_auto_timeout_t);
847 tpl_addVar(vars, TPLADDONCE, "CONFIG_CONTROL", tpl_getTpl(vars, "CONFIGLOADBALANCERCTRL"));
849 return tpl_getTpl(vars, "CONFIGLOADBALANCER");
851 #endif
853 #ifdef MODULE_CAMD33
854 static char *send_oscam_config_camd33(struct templatevars *vars, struct uriparams *params)
856 int32_t i;
858 setActiveSubMenu(vars, MNU_CFG_CAMD33);
860 webif_save_config("camd33", vars, params);
862 if(cfg.c33_port)
864 tpl_printf(vars, TPLADD, "PORT", "%d", cfg.c33_port);
865 if(IP_ISSET(cfg.c33_srvip)) { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.c33_srvip)); }
866 tpl_addVar(vars, TPLADD, "PASSIVECHECKED", (cfg.c33_passive == 1) ? "checked" : "");
868 for(i = 0; i < (int) sizeof(cfg.c33_key); ++i) { tpl_printf(vars, TPLAPPEND, "KEY", "%02X", cfg.c33_key[i]); }
869 char *value = mk_t_iprange(cfg.c33_plain);
870 tpl_addVar(vars, TPLADD, "NOCRYPT", value);
871 free_mk_t(value);
874 return tpl_getTpl(vars, "CONFIGCAMD33");
876 #endif
878 #ifdef MODULE_CAMD35
879 static char *send_oscam_config_camd35(struct templatevars *vars, struct uriparams *params)
881 setActiveSubMenu(vars, MNU_CFG_CAMD35);
883 webif_save_config("cs357x", vars, params);
885 if(cfg.c35_port)
887 tpl_printf(vars, TPLADD, "PORT", "%d", cfg.c35_port);
888 if(IP_ISSET(cfg.c35_srvip))
889 { tpl_addVar(vars, TPLAPPEND, "SERVERIP", cs_inet_ntoa(cfg.c35_srvip)); }
891 if(cfg.c35_udp_suppresscmd08)
892 { tpl_addVar(vars, TPLADD, "SUPPRESSCMD08UDP", "checked"); }
895 return tpl_getTpl(vars, "CONFIGCAMD35");
897 #endif
899 #ifdef MODULE_CAMD35_TCP
900 static char *send_oscam_config_camd35tcp(struct templatevars *vars, struct uriparams *params)
902 setActiveSubMenu(vars, MNU_CFG_CAMD35TCP);
904 webif_save_config("cs378x", vars, params);
906 if((cfg.c35_tcp_ptab.nports > 0) && (cfg.c35_tcp_ptab.ports[0].s_port > 0))
909 char *value = mk_t_camd35tcp_port();
910 tpl_addVar(vars, TPLADD, "PORT", value);
911 free_mk_t(value);
913 if(IP_ISSET(cfg.c35_tcp_srvip))
914 { tpl_addVar(vars, TPLAPPEND, "SERVERIP", cs_inet_ntoa(cfg.c35_tcp_srvip)); }
916 if(cfg.c35_tcp_suppresscmd08)
917 { tpl_addVar(vars, TPLADD, "SUPPRESSCMD08TCP", "checked"); }
919 return tpl_getTpl(vars, "CONFIGCAMD35TCP");
921 #endif
923 static char *send_oscam_config_cache(struct templatevars *vars, struct uriparams *params)
925 setActiveSubMenu(vars, MNU_CFG_CACHE);
927 webif_save_config("cache", vars, params);
929 tpl_printf(vars, TPLADD, "CACHEDELAY", "%u", cfg.delay);
931 tpl_printf(vars, TPLADD, "MAXCACHETIME", "%d", cfg.max_cache_time);
933 #ifdef CS_CACHEEX
934 char *value = NULL;
936 #ifdef CS_CACHEEX_AIO
937 value = mk_t_cacheex_cwcheck_valuetab(&cfg.cw_cache_settings);
938 tpl_addVar(vars, TPLADD, "CWCACHESETTINGS", value);
939 free_mk_t(value);
941 tpl_printf(vars, TPLADD, "CWCACHESIZE", "%d", cfg.cw_cache_size);
943 tpl_printf(vars, TPLADD, "CWCACHEMEMORY", "%d", cfg.cw_cache_memory);
945 tpl_printf(vars, TPLADD, "ECMCACHESIZE", "%d", cfg.ecm_cache_size);
947 tpl_printf(vars, TPLADD, "ECMCACHEMEMORY", "%d", cfg.ecm_cache_memory);
949 tpl_printf(vars, TPLADD, "ECMDROPTIME", "%d", cfg.ecm_cache_droptime);
950 #endif
952 value = mk_t_cacheex_valuetab(&cfg.cacheex_wait_timetab);
953 tpl_addVar(vars, TPLADD, "WAIT_TIME", value);
954 free_mk_t(value);
956 #ifdef CS_CACHEEX_AIO
957 tpl_printf(vars, TPLADD, "WAITTIME_BLOCK_START", "%d", cfg.waittime_block_start);
959 tpl_printf(vars, TPLADD, "WAITTIME_BLOCK_TIME", "%d", cfg.waittime_block_time);
960 #endif
962 value = mk_t_caidvaluetab(&cfg.cacheex_mode1_delay_tab);
963 tpl_addVar(vars, TPLADD, "CACHEEXMODE1DELAY", value);
964 free_mk_t(value);
966 #ifdef CS_CACHEEX_AIO
967 value = mk_t_caidvaluetab(&cfg.cacheex_nopushafter_tab);
968 tpl_addVar(vars, TPLADD, "CACHEEXNOPUSHAFTER", value);
969 free_mk_t(value);
970 #endif
972 tpl_printf(vars, TPLADD, "MAX_HIT_TIME", "%d", cfg.max_hitcache_time);
974 tpl_addVar(vars, TPLADD, "CACHEEXSTATSSELECTED", (cfg.cacheex_enable_stats == 1) ? "checked" : "");
976 tpl_addVar(vars, TPLADD, "WTTCHECKED", (cfg.wait_until_ctimeout == 1) ? "checked" : "");
978 #ifdef CS_CACHEEX_AIO
979 tpl_addVar(vars, TPLADD, "CACHEEXDROPDIFFS", (cfg.cacheex_dropdiffs == 1) ? "checked" : "");
981 value = mk_t_group(cfg.cacheex_push_lg_groups);
982 tpl_addVar(vars, TPLADD, "CACHEEXPUSHLGGRPS", value);
983 free_mk_t(value);
985 tpl_addVar(vars, TPLADD, "LGONLYREMOTESETTINGSCHECKED", (cfg.cacheex_lg_only_remote_settings == 1) ? "checked" : "");
987 tpl_addVar(vars, TPLADD, "LOCALGENERATEDONLYCHECKED", (cfg.cacheex_localgenerated_only == 1) ? "checked" : "");
989 value = mk_t_ftab(&cfg.cacheex_lg_only_tab);
990 tpl_addVar(vars, TPLADD, "LGONLYTAB", value);
991 free_mk_t(value);
993 tpl_addVar(vars, TPLADD, "LOCALGENERATEDONLYINCHECKED", (cfg.cacheex_localgenerated_only_in == 1) ? "checked" : "");
995 tpl_addVar(vars, TPLADD, "LGONLYINAIOONLYCHECKED", (cfg.cacheex_lg_only_in_aio_only == 1) ? "checked" : "");
997 value = mk_t_ftab(&cfg.cacheex_lg_only_in_tab);
998 tpl_addVar(vars, TPLADD, "LGONLYINTAB", value);
999 free_mk_t(value);
1001 value = mk_t_cacheex_hitvaluetab(&cfg.cacheex_filter_caidtab);
1002 tpl_addVar(vars, TPLADD, "CACHEEXECMFILTER", value);
1003 free_mk_t(value);
1005 value = mk_t_cacheex_hitvaluetab(&cfg.cacheex_filter_caidtab_aio);
1006 tpl_addVar(vars, TPLADD, "CACHEEXECMFILTERAIO", value);
1007 free_mk_t(value);
1008 #endif
1010 if(cfg.csp_port)
1011 { tpl_printf(vars, TPLADD, "PORT", "%d", cfg.csp_port); }
1013 if(IP_ISSET(cfg.csp_srvip))
1014 { tpl_addVar(vars, TPLAPPEND, "SERVERIP", cs_inet_ntoa(cfg.csp_srvip)); }
1016 value = mk_t_cacheex_hitvaluetab(&cfg.csp.filter_caidtab);
1017 tpl_addVar(vars, TPLADD, "CSP_ECM_FILTER", value);
1018 free_mk_t(value);
1020 value = mk_t_cacheex_cwcheck_valuetab(&cfg.cacheex_cwcheck_tab);
1021 tpl_addVar(vars, TPLADD, "CACHEEXCWCHECK", value);
1022 free_mk_t(value);
1024 tpl_addVar(vars, TPLADD, "ARCHECKED", (cfg.csp.allow_request == 1) ? "checked" : "");
1025 tpl_addVar(vars, TPLADD, "ARFCHECKED", (cfg.csp.allow_reforward == 1) ? "checked" : "");
1026 tpl_addVar(vars, TPLADD, "BLOCKFAKECWSCHECKED", (cfg.csp.block_fakecws == 1) ? "checked" : "");
1027 #endif
1029 #ifdef CW_CYCLE_CHECK
1030 #ifndef CS_CACHEEX
1031 char *value = NULL;
1032 #endif
1034 tpl_addVar(vars, TPLADD, "CWCYCLECHECK", (cfg.cwcycle_check_enable == 1) ? "checked" : "");
1036 value = mk_t_caidtab(&cfg.cwcycle_check_caidtab);
1037 tpl_addVar(vars, TPLADD, "CWCYCLECHECKCAID", value);
1038 free_mk_t(value);
1040 tpl_printf(vars, TPLADD, "MAXCYCLELIST", "%d", cfg.maxcyclelist);
1041 tpl_printf(vars, TPLADD, "KEEPCYCLETIME", "%d", cfg.keepcycletime);
1043 if(cfg.onbadcycle)
1045 tpl_printf(vars, TPLADD, "TMP", "ONBADCYCLE%d", cfg.onbadcycle);
1046 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1049 tpl_addVar(vars, TPLADD, "DROPOLD", (cfg.cwcycle_dropold == 1) ? "checked" : "");
1051 if(cfg.cwcycle_sensitive)
1053 tpl_printf(vars, TPLADD, "TMP", "CWCSEN%d", cfg.cwcycle_sensitive);
1054 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1057 tpl_addVar(vars, TPLADD, "ALLOWBADFROMFFB", (cfg.cwcycle_allowbadfromffb == 1) ? "checked" : "");
1059 tpl_addVar(vars, TPLADD, "USECWCFROMCE", (cfg.cwcycle_usecwcfromce == 1) ? "checked" : "");
1062 #endif
1064 #ifdef CS_CACHEEX_AIO
1065 return tpl_getTpl(vars, "CONFIGCACHEAIO");
1066 #else
1067 return tpl_getTpl(vars, "CONFIGCACHE");
1068 #endif
1071 #ifdef MODULE_NEWCAMD
1072 static char *send_oscam_config_newcamd(struct templatevars *vars, struct uriparams *params)
1074 int32_t i;
1076 setActiveSubMenu(vars, MNU_CFG_NEWCAMD);
1078 webif_save_config("newcamd", vars, params);
1080 if((cfg.ncd_ptab.nports > 0) && (cfg.ncd_ptab.ports[0].s_port > 0))
1083 char *value = mk_t_newcamd_port();
1084 tpl_addVar(vars, TPLADD, "PORT", value);
1085 free_mk_t(value);
1087 if(IP_ISSET(cfg.ncd_srvip))
1088 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.ncd_srvip)); }
1090 for(i = 0; i < (int32_t)sizeof(cfg.ncd_key); i++)
1091 { tpl_printf(vars, TPLAPPEND, "KEY", "%02X", cfg.ncd_key[i]); }
1093 value = mk_t_iprange(cfg.ncd_allowed);
1094 tpl_addVar(vars, TPLADD, "ALLOWED", value);
1095 free_mk_t(value);
1097 if(cfg.ncd_keepalive)
1098 { tpl_addVar(vars, TPLADD, "KEEPALIVE", "checked"); }
1099 if(cfg.ncd_mgclient)
1100 { tpl_addVar(vars, TPLADD, "MGCLIENTCHK", "checked"); }
1102 return tpl_getTpl(vars, "CONFIGNEWCAMD");
1104 #endif
1106 #ifdef MODULE_GBOX
1107 static char *send_oscam_config_gbox(struct templatevars *vars, struct uriparams *params)
1109 uint8_t i=0;
1110 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] ;
1111 int n=0, len_gbox_save_gsms=0, len_gbox_msg_type=0, len_gbox_dest_peers=0, len_gbox_msg_txt=0;
1112 char *ptr1, *saveptr1, *isbroadcast = NULL;
1113 const char *s;
1114 uint16_t gbox_dest_peers_tmp;
1116 setActiveSubMenu(vars, MNU_CFG_GBOX);
1117 webif_save_config("gbox", vars, params);
1119 * Action when GetOnlinePeers is pressed
1121 if(streq(getParam(params, "action"), "Online peers"))
1123 gbox_get_online_peers();
1124 // init var
1125 len_gbox_save_gsms=cs_strlen(getParam(params, "gbox_msg_type"));
1126 len_gbox_msg_type=cs_strlen(getParam(params, "gbox_msg_type"));
1127 len_gbox_msg_txt=cs_strlen(getParam(params, "gbox_msg_txt"));
1128 if(len_gbox_msg_txt>GBOX_MAX_MSG_TXT) { len_gbox_msg_txt=GBOX_MAX_MSG_TXT; }
1129 // retrieve value from Webif
1130 cs_strncpy(local_gbox_save_gsms, getParam(params, "gbox_save_gsms"), len_gbox_save_gsms+1);
1131 cfg.gbox_save_gsms=atoi(local_gbox_save_gsms);
1132 cs_strncpy(local_gbox_msg_type, getParam(params, "gbox_msg_type"), len_gbox_msg_type+1);
1133 cfg.gbox_msg_type=atoi(local_gbox_msg_type);
1134 cs_strncpy(cfg.gbox_msg_txt,getParam(params, "gbox_msg_txt"), len_gbox_msg_txt+1);
1137 * Action when ResetGSMS button is pressed
1139 if(streq(getParam(params, "action"), "resetallgsms"))
1141 cfg.gbox_save_gsms = 0;
1142 cfg.gbox_msg_type = 0;
1143 for(i = 0; i < GBOX_MAX_DEST_PEERS; i++)
1145 cfg.gbox_dest_peers[i]='\0';
1147 cfg.gbox_dest_peers_num=0;
1148 for(i = 0; i < GBOX_MAX_MSG_TXT; i++)
1150 cfg.gbox_msg_txt[i]='\0';
1152 tpl_addMsg(vars, "GBOX: Reset GSMS datas done!");
1155 * Action when Send GSMS is pressed
1157 if(streq(getParam(params, "action"), "Send GSMS"))
1159 // init var
1160 len_gbox_msg_type=cs_strlen(getParam(params, "gbox_msg_type"));
1161 len_gbox_dest_peers=cs_strlen(trim(getParam(params, "gbox_dest_peers")));
1162 len_gbox_msg_txt=cs_strlen(getParam(params, "gbox_msg_txt"));
1163 if(len_gbox_msg_txt>GBOX_MAX_MSG_TXT) { len_gbox_msg_txt=GBOX_MAX_MSG_TXT; }
1164 // retrieve value from Webif
1165 cs_strncpy(local_gbox_msg_type, getParam(params, "gbox_msg_type"), len_gbox_msg_type+1);
1166 cfg.gbox_msg_type=atoi(local_gbox_msg_type);
1167 cs_strncpy(local_gbox_dest_peers, strtoupper(trim(getParam(params, "gbox_dest_peers"))), len_gbox_dest_peers+1);
1168 cs_strncpy(tmp_gbox_dest_peers, strtoupper(trim(getParam(params, "gbox_dest_peers"))), len_gbox_dest_peers+1);
1169 cs_strncpy(cfg.gbox_msg_txt,getParam(params, "gbox_msg_txt"), len_gbox_msg_txt+1);
1170 n=0;
1171 for (ptr1 = strtok_r(tmp_gbox_dest_peers, ",", &saveptr1); (ptr1); ptr1 = strtok_r(NULL, ",", &saveptr1))
1173 s=trim(ptr1);
1174 if ((n < GBOX_MAX_DEST_PEERS) && (s[strspn(s, "0123456789abcdefABCDEF")] == 0))
1175 { cfg.gbox_dest_peers[n++] = a2i(trim(ptr1), cs_strlen(trim(ptr1))); }
1177 cfg.gbox_dest_peers_num = n;
1179 Start sending GBox SMS
1181 if((cs_strlen(cfg.gbox_msg_txt) > 5))
1183 isbroadcast=strstr(local_gbox_dest_peers, "FFFF");
1184 if(isbroadcast == NULL)
1186 n =0;
1187 for (i = 0, ptr1 = strtok_r(local_gbox_dest_peers, ",", &saveptr1); (i < 4) && (ptr1); ptr1 = strtok_r(NULL, ",", &saveptr1))
1189 s=ptr1;
1190 if ((n < GBOX_MAX_DEST_PEERS) && (s[strspn(s, "0123456789abcdefABCDEF")] == 0))
1192 gbox_dest_peers_tmp = a2i(ptr1, 4);
1193 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);}
1194 n++;
1197 tpl_addMsg(vars, "GBOX Send SMS: individual messages started.");
1199 else
1201 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);}
1202 tpl_addMsg(vars, "GBOX Send SMS: broadcast started.");
1205 else
1207 cs_log("GBox SMS: destination peers or message text not specified or too short");
1208 tpl_addMsg(vars, "GBOX: Send SMS failed - error in input fields: dest peers or text message.");
1212 tpl_addVar(vars, TPLADD, "HOSTNAME", xml_encode(vars, cfg.gbox_hostname));
1213 char *value0 = mk_t_gbox_port();
1214 tpl_addVar(vars, TPLAPPEND, "PORT", value0);
1215 free_mk_t(value0);
1216 tpl_printf(vars, TPLADD, "MYGBOXPASSWORD", "%08X", cfg.gbox_password);
1217 tpl_printf(vars, TPLADD, "MYGBOXID", "%04X", gbox_get_local_gbox_id());
1218 tpl_printf(vars, TPLADD, "GBOXRECONNECT", "%d", cfg.gbox_reconnect);
1219 tpl_printf(vars, TPLADD, "GBOXMYVERS", "%02X", cfg.gbox_my_vers);
1220 tpl_printf(vars, TPLAPPEND, "GBOXMYCPUAPI", "%02X", cfg.gbox_my_cpu_api);
1221 #ifdef MODULE_CCCAM
1222 if(cfg.cc_gbx_reshare_en == 1) { tpl_addVar(vars, TPLADD, "GBOXCCCRESHARE", "checked"); }
1223 tpl_addVar(vars, TPLAPPEND, "CCCDEPENDINGCONFIG", tpl_getTpl(vars, "CCCAMRESHAREBIT"));
1224 #endif
1225 if(cfg.log_hello == 1) { tpl_addVar(vars, TPLADD, "GBOXLOGHELLO", "checked"); }
1226 if(cfg.gsms_dis == 1) { tpl_addVar(vars, TPLADD, "GBOXGSMSDISABLE", "checked"); }
1227 if(cfg.dis_attack_txt == 1) { tpl_addVar(vars, TPLADD, "GBOXDISATTACKTXT", "checked"); }
1228 if(cfg.gbox_tmp_dir != NULL) { tpl_addVar(vars, TPLADD, "GBOXTMPDIR", cfg.gbox_tmp_dir); }
1229 char *value1 = mk_t_gbox_proxy_card();
1230 tpl_addVar(vars, TPLAPPEND, "GBOXPROXYCARD", value1);
1231 free_mk_t(value1);
1232 char *value2 = mk_t_gbox_ignored_peer();
1233 tpl_addVar(vars, TPLAPPEND, "GBOXIGNOREDPEER", value2);
1234 free_mk_t(value2);
1235 char *value3 = mk_t_gbox_block_ecm();
1236 tpl_addVar(vars, TPLAPPEND, "GBOXBLOCKECM", value3);
1237 free_mk_t(value3);
1238 char *value4 = mk_t_accept_remm_peer();
1239 tpl_addVar(vars, TPLAPPEND, "GBOXACCEPTREMM", value4);
1240 free_mk_t(value4);
1242 * GBOX SMS
1244 tpl_addVar(vars, TPLADD, "GBOXSAVEGSMS", (cfg.gbox_save_gsms == 1) ? "checked" : "");
1245 if(cfg.gbox_msg_type == 0)
1247 tpl_addVar(vars, TPLADD, "GBOXMSGTYPENORMAL", "selected");
1249 else if(cfg.gbox_msg_type == 1)
1251 tpl_addVar(vars, TPLADD, "GBOXMSGTYPEOSD", "selected");
1253 char *gmsg_dest_peers = mk_t_gbox_dest_peers();
1254 tpl_addVar(vars, TPLADD, "GBOXMSGDESTPEERS", gmsg_dest_peers);
1255 free_mk_t(gmsg_dest_peers);
1256 tpl_addVar(vars, TPLADD, "GBOXMSGTXT", cfg.gbox_msg_txt);
1258 return tpl_getTpl(vars, "CONFIGGBOX");
1260 #endif
1262 #ifdef MODULE_RADEGAST
1263 static char *send_oscam_config_radegast(struct templatevars *vars, struct uriparams *params)
1265 setActiveSubMenu(vars, MNU_CFG_RADEGAST);
1267 webif_save_config("radegast", vars, params);
1269 tpl_printf(vars, TPLADD, "PORT", "%d", cfg.rad_port);
1270 if(IP_ISSET(cfg.rad_srvip))
1271 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.rad_srvip)); }
1272 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, cfg.rad_usr));
1274 char *value = mk_t_iprange(cfg.rad_allowed);
1275 tpl_addVar(vars, TPLADD, "ALLOWED", value);
1276 free_mk_t(value);
1278 return tpl_getTpl(vars, "CONFIGRADEGAST");
1280 #endif
1282 #ifdef MODULE_SCAM
1283 static char *send_oscam_config_scam(struct templatevars *vars, struct uriparams *params)
1285 setActiveSubMenu(vars, MNU_CFG_SCAM);
1287 webif_save_config("scam", vars, params);
1289 tpl_printf(vars, TPLADD, "PORT", "%d", cfg.scam_port);
1290 if(IP_ISSET(cfg.scam_srvip))
1291 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.scam_srvip)); }
1293 char *value = mk_t_iprange(cfg.scam_allowed);
1294 tpl_addVar(vars, TPLADD, "ALLOWED", value);
1295 free_mk_t(value);
1297 return tpl_getTpl(vars, "CONFIGSCAM");
1299 #endif
1301 #ifdef MODULE_STREAMRELAY
1302 static char *send_oscam_config_streamrelay(struct templatevars *vars, struct uriparams *params)
1304 char *value;
1306 setActiveSubMenu(vars, MNU_CFG_STREAMRELAY);
1308 webif_save_config("streamrelay", vars, params);
1310 tpl_printf(vars, TPLADD, "STREAM_SOURCE_HOST", "%s", cfg.stream_source_host);
1311 tpl_printf(vars, TPLADD, "STREAM_SOURCE_PORT", "%d", cfg.stream_source_port);
1312 if(cfg.stream_source_auth_user)
1313 { tpl_printf(vars, TPLADD, "STREAM_SOURCE_AUTH_USER", "%s", cfg.stream_source_auth_user); }
1314 if(cfg.stream_source_auth_password)
1315 { tpl_printf(vars, TPLADD, "STREAM_SOURCE_AUTH_PASSWORD", "%s", cfg.stream_source_auth_password); }
1316 #ifdef MODULE_RADEGAST
1317 tpl_addVar(vars, TPLADD, "STREAM_CLIENT_SOURCE_HOST", (cfg.stream_client_source_host == 1) ? "checked" : "");
1318 #endif
1319 tpl_printf(vars, TPLADD, "STREAM_RELAY_PORT", "%d", cfg.stream_relay_port);
1320 tpl_printf(vars, TPLADD, "STREAM_RELAY_BUFFER_TIME", "%d", cfg.stream_relay_buffer_time);
1322 tpl_printf(vars, TPLADD, "TMP", "STREAMRELAYENABLEDSELECTED%d", cfg.stream_relay_enabled);
1323 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1325 value = mk_t_caidtab(&cfg.stream_relay_ctab);
1326 tpl_addVar(vars, TPLADD, "STREAM_RELAY_CTAB", value);
1327 free_mk_t(value);
1329 return tpl_getTpl(vars, "CONFIGSTREAMRELAY");
1331 #endif
1333 #ifdef MODULE_CCCAM
1334 static char *send_oscam_config_cccam(struct templatevars *vars, struct uriparams *params)
1337 setActiveSubMenu(vars, MNU_CFG_CCCAM);
1339 if(strcmp(getParam(params, "button"), "Refresh list") == 0)
1341 cs_log_dbg(D_TRACE, "Entitlements: Refresh Shares start");
1342 #ifdef MODULE_CCCSHARE
1343 refresh_shares();
1344 #endif
1345 cs_log_dbg(D_TRACE, "Entitlements: Refresh Shares finished");
1346 tpl_addMsg(vars, "Refresh Shares started");
1349 webif_save_config("cccam", vars, params);
1351 if(streq(getParam(params, "action"), "execute") && !cfg.http_readonly)
1352 { cc_update_nodeid(); }
1354 char *value = mk_t_cccam_port();
1355 tpl_addVar(vars, TPLAPPEND, "PORT", value);
1356 free_mk_t(value);
1358 if(IP_ISSET(cfg.cc_srvip))
1359 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.cc_srvip)); }
1361 tpl_printf(vars, TPLADD, "RESHARE", "%d", cfg.cc_reshare);
1363 if(!strcmp((char *)cfg.cc_version, "2.0.11"))
1365 tpl_addVar(vars, TPLADD, "VERSIONSELECTED0", "selected");
1367 else if(!strcmp((char *)cfg.cc_version, "2.1.1"))
1369 tpl_addVar(vars, TPLADD, "VERSIONSELECTED1", "selected");
1371 else if(!strcmp((char *)cfg.cc_version, "2.1.2"))
1373 tpl_addVar(vars, TPLADD, "VERSIONSELECTED2", "selected");
1375 else if(!strcmp((char *)cfg.cc_version, "2.1.3"))
1377 tpl_addVar(vars, TPLADD, "VERSIONSELECTED3", "selected");
1379 else if(!strcmp((char *)cfg.cc_version, "2.1.4"))
1381 tpl_addVar(vars, TPLADD, "VERSIONSELECTED4", "selected");
1383 else if(!strcmp((char *)cfg.cc_version, "2.2.0"))
1385 tpl_addVar(vars, TPLADD, "VERSIONSELECTED5", "selected");
1387 else if(!strcmp((char *)cfg.cc_version, "2.2.1"))
1389 tpl_addVar(vars, TPLADD, "VERSIONSELECTED6", "selected");
1391 else if(!strcmp((char *)cfg.cc_version, "2.3.0"))
1393 tpl_addVar(vars, TPLADD, "VERSIONSELECTED7", "selected");
1395 else if(!strcmp((char *)cfg.cc_version, "2.3.1"))
1397 tpl_addVar(vars, TPLADD, "VERSIONSELECTED8", "selected");
1399 else if(!strcmp((char *)cfg.cc_version, "2.3.2"))
1401 tpl_addVar(vars, TPLADD, "VERSIONSELECTED9", "selected");
1404 tpl_printf(vars, TPLADD, "UPDATEINTERVAL", "%d", cfg.cc_update_interval);
1405 tpl_printf(vars, TPLADD, "RECV_TIMEOUT", "%u", cfg.cc_recv_timeout);
1407 tpl_addVar(vars, TPLADD, "STEALTH", (cfg.cc_stealth == 1) ? "checked" : "");
1409 tpl_printf(vars, TPLADD, "NODEID", "%02X%02X%02X%02X%02X%02X%02X%02X",
1410 cfg.cc_fixed_nodeid[0], cfg.cc_fixed_nodeid[1], cfg.cc_fixed_nodeid[2], cfg.cc_fixed_nodeid[3],
1411 cfg.cc_fixed_nodeid[4], cfg.cc_fixed_nodeid[5], cfg.cc_fixed_nodeid[6], cfg.cc_fixed_nodeid[7]);
1413 tpl_printf(vars, TPLADD, "TMP", "MINIMIZECARDSELECTED%d", cfg.cc_minimize_cards);
1414 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1416 tpl_printf(vars, TPLADD, "TMP", "RESHAREMODE%d", cfg.cc_reshare_services);
1417 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1419 tpl_printf(vars, TPLADD, "TMP", "IGNRSHRSELECTED%d", cfg.cc_ignore_reshare);
1420 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1422 tpl_addVar(vars, TPLADD, "FORWARDORIGINCARD", (cfg.cc_forward_origin_card == 1) ? "checked" : "");
1424 tpl_addVar(vars, TPLADD, "KEEPCONNECTED", (cfg.cc_keep_connected == 1) ? "checked" : "");
1426 tpl_addVar(vars, TPLADDONCE, "CONFIG_CONTROL", tpl_getTpl(vars, "CONFIGCCCAMCTRL"));
1428 return tpl_getTpl(vars, "CONFIGCCCAM");
1430 #endif
1432 static bool is_ext(const char *path, const char *ext)
1434 size_t lenpath = cs_strlen(path);
1435 size_t lenext = cs_strlen(ext);
1436 if(lenext > lenpath)
1437 { return 0; }
1438 return memcmp(path + lenpath - lenext, ext, lenext) == 0;
1441 static char *send_oscam_config_webif(struct templatevars *vars, struct uriparams *params)
1443 int32_t i;
1445 setActiveSubMenu(vars, MNU_CFG_WEBIF);
1447 webif_save_config("webif", vars, params);
1449 tpl_printf(vars, TPLADD, "HTTPPORT", "%s%d", cfg.http_use_ssl ? "+" : "", cfg.http_port);
1450 if(IP_ISSET(cfg.http_srvip))
1451 { tpl_addVar(vars, TPLAPPEND, "SERVERIP", cs_inet_ntoa(cfg.http_srvip)); }
1453 tpl_addVar(vars, TPLADD, "HTTPUSER", cfg.http_user);
1454 tpl_addVar(vars, TPLADD, "HTTPPASSWORD", cfg.http_pwd);
1455 tpl_addVar(vars, TPLADD, "HTTPOSCAMLABEL", cfg.http_oscam_label);
1457 // css style selector
1458 tpl_printf(vars, TPLADD, "CSSOPTIONS", "\t\t\t\t\t\t<option value=\"\"%s>embedded</option>\n",
1459 !cfg.http_css ? " selected" : "");
1461 if(cfg.http_tpl)
1463 char path[255];
1464 tpl_getFilePathInSubdir(cfg.http_tpl, "", "style", ".css", path, 255);
1465 if(file_exists(path))
1466 tpl_printf(vars, TPLAPPEND, "CSSOPTIONS", "\t\t\t\t\t\t<option value=\"%s\"%s>%s (template)</option>\n",
1467 path,
1468 cfg.http_css && strstr(cfg.http_css, path) ? " selected" : "",
1469 path);
1472 struct dirent **namelist;
1473 int count;
1474 count = scandir(cs_confdir, &namelist, 0, alphasort );
1476 if( count >= 0 )
1478 for( i = 0 ; i < count; i++ )
1480 if(is_ext(namelist[i]->d_name, ".css"))
1482 tpl_printf(vars, TPLAPPEND, "CSSOPTIONS", "\t\t\t\t\t\t<option value=\"%s%s\"%s>%s%s</option>\n",
1483 cs_confdir,
1484 namelist[i]->d_name,
1485 cfg.http_css && strstr(cfg.http_css, namelist[i]->d_name) ? " selected" : "",
1486 cs_confdir, namelist[i]->d_name);
1488 free( namelist[i] );
1490 free(namelist);
1493 if(cfg.http_prepend_embedded_css)
1494 { tpl_addVar(vars, TPLADD, "HTTPPREPENDEMBEDDEDCSS", "checked"); }
1496 tpl_addVar(vars, TPLADD, "HTTPHELPLANG", cfg.http_help_lang);
1497 tpl_addVar(vars, TPLADD, "HTTPLOCALE", cfg.http_locale);
1498 tpl_printf(vars, TPLADD, "HTTPEMMUCLEAN", "%d", cfg.http_emmu_clean);
1499 tpl_printf(vars, TPLADD, "HTTPEMMSCLEAN", "%d", cfg.http_emms_clean);
1500 tpl_printf(vars, TPLADD, "HTTPEMMGCLEAN", "%d", cfg.http_emmg_clean);
1501 tpl_printf(vars, TPLADD, "HTTPREFRESH", "%d", cfg.http_refresh);
1502 tpl_printf(vars, TPLADD, "HTTPPOLLREFRESH", "%d", cfg.poll_refresh);
1503 tpl_addVar(vars, TPLADD, "HTTPTPL", cfg.http_tpl);
1504 tpl_addVar(vars, TPLADD, "HTTPPICONPATH", cfg.http_piconpath);
1505 tpl_addVar(vars, TPLADD, "HTTPSCRIPT", cfg.http_script);
1506 tpl_addVar(vars, TPLADD, "HTTPJSCRIPT", cfg.http_jscript);
1507 #ifndef WEBIF_JQUERY
1508 tpl_addVar(vars, TPLADD, "HTTPEXTERNJQUERY", cfg.http_extern_jquery);
1509 #endif
1510 tpl_printf(vars, TPLADD, "HTTPPICONSIZE", "%d", cfg.http_picon_size);
1512 if(cfg.http_hide_idle_clients > 0) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
1513 tpl_addVar(vars, TPLADD, "HTTPHIDETYPE", cfg.http_hide_type);
1514 if(cfg.http_status_log > 0) { tpl_addVar(vars, TPLADD, "SHOWLOGCHECKED", "checked"); }
1515 if(cfg.http_showpicons > 0) { tpl_addVar(vars, TPLADD, "SHOWPICONSCHECKED", "checked"); }
1516 if(cfg.http_showmeminfo > 0) { tpl_addVar(vars, TPLADD, "SHOWMEMINFOCHECKED", "checked"); }
1517 if(cfg.http_showuserinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWUSERINFOCHECKED", "checked"); }
1518 if(cfg.http_showreaderinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWREADERINFOCHECKED", "checked"); }
1519 if(cfg.http_showcacheexinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWCACHEEXINFOCHECKED", "checked"); }
1520 if(cfg.http_showloadinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWLOADINFOCHECKED", "checked"); }
1521 if(cfg.http_showecminfo > 0) { tpl_addVar(vars, TPLADD, "SHOWECMINFOCHECKED", "checked"); }
1523 char *value = mk_t_iprange(cfg.http_allowed);
1524 tpl_addVar(vars, TPLADD, "HTTPALLOW", value);
1525 free_mk_t(value);
1527 for(i = 0; i < MAX_HTTP_DYNDNS; i++)
1529 if(cfg.http_dyndns[i][0])
1531 tpl_addVar(vars, TPLAPPEND, "HTTPDYNDNS", i > 0 ? "," : "");
1532 tpl_addVar(vars, TPLAPPEND, "HTTPDYNDNS", (char *)cfg.http_dyndns[i]);
1536 tpl_addVar(vars, TPLADD, "HTTPSAVEFULLSELECT", (cfg.http_full_cfg == 1) ? "checked" : "");
1537 tpl_addVar(vars, TPLADD, "HTTPOVERWRITEBAKFILE", (cfg.http_overwrite_bak_file == 1) ? "checked" : "");
1538 tpl_addVar(vars, TPLADD, "HTTPREADONLY", (cfg.http_readonly == 1) ? "checked" : "");
1541 #ifdef WITH_SSL
1542 if(cfg.http_cert != NULL) { tpl_addVar(vars, TPLADD, "HTTPCERT", cfg.http_cert); }
1543 tpl_addVar(vars, TPLADD, "HTTPFORCESECUREMODESELECT", (cfg.https_force_secure_mode == 1) ? "checked" : "");
1544 #endif
1546 #ifndef WEBIF_JQUERY
1547 tpl_addVar(vars, TPLADDONCE, "CONFIGWEBIFJQUERY", tpl_getTpl(vars, "CONFIGWEBIFJQUERYBIT"));
1548 #endif
1550 tpl_printf(vars, TPLADD, "AULOW", "%d", cfg.aulow);
1551 tpl_printf(vars, TPLADD, "HIDECLIENTTO", "%d", cfg.hideclient_to);
1553 return tpl_getTpl(vars, "CONFIGWEBIF");
1556 #ifdef LCDSUPPORT
1557 static char *send_oscam_config_lcd(struct templatevars *vars, struct uriparams *params)
1559 setActiveSubMenu(vars, MNU_CFG_LCD);
1561 webif_save_config("lcd", vars, params);
1563 tpl_addVar(vars, TPLADD, "ENABLELCDSELECTED", (cfg.enablelcd == 1) ? "checked" : "");
1565 if(cfg.lcd_output_path != NULL)
1566 { tpl_addVar(vars, TPLADD, "LCDOUTPUTPATH", cfg.lcd_output_path); }
1568 tpl_addVar(vars, TPLADD, "LCDHIDEIDLE", (cfg.lcd_hide_idle == 1) ? "checked" : "");
1570 tpl_printf(vars, TPLADD, "LCDREFRESHINTERVAL", "%d", cfg.lcd_write_intervall);
1572 return tpl_getTpl(vars, "CONFIGLCD");
1574 #endif
1576 #ifdef MODULE_MONITOR
1577 static char *send_oscam_config_monitor(struct templatevars *vars, struct uriparams *params)
1579 setActiveSubMenu(vars, MNU_CFG_MONITOR);
1581 webif_save_config("monitor", vars, params);
1583 tpl_printf(vars, TPLADD, "MONPORT", "%d", cfg.mon_port);
1584 if(IP_ISSET(cfg.mon_srvip))
1585 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.mon_srvip)); }
1587 tpl_printf(vars, TPLADD, "AULOW", "%d", cfg.aulow);
1588 tpl_printf(vars, TPLADD, "HIDECLIENTTO", "%d", cfg.hideclient_to);
1590 char *value = mk_t_iprange(cfg.mon_allowed);
1591 tpl_addVar(vars, TPLADD, "NOCRYPT", value);
1592 free_mk_t(value);
1594 //Monlevel selector
1595 tpl_printf(vars, TPLADD, "TMP", "MONSELECTED%d", cfg.mon_level);
1596 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1598 return tpl_getTpl(vars, "CONFIGMONITOR");
1600 #endif
1602 #ifdef MODULE_SERIAL
1603 static char *send_oscam_config_serial(struct templatevars *vars, struct uriparams *params)
1605 setActiveSubMenu(vars, MNU_CFG_SERIAL);
1607 webif_save_config("serial", vars, params);
1609 if(cfg.ser_device)
1611 char sdevice[cs_strlen(cfg.ser_device)];
1612 cs_strncpy(sdevice, cfg.ser_device, sizeof(sdevice));
1613 char *ptr, *saveptr1 = NULL;
1614 char delimiter[2];
1615 delimiter[0] = 1;
1616 delimiter[1] = '\0';
1617 for(ptr = strtok_r(sdevice, delimiter, &saveptr1); ptr; ptr = strtok_r(NULL, delimiter, &saveptr1))
1619 tpl_addVar(vars, TPLADD, "SERIALDEVICE", xml_encode(vars, ptr));
1620 tpl_addVar(vars, TPLAPPEND, "DEVICES", tpl_getTpl(vars, "CONFIGSERIALDEVICEBIT"));
1624 tpl_addVar(vars, TPLADD, "SERIALDEVICE", "");
1625 tpl_addVar(vars, TPLAPPEND, "DEVICES", tpl_getTpl(vars, "CONFIGSERIALDEVICEBIT"));
1627 return tpl_getTpl(vars, "CONFIGSERIAL");
1629 #endif
1631 #ifdef HAVE_DVBAPI
1632 extern const char *boxdesc[];
1634 static char *send_oscam_config_dvbapi(struct templatevars *vars, struct uriparams *params)
1636 int32_t i;
1638 setActiveSubMenu(vars, MNU_CFG_DVBAPI);
1640 webif_save_config("dvbapi", vars, params);
1642 if(cfg.dvbapi_enabled > 0)
1643 { tpl_addVar(vars, TPLADD, "ENABLEDCHECKED", "checked"); }
1645 if(cfg.dvbapi_au > 0)
1646 { tpl_addVar(vars, TPLADD, "AUCHECKED", "checked"); }
1648 if(cfg.dvbapi_delayer > 0)
1649 { tpl_printf(vars, TPLADD, "DELAYER", "%d", cfg.dvbapi_delayer); }
1651 tpl_printf(vars, TPLADD, "BOXTYPE", "<option value=\"\"%s>None</option>\n", cfg.dvbapi_boxtype == 0 ? " selected" : "");
1652 for(i = 1; i <= BOXTYPES; i++)
1654 tpl_printf(vars, TPLAPPEND, "BOXTYPE", "<option%s>%s</option>\n", cfg.dvbapi_boxtype == i ? " selected" : "", boxdesc[i]);
1657 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, cfg.dvbapi_usr));
1659 //PMT Mode
1660 tpl_printf(vars, TPLADD, "TMP", "PMTMODESELECTED%d", cfg.dvbapi_pmtmode);
1661 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1663 //Request Mode
1664 tpl_printf(vars, TPLADD, "TMP", "REQMODESELECTED%d", cfg.dvbapi_requestmode);
1665 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1667 //ecminfo_file
1668 if(cfg.dvbapi_ecminfo_file > 0)
1669 { tpl_addVar(vars, TPLADD, "ECMINFOFILECHECKED", "checked"); }
1671 //ecminfo_type
1672 tpl_printf(vars, TPLADD, "TMP", "ECMINFOTYPESELECTED%d", cfg.dvbapi_ecminfo_type);
1673 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1675 //read_sdt
1676 tpl_printf(vars, TPLADD, "TMP", "READSDTSELECTED%d", cfg.dvbapi_read_sdt);
1677 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1679 //extended_cw_api
1680 tpl_printf(vars, TPLADD, "TMP", "EXTENDEDCWAPISELECTED%d", cfg.dvbapi_extended_cw_api);
1681 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1683 //write_sdt_prov
1684 if(cfg.dvbapi_write_sdt_prov > 0)
1685 { tpl_addVar(vars, TPLADD, "WRITESDTPROVCHECKED", "checked"); }
1687 #ifdef MODULE_STREAMRELAY
1688 //demuxer_fix
1689 if(cfg.dvbapi_demuxer_fix > 0)
1690 { tpl_addVar(vars, TPLADD, "DEMUXERFIXCHECKED", "checked"); }
1691 #endif
1693 //TCP listen port
1694 if(cfg.dvbapi_listenport > 0)
1695 { tpl_printf(vars, TPLADD, "LISTENPORT", "%d", cfg.dvbapi_listenport); }
1697 return tpl_getTpl(vars, "CONFIGDVBAPI");
1699 #endif
1701 #ifdef CS_ANTICASC
1702 static char *send_oscam_config_anticasc(struct templatevars *vars, struct uriparams *params)
1704 setActiveSubMenu(vars, MNU_CFG_ANTICASC);
1706 webif_save_config("anticasc", vars, params);
1708 if(cfg.ac_enabled > 0) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
1709 tpl_printf(vars, TPLADD, "NUMUSERS", "%d", cfg.ac_users);
1710 tpl_printf(vars, TPLADD, "SAMPLETIME", "%d", cfg.ac_stime);
1711 tpl_printf(vars, TPLADD, "SAMPLES", "%d", cfg.ac_samples);
1713 tpl_printf(vars, TPLADD, "TMP", "PENALTY%d", cfg.ac_penalty);
1714 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1716 if(cfg.ac_logfile)
1717 { tpl_addVar(vars, TPLADD, "ACLOGFILE", cfg.ac_logfile); }
1718 tpl_printf(vars, TPLADD, "FAKEDELAY", "%d", cfg.ac_fakedelay);
1719 tpl_printf(vars, TPLADD, "DENYSAMPLES", "%d", cfg.ac_denysamples);
1721 if(cfg.acosc_enabled == 1)
1722 { tpl_addVar(vars, TPLADD, "ACOSC_CHECKED", "checked"); }
1723 tpl_printf(vars, TPLADD, "ACOSC_MAX_ECMS_PER_MINUTE", "%d", cfg.acosc_max_ecms_per_minute);
1724 tpl_printf(vars, TPLADD, "ACOSC_MAX_ACTIVE_SIDS", "%d", cfg.acosc_max_active_sids);
1725 tpl_printf(vars, TPLADD, "ACOSC_ZAP_LIMIT", "%d", cfg.acosc_zap_limit);
1726 tpl_printf(vars, TPLADD, "TMP", "ACOSC_PENALTY%d", cfg.acosc_penalty);
1727 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1728 tpl_printf(vars, TPLADD, "ACOSC_PENALTY_DURATION", "%d", cfg.acosc_penalty_duration);
1729 tpl_printf(vars, TPLADD, "ACOSC_DELAY", "%d", cfg.acosc_delay);
1731 return tpl_getTpl(vars, "CONFIGANTICASC");
1733 #endif
1735 static char *send_oscam_config(struct templatevars *vars, struct uriparams *params)
1738 setActiveMenu(vars, MNU_CONFIG);
1740 char *part = getParam(params, "part");
1741 if(!strcmp(part, "webif")) { return send_oscam_config_webif(vars, params); }
1742 #ifdef MODULE_MONITOR
1743 else if(!strcmp(part, "monitor")) { return send_oscam_config_monitor(vars, params); }
1744 #endif
1745 #ifdef LCDSUPPORT
1746 else if(!strcmp(part, "lcd")) { return send_oscam_config_lcd(vars, params); }
1747 #endif
1748 #ifdef MODULE_CAMD33
1749 else if(!strcmp(part, "camd33")) { return send_oscam_config_camd33(vars, params); }
1750 #endif
1751 #ifdef MODULE_CAMD35
1752 else if(!strcmp(part, "camd35")) { return send_oscam_config_camd35(vars, params); }
1753 #endif
1754 #ifdef MODULE_CAMD35_TCP
1755 else if(!strcmp(part, "camd35tcp")) { return send_oscam_config_camd35tcp(vars, params); }
1756 #endif
1757 else if(!strcmp(part, "cache")) { return send_oscam_config_cache(vars, params); }
1758 #ifdef MODULE_NEWCAMD
1759 else if(!strcmp(part, "newcamd")) { return send_oscam_config_newcamd(vars, params); }
1760 #endif
1761 #ifdef MODULE_RADEGAST
1762 else if(!strcmp(part, "radegast")) { return send_oscam_config_radegast(vars, params); }
1763 #endif
1764 #ifdef MODULE_SCAM
1765 else if(!strcmp(part, "scam")) { return send_oscam_config_scam(vars, params); }
1766 #endif
1767 #ifdef MODULE_STREAMRELAY
1768 else if(!strcmp(part, "streamrelay")) { return send_oscam_config_streamrelay(vars, params); }
1769 #endif
1770 #ifdef MODULE_CCCAM
1771 else if(!strcmp(part, "cccam")) { return send_oscam_config_cccam(vars, params); }
1772 #endif
1773 #ifdef MODULE_GBOX
1774 else if(!strcmp(part, "gbox")) { return send_oscam_config_gbox(vars, params); }
1775 #endif
1776 #ifdef HAVE_DVBAPI
1777 else if(!strcmp(part, "dvbapi")) { return send_oscam_config_dvbapi(vars, params); }
1778 #endif
1779 #ifdef CS_ANTICASC
1780 else if(!strcmp(part, "anticasc")) { return send_oscam_config_anticasc(vars, params); }
1781 #endif
1782 #ifdef MODULE_SERIAL
1783 else if(!strcmp(part, "serial")) { return send_oscam_config_serial(vars, params); }
1784 #endif
1785 #ifdef WITH_LB
1786 else if(!strcmp(part, "loadbalancer")) { return send_oscam_config_loadbalancer(vars, params); }
1787 #endif
1788 else { return send_oscam_config_global(vars, params); }
1791 static void inactivate_reader(struct s_reader *rdr)
1793 struct s_client *cl = rdr->client;
1794 if(cl)
1795 { kill_thread(cl); }
1798 static bool picon_exists(char *name)
1800 char picon_name[255], path[255];
1801 char *tpl_path;
1802 tpl_path = cfg.http_piconpath ? cfg.http_piconpath : cfg.http_tpl;
1803 if(!tpl_path)
1804 { return false; }
1805 snprintf(picon_name, sizeof(picon_name) - 1, "IC_%s", name);
1806 return cs_strlen(tpl_getTplPath(picon_name, tpl_path, path, sizeof(path) - 1)) && file_exists(path);
1809 static void clear_rdr_stats(struct s_reader *rdr)
1811 int i;
1812 for(i = 0; i < 4; i++)
1814 rdr->emmerror[i] = 0;
1815 rdr->emmwritten[i] = 0;
1816 rdr->emmskipped[i] = 0;
1817 rdr->emmblocked[i] = 0;
1819 rdr->ecmsok = 0;
1820 #ifdef CS_CACHEEX_AIO
1821 rdr->ecmsoklg = 0;
1822 #endif
1823 rdr->ecmsnok = 0;
1824 rdr->ecmstout = 0;
1825 rdr->ecmshealthok = 0;
1826 #ifdef CS_CACHEEX_AIO
1827 rdr->ecmshealthoklg = 0;
1828 #endif
1829 rdr->ecmshealthnok = 0;
1830 rdr->ecmshealthtout = 0;
1831 rdr->ecmsfilteredhead = 0;
1832 rdr->ecmsfilteredlen = 0;
1835 static void clear_all_rdr_stats(void)
1837 struct s_reader *rdr;
1838 LL_ITER itr = ll_iter_create(configured_readers);
1839 while((rdr = ll_iter_next(&itr)))
1841 clear_rdr_stats(rdr);
1845 static char *send_oscam_reader(struct templatevars *vars, struct uriparams *params, int32_t apicall)
1847 struct s_reader *rdr;
1848 int32_t i;
1849 uint8_t md5tmp[MD5_DIGEST_LENGTH];
1850 char *status;
1852 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
1853 if(!apicall)
1855 if(strcmp(getParam(params, "action"), "resetallrdrstats") == 0)
1857 clear_all_rdr_stats();
1861 tpl_addVar(vars, TPLADD, "READERACTIONCOLS", config_enabled(WITH_LB) ? "6" : "5");
1863 if(strcmp(getParam(params, "action"), "resetuserstats") == 0)
1865 clear_info_clients_stats();
1867 if(strcmp(getParam(params, "action"), "resetreaderstats") == 0)
1869 clear_info_readers_stats();
1871 if(strcmp(getParam(params, "action"), "reloadreaders") == 0)
1873 if(!cfg.http_readonly)
1874 { refresh_oscam(REFR_READERS); }
1876 if((strcmp(getParam(params, "action"), "disable") == 0) || (strcmp(getParam(params, "action"), "enable") == 0))
1878 if(cfg.http_readonly)
1880 tpl_addMsg(vars, "WebIf is in readonly mode. Enabling or disabling readers is not possible!");
1882 else
1884 rdr = get_reader_by_label(getParam(params, "label"));
1885 if(rdr)
1887 if(strcmp(getParam(params, "action"), "enable") == 0)
1889 if(!rdr->enable)
1891 rdr->enable = 1;
1894 else
1896 if(rdr->enable)
1898 rdr->enable = 0;
1901 if(rdr->typ != R_GBOX)
1903 restart_cardreader(rdr, 1);
1905 #ifdef MODULE_GBOX
1906 else
1908 restart_gbox_peer(rdr->label, 0, 0);
1909 cs_log("gbox -> you must restart oscam so that setting becomes effective");
1911 #endif
1913 cs_log("reader %s %s by WebIf", rdr->label, rdr->enable == 1 ? "enabled":"disabled");
1915 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
1917 #ifdef MODULE_GBOX
1918 if(!is_network_reader(rdr) && !rdr->enable)
1920 gbx_local_card_stat(LOCALCARDDISABLED, 0);
1922 #endif
1927 if(strcmp(getParam(params, "action"), "delete") == 0)
1929 if(cfg.http_readonly)
1931 tpl_addMsg(vars, "WebIf is in readonly mode. No deletion will be made!");
1933 else
1935 rdr = get_reader_by_label(getParam(params, "label"));
1936 if(rdr)
1938 inactivate_reader(rdr);
1939 ll_remove(configured_readers, rdr);
1941 free_reader(rdr);
1943 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
1948 if(strcmp(getParam(params, "action"), "reread") == 0)
1950 rdr = get_reader_by_label(getParam(params, "label"));
1951 if(rdr)
1953 struct s_client *cl = rdr->client;
1954 //reset the counters
1955 for(i = 0; i < 4; i++)
1957 rdr->emmerror[i] = 0;
1958 rdr->emmwritten[i] = 0;
1959 rdr->emmskipped[i] = 0;
1960 rdr->emmblocked[i] = 0;
1963 if(rdr->enable == 1 && cl && cl->typ == 'r')
1965 add_job(cl, ACTION_READER_CARDINFO, NULL, 0);
1970 LL_ITER itr = ll_iter_create(configured_readers);
1972 if(!apicall)
1974 for(i = 0, rdr = ll_iter_next(&itr); rdr && rdr->label[0]; rdr = ll_iter_next(&itr), i++) { ; }
1975 tpl_printf(vars, TPLADD, "NEXTREADER", "Reader-%d", i); //Next Readername
1978 int jsondelimiter = 0;
1979 int existing_insert = 0;
1981 int32_t total_readers = 0;
1982 int32_t disabled_readers = 0;
1983 int32_t active_readers = 0;
1984 int32_t connected_readers = 0;
1986 ll_iter_reset(&itr); //going to iterate all configured readers
1987 while((rdr = ll_iter_next(&itr)))
1989 #ifdef CS_CACHEEX_AIO
1990 const char *proto = reader_get_type_desc(rdr, 0);
1991 #endif
1992 struct s_client *cl = rdr->client;
1993 if(rdr->label[0] && rdr->typ)
1995 #ifdef CS_CACHEEX_AIO
1996 char *new_proto;
1997 #if defined(MODULE_CAMD35) || defined (MODULE_CAMD35_TCP)
1998 if(rdr->cacheex.feature_bitfield || (cl && cl->c35_extmode > 1))
1999 #else
2000 if(rdr->cacheex.feature_bitfield)
2001 #endif
2003 const char *aio_suffix = " (cx-aio)";
2005 if(cs_malloc(&new_proto, cs_strlen(proto)+cs_strlen(aio_suffix)+1)) {
2006 if (!cs_strncat(new_proto, (char *)proto, cs_strlen(proto)+cs_strlen(aio_suffix)+1)) {
2007 cs_log("FIXME!");
2009 if (!cs_strncat(new_proto, (char *)aio_suffix, cs_strlen(proto)+cs_strlen(aio_suffix)+1)) {
2010 cs_log("FIXME!");
2014 #endif
2015 total_readers += 1;
2017 // used for API and WebIf
2018 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
2020 MD5((uint8_t *)rdr->label, cs_strlen(rdr->label), md5tmp);
2021 int z;
2022 tpl_addVar(vars, TPLADD, "LABELMD5","id_");
2023 for (z = 0; z < MD5_DIGEST_LENGTH; z++)
2025 tpl_printf(vars, TPLAPPEND, "LABELMD5", "%02x", md5tmp[z]);
2027 #ifdef MODULE_GBOX
2028 if(apicall)
2030 tpl_addVar(vars, TPLADD, "LASTGSMS", "");
2031 tpl_addVar(vars, TPLADD, "LASTGSMS", rdr->last_gsms);
2033 #endif
2034 if(apicall)
2036 tpl_printf(vars, TPLADD, "PICONENABLED", "%d", cfg.http_showpicons?1:0);
2038 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, rdr->label));
2039 if(!existing_insert)
2041 tpl_printf(vars, TPLADD, "EXISTING_INS", "'%s'", urlencode(vars, rdr->label));
2042 existing_insert++;
2043 }else
2045 tpl_printf(vars, TPLAPPEND, "EXISTING_INS", ",'%s'", urlencode(vars, rdr->label));
2047 tpl_addVar(vars, TPLADD, "READERCLASS", rdr->enable ? "enabledreader" : "disabledreader");
2049 if(rdr->enable) { active_readers += 1; }
2050 else { disabled_readers += 1; }
2052 if(rdr->tcp_connected)
2054 connected_readers += 1;
2056 #ifdef CS_CACHEEX_AIO
2057 if(rdr->cacheex.feature_bitfield)
2059 tpl_addVar(vars, TPLADD, "CLIENTPROTOSORT", (const char*)new_proto);
2060 tpl_addVar(vars, TPLADD, "CLIENTPROTO", (const char*)new_proto);
2061 if(cfg.http_showpicons)
2063 char picon_name[32];
2064 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", new_proto);
2065 if(picon_exists(picon_name))
2067 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s",(char*)new_proto);
2071 if(rdr->cacheex.feature_bitfield & 32)
2072 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", rdr->cacheex.aio_version);
2073 else if(cl->reader->cacheex.feature_bitfield)
2074 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", "[cx-aio < 9.2.3]");
2076 else
2078 tpl_addVar(vars, TPLADD, "CLIENTPROTOSORT", proto);
2079 tpl_addVar(vars, TPLADD, "CLIENTPROTO", proto);
2080 if(cfg.http_showpicons)
2082 char picon_name[32];
2083 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", proto);
2084 if(picon_exists(picon_name))
2086 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s",(char *)proto);
2090 #else
2091 tpl_addVar(vars, TPLADD, "CLIENTPROTO", reader_get_type_desc(rdr, 0));
2092 tpl_addVar(vars, TPLADD, "CLIENTPROTOSORT", reader_get_type_desc(rdr, 0));
2093 if(cfg.http_showpicons)
2095 char picon_name[32];
2096 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", reader_get_type_desc(rdr, 0));
2097 if(picon_exists(picon_name))
2099 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s", reader_get_type_desc(rdr, 0));
2102 #endif
2103 switch(rdr->card_status)
2105 case CARD_INSERTED:
2106 status = "<B>online</B>";
2107 tpl_addVar(vars, TPLADD, "RSTATUS", status);
2108 tpl_addVar(vars, TPLADD, "READERCLASS", "r_connected");
2109 break;
2111 case NO_CARD:
2112 case UNKNOWN:
2113 case READER_DEVICE_ERROR:
2114 case CARD_NEED_INIT:
2115 case CARD_FAILURE:
2116 default:
2117 status = "<B>connected</B>";
2118 tpl_addVar(vars, TPLADD, "RSTATUS", status);
2119 tpl_addVar(vars, TPLADD, "READERCLASS", "r_undefined");
2120 break;
2123 tpl_addVar(vars, TPLADD, "READERIP", cs_inet_ntoa(rdr->client->ip));
2125 else
2127 /* default initial values */
2128 tpl_addVar(vars, TPLADDONCE, "RSTATUS", "offline");
2129 tpl_addVar(vars, TPLADDONCE, "READERIP", "");
2130 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTO", "");
2131 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOSORT", "");
2132 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOTITLE", "");
2133 tpl_addVar(vars, TPLADDONCE, "PROTOICON", "");
2135 if(!is_network_reader(rdr) && rdr->enable)
2137 switch(rdr->card_status)
2139 case CARD_INSERTED:
2140 status = "<B>active</B>";
2141 tpl_addVar(vars, TPLADD, "RSTATUS", status);
2142 tpl_addVar(vars, TPLADD, "READERCLASS", "r_connected");
2143 break;
2145 case NO_CARD:
2146 case UNKNOWN:
2147 case READER_DEVICE_ERROR:
2148 case CARD_NEED_INIT:
2149 case CARD_FAILURE:
2150 default:
2151 status = "<B>connected</B>";
2152 tpl_addVar(vars, TPLADD, "RSTATUS", status);
2153 tpl_addVar(vars, TPLADD, "READERCLASS", "r_undefined");
2154 break;
2157 tpl_addVar(vars, TPLADD, "CLIENTPROTO", reader_get_type_desc(rdr, 0));
2158 tpl_addVar(vars, TPLADD, "CLIENTPROTOSORT", reader_get_type_desc(rdr, 0));
2159 if(cfg.http_showpicons)
2161 char picon_name[32];
2162 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", reader_get_type_desc(rdr, 0));
2163 if(picon_exists(picon_name))
2165 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s", reader_get_type_desc(rdr, 0));
2171 if(rdr->description)
2172 tpl_printf(vars, TPLADD, "DESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, rdr->description));
2173 else
2174 tpl_addVar(vars, TPLADD, "DESCRIPTION", "");
2176 if(cfg.http_showpicons && !apicall)
2178 tpl_addVar(vars, TPLADD, "READERBIT", tpl_getTpl(vars, picon_exists(xml_encode(vars, rdr->label)) ? "READERNAMEBIT" : "READERNOICON"));
2179 #ifdef CS_CACHEEX_AIO
2180 if(rdr->cacheex.feature_bitfield)
2182 tpl_addVar(vars, TPLADD, "CLIENTPROTO", picon_exists(xml_encode(vars, (const char*)new_proto)) ? tpl_getTpl(vars, "READERCTYPBIT") : tpl_getTpl(vars, "READERCTYPNOICON"));
2184 else
2186 #endif
2187 tpl_addVar(vars, TPLADD, "CLIENTPROTO", picon_exists(xml_encode(vars, reader_get_type_desc(rdr, 0))) ? tpl_getTpl(vars, "READERCTYPBIT") : tpl_getTpl(vars, "READERCTYPNOICON"));
2188 #ifdef CS_CACHEEX_AIO
2190 #endif
2192 else
2193 tpl_addVar(vars, TPLADD, "READERBIT", tpl_getTpl(vars, "READERLABEL"));
2195 char *value = mk_t_group(rdr->grp);
2196 tpl_addVar(vars, TPLADD, "GROUPS", value);
2197 free_mk_t(value);
2198 tpl_printf(vars, TPLADD, "EMMERRORUK", PRINTF_LOCAL_D, rdr->emmerror[UNKNOWN]);
2199 tpl_printf(vars, TPLADD, "EMMERRORG", PRINTF_LOCAL_D, rdr->emmerror[GLOBAL]);
2200 tpl_printf(vars, TPLADD, "EMMERRORS", PRINTF_LOCAL_D, rdr->emmerror[SHARED]);
2201 tpl_printf(vars, TPLADD, "EMMERRORUQ", PRINTF_LOCAL_D, rdr->emmerror[UNIQUE]);
2203 tpl_printf(vars, TPLADD, "EMMWRITTENUK", PRINTF_LOCAL_D, rdr->emmwritten[UNKNOWN]);
2204 tpl_printf(vars, TPLADD, "EMMWRITTENG", PRINTF_LOCAL_D, rdr->emmwritten[GLOBAL]);
2205 tpl_printf(vars, TPLADD, "EMMWRITTENS", PRINTF_LOCAL_D, rdr->emmwritten[SHARED]);
2206 tpl_printf(vars, TPLADD, "EMMWRITTENUQ", PRINTF_LOCAL_D, rdr->emmwritten[UNIQUE]);
2208 tpl_printf(vars, TPLADD, "EMMSKIPPEDUK", PRINTF_LOCAL_D, rdr->emmskipped[UNKNOWN]);
2209 tpl_printf(vars, TPLADD, "EMMSKIPPEDG", PRINTF_LOCAL_D, rdr->emmskipped[GLOBAL]);
2210 tpl_printf(vars, TPLADD, "EMMSKIPPEDS", PRINTF_LOCAL_D, rdr->emmskipped[SHARED]);
2211 tpl_printf(vars, TPLADD, "EMMSKIPPEDUQ", PRINTF_LOCAL_D, rdr->emmskipped[UNIQUE]);
2213 tpl_printf(vars, TPLADD, "EMMBLOCKEDUK", PRINTF_LOCAL_D, rdr->emmblocked[UNKNOWN]);
2214 tpl_printf(vars, TPLADD, "EMMBLOCKEDG", PRINTF_LOCAL_D, rdr->emmblocked[GLOBAL]);
2215 tpl_printf(vars, TPLADD, "EMMBLOCKEDS", PRINTF_LOCAL_D, rdr->emmblocked[SHARED]);
2216 tpl_printf(vars, TPLADD, "EMMBLOCKEDUQ", PRINTF_LOCAL_D, rdr->emmblocked[UNIQUE]);
2218 tpl_printf(vars, TPLADD, "ECMSOK", PRINTF_LOCAL_D, rdr->ecmsok);
2219 tpl_printf(vars, TPLADD, "ECMSOKREL", " (%.2f %%)", rdr->ecmshealthok);
2220 #ifdef CS_CACHEEX_AIO
2221 tpl_printf(vars, TPLADD, "ECMSOKLG", PRINTF_LOCAL_D, rdr->ecmsoklg);
2222 tpl_printf(vars, TPLADD, "ECMSOKLGREL", " (%.2f %%)", rdr->ecmshealthoklg);
2223 #endif
2224 tpl_printf(vars, TPLADD, "ECMSNOK", PRINTF_LOCAL_D, rdr->ecmsnok);
2225 tpl_printf(vars, TPLADD, "ECMSNOKREL", " (%.2f %%)",rdr->ecmshealthnok);
2226 tpl_printf(vars, TPLADD, "ECMSTOUT", PRINTF_LOCAL_D, rdr->ecmstout);
2227 tpl_printf(vars, TPLADD, "ECMSTOUTREL", " (%.2f %%)",rdr->ecmshealthtout);
2228 tpl_printf(vars, TPLADD, "ECMSFILTEREDHEAD", PRINTF_LOCAL_D, rdr->ecmsfilteredhead);
2229 tpl_printf(vars, TPLADD, "ECMSFILTEREDLEN", PRINTF_LOCAL_D, rdr->ecmsfilteredlen);
2230 #ifdef WITH_LB
2231 tpl_printf(vars, TPLADD, "LBWEIGHT", "%d", rdr->lb_weight);
2232 #endif
2233 if(!is_network_reader(rdr)) //reader is physical
2235 tpl_addVar(vars, TPLADD, "REFRICO", "image?i=ICREF");
2236 tpl_addVar(vars, TPLADD, "READERREFRESH", tpl_getTpl(vars, "READERREFRESHBIT"));
2237 tpl_addVar(vars, TPLADD, "ENTICO", "image?i=ICENT");
2238 tpl_addVar(vars, TPLADD, "ENTITLEMENT", tpl_getTpl(vars, "READERENTITLEBIT"));
2240 else
2242 tpl_addVar(vars, TPLADD, "READERREFRESH", "");
2243 if(rdr->typ == R_CCCAM)
2245 tpl_addVar(vars, TPLADD, "ENTICO", "image?i=ICENT");
2246 tpl_addVar(vars, TPLADD, "ENTITLEMENT", tpl_getTpl(vars, "READERENTITLEBIT"));
2248 else
2250 tpl_addVar(vars, TPLADD, "ENTITLEMENT", "");
2254 if(rdr->enable == 0)
2256 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICENA");
2257 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Enable");
2258 tpl_addVar(vars, TPLADD, "SWITCH", "enable");
2259 tpl_addVar(vars, TPLADD, "WRITEEMM", "");
2261 else
2263 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICDIS");
2264 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Disable");
2265 tpl_addVar(vars, TPLADD, "SWITCH", "disable");
2267 tpl_addVar(vars, TPLADD, "EMMICO", "image?i=ICEMM");
2268 tpl_addVar(vars, TPLADD, "WRITEEMM", tpl_getTpl(vars, "READERWRITEEMMBIT"));
2271 if(!apicall)
2273 // Add to WebIf Template
2274 #ifdef CS_CACHEEX_AIO
2275 tpl_addVar(vars, TPLAPPEND, "READERLIST", tpl_getTpl(vars, "READERSBITAIO"));
2276 #else
2277 tpl_addVar(vars, TPLAPPEND, "READERLIST", tpl_getTpl(vars, "READERSBIT"));
2278 #endif
2280 else
2283 // used only for API
2284 tpl_addVar(vars, TPLADD, "APIREADERENABLED", !rdr->enable ? "0" : "1");
2285 if(cl)
2287 tpl_printf(vars, TPLADD, "APIREADERTYPE", "%c", cl->typ ? cl->typ : 'x');
2290 if(apicall==1)
2292 // Add to API Template
2293 tpl_addVar(vars, TPLAPPEND, "APIREADERLIST", tpl_getTpl(vars, "APIREADERSBIT"));
2295 if(apicall==2)
2297 tpl_printf(vars, TPLAPPEND, "APIREADERLIST","%s%s",jsondelimiter?",":"", tpl_getTpl(vars, "JSONREADERBIT"));
2298 jsondelimiter++;
2301 #ifdef CS_CACHEEX_AIO
2302 if(rdr->cacheex.feature_bitfield)
2304 free(new_proto);
2306 #endif
2310 tpl_printf(vars, TPLADD, "TOTAL_READERS", "%d", total_readers);
2311 tpl_printf(vars, TPLADD, "TOTAL_DISABLED_READERS", "%d", disabled_readers);
2312 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE_READERS", "%d", active_readers);
2313 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED_READERS", "%d", connected_readers);
2315 //CM info
2316 tpl_addVar(vars, TPLADD, "DISPLAYUSERINFO", "hidden"); // no userinfo in readers
2317 set_ecm_info(vars);
2319 if(!apicall)
2321 #ifdef MODULE_CAMD33
2322 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>camd33</option>\n");
2323 #endif
2324 #ifdef MODULE_CAMD35
2325 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>cs357x</option>\n");
2326 #endif
2327 #ifdef MODULE_CAMD35_TCP
2328 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>cs378x</option>\n");
2329 #endif
2330 #ifdef MODULE_NEWCAMD
2331 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>newcamd</option>\n");
2332 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>newcamd524</option>\n");
2333 #endif
2334 #ifdef MODULE_CCCAM
2335 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>cccam</option>\n");
2336 #endif
2337 #ifdef MODULE_GBOX
2338 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>gbox</option>\n");
2339 #endif
2340 #ifdef MODULE_RADEGAST
2341 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>radegast</option>\n");
2342 #endif
2343 #ifdef MODULE_SERIAL
2344 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>serial</option>\n");
2345 #endif
2346 #ifdef MODULE_CONSTCW
2347 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>constcw</option>\n");
2348 #endif
2349 #ifdef MODULE_SCAM
2350 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>scam</option>\n");
2351 #endif
2353 for(i = 0; cardreaders[i]; i++)
2355 tpl_printf(vars, TPLAPPEND, "ADDPROTOCOL", "<option>%s</option>\n", xml_encode(vars, cardreaders[i]->desc));
2357 #ifdef CS_CACHEEX_AIO
2358 return tpl_getTpl(vars, "READERSAIO");
2359 #else
2360 return tpl_getTpl(vars, "READERS");
2361 #endif
2363 else
2365 if(apicall == 1)
2367 return tpl_getTpl(vars, "APIREADERS");
2369 else
2371 return tpl_getTpl(vars, "JSONREADER");
2376 static char *send_oscam_reader_config(struct templatevars *vars, struct uriparams *params)
2378 int32_t i;
2379 int32_t apicall = 0;
2380 char *reader_ = getParam(params, "label");
2381 char *value;
2383 struct s_reader *rdr;
2385 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
2387 if(strcmp(getParam(params, "action"), "Add") == 0)
2389 // Add new reader
2390 struct s_reader *newrdr;
2391 if(!cs_malloc(&newrdr, sizeof(struct s_reader))) { return "0"; }
2392 for(i = 0; i < (*params).paramcount; ++i)
2394 if(strcmp((*params).params[i], "action"))
2395 { chk_reader((*params).params[i], (*params).values[i], newrdr); }
2397 module_reader_set(newrdr);
2398 reader_ = newrdr->label;
2399 reader_set_defaults(newrdr);
2400 newrdr->enable = 0; // do not start the reader because must configured before
2401 ll_append(configured_readers, newrdr);
2402 tpl_addMsg(vars, "New Reader has been added with default settings");
2404 else if(strcmp(getParam(params, "action"), "Save") == 0)
2407 rdr = get_reader_by_label(getParam(params, "label"));
2408 if(!rdr)
2409 { return NULL; }
2410 //if (is_network_reader(rdr))
2411 // inactivate_reader(rdr); //Stop reader before reinitialization
2412 char servicelabels[1024] = "";
2413 char servicelabelslb[1024] = "";
2415 for(i = 0; i < (*params).paramcount; ++i)
2417 if((strcmp((*params).params[i], "reader")) && (strcmp((*params).params[i], "action")))
2419 if(!strcmp((*params).params[i], "services"))
2420 { snprintf(servicelabels + cs_strlen(servicelabels), sizeof(servicelabels) - cs_strlen(servicelabels), "%s,", (*params).values[i]); }
2421 else if(!strcmp((*params).params[i], "lb_whitelist_services"))
2422 { snprintf(servicelabelslb + cs_strlen(servicelabelslb), sizeof(servicelabelslb) - cs_strlen(servicelabelslb), "%s,", (*params).values[i]); }
2423 else
2424 /*if(cs_strlen((*params).values[i]) > 0)*/
2425 { chk_reader((*params).params[i], (*params).values[i], rdr); }
2427 //printf("param %s value %s\n",(*params).params[i], (*params).values[i]);
2429 chk_reader("services", servicelabels, rdr);
2430 chk_reader("lb_whitelist_services", servicelabelslb, rdr);
2432 if(is_network_reader(rdr) || rdr->typ == R_EMU) //physical readers make trouble if re-started
2434 if(rdr)
2436 if(rdr->typ != R_GBOX)
2438 restart_cardreader(rdr, 1);
2440 #ifdef MODULE_GBOX
2441 else
2443 //cs_log("SAVE - single gbox reader %s restarted by WebIf", rdr->label);
2444 restart_gbox_peer(rdr->label, 0, 0);
2446 #endif
2450 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); } else { tpl_addMsg(vars, "Reader config updated and saved"); }
2454 rdr = get_reader_by_label(reader_);
2455 if(!rdr)
2456 { return NULL; }
2458 // Label, Description
2459 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
2460 tpl_addVar(vars, TPLADD, "DESCRIPTION", xml_encode(vars, rdr->description));
2462 // enabled
2463 if(!apicall)
2465 tpl_addVar(vars, TPLADD, "ENABLED", (rdr->enable == 1) ? "checked" : "");
2467 else
2469 tpl_addVar(vars, TPLADD, "ENABLEDVALUE", (rdr->enable == 1) ? "1" : "0");
2472 tpl_addVar(vars, TPLADD, "PASSWORD", xml_encode(vars, rdr->r_pwd));
2473 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, rdr->r_usr));
2474 tpl_addVar(vars, TPLADD, "PASS", xml_encode(vars, rdr->r_pwd));
2476 // Key Newcamd
2477 for(i = 0; i < (int32_t)sizeof(rdr->ncd_key); i++)
2478 { tpl_printf(vars, TPLAPPEND, "NCD_KEY", "%02X", rdr->ncd_key[i]); }
2480 // Pincode
2481 tpl_addVar(vars, TPLADD, "PINCODE", rdr->pincode);
2483 // Emmfile Path
2484 if(rdr->emmfile) { tpl_addVar(vars, TPLADD, "EMMFILE", (char *)rdr->emmfile); }
2486 // Inactivity timeout
2487 tpl_printf(vars, TPLADD, "INACTIVITYTIMEOUT", "%d", rdr->tcp_ito);
2489 // Receive timeout
2490 tpl_printf(vars, TPLADD, "RECEIVETIMEOUT", "%d", rdr->tcp_rto);
2492 // keepalive
2493 tpl_addVar(vars, TPLADD, "RDRKEEPALIVE", (rdr->keepalive == 1) ? "checked" : "");
2495 // Connect on init (newcamd)
2496 if(!apicall)
2498 tpl_addVar(vars, TPLADD, "CONNECTONINITCHECKED", (rdr->ncd_connect_on_init == 1) ? "checked" : "");
2500 else
2502 tpl_addVar(vars, TPLADD, "CONNECTONINITCHECKED", (rdr->ncd_connect_on_init == 1) ? "1" : "0");
2505 // Reset Cycle
2506 tpl_printf(vars, TPLADD, "RESETCYCLE", "%d", rdr->resetcycle);
2508 // Disable Serverfilter
2509 if(!apicall)
2511 tpl_addVar(vars, TPLADD, "DISABLESERVERFILTERCHECKED", (rdr->ncd_disable_server_filt == 1) ? "checked" : "");
2513 else
2515 tpl_addVar(vars, TPLADD, "DISABLESERVERFILTERVALUE", (rdr->ncd_disable_server_filt == 1) ? "1" : "0");
2518 #ifdef MODULE_GHTTP
2519 // Use SSL
2520 if(!apicall)
2522 tpl_addVar(vars, TPLADD, "USESSLCHECKED", (rdr->ghttp_use_ssl == 1) ? "checked" : "");
2524 else
2526 tpl_addVar(vars, TPLADD, "USESSLVALUE", (rdr->ghttp_use_ssl == 1) ? "1" : "0");
2528 #endif
2530 // Fallback
2531 if(!apicall)
2533 tpl_addVar(vars, TPLADD, "FALLBACKCHECKED", (rdr->fallback == 1) ? "checked" : "");
2535 else
2537 tpl_addVar(vars, TPLADD, "FALLBACKVALUE", (rdr->fallback == 1) ? "1" : "0");
2540 // Fallback per caid
2541 value = mk_t_ftab(&rdr->fallback_percaid);
2542 tpl_addVar(vars, TPLADD, "FALLBACK_PERCAID", value);
2543 free_mk_t(value);
2545 // disable checksum test only for selected caid/provid
2546 value = mk_t_ftab(&rdr->disablecrccws_only_for);
2547 tpl_addVar(vars, TPLADD, "IGN_CHKSUM_ONLYFOR", value);
2548 free_mk_t(value);
2550 #ifdef WITH_LB
2551 tpl_addVar(vars, TPLADD, "LBFORCEFALLBACK", (rdr->lb_force_fallback == 1) ? "checked" : "");
2552 #endif
2554 #ifdef CS_CACHEEX
2555 // Cacheex
2556 if(!apicall)
2558 tpl_printf(vars, TPLADD, "TMP", "CACHEEXSELECTED%d", rdr->cacheex.mode);
2559 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
2561 else
2563 tpl_printf(vars, TPLADD, "CACHEEX", "%d", rdr->cacheex.mode);
2565 tpl_printf(vars, TPLADD, "CACHEEX_MAXHOP", "%d", rdr->cacheex.maxhop);
2566 #ifdef CS_CACHEEX_AIO
2567 tpl_printf(vars, TPLADD, "CACHEEX_MAXHOP_LG", "%d", rdr->cacheex.maxhop_lg);
2568 #endif
2569 value = mk_t_cacheex_hitvaluetab(&rdr->cacheex.filter_caidtab);
2570 //if (cs_strlen(value) > 0)
2571 tpl_printf(vars, TPLADD, "CACHEEX_ECM_FILTER", "%s", value);
2572 free_mk_t(value);
2574 tpl_addVar(vars, TPLADD, "DCCHECKED", (rdr->cacheex.drop_csp == 1) ? "checked" : "");
2575 tpl_addVar(vars, TPLADD, "ARCHECKED", (rdr->cacheex.allow_request == 1) ? "checked" : "");
2576 tpl_addVar(vars, TPLADD, "AFCHECKED", (rdr->cacheex.allow_filter == 1) ? "checked" : "");
2577 #ifdef CS_CACHEEX_AIO
2578 tpl_addVar(vars, TPLADD, "AMCHECKED", (rdr->cacheex.allow_maxhop == 1) ? "checked" : "");
2579 #endif
2580 tpl_addVar(vars, TPLADD, "BLOCKFAKECWSCHECKED", (rdr->cacheex.block_fakecws == 1) ? "checked" : "");
2581 #ifdef CS_CACHEEX_AIO
2582 tpl_addVar(vars, TPLADD, "USECWCHECKFORPUSHCHECKED", (rdr->cacheex.cw_check_for_push == 1) ? "checked" : "");
2583 tpl_addVar(vars, TPLADD, "LGONLYREMOTESETTINGSCHECKED", (rdr->cacheex.lg_only_remote_settings == 1) ? "checked" : "");
2584 tpl_addVar(vars, TPLADD, "LOCALGENERATEDONLYCHECKED", (rdr->cacheex.localgenerated_only == 1) ? "checked" : "");
2586 value = mk_t_ftab(&rdr->cacheex.lg_only_tab);
2587 tpl_addVar(vars, TPLADD, "LGONLYTAB", value);
2588 free_mk_t(value);
2590 tpl_addVar(vars, TPLADD, "LOCALGENERATEDONLYINCHECKED", (rdr->cacheex.localgenerated_only_in == 1) ? "checked" : "");
2592 tpl_addVar(vars, TPLADD, "LGONLYINAIOONLYCHECKED", (rdr->cacheex.lg_only_in_aio_only == 1) ? "checked" : "");
2594 value = mk_t_ftab(&rdr->cacheex.lg_only_in_tab);
2595 tpl_addVar(vars, TPLADD, "LGONLYINTAB", value);
2596 free_mk_t(value);
2598 value = mk_t_caidvaluetab(&rdr->cacheex.cacheex_nopushafter_tab);
2599 tpl_addVar(vars, TPLADD, "CACHEEXNOPUSHAFTER", value);
2600 free_mk_t(value);
2601 #endif
2602 #endif
2604 // BoxID
2605 if(rdr->boxid)
2606 { tpl_printf(vars, TPLADD, "BOXID", "%08X", rdr->boxid); }
2608 // Filt 07
2609 if(!apicall)
2611 tpl_addVar(vars, TPLADD, "FIX07CHECKED", (rdr->fix_07 == 1) ? "checked" : "");
2613 else
2615 tpl_addVar(vars, TPLADD, "FIX07VALUE", (rdr->fix_07 == 1) ? "1" : "0");
2619 // Fix 9993
2620 if(!apicall)
2622 tpl_addVar(vars, TPLADD, "FIX9993CHECKED", (rdr->fix_9993 == 1) ? "checked" : "");
2624 else
2626 tpl_addVar(vars, TPLADD, "FIX9993VALUE", (rdr->fix_9993 == 1) ? "1" : "0");
2629 // Drop CWs with wrong checksum:
2630 if(!apicall)
2632 tpl_addVar(vars, TPLADD, "DROPBADCWSCHECKED", (rdr->dropbadcws == 1) ? "checked" : "");
2634 else
2636 tpl_addVar(vars, TPLADD, "DROPBADCWSVALUE", (rdr->dropbadcws == 1) ? "1" : "0");
2639 // Disable CWs checksum test:
2640 if(!apicall)
2642 tpl_addVar(vars, TPLADD, "DISABLECRCCWSCHECKED", (rdr->disablecrccws == 1) ? "checked" : "");
2644 else
2646 tpl_addVar(vars, TPLADD, "DISABLECRCCWSVALUE", (rdr->disablecrccws == 1) ? "1" : "0");
2649 // Set reader to use GPIO
2650 if(!apicall)
2652 tpl_addVar(vars, TPLADD, "USE_GPIOCHECKED", rdr->use_gpio ? "checked" : "");
2654 else
2656 tpl_addVar(vars, TPLADD, "USE_GPIOVALUE", rdr->use_gpio ? "1" : "0");
2659 // AUdisabled
2660 if(!apicall)
2662 tpl_addVar(vars, TPLADD, "AUDISABLED", (rdr->audisabled == 1) ? "checked" : "");
2664 else
2666 tpl_addVar(vars, TPLADD, "AUDISABLEDVALUE", (rdr->audisabled == 1) ? "1" : "0");
2669 tpl_printf(vars, TPLADD, "TMP", "AUTYPE%d", rdr->autype);
2670 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
2672 // AUprovid
2673 if(rdr->auprovid)
2674 { tpl_printf(vars, TPLADD, "AUPROVID", "%06X", rdr->auprovid); }
2676 if(rdr->ecmnotfoundlimit)
2677 { tpl_printf(vars, TPLADD, "ECMNOTFOUNDLIMIT", "%u", rdr->ecmnotfoundlimit); }
2679 // Force Irdeto
2680 if(!apicall)
2682 tpl_addVar(vars, TPLADD, "FORCEIRDETOCHECKED", (rdr->force_irdeto == 1) ? "checked" : "");
2684 else
2686 tpl_addVar(vars, TPLADD, "FORCEIRDETOVALUE", (rdr->force_irdeto == 1) ? "1" : "0");
2689 // needsemmfirst
2691 if(!apicall)
2693 tpl_addVar(vars, TPLADD, "NEEDSEMMFIRST", (rdr->needsemmfirst == 1) ? "checked" : "");
2695 else
2697 tpl_addVar(vars, TPLADD, "NEEDSEMMFIRST", (rdr->needsemmfirst == 1) ? "1" : "0");
2700 #ifdef READER_CRYPTOWORKS
2701 // needsglobalfirst
2702 if(!apicall)
2704 tpl_addVar(vars, TPLADD, "NEEDSGLOBALFIRST", (rdr->needsglobalfirst == 1) ? "checked" : "");
2706 else
2708 tpl_addVar(vars, TPLADD, "NEEDSGLOBALFIRST", (rdr->needsglobalfirst == 1) ? "1" : "0");
2710 #endif
2712 // RSA Key
2713 int32_t len = rdr->rsa_mod_length;
2714 if(len > 0)
2716 for(i = 0; i < len; i++) { tpl_printf(vars, TPLAPPEND, "RSAKEY", "%02X", rdr->rsa_mod[i]); }
2719 // 3DES Key
2720 len = rdr->des_key_length;
2721 if(len > 0)
2723 for(i = 0; i < len; i++) { tpl_printf(vars, TPLAPPEND, "DESKEY", "%02X", rdr->des_key[i]); }
2726 // BoxKey
2727 len = rdr->boxkey_length;
2728 if(len > 0)
2730 for(i = 0; i < len ; i++)
2731 { tpl_printf(vars, TPLAPPEND, "BOXKEY", "%02X", rdr->boxkey[i]); }
2734 #ifdef READER_CONAX
2735 // CWPK Key
2736 len = rdr->cwpk_mod_length;
2737 if(len > 0)
2739 for(i = 0; i < len; i++) { tpl_printf(vars, TPLAPPEND, "CWPKKEY", "%02X", rdr->cwpk_mod[i]); }
2741 #endif
2743 #ifdef READER_NAGRA
2744 // nuid (CAK6.3)
2745 len = rdr->cak63nuid_length;
2746 if(len > 0)
2748 for(i = 0; i < len ; i++)
2749 { tpl_printf(vars, TPLAPPEND, "CAK63NUID", "%02X", rdr->cak63nuid[i]); }
2752 // cwekey (CAK6.3)
2753 len = rdr->cak63cwekey_length;
2754 if(len > 0)
2756 for(i = 0; i < len ; i++)
2757 { tpl_printf(vars, TPLAPPEND, "CAK63CWEKEY", "%02X", rdr->cak63cwekey[i]); }
2759 #endif
2761 #ifdef READER_NAGRA_MERLIN
2762 // idird (CAK7)
2763 len = rdr->idird_length;
2764 if(len > 0)
2766 for(i = 0; i < len ; i++)
2767 { tpl_printf(vars, TPLAPPEND, "IDIRD", "%02X", rdr->idird[i]); }
2770 // cmd0e_provider (CAK7)
2771 len = rdr->cmd0eprov_length;
2772 if(len > 0)
2774 for(i = 0; i < len ; i++)
2775 { tpl_printf(vars, TPLAPPEND, "CMD0EPROV", "%02X", rdr->cmd0eprov[i]); }
2778 // mod1 (CAK7)
2779 len = rdr->mod1_length;
2780 if(len > 0)
2782 for(i = 0; i < len ; i++)
2783 { tpl_printf(vars, TPLAPPEND, "MOD1", "%02X", rdr->mod1[i]); }
2786 // mod2 (CAK7)
2787 len = rdr->mod2_length;
2788 if(len > 0)
2790 for(i = 0; i < len ; i++)
2791 { tpl_printf(vars, TPLAPPEND, "MOD2", "%02X", rdr->mod2[i]); }
2794 // key3588 (CAK7)
2795 len = rdr->key3588_length;
2796 if(len > 0)
2798 for(i = 0; i < len ; i++)
2799 { tpl_printf(vars, TPLAPPEND, "KEY3588", "%02X", rdr->key3588[i]); }
2802 // key3310 (CAK7)
2803 len = rdr->key3310_length;
2804 if(len > 0)
2806 for(i = 0; i < len ; i++)
2807 { tpl_printf(vars, TPLAPPEND, "KEY3310", "%02X", rdr->key3310[i]); }
2810 // key3460 (CAK7)
2811 len = rdr->key3460_length;
2812 if(len > 0)
2814 for(i = 0; i < len ; i++)
2815 { tpl_printf(vars, TPLAPPEND, "KEY3460", "%02X", rdr->key3460[i]); }
2818 // data50 (CAK7)
2819 len = rdr->data50_length;
2820 if(len > 0)
2822 for(i = 0; i < len ; i++)
2823 { tpl_printf(vars, TPLAPPEND, "DATA50", "%02X", rdr->data50[i]); }
2826 // mod50 (CAK7)
2827 len = rdr->mod50_length;
2828 if(len > 0)
2830 for(i = 0; i < len ; i++)
2831 { tpl_printf(vars, TPLAPPEND, "MOD50", "%02X", rdr->mod50[i]); }
2834 // nuid (CAK7)
2835 len = rdr->nuid_length;
2836 if(len > 0)
2838 for(i = 0; i < len ; i++)
2839 { tpl_printf(vars, TPLAPPEND, "NUID", "%02X", rdr->nuid[i]); }
2842 // OTP CSC (CAK7)
2843 len = rdr->otpcsc_length;
2844 if(len > 0)
2846 for(i = 0; i < len ; i++)
2847 { tpl_printf(vars, TPLAPPEND, "OTPCSC", "%02X", rdr->otpcsc[i]); }
2850 // OTA CSC (CAK7)
2851 len = rdr->otacsc_length;
2852 if(len > 0)
2854 for(i = 0; i < len ; i++)
2855 { tpl_printf(vars, TPLAPPEND, "OTACSC", "%02X", rdr->otacsc[i]); }
2858 // Force Pairing Type (CAK7)
2859 len = rdr->forcepair_length;
2860 if(len > 0)
2862 for(i = 0; i < len ; i++)
2863 { tpl_printf(vars, TPLAPPEND, "FORCEPAIR", "%02X", rdr->forcepair[i]); }
2866 // cwekey0 (CAK7)
2867 len = rdr->cwekey0_length;
2868 if(len > 0)
2870 for(i = 0; i < len ; i++)
2871 { tpl_printf(vars, TPLAPPEND, "CWEKEY0", "%02X", rdr->cwekey0[i]); }
2874 // cwekey1 (CAK7)
2875 len = rdr->cwekey1_length;
2876 if(len > 0)
2878 for(i = 0; i < len ; i++)
2879 { tpl_printf(vars, TPLAPPEND, "CWEKEY1", "%02X", rdr->cwekey1[i]); }
2882 // cwekey2 (CAK7)
2883 len = rdr->cwekey2_length;
2884 if(len > 0)
2886 for(i = 0; i < len ; i++)
2887 { tpl_printf(vars, TPLAPPEND, "CWEKEY2", "%02X", rdr->cwekey2[i]); }
2890 // cwekey3 (CAK7)
2891 len = rdr->cwekey3_length;
2892 if(len > 0)
2894 for(i = 0; i < len ; i++)
2895 { tpl_printf(vars, TPLAPPEND, "CWEKEY3", "%02X", rdr->cwekey3[i]); }
2898 // cwekey4 (CAK7)
2899 len = rdr->cwekey4_length;
2900 if(len > 0)
2902 for(i = 0; i < len ; i++)
2903 { tpl_printf(vars, TPLAPPEND, "CWEKEY4", "%02X", rdr->cwekey4[i]); }
2906 // cwekey5 (CAK7)
2907 len = rdr->cwekey5_length;
2908 if(len > 0)
2910 for(i = 0; i < len ; i++)
2911 { tpl_printf(vars, TPLAPPEND, "CWEKEY5", "%02X", rdr->cwekey5[i]); }
2914 // cwekey6 (CAK7)
2915 len = rdr->cwekey6_length;
2916 if(len > 0)
2918 for(i = 0; i < len ; i++)
2919 { tpl_printf(vars, TPLAPPEND, "CWEKEY6", "%02X", rdr->cwekey6[i]); }
2922 // cwekey7 (CAK7)
2923 len = rdr->cwekey7_length;
2924 if(len > 0)
2926 for(i = 0; i < len ; i++)
2927 { tpl_printf(vars, TPLAPPEND, "CWEKEY7", "%02X", rdr->cwekey7[i]); }
2930 // force_cw_swap
2931 if(rdr->forcecwswap)
2932 { tpl_addVar(vars, TPLADD, "FORCECWSWAPCHECKED", "checked"); }
2934 // only_even_SA
2935 if(rdr->evensa)
2936 { tpl_addVar(vars, TPLADD, "EVENSACHECKED", "checked"); }
2938 // force_EMM_82
2939 if(rdr->forceemmg)
2940 { tpl_addVar(vars, TPLADD, "FORCEEMMGCHECKED", "checked"); }
2942 // OTA_CWPKs
2943 if(rdr->cwpkota)
2944 { tpl_addVar(vars, TPLADD, "CWPKOTACHECKED", "checked"); }
2945 #endif
2947 // CWPK CaID (CAK7)
2948 len = rdr->cwpkcaid_length;
2949 if(len > 0)
2951 for(i = 0; i < len ; i++)
2952 { tpl_printf(vars, TPLAPPEND, "CWPKCAID", "%02X", rdr->cwpkcaid[i]); }
2955 // cak7_mode
2956 if(rdr->cak7_mode)
2957 { tpl_addVar(vars, TPLADD, "NAGRACAK7MODECHECKED", "checked"); }
2959 // ins7E
2960 if(rdr->ins7E[0x1A])
2962 for(i = 0; i < 26 ; i++) { tpl_printf(vars, TPLAPPEND, "INS7E", "%02X", rdr->ins7E[i]); }
2964 // ins42
2965 if(rdr->ins42[0x25])
2967 for(i = 0; i < 37 ; i++) { tpl_printf(vars, TPLAPPEND, "INS42", "%02X", rdr->ins42[i]); }
2970 // ins7E11
2971 if(rdr->ins7E11[0x01])
2973 tpl_printf(vars, TPLAPPEND, "INS7E11", "%02X", rdr->ins7E11[0]);
2976 // ins2e06
2977 if(rdr->ins2e06[0x04])
2979 for(i = 0; i < 4 ; i++) { tpl_printf(vars, TPLAPPEND, "INS2E06", "%02X", rdr->ins2e06[i]); }
2982 // k1 for generic pairing mode
2983 if(rdr->k1_generic[0x10])
2985 for(i = 0; i < rdr->k1_generic[0x10] ; i++) { tpl_printf(vars, TPLAPPEND, "K1_GENERIC", "%02X", rdr->k1_generic[i]); }
2988 // k1 for unique pairing mode
2989 if(rdr->k1_unique[0x10])
2991 for(i = 0; i < rdr->k1_unique[0x10] ; i++) { tpl_printf(vars, TPLAPPEND, "K1_UNIQUE", "%02X", rdr->k1_unique[i]); }
2994 // ATR
2995 if(rdr->atr[0])
2996 for(i = 0; i < rdr->atrlen / 2; i++)
2997 { tpl_printf(vars, TPLAPPEND, "ATR", "%02X", rdr->atr[i]); }
2999 // ECM Whitelist
3000 value = mk_t_ecm_whitelist(&rdr->ecm_whitelist);
3001 tpl_addVar(vars, TPLADD, "ECMWHITELIST", value);
3002 free_mk_t(value);
3004 // ECM Header Whitelist
3005 value = mk_t_ecm_hdr_whitelist(&rdr->ecm_hdr_whitelist);
3006 tpl_addVar(vars, TPLADD, "ECMHEADERWHITELIST", value);
3007 free_mk_t(value);
3009 // Deprecated
3010 if(!apicall)
3012 tpl_addVar(vars, TPLADD, "DEPRECATEDCHECKED", (rdr->deprecated == 1) ? "checked" : "");
3014 else
3016 tpl_addVar(vars, TPLADD, "DEPRECATEDVALUE", (rdr->deprecated == 1) ? "1" : "0");
3019 // Smargopatch
3020 if(!apicall)
3022 tpl_addVar(vars, TPLADD, "SMARGOPATCHCHECKED", (rdr->smargopatch == 1) ? "checked" : "");
3024 else
3026 tpl_addVar(vars, TPLADD, "SMARGOPATCHVALUE", (rdr->smargopatch == 1) ? "1" : "0");
3029 // Autospeed
3030 if(!apicall)
3032 tpl_addVar(vars, TPLADD, "AUTOSPEEDCHECKED", (rdr->autospeed == 1) ? "checked" : "");
3034 else
3036 tpl_addVar(vars, TPLADD, "AUTOSPEEDVALUE", (rdr->autospeed == 1) ? "1" : "0");
3038 // sc8in1 dtrrts patch
3039 if(!apicall)
3041 tpl_addVar(vars, TPLADD, "SC8IN1DTRRTSPATCHCHECKED", (rdr->sc8in1_dtrrts_patch == 1) ? "checked" : "");
3043 else
3045 tpl_addVar(vars, TPLADD, "SC8IN1DTRRTSPATCHVALUE", (rdr->sc8in1_dtrrts_patch == 1) ? "1" : "0");
3048 if(!apicall)
3050 tpl_addVar(vars, TPLADD, "READOLDCLASSES", (rdr->read_old_classes == 1) ? "checked" : "");
3052 else
3054 tpl_addVar(vars, TPLADD, "READOLDCLASSES", (rdr->read_old_classes == 1) ? "1" : "0");
3057 // Detect
3058 if(rdr->detect & 0x80)
3059 { tpl_printf(vars, TPLADD, "DETECT", "!%s", RDR_CD_TXT[rdr->detect & 0x7f]); }
3060 else
3061 { tpl_addVar(vars, TPLADD, "DETECT", RDR_CD_TXT[rdr->detect & 0x7f]); }
3063 // Ratelimit
3064 if(rdr->ratelimitecm)
3066 tpl_printf(vars, TPLADD, "RATELIMITECM", "%d", rdr->ratelimitecm);
3067 // ECMUNIQUE
3068 if(!apicall)
3070 tpl_addVar(vars, TPLADD, "ECMUNIQUECHECKED", (rdr->ecmunique == 1) ? "checked" : "");
3072 else
3074 tpl_addVar(vars, TPLADD, "ECMUNIQUE", (rdr->ecmunique == 1) ? "1" : "0");
3076 tpl_printf(vars, TPLADD, "RATELIMITTIME", "%d", rdr->ratelimittime);
3077 tpl_printf(vars, TPLADD, "SRVIDHOLDTIME", "%d", rdr->srvidholdtime);
3079 // Cooldown
3080 if(rdr->cooldown[0] && rdr->cooldown[1])
3082 tpl_printf(vars, TPLADD, "COOLDOWNDELAY", "%d", rdr->cooldown[0]);
3083 tpl_printf(vars, TPLADD, "COOLDOWNTIME", "%d", rdr->cooldown[1]);
3085 // Frequencies
3086 tpl_printf(vars, TPLADD, "MHZ", "%d", rdr->mhz);
3087 tpl_printf(vars, TPLADD, "CARDMHZ", "%d", rdr->cardmhz);
3089 // Device
3090 if(!apicall)
3092 tpl_addVar(vars, TPLADD, "DEVICE", xml_encode(vars, rdr->device));
3094 else
3096 tpl_addVar(vars, TPLADD, "DEVICE", rdr->device);
3099 if(rdr->r_port)
3100 { tpl_printf(vars, TPLAPPEND, "DEVICE", ",%d", rdr->r_port); }
3101 if(rdr->l_port)
3103 if(rdr->r_port)
3104 { tpl_printf(vars, TPLAPPEND, "DEVICE", ",%d", rdr->l_port); }
3105 else
3106 { tpl_printf(vars, TPLAPPEND, "DEVICE", ",,%d", rdr->l_port); }
3109 // Group
3110 value = mk_t_group(rdr->grp);
3111 tpl_addVar(vars, TPLADD, "GRP", value);
3112 free_mk_t(value);
3114 #ifdef WITH_LB
3115 if(rdr->lb_weight)
3116 { tpl_printf(vars, TPLADD, "LBWEIGHT", "%d", rdr->lb_weight); }
3117 #endif
3119 //services
3120 if(!apicall)
3122 struct s_sidtab *sidtab = cfg.sidtab;
3123 //build matrix
3124 i = 0;
3125 while(sidtab != NULL)
3127 tpl_addVar(vars, TPLADD, "SIDLABEL", xml_encode(vars, sidtab->label));
3128 if(rdr->sidtabs.ok & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
3129 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
3130 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "READERCONFIGSIDOKBIT"));
3131 if(rdr->sidtabs.no & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
3132 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
3133 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "READERCONFIGSIDNOBIT"));
3134 if(rdr->lb_sidtabs.ok & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
3135 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
3136 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "READERCONFIGSIDLBOKBIT"));
3137 sidtab = sidtab->next;
3138 i++;
3140 if(i){
3141 tpl_addVar(vars, TPLADD, "READERCONFIGSIDINS", tpl_getTpl(vars, "READERCONFIGSID"));
3144 else
3146 value = mk_t_service(&rdr->sidtabs);
3147 if(cs_strlen(value) > 0)
3148 { tpl_addVar(vars, TPLADD, "SERVICES", value); }
3149 free_mk_t(value);
3152 // CAID
3153 value = mk_t_caidtab(&rdr->ctab);
3154 tpl_addVar(vars, TPLADD, "CAIDS", value);
3155 free_mk_t(value);
3157 // AESkeys
3158 value = mk_t_aeskeys(rdr);
3159 tpl_addVar(vars, TPLADD, "AESKEYS", value);
3160 free_mk_t(value);
3162 //ident
3163 value = mk_t_ftab(&rdr->ftab);
3164 tpl_addVar(vars, TPLADD, "IDENTS", value);
3165 free_mk_t(value);
3167 //CHID
3168 value = mk_t_ftab(&rdr->fchid);
3169 tpl_addVar(vars, TPLADD, "CHIDS", value);
3170 free_mk_t(value);
3172 //Local cards
3173 value = mk_t_ftab(&rdr->localcards);
3174 tpl_addVar(vars, TPLADD, "LOCALCARDS", value);
3175 free_mk_t(value);
3177 //class
3178 value = mk_t_cltab(&rdr->cltab);
3179 tpl_addVar(vars, TPLADD, "CLASS", value);
3180 free_mk_t(value);
3182 if(rdr->cachemm || rdr->logemm)
3183 { tpl_printf(vars, TPLADD, "EMMCACHE", "%d,%d,%d,%d", rdr->cachemm, rdr->rewritemm, rdr->logemm, rdr->deviceemm); }
3185 //savenano
3186 value = mk_t_nano(rdr->s_nano);
3187 tpl_addVar(vars, TPLADD, "SAVENANO", value);
3188 free_mk_t(value);
3190 //blocknano
3191 value = mk_t_nano(rdr->b_nano);
3192 tpl_addVar(vars, TPLADD, "BLOCKNANO", value);
3193 free_mk_t(value);
3195 // Blocke EMM
3196 if(!apicall)
3198 tpl_addVar(vars, TPLADD, "BLOCKEMMUNKNOWNCHK", (rdr->blockemm & EMM_UNKNOWN) ? "checked" : "");
3199 tpl_addVar(vars, TPLADD, "BLOCKEMMUNIQCHK", (rdr->blockemm & EMM_UNIQUE) ? "checked" : "");
3200 tpl_addVar(vars, TPLADD, "BLOCKEMMSHAREDCHK", (rdr->blockemm & EMM_SHARED) ? "checked" : "");
3201 tpl_addVar(vars, TPLADD, "BLOCKEMMGLOBALCHK", (rdr->blockemm & EMM_GLOBAL) ? "checked" : "");
3203 else
3205 tpl_addVar(vars, TPLADD, "BLOCKEMMUNKNOWNVALUE", (rdr->blockemm & EMM_UNKNOWN) ? "1" : "0");
3206 tpl_addVar(vars, TPLADD, "BLOCKEMMUNIQVALUE", (rdr->blockemm & EMM_UNIQUE) ? "1" : "0");
3207 tpl_addVar(vars, TPLADD, "BLOCKEMMSHAREDVALUE", (rdr->blockemm & EMM_SHARED) ? "1" : "0");
3208 tpl_addVar(vars, TPLADD, "BLOCKEMMGLOBALVALUE", (rdr->blockemm & EMM_GLOBAL) ? "1" : "0");
3211 // Save EMM
3212 if(!apicall)
3214 tpl_addVar(vars, TPLADD, "SAVEEMMUNKNOWNCHK", (rdr->saveemm & EMM_UNKNOWN) ? "checked" : "");
3215 tpl_addVar(vars, TPLADD, "SAVEEMMUNIQCHK", (rdr->saveemm & EMM_UNIQUE) ? "checked" : "");
3216 tpl_addVar(vars, TPLADD, "SAVEEMMSHAREDCHK", (rdr->saveemm & EMM_SHARED) ? "checked" : "");
3217 tpl_addVar(vars, TPLADD, "SAVEEMMGLOBALCHK", (rdr->saveemm & EMM_GLOBAL) ? "checked" : "");
3219 else
3221 tpl_addVar(vars, TPLADD, "SAVEEMMUNKNOWNVALUE", (rdr->saveemm & EMM_UNKNOWN) ? "1" : "0");
3222 tpl_addVar(vars, TPLADD, "SAVEEMMUNIQVALUE", (rdr->saveemm & EMM_UNIQUE) ? "1" : "0");
3223 tpl_addVar(vars, TPLADD, "SAVEEMMSHAREDVALUE", (rdr->saveemm & EMM_SHARED) ? "1" : "0");
3224 tpl_addVar(vars, TPLADD, "SAVEEMMGLOBALVALUE", (rdr->saveemm & EMM_GLOBAL) ? "1" : "0");
3227 value = mk_t_emmbylen(rdr);
3228 if(cs_strlen(value) > 0)
3229 { tpl_addVar(vars, TPLADD, "BLOCKEMMBYLEN", value); }
3230 free_mk_t(value);
3232 #ifdef MODULE_CCCAM
3233 if(!strcmp(rdr->cc_version, "2.0.11"))
3235 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED0", "selected");
3237 else if(!strcmp(rdr->cc_version, "2.1.1"))
3239 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED1", "selected");
3241 else if(!strcmp(rdr->cc_version, "2.1.2"))
3243 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED2", "selected");
3245 else if(!strcmp(rdr->cc_version, "2.1.3"))
3247 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED3", "selected");
3249 else if(!strcmp(rdr->cc_version, "2.1.4"))
3251 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED4", "selected");
3253 else if(!strcmp(rdr->cc_version, "2.2.0"))
3255 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED5", "selected");
3257 else if(!strcmp(rdr->cc_version, "2.2.1"))
3259 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED6", "selected");
3261 else if(!strcmp(rdr->cc_version, "2.3.0"))
3263 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED7", "selected");
3265 else if(!strcmp(rdr->cc_version, "2.3.1"))
3267 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED8", "selected");
3269 else if(!strcmp(rdr->cc_version, "2.3.2"))
3271 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED9", "selected");
3273 #endif
3275 tpl_printf(vars, TPLADD, "TMP", "NDSVERSION%d", rdr->ndsversion);
3276 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3278 tpl_printf(vars, TPLADD, "TMP", "NDSREADTIERS%d", rdr->readtiers);
3279 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3281 tpl_printf(vars, TPLADD, "TMP", "NAGRAREAD%d", rdr->nagra_read);
3282 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3284 if(rdr->detect_seca_nagra_tunneled_card)
3285 { tpl_addVar(vars, TPLADD, "NAGRADETECTSECACARDCHECKED", "checked"); }
3287 #ifdef MODULE_CCCAM
3288 tpl_printf(vars, TPLADD, "CCCMAXHOPS", "%d", rdr->cc_maxhops);
3289 tpl_printf(vars, TPLADD, "CCCMINDOWN", "%d", rdr->cc_mindown);
3290 tpl_printf(vars, TPLADD, "CCCRESHARE", "%d", rdr->cc_reshare);
3291 tpl_printf(vars, TPLADD, "RESHARE", "%d", cfg.cc_reshare);
3292 tpl_printf(vars, TPLADD, "CCCRECONNECT", "%d", rdr->cc_reconnect);
3294 if(rdr->cc_want_emu)
3295 { tpl_addVar(vars, TPLADD, "CCCWANTEMUCHECKED", "checked"); }
3296 if(rdr->cc_keepalive)
3297 { tpl_addVar(vars, TPLADD, "KEEPALIVECHECKED", "checked"); }
3298 #endif
3300 #ifdef MODULE_GBOX
3301 tpl_printf(vars, TPLADD, "GBOXMAXDISTANCE", "%d", rdr->gbox_maxdist);
3302 tpl_printf(vars, TPLADD, "GBOXMAXECMSEND", "%d", rdr->gbox_maxecmsend);
3303 tpl_printf(vars, TPLADD, "GBOXRESHARE", "%d", rdr->gbox_reshare);
3304 tpl_printf(vars, TPLADD, "PEERGBOXID", "%04X", gbox_convert_password_to_id((uint32_t)a2i(rdr->r_pwd, 4)));
3305 tpl_addVar(vars, TPLADD, "PEERONLSTAT", (get_peer_onl_status(gbox_convert_password_to_id((uint32_t)a2i(rdr->r_pwd, 4)))) ? "checked" : "");
3306 tpl_printf(vars, TPLADD, "FORCEREMM", "%d", rdr->gbox_force_remm);
3307 tpl_printf(vars, TPLADD, "CMDHERE", rdr->send_offline_cmd ? "checked" : "");
3309 if(rdr->blockemm & 0x80)
3311 tpl_addVar(vars, TPLADD, "REMMCNLDCHK", "checked");
3312 tpl_printf(vars, TPLADD, "GBOXREMMPEER", "%04X", rdr->gbox_remm_peer);
3313 tpl_addVar(vars, TPLADD, "REMMUNIQCHK", (rdr->blockemm & EMM_UNIQUE) ? "" : "checked");
3314 tpl_addVar(vars, TPLADD, "REMMSHAREDCHK", (rdr->blockemm & EMM_SHARED) ? "" : "checked");
3315 tpl_addVar(vars, TPLADD, "REMMGLOBALCHK", (rdr->blockemm & EMM_GLOBAL) ? "" : "checked");
3316 tpl_addVar(vars, TPLADD, "REMMEMMUNKNOWNCHK", (rdr->blockemm & EMM_UNKNOWN) ? "" : "checked");
3318 if(rdr->gbox_gsms_peer)
3320 tpl_printf(vars, TPLADD, "LASTGSMS", "%s", rdr->last_gsms);
3321 tpl_printf(vars, TPLADD, "GBOXGSMSPEER", "%04X", rdr->gbox_gsms_peer);
3323 #endif
3325 #ifdef READER_DRECAS
3326 tpl_addVar(vars, TPLADD, "STMKEYS", rdr->stmkeys);
3327 #endif
3329 #if defined(READER_DRE) || defined(READER_DRECAS)
3330 tpl_addVar(vars, TPLADD, "USERSCRIPT", rdr->userscript);
3331 #endif
3333 #ifdef WITH_EMU
3334 //emu_auproviders
3335 value = mk_t_ftab(&rdr->emu_auproviders);
3336 tpl_addVar(vars, TPLADD, "EMUAUPROVIDERS", value);
3337 free_mk_t(value);
3339 // Date-coded BISS keys
3340 if(!apicall)
3342 tpl_addVar(vars, TPLADD, "EMUDATECODEDENABLED", (rdr->emu_datecodedenabled == 1) ? "checked" : "");
3344 else
3346 tpl_addVar(vars, TPLADD, "EMUDATECODEDENABLED", (rdr->emu_datecodedenabled == 1) ? "1" : "0");
3348 #endif
3350 tpl_addVar(vars, TPLADD, "PROTOCOL", reader_get_type_desc(rdr, 0));
3352 // Show only parameters which needed for the reader
3353 switch(rdr->typ)
3355 case R_CONSTCW:
3356 case R_DB2COM1:
3357 case R_DB2COM2:
3358 case R_MOUSE :
3359 case R_DRECAS :
3360 case R_MP35:
3361 case R_SC8in1 :
3362 case R_SMART :
3363 case R_INTERNAL:
3364 case R_SERIAL :
3365 case R_PCSC :
3366 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGSTDHWREADERBIT"));
3367 break;
3368 case R_CAMD35 :
3369 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGCAMD35BIT"));
3370 break;
3371 case R_EMU :
3372 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGEMUBIT"));
3373 break;
3374 case R_CS378X :
3375 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGCS378XBIT"));
3376 break;
3377 case R_RADEGAST:
3378 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGRADEGASTBIT"));
3379 break;
3380 case R_SCAM:
3381 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGSCAMBIT"));
3382 break;
3383 case R_GHTTP:
3384 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGGHTTPBIT"));
3385 break;
3386 case R_GBOX:
3387 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGGBOXBIT"));
3388 #if defined (MODULE_CCCAM) && defined (MODULE_GBOX)
3389 if(cfg.cc_gbx_reshare_en)
3391 tpl_printf(vars, TPLADD, "GBOXCCCAMRESHARE", "%d", rdr->gbox_cccam_reshare);
3392 value = mk_t_ftab(&rdr->ccc_gbx_reshare_ident);
3393 tpl_addVar(vars, TPLADD, "CCCGBXRESHAREIDENT", value);
3394 free_mk_t(value);
3395 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "GBOXCCCAMRESHAREBIT"));
3397 #endif
3398 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERINFOGBOXREMM"));
3399 break;
3400 case R_NEWCAMD:
3401 if(rdr->ncd_proto == NCD_525)
3403 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGNCD525BIT"));
3405 else if(rdr->ncd_proto == NCD_524)
3407 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGNCD524BIT"));
3409 break;
3410 #ifdef MODULE_CCCAM
3411 case R_CCCAM :
3412 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGCCCAMBIT"));
3413 break;
3414 #endif
3415 default :
3416 tpl_addMsg(vars, "Error: protocol not resolvable");
3417 break;
3421 #ifdef MODULE_CCCAM
3422 if(rdr->typ != R_CCCAM && rdr->typ != R_GBOX)
3424 tpl_printf(vars, TPLADD, "CCCHOP", "%d", rdr->cc_hop);
3425 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGHOPBIT"));
3427 #endif
3429 #ifdef CS_CACHEEX_AIO
3430 return tpl_getTpl(vars, "READERCONFIGAIO");
3431 #else
3432 return tpl_getTpl(vars, "READERCONFIG");
3433 #endif
3436 static char *send_oscam_reader_stats(struct templatevars *vars, struct uriparams *params, int32_t apicall)
3439 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
3441 int8_t error;
3442 struct s_client *cl = NULL;
3443 struct s_reader *rdr;
3445 rdr = get_reader_by_label(getParam(params, "label"));
3446 error = (rdr ? 0 : 1);
3448 if(!error && rdr)
3450 cl = rdr->client;
3451 error = (cl ? 0 : 1);
3454 if(error)
3456 tpl_addVar(vars, TPLAPPEND, "READERSTATSROW", tpl_getTpl(vars, "READERSTATSROWBIT"));
3457 if(!apicall)
3458 { return tpl_getTpl(vars, "READERSTATS"); }
3459 else
3460 { return tpl_getTpl(vars, "APIREADERSTATS"); }
3463 #ifdef WITH_LB
3464 char *stxt[] = {"found", "cache1", "cache2", "cache3",
3465 "not found", "timeout", "sleeping",
3466 "fake", "invalid", "corrupt", "no card", "expdate",
3467 "disabled", "stopped"
3470 if(strcmp(getParam(params, "action"), "resetstat") == 0)
3472 char *rcs = getParam(params, "rc");
3473 int32_t retval = 0;
3474 if(cs_strlen(rcs) > 0)
3476 int8_t rc;
3477 rc = atoi(rcs);
3478 retval = clean_stat_by_rc(rdr, rc, 0);
3479 cs_log("Reader %s stats %d %s entr%s deleted by WebIF from %s",
3480 rdr->label, retval, stxt[rc],
3481 retval == 1 ? "y" : "ies",
3482 cs_inet_ntoa(GET_IP()));
3484 else
3486 clear_reader_stat(rdr);
3487 cs_log("Reader %s stats resetted by WebIF from %s", rdr->label, cs_inet_ntoa(GET_IP()));
3492 if(strcmp(getParam(params, "action"), "deleterecord") == 0)
3494 char *record = getParam(params, "record");
3495 if(cs_strlen(record) > 0)
3497 int32_t retval = 0;
3498 uint32_t caid, provid, sid, cid, len;
3499 sscanf(record, "%4x@%6x:%4x:%4x:%4x", &caid, &provid, &sid, &cid, &len);
3500 retval = clean_stat_by_id(rdr, caid, provid, sid, cid, len);
3501 cs_log("Reader %s stats %d entr%s deleted by WebIF from %s",
3502 rdr->label, retval,
3503 retval == 1 ? "y" : "ies",
3504 cs_inet_ntoa(GET_IP()));
3508 if(strcmp(getParam(params, "action"), "updateecmlen") == 0)
3510 update_ecmlen_from_stat(rdr);
3511 write_server();
3514 #endif
3516 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
3517 tpl_addVar(vars, TPLADD, "LABEL", xml_encode(vars, rdr->label));
3518 tpl_addVar(vars, TPLADD, "ENCODEDLABEL", urlencode(vars, rdr->label));
3520 if(apicall)
3522 int32_t i, emmcount = 0;
3523 char *ttxt[] = {"unknown", "unique", "shared", "global"};
3525 for(i = 0; i < 4; i++)
3527 tpl_addVar(vars, TPLADD, "EMMRESULT", "error");
3528 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
3529 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmerror[i]);
3530 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
3531 emmcount += rdr->emmerror[i];
3532 tpl_printf(vars, TPLADD, "TOTALERROR", "%d", emmcount);
3534 emmcount = 0;
3535 for(i = 0; i < 4; i++)
3537 tpl_addVar(vars, TPLADD, "EMMRESULT", "written");
3538 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
3539 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmwritten[i]);
3540 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
3541 emmcount += rdr->emmwritten[i];
3542 tpl_printf(vars, TPLADD, "TOTALWRITTEN", "%d", emmcount);
3544 emmcount = 0;
3545 for(i = 0; i < 4; i++)
3547 tpl_addVar(vars, TPLADD, "EMMRESULT", "skipped");
3548 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
3549 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmskipped[i]);
3550 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
3551 emmcount += rdr->emmskipped[i];
3552 tpl_printf(vars, TPLADD, "TOTALSKIPPED", "%d", emmcount);
3554 emmcount = 0;
3555 for(i = 0; i < 4; i++)
3557 tpl_addVar(vars, TPLADD, "EMMRESULT", "blocked");
3558 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
3559 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmblocked[i]);
3560 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
3561 emmcount += rdr->emmblocked[i];
3562 tpl_printf(vars, TPLADD, "TOTALBLOCKED", "%d", emmcount);
3566 if(apicall)
3568 char *txt = "UNDEF";
3569 switch(rdr->card_status)
3571 case NO_CARD:
3572 if(rdr->typ == R_GBOX)
3573 { txt = "ONL no crd"; }
3574 else
3575 { txt = "OFF"; }
3576 break;
3577 case UNKNOWN:
3578 txt = "UNKNOWN";
3579 break;
3580 case READER_DEVICE_ERROR:
3581 txt = "READER DEVICE ERROR";
3582 break;
3583 case CARD_NEED_INIT:
3584 if(rdr->typ == R_GBOX)
3585 { txt = "OFFLINE"; }
3586 else
3587 { txt = "NEEDINIT"; }
3588 break;
3589 case CARD_INSERTED:
3590 if(cl->typ == 'p')
3592 if(rdr->typ == R_GBOX)
3593 { txt = "ONL w/crd"; }
3594 else
3595 { txt = "CONNECTED"; }
3597 else
3598 { txt = "CARDOK"; }
3599 break;
3600 case CARD_FAILURE:
3601 txt = "ERROR";
3602 break;
3603 default:
3604 txt = "UNDEF";
3606 tpl_addVar(vars, TPLADD, "READERSTATUS", txt);
3607 tpl_printf(vars, TPLADD, "READERCAID", "%04X", rdr->caid);
3610 int32_t rowcount = 0;
3611 uint64_t ecmcount = 0;
3612 time_t lastaccess = 0;
3614 #ifdef WITH_LB
3615 int32_t rc2hide = (-1);
3616 if(cs_strlen(getParam(params, "hide")) > 0)
3617 { rc2hide = atoi(getParam(params, "hide")); }
3619 int32_t rc2show = (-1);
3620 if(cs_strlen(getParam(params, "show")) > 0)
3621 { rc2show = atoi(getParam(params, "show")); }
3623 if(rdr->lb_stat)
3625 int32_t statsize;
3626 // @todo alno: sort by click, 0=ascending, 1=descending (maybe two buttons or reverse on second click)
3627 READER_STAT **statarray = get_sorted_stat_copy(rdr, 0, &statsize);
3628 char channame[CS_SERVICENAME_SIZE];
3629 for(; rowcount < statsize; ++rowcount)
3631 READER_STAT *s = statarray[rowcount];
3632 if(!(s->rc == rc2hide) && ((rc2show == -1) || (s->rc == rc2show)))
3634 struct tm lt;
3635 localtime_r(&s->last_received.time, &lt); // fixme we need walltime!
3636 ecmcount += s->ecm_count;
3637 if(!apicall)
3639 tpl_printf(vars, TPLADD, "CHANNEL", "%04X@%06X:%04X:%04X", s->caid, s->prid, s->srvid, s->chid);
3640 tpl_addVar(vars, TPLADD, "CHANNELNAME", xml_encode(vars, get_servicename(cur_client(), s->srvid, s->prid, s->caid, channame, sizeof(channame))));
3641 tpl_printf(vars, TPLADD, "ECMLEN", "%04hX", s->ecmlen);
3642 tpl_addVar(vars, TPLADD, "RC", stxt[s->rc]);
3643 tpl_printf(vars, TPLADD, "TIME", PRINTF_LOCAL_D " ms", s->time_avg);
3644 if(s->time_stat[s->time_idx])
3645 { tpl_printf(vars, TPLADD, "TIMELAST", PRINTF_LOCAL_D " ms", s->time_stat[s->time_idx]); }
3646 else
3647 { tpl_addVar(vars, TPLADD, "TIMELAST", ""); }
3648 tpl_printf(vars, TPLADD, "COUNT", PRINTF_LOCAL_D, s->ecm_count);
3650 if(s->last_received.time)
3652 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);
3655 else
3657 tpl_addVar(vars, TPLADD, "LAST", "never");
3660 else
3662 tpl_printf(vars, TPLADD, "ECMCAID", "%04X", s->caid);
3663 tpl_printf(vars, TPLADD, "ECMPROVID", "%06X", s->prid);
3664 tpl_printf(vars, TPLADD, "ECMSRVID", "%04X", s->srvid);
3665 tpl_printf(vars, TPLADD, "ECMLEN", "%04hX", s->ecmlen);
3666 tpl_addVar(vars, TPLADD, "ECMCHANNELNAME", xml_encode(vars, get_servicename(cur_client(), s->srvid, s->prid, s->caid, channame, sizeof(channame))));
3667 tpl_printf(vars, TPLADD, "ECMTIME", PRINTF_LOCAL_D, s->time_avg);
3668 tpl_printf(vars, TPLADD, "ECMTIMELAST", PRINTF_LOCAL_D, s->time_stat[s->time_idx]);
3669 tpl_printf(vars, TPLADD, "ECMRC", "%d", s->rc);
3670 tpl_addVar(vars, TPLADD, "ECMRCS", stxt[s->rc]);
3671 if(s->last_received.time)
3673 char tbuffer [30];
3674 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &lt);
3675 tpl_addVar(vars, TPLADD, "ECMLAST", tbuffer);
3677 else
3679 tpl_addVar(vars, TPLADD, "ECMLAST", "");
3681 tpl_printf(vars, TPLADD, "ECMCOUNT", PRINTF_LOCAL_D, s->ecm_count);
3683 if(s->last_received.time > lastaccess)
3684 { lastaccess = s->last_received.time; }
3687 if(!apicall)
3689 if(s->rc == E_NOTFOUND)
3691 tpl_addVar(vars, TPLAPPEND, "READERSTATSROWNOTFOUND", tpl_getTpl(vars, "READERSTATSBIT"));
3692 tpl_addVar(vars, TPLADD, "RESETA", urlencode(vars, rdr->label));
3693 tpl_addVar(vars, TPLADD, "READERSTATSNFHEADLINE", tpl_getTpl(vars, "READERSTATSROWNOTFOUNDBIT"));
3695 else if(s->rc == E_TIMEOUT)
3697 tpl_addVar(vars, TPLAPPEND, "READERSTATSROWTIMEOUT", tpl_getTpl(vars, "READERSTATSBIT"));
3698 tpl_addVar(vars, TPLADD, "RESETB", urlencode(vars, rdr->label));
3699 tpl_addVar(vars, TPLADD, "READERSTATSTOHEADLINE", tpl_getTpl(vars, "READERSTATSROWTIMEOUTBIT"));
3701 else if(s->rc == E_INVALID)
3703 tpl_addVar(vars, TPLAPPEND, "READERSTATSROWINVALID", tpl_getTpl(vars, "READERSTATSBIT"));
3704 tpl_addVar(vars, TPLADD, "RESETC", urlencode(vars, rdr->label));
3705 tpl_addVar(vars, TPLADD, "READERSTATSIVHEADLINE", tpl_getTpl(vars, "READERSTATSROWINVALIDBIT"));
3707 else
3708 { tpl_addVar(vars, TPLAPPEND, "READERSTATSROWFOUND", tpl_getTpl(vars, "READERSTATSBIT")); }
3710 else
3713 tpl_addVar(vars, TPLAPPEND, "ECMSTATS", tpl_getTpl(vars, "APIREADERSTATSECMBIT"));
3717 NULLFREE(statarray);
3719 else
3720 #endif
3721 tpl_addVar(vars, TPLAPPEND, "READERSTATSROW", tpl_getTpl(vars, "READERSTATSNOSTATS"));
3723 tpl_printf(vars, TPLADD, "ROWCOUNT", "%d", rowcount);
3725 if(lastaccess > 0)
3727 char tbuffer [30];
3728 struct tm lt;
3729 localtime_r(&lastaccess, &lt);
3730 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &lt);
3731 tpl_addVar(vars, TPLADD, "LASTACCESS", tbuffer);
3733 else
3735 tpl_addVar(vars, TPLADD, "LASTACCESS", "");
3738 if(apicall)
3740 if(cl)
3742 char *value = get_ecm_historystring(cl);
3743 tpl_addVar(vars, TPLADD, "ECMHISTORY", value);
3744 free_mk_t(value);
3748 tpl_printf(vars, TPLADD, "TOTALECM", "%'" PRIu64, ecmcount);
3750 if(!apicall)
3751 { return tpl_getTpl(vars, "READERSTATS"); }
3752 else
3753 { return tpl_getTpl(vars, "APIREADERSTATS"); }
3756 static char *send_oscam_user_config_edit(struct templatevars *vars, struct uriparams *params, int32_t apicall)
3758 struct s_auth *account, *ptr, *chk;
3759 char user[sizeof(first_client->account->usr)];
3761 int32_t i;
3762 int existing_insert = 0;
3764 if(!apicall) { setActiveMenu(vars, MNU_USERS); }
3766 if(strcmp(getParam(params, "action"), "Save As") == 0) { cs_strncpy(user, getParam(params, "newuser"), sizeof(user)); }
3767 else { cs_strncpy(user, getParam(params, "user"), sizeof(user)); }
3769 account = NULL;
3770 for(chk = cfg.account; chk != NULL; chk = chk->next)
3772 if(strcmp(user, chk->usr) == 0)
3773 { account = chk; }
3774 if(!existing_insert)
3776 tpl_printf(vars, TPLADD, "EXISTING_INS", "'%s'", urlencode(vars, chk->usr));
3777 existing_insert++;
3779 else
3781 tpl_printf(vars, TPLAPPEND, "EXISTING_INS", ",'%s'", urlencode(vars, chk->usr));
3785 // Create a new user if it doesn't yet
3786 if(account == NULL)
3788 i = 1;
3789 while(cs_strlen(user) < 1)
3791 snprintf(user, sizeof(user) / sizeof(char) - 1, "NEWUSER%d", i);
3792 for(account = cfg.account; account != NULL && strcmp(user, account->usr) != 0; account = account->next) { ; }
3793 if(account != NULL) { user[0] = '\0'; }
3794 ++i;
3796 if(!cs_malloc(&account, sizeof(struct s_auth))) { return "0"; }
3797 if(cfg.account == NULL) { cfg.account = account; }
3798 else
3800 for(ptr = cfg.account; ptr != NULL && ptr->next != NULL; ptr = ptr->next) { ; }
3801 ptr->next = account;
3803 account_set_defaults(account);
3804 account->disabled = 1;
3805 cs_strncpy((char *)account->usr, user, sizeof(account->usr));
3806 if(!account->grp)
3807 { account->grp = 1; }
3808 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
3809 else if(strcmp(getParam(params, "action"), "Save As") == 0) { tpl_addMsg(vars, "New user has been added with cloned settings"); }
3810 else { tpl_addMsg(vars, "New user has been added with default settings"); }
3811 // no need to refresh anything here as the account is disabled by default and there's no client with this new account anyway!
3814 if((strcmp(getParam(params, "action"), "Save") == 0) || (strcmp(getParam(params, "action"), "Save As") == 0))
3816 char servicelabels[1024] = "";
3818 for(i = 0; i < (*params).paramcount; i++)
3820 if((strcmp((*params).params[i], "action")) &&
3821 (strcmp((*params).params[i], "user")) &&
3822 (strcmp((*params).params[i], "newuser")) &&
3823 (strcmp((*params).params[i], "part")))
3826 if(!strcmp((*params).params[i], "services"))
3827 { snprintf(servicelabels + cs_strlen(servicelabels), sizeof(servicelabels) - cs_strlen(servicelabels), "%s,", (*params).values[i]); }
3828 else
3829 { chk_account((*params).params[i], (*params).values[i], account); }
3832 chk_account("services", servicelabels, account);
3834 refresh_oscam(REFR_CLIENTS);
3836 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
3837 else if(strcmp(getParam(params, "action"), "Save As") != 0) { tpl_addMsg(vars, "User Account updated and saved"); }
3840 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, account->usr));
3841 tpl_addVar(vars, TPLADD, "PASSWORD", xml_encode(vars, account->pwd));
3842 tpl_addVar(vars, TPLADD, "DESCRIPTION", xml_encode(vars, account->description));
3844 //Disabled
3845 if(!apicall)
3847 if(account->disabled)
3848 { tpl_addVar(vars, TPLADD, "DISABLEDCHECKED", "checked"); }
3850 else
3852 tpl_printf(vars, TPLADD, "DISABLEDVALUE", "%d", account->disabled);
3855 //Expirationdate
3856 struct tm timeinfo;
3857 cs_gmtime_r(&account->expirationdate, &timeinfo);
3858 char buf [80];
3859 strftime(buf, 80, "%Y-%m-%d", &timeinfo);
3860 if(strcmp(buf, "1970-01-01")) { tpl_addVar(vars, TPLADD, "EXPDATE", buf); }
3862 //Allowed TimeFrame
3863 char *allowedtf = mk_t_allowedtimeframe(account);
3864 tpl_printf(vars, TPLADD, "ALLOWEDTIMEFRAME", "%s", allowedtf);
3865 free_mk_t(allowedtf);
3867 //Group
3868 char *value = mk_t_group(account->grp);
3869 tpl_addVar(vars, TPLADD, "GROUPS", value);
3870 free_mk_t(value);
3872 // allowed protocols
3873 value = mk_t_allowedprotocols(account);
3874 tpl_addVar(vars, TPLADD, "ALLOWEDPROTOCOLS", value);
3875 free_mk_t(value);
3877 //Hostname
3878 tpl_addVar(vars, TPLADD, "DYNDNS", xml_encode(vars, account->dyndns));
3880 //Uniq
3881 if(!apicall)
3883 tpl_printf(vars, TPLADD, "TMP", "UNIQSELECTED%d", account->uniq);
3884 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3886 else
3888 tpl_printf(vars, TPLADD, "UNIQVALUE", "%d", account->uniq);
3891 //Sleep
3892 if(!account->tosleep) { tpl_addVar(vars, TPLADD, "SLEEP", "0"); }
3893 else { tpl_printf(vars, TPLADD, "SLEEP", "%d", account->tosleep); }
3895 //Monlevel selector
3896 if(!apicall)
3898 tpl_printf(vars, TPLADD, "TMP", "MONSELECTED%d", account->monlvl);
3899 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3901 else
3903 tpl_printf(vars, TPLADD, "MONVALUE", "%d", account->monlvl);
3906 //Au
3907 if(account->autoau == 1)
3908 { tpl_addVar(vars, TPLADD, "AUREADER", "1"); }
3909 else if(account->aureader_list)
3911 value = mk_t_aureader(account);
3912 tpl_addVar(vars, TPLADD, "AUREADER", value);
3913 free_mk_t(value);
3916 if(!apicall)
3918 /* SERVICES */
3919 struct s_sidtab *sidtab = cfg.sidtab;
3920 //build matrix
3921 i = 0;
3922 while(sidtab != NULL)
3924 tpl_addVar(vars, TPLADD, "SIDLABEL", xml_encode(vars, sidtab->label));
3925 if(account->sidtabs.ok & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
3926 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
3927 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "USEREDITSIDOKBIT"));
3928 if(account->sidtabs.no & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
3929 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
3930 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "USEREDITSIDNOBIT"));
3931 sidtab = sidtab->next;
3932 i++;
3934 if(i){
3935 tpl_addVar(vars, TPLADD, "USEREDITSIDINS", tpl_getTpl(vars, "USEREDITSID"));
3938 else
3940 value = mk_t_service(&account->sidtabs);
3941 if(cs_strlen(value) > 0)
3942 { tpl_addVar(vars, TPLADD, "SERVICES", value); }
3943 free_mk_t(value);
3946 // CAID
3947 value = mk_t_caidtab(&account->ctab);
3948 tpl_addVar(vars, TPLADD, "CAIDS", value);
3949 free_mk_t(value);
3951 //ident
3952 value = mk_t_ftab(&account->ftab);
3953 tpl_addVar(vars, TPLADD, "IDENTS", value);
3954 free_mk_t(value);
3956 //CHID
3957 value = mk_t_ftab(&account->fchid);
3958 tpl_addVar(vars, TPLADD, "CHIDS", value);
3959 free_mk_t(value);
3961 //class
3962 value = mk_t_cltab(&account->cltab);
3963 tpl_addVar(vars, TPLADD, "CLASS", value);
3964 free_mk_t(value);
3966 //Betatunnel
3967 value = mk_t_tuntab(&account->ttab);
3968 tpl_addVar(vars, TPLADD, "BETATUNNELS", value);
3969 free_mk_t(value);
3971 //SUPPRESSCMD08
3972 if(!apicall)
3974 if(account->c35_suppresscmd08)
3975 { tpl_addVar(vars, TPLADD, "SUPPRESSCMD08", "selected"); }
3977 else
3979 tpl_printf(vars, TPLADD, "SUPPRESSCMD08VALUE", "%d", account->c35_suppresscmd08);
3982 //Sleepsend
3983 if(account->c35_sleepsend)
3985 tpl_printf(vars, TPLADD, "SLEEPSEND", "selected");
3988 //max_connections
3989 tpl_printf(vars, TPLADD, "MAXCONNECTIONS", "%d", account->max_connections);
3991 //User Max Idle
3992 tpl_printf(vars, TPLADD, "UMAXIDLE", "%d", account->umaxidle);
3994 //EMM Reassembly selector
3995 if(!apicall)
3997 tpl_printf(vars, TPLADD, "TMP", "EMMRSELECTED%d", account->emm_reassembly);
3998 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
4000 else
4002 tpl_printf(vars, TPLADD, "EMMRVALUE", "%d", account->emm_reassembly);
4005 //Prefer local cards
4006 if(!apicall)
4008 tpl_printf(vars, TPLADD, "TMP", "PREFERLOCALCARDS%d", account->preferlocalcards);
4009 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
4010 char *tmp = NULL;
4011 switch(cfg.preferlocalcards)
4013 case -1:
4014 tmp = "-1 - Use Global prefer local cards";
4015 break;
4016 case 0:
4017 tmp = "0 - local cards like proxied";
4018 break;
4019 case 1:
4020 tmp = "1 - prefer cache-ex then local cards";
4021 break;
4022 case 2:
4023 tmp = "2 - prefer local cards above cache-ex";
4024 break;
4026 tpl_addVar(vars, TPLADD, "CFGPREFERLOCALCARDS", tmp);
4028 else
4030 tpl_printf(vars, TPLADD, "PREFERLOCALCARDSVALUE", "%d", account->preferlocalcards);
4033 #ifdef CS_CACHEEX
4034 // Cacheex
4035 if(!apicall)
4037 tpl_printf(vars, TPLADD, "TMP", "CACHEEXSELECTED%d", account->cacheex.mode);
4038 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
4041 else
4043 tpl_printf(vars, TPLADD, "CACHEEX", "%d", account->cacheex.mode);
4045 tpl_printf(vars, TPLADD, "CACHEEX_MAXHOP", "%d", account->cacheex.maxhop);
4046 #ifdef CS_CACHEEX_AIO
4047 tpl_printf(vars, TPLADD, "CACHEEX_MAXHOP_LG", "%d", account->cacheex.maxhop_lg);
4048 #endif
4050 value = mk_t_cacheex_hitvaluetab(&account->cacheex.filter_caidtab);
4051 //if (cs_strlen(value) > 0)
4052 tpl_printf(vars, TPLADD, "CACHEEX_ECM_FILTER", "%s", value);
4053 free_mk_t(value);
4055 tpl_addVar(vars, TPLADD, "DCCHECKED", (account->cacheex.drop_csp == 1) ? "checked" : "");
4056 tpl_addVar(vars, TPLADD, "ARCHECKED", (account->cacheex.allow_request == 1) ? "checked" : "");
4057 tpl_addVar(vars, TPLADD, "AFCHECKED", (account->cacheex.allow_filter == 1) ? "checked" : "");
4058 #ifdef CS_CACHEEX_AIO
4059 tpl_addVar(vars, TPLADD, "AMCHECKED", (account->cacheex.allow_maxhop == 1) ? "checked" : "");
4060 #endif
4061 tpl_addVar(vars, TPLADD, "BLOCKFAKECWSCHECKED", (account->cacheex.block_fakecws == 1) ? "checked" : "");
4062 #ifdef CS_CACHEEX_AIO
4063 tpl_addVar(vars, TPLADD, "USECWCHECKFORPUSHCHECKED", (account->cacheex.cw_check_for_push == 1) ? "checked" : "");
4064 tpl_addVar(vars, TPLADD, "LGONLYREMOTESETTINGSCHECKED", (account->cacheex.lg_only_remote_settings == 1) ? "checked" : "");
4065 tpl_addVar(vars, TPLADD, "LOCALGENERATEDONLYCHECKED", (account->cacheex.localgenerated_only == 1) ? "checked" : "");
4067 value = mk_t_ftab(&account->cacheex.lg_only_tab);
4068 tpl_addVar(vars, TPLADD, "LGONLYTAB", value);
4069 free_mk_t(value);
4071 tpl_addVar(vars, TPLADD, "LOCALGENERATEDONLYINCHECKED", (account->cacheex.localgenerated_only_in == 1) ? "checked" : "");
4073 tpl_addVar(vars, TPLADD, "LGONLYINAIOONLYCHECKED", (account->cacheex.lg_only_in_aio_only == 1) ? "checked" : "");
4075 value = mk_t_ftab(&account->cacheex.lg_only_in_tab);
4076 tpl_addVar(vars, TPLADD, "LGONLYINTAB", value);
4077 free_mk_t(value);
4079 value = mk_t_caidvaluetab(&account->cacheex.cacheex_nopushafter_tab);
4080 tpl_addVar(vars, TPLADD, "CACHEEXNOPUSHAFTER", value);
4081 free_mk_t(value);
4082 #endif
4083 tpl_addVar(vars, TPLADD, "NWTCHECKED", (account->no_wait_time == 1) ? "checked" : "");
4084 tpl_addVar(vars, TPLADD, "DISABLECRCCEX4USER", (account->disablecrccacheex == 1) ? "checked" : "");
4085 value = mk_t_ftab(&account->disablecrccacheex_only_for);
4086 tpl_addVar(vars, TPLADD, "IGNCRCCEX4USERONLYFOR", value);
4087 free_mk_t(value);
4089 #endif
4091 #ifdef CW_CYCLE_CHECK
4092 tpl_addVar(vars, TPLADD, "USERCWCYCLEDISABLE", (account->cwc_disable == 1) ? "checked" : "");
4093 #endif
4095 //Keepalive
4096 if(!apicall)
4098 if(account->ncd_keepalive)
4099 { tpl_addVar(vars, TPLADD, "KEEPALIVE", "checked"); }
4101 else
4103 tpl_printf(vars, TPLADD, "KEEPALIVEVALUE", "%d", account->ncd_keepalive);
4106 #ifdef CS_ANTICASC
4107 tpl_printf(vars, TPLADD, "AC_USERS", "%d", account->ac_users);
4108 tpl_printf(vars, TPLADD, "CFGNUMUSERS", "%d", cfg.ac_users);
4109 if(!apicall)
4111 tpl_printf(vars, TPLADD, "TMP", "PENALTY%d", account->ac_penalty);
4112 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
4113 char *tmp = NULL;
4114 switch(cfg.ac_penalty)
4116 case 0:
4117 tmp = "(0) Only write to log";
4118 break;
4119 case 1:
4120 tmp = "(1) NULL CW";
4121 break;
4122 case 2:
4123 tmp = "(2) Ban";
4124 break;
4125 case 3:
4126 tmp = "(3) Real CW delayed";
4127 break;
4129 tpl_addVar(vars, TPLADD, "CFGPENALTY", tmp);
4131 else
4133 tpl_printf(vars, TPLADD, "PENALTYVALUE", "%d", account->ac_penalty);
4135 tpl_printf(vars, TPLADD, "ACOSC_MAX_ECMS_PER_MINUTE", "%d", account->acosc_max_ecms_per_minute);
4136 tpl_printf(vars, TPLADD, "ACOSC_MAX_ACTIVE_SIDS", "%d", account->acosc_max_active_sids);
4137 tpl_printf(vars, TPLADD, "CFG_ACOSC_MAX_ECMS_PER_MINUTE", "%d", cfg.acosc_max_ecms_per_minute);
4138 tpl_printf(vars, TPLADD, "CFG_ACOSC_MAX_ACTIVE_SIDS", "%d", cfg.acosc_max_active_sids);
4139 tpl_printf(vars, TPLADD, "ACOSC_ZAP_LIMIT", "%d", account->acosc_zap_limit);
4140 tpl_printf(vars, TPLADD, "CFG_ACOSC_ZAP_LIMIT", "%d", cfg.acosc_zap_limit);
4141 if(!apicall)
4143 tpl_printf(vars, TPLADD, "TMP", "ACOSC_PENALTY%d", account->acosc_penalty);
4144 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
4145 char *tmp = NULL;
4146 switch(cfg.acosc_penalty)
4148 case -1:
4149 tmp = "(-1) Use Global Value";
4150 break;
4151 case 0:
4152 tmp = "(0) Only write to log";
4153 break;
4154 case 1:
4155 tmp = "(1) NULL CW";
4156 break;
4157 case 2:
4158 tmp = "(2) Ban";
4159 break;
4160 case 3:
4161 tmp = "(3) CW delayed";
4162 break;
4163 case 4:
4164 tmp = "(4) Hidecards";
4165 break;
4167 tpl_addVar(vars, TPLADD, "CFG_ACOSC_PENALTY", tmp);
4168 } else
4170 tpl_printf(vars, TPLADD, "ACOSC_PENALTYVALUE", "%d", account->acosc_penalty);
4173 tpl_printf(vars, TPLADD, "ACOSC_PENALTY_DURATION", "%d", account->acosc_penalty_duration);
4174 tpl_printf(vars, TPLADD, "CFG_ACOSC_PENALTY_DURATION", "%d", cfg.acosc_penalty_duration);
4175 tpl_printf(vars, TPLADD, "ACOSC_DELAY", "%d", account->acosc_delay);
4176 tpl_printf(vars, TPLADD, "CFG_ACOSC_DELAY", "%d", cfg.acosc_delay);
4177 #endif
4179 #ifdef MODULE_CCCAM
4180 tpl_printf(vars, TPLADD, "CCCMAXHOPS", "%d", account->cccmaxhops);
4181 tpl_printf(vars, TPLADD, "CCCRESHARE", "%d", account->cccreshare);
4182 tpl_printf(vars, TPLADD, "RESHARE", "%d", cfg.cc_reshare);
4184 //CCcam Ignore Reshare
4185 tpl_printf(vars, TPLADD, "TMP", "CCCIGNRSHRSELECTED%d", account->cccignorereshare);
4186 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
4187 tpl_addVar(vars, TPLADD, "CFGIGNORERESHARE",
4188 cfg.cc_ignore_reshare == 0 ?
4189 "0 - use reshare level of Server" : "1 - use reshare level of Reader or User");
4191 //CCcam Stealth Mode
4192 tpl_printf(vars, TPLADD, "TMP", "CCCSTEALTHSELECTED%d", account->cccstealth);
4193 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
4195 tpl_addVar(vars, TPLADD, "STEALTH", cfg.cc_stealth ? "enable" : "disable");
4196 #endif
4198 //Failban
4199 tpl_printf(vars, TPLADD, "FAILBAN", "%d", account->failban);
4201 if(!apicall)
4203 #ifdef CS_CACHEEX_AIO
4204 return tpl_getTpl(vars, "USEREDITAIO");
4205 #else
4206 return tpl_getTpl(vars, "USEREDIT");
4207 #endif
4209 else
4211 return tpl_getTpl(vars, "APIUSEREDIT");
4216 static void webif_add_client_proto(struct templatevars *vars, struct s_client *cl, const char *proto, int8_t apicall)
4218 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTO", "");
4219 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOSORT", "");
4220 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOTITLE", "");
4221 tpl_addVar(vars, TPLADDONCE, "PROTOICON", "");
4222 if(!cl) { return; }
4223 #ifdef MODULE_NEWCAMD
4224 if(streq(proto, "newcamd") && cl->typ == 'c')
4226 tpl_printf(vars, TPLADD, "CLIENTPROTO", "%s (%s)", proto, newcamd_get_client_name(cl->ncd_client_id));
4227 tpl_printf(vars, TPLADD, "CLIENTPROTOSORT", "%s (%s)", proto, newcamd_get_client_name(cl->ncd_client_id));
4228 if(cfg.http_showpicons )
4230 char picon_name[32];
4231 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s_%s", (char *)proto, newcamd_get_client_name(cl->ncd_client_id));
4232 if(picon_exists(picon_name))
4234 if (!apicall)
4236 tpl_addVar(vars, TPLADD, "NCMDA", (char *)proto);
4237 tpl_addVar(vars, TPLADD, "NCMDB", (char *)newcamd_get_client_name(cl->ncd_client_id));
4238 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTONEWCAMDPIC"));
4240 else
4242 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s_%s",(char *)proto, (char *)newcamd_get_client_name(cl->ncd_client_id));
4245 else
4247 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s_%s.tpl", proto, newcamd_get_client_name(cl->ncd_client_id));
4250 return;
4252 #endif
4253 #ifdef MODULE_CCCAM
4254 if(strncmp(proto, "cccam", 5) == 0)
4256 struct cc_data *cc = cl->cc;
4257 if(cc && *cc->remote_version && *cc->remote_build)
4259 tpl_printf(vars, TPLADD, "CLIENTPROTO", "%s (%s-%s)", proto, cc->remote_version, cc->remote_build);
4260 tpl_printf(vars, TPLADD, "CLIENTPROTOSORT", "%s (%s-%s)", proto, cc->remote_version, cc->remote_build);
4261 if(cccam_client_multics_mode(cl))
4263 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "Multics, revision r%d", cc->multics_version[0] | (cc->multics_version[1] << 8));
4265 else
4267 #endif
4268 #ifdef CS_CACHEEX_AIO
4269 #if defined(MODULE_CCCAM) && defined(CS_CACHEEX)
4270 if(cl->reader && cl->reader->cacheex.feature_bitfield)
4272 if(cl->reader->cacheex.feature_bitfield & 32)
4274 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "%s [cx-aio %s]", (cc->extended_mode ? cc->remote_oscam : ""), cl->reader->cacheex.aio_version);
4276 else if(cl->reader->cacheex.feature_bitfield)
4278 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "%s [cx-aio < 9.2.3]", (cc->extended_mode ? cc->remote_oscam : ""));
4281 else if(cl->account && cl->account->cacheex.feature_bitfield)
4283 if(cl->account->cacheex.feature_bitfield & 32)
4285 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "%s [cx-aio %s]", (cc->extended_mode ? cc->remote_oscam : ""), cl->account->cacheex.aio_version);
4287 else if(cl->account->cacheex.feature_bitfield)
4289 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "%s [cx-aio < 9.2.3]", (cc->extended_mode ? cc->remote_oscam : ""));
4292 else
4294 #endif
4295 #endif
4296 #ifdef MODULE_CCCAM
4297 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", cc->extended_mode ? cc->remote_oscam : "");
4298 #endif
4299 #ifdef CS_CACHEEX_AIO
4300 #if defined(MODULE_CCCAM) && defined(CS_CACHEEX)
4302 #endif
4303 #endif
4304 #ifdef MODULE_CCCAM
4307 if(cfg.http_showpicons)
4309 char picon_name[32];
4311 int8_t is_other_proto = 0;
4312 if(cccam_client_multics_mode(cl)) { is_other_proto = 1; }
4314 switch(is_other_proto)
4316 case 1:
4317 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s_r_%d", proto, cc->multics_version[0] | (cc->multics_version[1] << 8));
4318 if(picon_exists(picon_name))
4320 if (!apicall)
4322 tpl_addVar(vars, TPLADD, "CCA", (char *)proto);
4323 tpl_addVar(vars, TPLADD, "CCB", "r");
4324 tpl_printf(vars, TPLADD, "CCC", "%d", cc->multics_version[0] | (cc->multics_version[1] << 8));
4325 tpl_addVar(vars, TPLADD, "CCD", "");
4326 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTOCCCAMPIC"));
4328 else
4330 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s_r_%d",(char *)proto, cc->multics_version[0] | (cc->multics_version[1] << 8));
4333 else
4335 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "Multics, revision r%d missing icon: IC_%s_r_%d.tpl",
4336 cc->multics_version[0] | (cc->multics_version[1] << 8), proto, cc->multics_version[0] | (cc->multics_version[1] << 8));
4338 break;
4340 default:
4341 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s_%s_%s", proto, cc->remote_version, cc->remote_build);
4342 if(picon_exists(picon_name))
4344 if (!apicall)
4346 tpl_addVar(vars, TPLADD, "CCA", (char *)proto);
4347 tpl_addVar(vars, TPLADD, "CCB", cc->remote_version);
4348 tpl_addVar(vars, TPLADD, "CCC", cc->remote_build);
4349 #ifdef CS_CACHEEX_AIO
4350 #if defined(MODULE_CCCAM) && defined(CS_CACHEEX)
4351 if(cl->reader && cl->reader->cacheex.feature_bitfield)
4353 if(cl->reader->cacheex.feature_bitfield & 32)
4355 tpl_printf(vars, TPLADD, "CCD", "%s [cx-aio %s]", (cc->extended_mode ? cc->remote_oscam : ""), cl->reader->cacheex.aio_version);
4357 else if(cl->reader->cacheex.feature_bitfield)
4359 tpl_printf(vars, TPLADD, "CCD", "%s [cx-aio < 9.2.3]", (cc->extended_mode ? cc->remote_oscam : ""));
4362 else if(cl->account && cl->account->cacheex.feature_bitfield)
4364 if(cl->account->cacheex.feature_bitfield & 32)
4366 tpl_printf(vars, TPLADD, "CCD", "%s [cx-aio %s]", (cc->extended_mode ? cc->remote_oscam : ""), cl->account->cacheex.aio_version);
4368 else if(cl->account->cacheex.feature_bitfield)
4370 tpl_printf(vars, TPLADD, "CCD", "%s [cx-aio < 9.2.3]", (cc->extended_mode ? cc->remote_oscam : ""));
4373 else
4375 #endif
4376 #endif
4377 tpl_addVar(vars, TPLADD, "CCD", cc->extended_mode ? cc->remote_oscam : "");
4378 #ifdef CS_CACHEEX_AIO
4379 #if defined(MODULE_CCCAM) && defined(CS_CACHEEX)
4381 #endif
4382 #endif
4383 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTOCCCAMPIC"));
4385 else
4387 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s_%s_%s",(char *)proto, cc->remote_version, cc->remote_build);
4390 else
4392 #endif
4393 #ifdef CS_CACHEEX_AIO
4394 #if defined(MODULE_CCCAM) && defined(CS_CACHEEX)
4395 if(cl->reader && cl->reader->cacheex.feature_bitfield)
4397 if(cl->reader->cacheex.feature_bitfield & 32)
4399 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "%s [cx-aio %s] missing icon: IC_%s_%s_%s.tpl", (cc->extended_mode ? cc->remote_oscam : ""), cl->reader->cacheex.aio_version, proto, cc->remote_version, cc->remote_build);
4401 else if(cl->reader->cacheex.feature_bitfield)
4403 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "%s [cx-aio < 9.2.3] missing icon: IC_%s_%s_%s.tpl", (cc->extended_mode ? cc->remote_oscam : ""), proto, cc->remote_version, cc->remote_build);
4406 else if(cl->account && cl->account->cacheex.feature_bitfield)
4408 if(cl->account->cacheex.feature_bitfield & 32)
4410 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "%s [cx-aio %s] missing icon: IC_%s_%s_%s.tpl", (cc->extended_mode ? cc->remote_oscam : ""), cl->account->cacheex.aio_version, proto, cc->remote_version, cc->remote_build);
4412 else if(cl->account->cacheex.feature_bitfield)
4414 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "%s [cx-aio < 9.2.3] missing icon: IC_%s_%s_%s.tpl", (cc->extended_mode ? cc->remote_oscam : ""), proto, cc->remote_version, cc->remote_build);
4417 else
4419 #endif
4420 #endif
4421 #ifdef MODULE_CCCAM
4422 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "%s missing icon: IC_%s_%s_%s.tpl",
4423 cc->extended_mode ? cc->remote_oscam : "", proto, cc->remote_version, cc->remote_build);
4424 #ifdef CS_CACHEEX_AIO
4425 #if defined(MODULE_CCCAM) && defined(CS_CACHEEX)
4427 #endif
4428 #endif
4430 break;
4434 return;
4436 #endif
4437 #ifdef CS_CACHEEX_AIO
4438 #if (defined(MODULE_CAMD35) || defined(MODULE_CAMD35_TCP)) && defined(CS_CACHEEX)
4439 if(strncmp(proto, "cs3", 3) == 0)
4441 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTO", (char *)proto);
4443 char aiover[32];
4444 aiover[0] = '\0';
4446 if(cl->account && cl->cacheex_aio_checked)
4448 if(cl->account->cacheex.feature_bitfield & 32)
4450 snprintf(aiover, sizeof(aiover) / sizeof(char) -1, "%s", cl->account->cacheex.aio_version);
4451 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", aiover);
4453 else if(cl->account->cacheex.feature_bitfield)
4455 snprintf(aiover, sizeof(aiover) / sizeof(char) -1, "%s", "[cx-aio: < 9.2.3]");
4456 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", aiover);
4458 else
4460 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", "");
4464 if(cl->reader && cl->cacheex_aio_checked)
4466 if(cl->reader->cacheex.feature_bitfield & 32)
4468 snprintf(aiover, sizeof(aiover) / sizeof(char) -1, "%s", cl->reader->cacheex.aio_version);
4469 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", aiover);
4471 else if(cl->reader->cacheex.feature_bitfield)
4473 snprintf(aiover, sizeof(aiover) / sizeof(char) -1, "%s", "[cx-aio: < 9.2.3]");
4474 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", aiover);
4476 else
4478 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", "");
4482 if(cfg.http_showpicons)
4484 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTO", (char *)proto);
4486 char picon_name[32];
4487 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", proto);
4488 if(picon_exists(picon_name))
4490 if (!apicall)
4492 tpl_addVar(vars, TPLADD, "CAMD3A", (char *)proto);
4493 if(aiover[0] == '\0')
4494 tpl_addVar(vars, TPLADD, "AIOVER", "");
4495 else
4496 tpl_printf(vars, TPLADD, "AIOVER", "[cx-aio %s]", aiover);
4498 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTOCAMD3AIOPIC"));
4500 else
4502 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s",(char *)proto);
4505 else
4507 if(cl->account && cl->cacheex_aio_checked)
4509 if(cl->account->cacheex.feature_bitfield & 32)
4510 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s.tpl [cx-aio %s]", proto, cl->account->cacheex.aio_version);
4511 else if(cl->account->cacheex.feature_bitfield)
4512 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s.tpl [cx-aio < 9.2.3]", proto);
4513 else
4514 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s.tpl", proto);
4517 if(cl->reader && cl->cacheex_aio_checked)
4519 if(cl->reader->cacheex.feature_bitfield & 32)
4520 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s.tpl [cx-aio %s]", proto, cl->reader->cacheex.aio_version);
4521 else if(cl->reader->cacheex.feature_bitfield)
4522 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s.tpl [cx-aio < 9.2.3]", proto);
4523 else
4524 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s.tpl", proto);
4528 return;
4530 #endif
4531 #endif
4533 #ifdef HAVE_DVBAPI
4534 if(streq(proto, "dvbapi") && cl->typ == 'c' && strcmp(dvbapi_get_client_name(), ""))
4536 if (!apicall)
4537 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());
4538 else
4539 tpl_printf(vars, TPLADD, "CLIENTPROTO", "%s (client: %s, protocol version: %d)", proto, dvbapi_get_client_name(), dvbapi_get_client_proto_version());
4540 tpl_printf(vars, TPLADD, "CLIENTPROTOSORT", "%s", proto);
4541 return;
4543 #endif
4544 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTO", (char *)proto);
4545 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOSORT", (char *)proto);
4546 if(cfg.http_showpicons)
4548 char picon_name[32];
4549 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", proto);
4550 if(picon_exists(picon_name))
4552 if (!apicall)
4554 tpl_addVar(vars, TPLADD, "OTHER", (char *)proto);
4555 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTOOTHERPIC"));
4557 else
4559 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s",(char *)proto);
4562 else
4564 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s.tpl", proto);
4569 static void kill_account_thread(struct s_auth *account)
4571 struct s_client *cl;
4572 for(cl = first_client->next; cl ; cl = cl->next)
4574 if(cl->account == account)
4576 if(get_module(cl)->type & MOD_CONN_NET)
4578 kill_thread(cl);
4580 else
4582 cl->account = first_client->account;
4588 static char *send_oscam_user_config(struct templatevars *vars, struct uriparams *params, int32_t apicall)
4590 struct s_auth *account;
4591 struct s_client *cl;
4592 char *user = getParam(params, "user");
4593 int32_t found = 0;
4594 uint8_t md5tmp[MD5_DIGEST_LENGTH];
4596 if(!apicall)
4598 setActiveMenu(vars, MNU_USERS);
4600 if(strcmp(getParam(params, "action"), "reinit") == 0)
4602 if(!cfg.http_readonly)
4603 { refresh_oscam(REFR_ACCOUNTS); }
4605 if(strcmp(getParam(params, "action"), "delete") == 0)
4607 if(cfg.http_readonly)
4609 tpl_addMsg(vars, "WebIf is in readonly mode. No deletion will be made!");
4611 else
4613 struct s_auth *account_prev = NULL;
4615 for(account = cfg.account; (account); account = account->next)
4617 if(strcmp(account->usr, user) == 0)
4619 if(account_prev == NULL)
4620 { cfg.account = account->next; }
4621 else
4622 { account_prev->next = account->next; }
4623 ll_clear(account->aureader_list);
4624 kill_account_thread(account);
4625 add_garbage(account);
4626 found = 1;
4627 break;
4629 account_prev = account;
4631 if(found > 0)
4633 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
4635 else { tpl_addMsg(vars, "Sorry but the specified user doesn't exist. No deletion will be made!"); }
4639 if((strcmp(getParam(params, "action"), "disable") == 0) || (strcmp(getParam(params, "action"), "enable") == 0))
4641 account = get_account_by_name(getParam(params, "user"));
4642 if(account)
4644 if(strcmp(getParam(params, "action"), "disable") == 0)
4646 account->disabled = 1;
4647 kill_account_thread(account);
4649 else
4650 { account->disabled = 0; }
4651 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
4653 else
4655 tpl_addMsg(vars, "Sorry but the specified user doesn't exist. No deletion will be made!");
4659 if(strcmp(getParam(params, "action"), "resetstats") == 0)
4661 account = get_account_by_name(getParam(params, "user"));
4662 if(account) { clear_account_stats(account); }
4665 if(strcmp(getParam(params, "action"), "resetuserstats") == 0)
4667 clear_info_clients_stats();
4670 if(strcmp(getParam(params, "action"), "resetreaderstats") == 0)
4672 clear_info_readers_stats();
4675 if(strcmp(getParam(params, "action"), "resetalluserstats") == 0)
4677 clear_all_account_stats();
4680 if((strcmp(getParam(params, "part"), "adduser") == 0) && (!cfg.http_readonly))
4682 tpl_addVar(vars, TPLAPPEND, "NEWUSERFORM", tpl_getTpl(vars, "ADDNEWUSER"));
4685 /* List accounts*/
4686 char *status, *expired, *classname, *lastchan;
4687 time_t now = time((time_t *)0);
4688 int32_t isec = 0, chsec = 0;
4690 char *filter = NULL;
4691 int32_t clientcount = 0;
4692 if(apicall)
4694 filter = getParam(params, "label");
4696 int8_t grp_set = 0;
4697 int8_t expdate_set = 0;
4698 int32_t total_users = 0;
4699 int32_t disabled_users = 0;
4700 int32_t expired_users = 0;
4701 int32_t expired_or_disabled_users = 0;
4702 int32_t connected_users = 0;
4703 int32_t online_users = 0;
4704 int32_t casc_users = 0;
4705 int32_t casc_users2 = 0;
4706 int32_t n_request = 0;
4707 int existing_insert = 0;
4709 for(account = cfg.account; (account); account = account->next)
4711 if(account->expirationdate){
4712 expdate_set = 1;
4715 if(account->next){
4716 if(account->grp != account->next->grp){
4717 grp_set = 1;
4720 if(expdate_set && grp_set)
4721 break;
4724 for(account = cfg.account; (account); account = account->next)
4726 //clear for next client
4727 total_users++;
4728 isactive = 1;
4730 status = "offline";
4731 classname = "offline";
4732 isec = 0;
4733 chsec = 0;
4735 //reset caid/srevid template variables
4736 tpl_addVar(vars, TPLADD, "CLIENTCAID", "");
4737 tpl_addVar(vars, TPLADD, "CLIENTPROVID", "");
4738 tpl_addVar(vars, TPLADD, "CLIENTSRVID", "");
4739 tpl_addVar(vars, TPLADD, "LASTCHANNEL", "");
4740 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", "");
4741 tpl_addVar(vars, TPLADD, "USERMD5", "");
4742 tpl_addVar(vars, TPLADD, "CWLASTRESPONSET", "");
4743 tpl_addVar(vars, TPLADD, "CWLASTRESPONSETMS", "");
4744 tpl_addVar(vars, TPLADD, "CLIENTIP", "");
4745 tpl_addVar(vars, TPLADD, "LASTCHANNELTITLE", "");
4746 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", "");
4747 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNELAPI", "");
4748 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", "");
4749 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEP", "");
4750 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEPAPI", "");
4751 tpl_addVar(vars, TPLADD, "IDLESECS", "");
4752 tpl_addVar(vars, TPLADD, "UNOTIFY", "");
4754 if(account->expirationdate && account->expirationdate < now)
4756 expired = " (expired)";
4757 classname = "expired";
4758 expired_users++;
4759 isactive = 0;
4761 else
4763 expired = "";
4766 if(account->disabled != 0)
4768 expired = " (disabled)";
4769 classname = "disabled";
4770 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICENA");
4771 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Enable");
4772 tpl_addVar(vars, TPLADD, "SWITCH", "enable");
4773 disabled_users++;
4774 isactive = 0;
4776 else
4778 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICDIS");
4779 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Disable");
4780 tpl_addVar(vars, TPLADD, "SWITCH", "disable");
4782 if((account->expirationdate && account->expirationdate < now)||account->disabled != 0)
4784 expired_or_disabled_users++;
4787 int32_t lastresponsetm = 0, latestactivity = 0;
4788 const char *proto = "";
4789 double cwrate = 0.0, cwrate2 = 0.0;
4791 //search account in active clients
4792 isactive = 0;
4793 int16_t nrclients = 0;
4794 struct s_client *latestclient = NULL;
4795 for(cl = first_client->next; cl ; cl = cl->next)
4797 if(cl->account && !strcmp(cl->account->usr, account->usr))
4799 if(cl->lastecm > latestactivity || cl->login > latestactivity)
4801 if(cl->lastecm > cl->login) { latestactivity = cl->lastecm; }
4802 else { latestactivity = cl->login; }
4803 latestclient = cl;
4805 nrclients++;
4808 if(account->cwfound + account->cwnot + account->cwcache > 0)
4810 cwrate = now - account->firstlogin;
4811 cwrate /= (account->cwfound + account->cwnot + account->cwcache);
4814 casc_users = 0;
4815 casc_users2 = 0;
4816 int8_t conn = 0;
4817 if(latestclient != NULL)
4819 char channame[CS_SERVICENAME_SIZE];
4820 status = (!apicall) ? "<B>connected</B>" : "connected";
4821 if(account->expirationdate && account->expirationdate < now) { classname = "expired"; }
4822 else { classname = "connected";conn = 1; }
4824 proto = client_get_proto(latestclient);
4825 int clientcaid = latestclient->last_caid;
4826 int clientsrvid = latestclient->last_srvid;
4827 int clientprovid = latestclient->last_provid;
4828 tpl_printf(vars, TPLADD, "CLIENTCAID", "%04X", clientcaid);
4829 tpl_printf(vars, TPLADD, "CLIENTPROVID", "%06X", clientprovid);
4830 tpl_printf(vars, TPLADD, "CLIENTSRVID", "%04X", clientsrvid);
4832 if(clientsrvid != NO_SRVID_VALUE || clientcaid != NO_CAID_VALUE)
4834 lastchan = xml_encode(vars, get_servicename(latestclient, clientsrvid, clientprovid, clientcaid, channame, sizeof(channame)));
4835 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", lastchan);
4837 else
4839 lastchan = "";
4840 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", "~~~~~");
4843 tpl_addVar(vars, TPLADDONCE, "LASTCHANNEL", lastchan);
4844 tpl_addVar(vars, TPLADD, "LASTCHANNELTITLE", lastchan);
4846 if(cfg.http_showpicons )
4848 char picon_name[128];
4849 char picon_channame[128];
4850 int8_t picon_ok = 0;
4852 get_picon_servicename_or_null(latestclient, clientsrvid, clientprovid, clientcaid, picon_channame, sizeof(picon_channame));
4853 if(picon_channame[0])
4855 snprintf(picon_name, sizeof(picon_name) / sizeof(char), "%s", picon_channame);
4856 picon_ok = picon_exists(picon_name);
4858 if(!picon_ok && picon_servicename_remve_hd(picon_channame, sizeof(picon_channame)))
4860 snprintf(picon_name, sizeof(picon_name) / sizeof(char), "%s", picon_channame);
4861 picon_ok = picon_exists(picon_name);
4864 if(!picon_ok)
4866 snprintf(picon_name, sizeof(picon_name) / sizeof(char), "%04X_%06X_%04X", clientcaid, clientprovid, clientsrvid);
4867 picon_ok = picon_exists(picon_name);
4869 if(!picon_ok)
4871 snprintf(picon_name, sizeof(picon_name) / sizeof(char), "%04X_%04X", clientcaid, clientsrvid);
4872 picon_ok = picon_exists(picon_name);
4874 if(!picon_ok)
4876 snprintf(picon_name, sizeof(picon_name) / sizeof(char), "0000_%04X", clientsrvid);
4877 picon_ok = picon_exists(picon_name);
4879 if(picon_ok)
4881 tpl_addVar(vars, TPLADDONCE, "LCA", picon_name);
4882 tpl_addVar(vars, TPLADDONCE, "LCB", lastchan);
4883 if(!apicall)
4885 tpl_addVar(vars, TPLADDONCE, "LASTCHANNEL", tpl_getTpl(vars, "USERCONFIGLASTCHANEL"));
4888 else
4890 tpl_printf(vars, TPLADD, "LASTCHANNELTITLE", "missing icon: IC_%s.tpl", picon_name);
4894 lastresponsetm = latestclient->cwlastresptime;
4895 tpl_addVar(vars, TPLADD, "CLIENTIP", cs_inet_ntoa(latestclient->ip));
4896 connected_users++;
4897 casc_users = ll_count(latestclient->cascadeusers);
4898 LL_ITER it = ll_iter_create(latestclient->cascadeusers);
4899 struct s_cascadeuser *cu;
4900 while((cu = ll_iter_next(&it)))
4902 if(cu->cwrate > 0)
4903 { casc_users2++; }
4905 if(latestactivity > 0)
4907 isec = now - latestactivity;
4908 chsec = latestclient->lastswitch ? now - latestclient->lastswitch : 0;
4909 if(isec < cfg.hideclient_to)
4911 isactive = 1;
4912 status = (!apicall) ? "<B>online</B>" : "online";
4913 if(account->expirationdate && account->expirationdate < now) { classname = "expired"; }
4914 else { classname = "online"; }
4915 if(latestclient->cwfound + latestclient->cwnot + latestclient->cwcache > 0)
4917 cwrate2 = now - latestclient->login;
4918 cwrate2 /= (latestclient->cwfound + latestclient->cwnot + latestclient->cwcache);
4919 tpl_printf(vars, TPLADDONCE, "CWRATE2", " (%.2f)", cwrate2);
4920 online_users++;
4926 n_request = 0;
4927 if(latestclient != NULL){
4928 n_request = latestclient->n_request[0];
4931 tpl_addVar(vars, TPLADD, "EXPIREVIEW", expdate_set ? "" : "exp");
4932 tpl_addVar(vars, TPLADD, "GRPVIEW", grp_set ? "" : "grp");
4933 #ifdef CS_ANTICASC
4934 tpl_addVar(vars, TPLADD, "ANTICASCVIEW", cfg.ac_enabled ? "" : "acas");
4935 #endif
4936 tpl_printf(vars, TPLADD, "CWOK", PRINTF_LOCAL_D, account->cwfound);
4937 tpl_printf(vars, TPLADD, "CWNOK", PRINTF_LOCAL_D, account->cwnot);
4938 tpl_printf(vars, TPLADD, "CWIGN", PRINTF_LOCAL_D, account->cwignored);
4939 tpl_printf(vars, TPLADD, "CWTOUT", PRINTF_LOCAL_D, account->cwtout);
4940 #ifdef CW_CYCLE_CHECK
4941 tpl_addVar(vars, TPLADD, "CWCCYCVIEW", cfg.cwcycle_check_enable ? "" : "cwc");
4942 tpl_printf(vars, TPLADD, "CWCYCLECHECKED", "%d", account->cwcycledchecked);
4943 tpl_printf(vars, TPLADD, "CWCYCLEOK", "%d", account->cwcycledok);
4944 tpl_printf(vars, TPLADD, "CWCYCLENOK", "%d", account->cwcyclednok);
4945 tpl_printf(vars, TPLADD, "CWCYCLEIGN", "%d", account->cwcycledign);
4946 #endif
4947 tpl_printf(vars, TPLADD, "CWCACHE", PRINTF_LOCAL_D, account->cwcache);
4948 tpl_printf(vars, TPLADD, "CWTUN", PRINTF_LOCAL_D, account->cwtun);
4949 tpl_printf(vars, TPLADD, "EMMOK", PRINTF_LOCAL_D, account->emmok);
4950 tpl_printf(vars, TPLADD, "EMMNOK", PRINTF_LOCAL_D, account->emmnok);
4951 tpl_printf(vars, TPLADD, "CWRATE", "%.2f", cwrate);
4952 tpl_printf(vars, TPLADD, "CASCUSERS", "%d", casc_users);
4953 tpl_printf(vars, TPLADD, "CASCUSERS2", "%d", casc_users2);
4954 tpl_printf(vars, TPLADD, "CASCUSERSCOMB", "%d/%d", casc_users, casc_users2);
4955 tpl_printf(vars, TPLADD, "N_REQUEST_MIN", "%d", n_request);
4957 if(isactive > 0 || conn > 0)
4959 if(casc_users+casc_users2>0)
4961 tpl_printf(vars, TPLADD, "CWLASTRESPONSET", "%d", lastresponsetm);
4962 tpl_printf(vars, TPLADD, "CWLASTRESPONSETMS", PRINTF_LOCAL_D " ms", lastresponsetm);
4964 tpl_addVar(vars, TPLADD, "IDLESECS", sec2timeformat(vars, isec));
4967 if(isactive > 0)
4969 tpl_printf(vars, TPLADD, "CLIENTTIMEONCHANNELAPI", "%d", chsec);
4970 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", sec2timeformat(vars, chsec));
4972 if(account->tosleep)
4974 if(account->tosleep >0){
4975 tpl_printf(vars, TPLADD, "CLIENTTIMETOSLEEP", "Sleeping in %d minutes", account->tosleep - (chsec / 60));
4976 } else {
4977 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEP", "Sleeping");
4979 tpl_printf(vars, TPLADD, "CLIENTTIMETOSLEEPAPI", "%d", account->tosleep - (chsec / 60));
4980 } else {
4981 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEPAPI", "undefined");
4984 #ifdef CS_CACHEEX_AIO
4985 #if defined(MODULE_CAMD35) || defined (MODULE_CAMD35_TCP)
4986 if(latestclient != NULL && (latestclient->account->cacheex.feature_bitfield || latestclient->c35_extmode > 1))
4987 #else
4988 if(latestclient != NULL && (latestclient->account->cacheex.feature_bitfield))
4989 #endif
4991 const char *aio_suffix = " (cx-aio)";
4992 char *new_proto;
4993 if(cs_malloc(&new_proto, cs_strlen(proto)+cs_strlen(aio_suffix)+1)) {
4994 if (!cs_strncat(new_proto, (char *)proto, cs_strlen(proto)+cs_strlen(aio_suffix)+1)) {
4995 cs_log("FIXME!");
4997 if (cs_strncat(new_proto, (char *)aio_suffix, cs_strlen(proto)+cs_strlen(aio_suffix)+1)) {
4998 webif_add_client_proto(vars, latestclient, (const char *)new_proto, apicall);
4999 } else {
5000 cs_log("FIXME!");
5002 free(new_proto);
5004 } else {
5005 #endif
5006 webif_add_client_proto(vars, latestclient, proto, apicall);
5007 #ifdef CS_CACHEEX_AIO
5009 #endif
5011 tpl_addVar(vars, TPLADD, "CLASSNAME", classname);
5012 MD5((uint8_t *)account->usr, cs_strlen(account->usr), md5tmp);
5013 int z;
5014 tpl_addVar(vars, TPLADD, "USERMD5","id_");
5015 for (z = 0; z < MD5_DIGEST_LENGTH; z++)
5017 tpl_printf(vars, TPLAPPEND, "USERMD5", "%02x", md5tmp[z]);
5019 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, account->usr));
5020 tpl_addVar(vars, TPLADD, "USERNAMEENC", urlencode(vars, account->usr));
5021 if(!existing_insert)
5023 tpl_printf(vars, TPLADD, "EXISTING_INS", "'%s'", urlencode(vars, account->usr));
5024 existing_insert++;
5025 }else
5027 tpl_printf(vars, TPLAPPEND, "EXISTING_INS", ",'%s'", urlencode(vars, account->usr));
5030 if(account->description)
5031 tpl_printf(vars, TPLADD, "DESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, account->description));
5032 else
5033 tpl_addVar(vars, TPLADD, "DESCRIPTION", "");
5035 if(cfg.http_showpicons && !apicall)
5036 tpl_addVar(vars, TPLADD, "USERBIT", tpl_getTpl(vars, picon_exists(xml_encode(vars, account->usr)) ? "USERICON" : "USERNOICON"));
5037 else
5038 tpl_addVar(vars, TPLADD, "USERBIT", tpl_getTpl(vars, "USERLABEL"));
5040 char *value = mk_t_group(account->grp);
5041 tpl_addVar(vars, TPLADD, "GROUPS", value);
5042 free_mk_t(value);
5043 tpl_addVar(vars, TPLADD, "STATUS", status);
5044 tpl_addVar(vars, TPLAPPEND, "STATUS", expired);
5046 if(nrclients > 1)
5048 tpl_printf(vars, TPLADD, "UNOTIFY", "%d", nrclients);
5049 tpl_addVar(vars, TPLADDONCE, "CLIENTCOUNTNOTIFIER", tpl_getTpl(vars, "CLIENTCOUNTNOTIFIERBIT"));
5052 //Expirationdate
5053 struct tm timeinfo;
5054 cs_gmtime_r(&account->expirationdate, &timeinfo);
5055 char buf [80];
5056 strftime(buf, 80, "%Y-%m-%d", &timeinfo);
5057 if(strcmp(buf, "1970-01-01")) { tpl_addVar(vars, TPLADD, "EXPDATE", buf); }
5058 else { tpl_addVar(vars, TPLADD, "EXPDATE", ""); }
5060 // append row to table template
5061 if(!apicall)
5062 { tpl_addVar(vars, TPLAPPEND, "USERCONFIGS", tpl_getTpl(vars, "USERCONFIGLISTBIT")); }
5063 else if(!filter || strcmp(filter, account->usr) == 0 || strcmp(filter, "all") == 0 || cs_strlen(filter) == 0)
5065 if(apicall == 1){
5066 tpl_addVar(vars, TPLAPPEND, "APIUSERCONFIGS", tpl_getTpl(vars, "APIUSERCONFIGLISTBIT"));
5067 } else if (apicall == 2){
5068 tpl_printf(vars, TPLADD, "JSONDELIMITER", "%s", (total_users > 1)?",":"");
5069 tpl_addVar(vars, TPLAPPEND, "APIUSERCONFIGS", tpl_getTpl(vars, "JSONUSERBIT"));
5071 ++clientcount;
5075 tpl_printf(vars, TPLADD, "TOTAL_USERS", "%d", total_users);
5076 tpl_printf(vars, TPLADD, "TOTAL_DISABLED", "%d", disabled_users);
5077 tpl_printf(vars, TPLADD, "TOTAL_EXPIRED", "%d", expired_users);
5078 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE", "%d", total_users - expired_or_disabled_users);
5079 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED", "%d", connected_users);
5080 tpl_printf(vars, TPLADD, "TOTAL_ONLINE", "%d", online_users);
5082 //CM info
5083 tpl_addVar(vars, TPLADD, "DISPLAYREADERINFO", "hidden"); // no readerinfo in users
5084 set_ecm_info(vars);
5086 if(!apicall)
5087 { return tpl_getTpl(vars, "USERCONFIGLIST"); }
5088 else
5090 if(!filter || clientcount > 0)
5092 return tpl_getTpl(vars, (apicall==1)?"APIUSERCONFIGLIST":"JSONUSER");
5094 else
5096 tpl_printf(vars, TPLADD, "APIERRORMESSAGE", "Invalid client %s", xml_encode(vars, filter));
5097 return tpl_getTpl(vars, "APIERROR");
5103 #define ENTITLEMENT_PAGE_SIZE 500
5105 #ifdef MODULE_CCCSHARE
5106 static void print_cards(struct templatevars *vars, struct uriparams *params, struct cc_card **cardarray, int32_t cardsize,
5107 int8_t show_global_list, struct s_reader *rdr, int32_t offset, int32_t apicall)
5109 if(cardarray)
5111 uint8_t serbuf[8];
5112 int32_t i, count = 0;
5113 char provname[83];
5114 struct cc_card *card;
5115 int32_t cardcount = 0;
5116 int32_t providercount = 0;
5117 int32_t nodecount = 0;
5119 char *provider = "";
5121 // @todo alno: sort by click, 0=ascending, 1=descending (maybe two buttons or reverse on second click)
5122 for(i = offset; i < cardsize; ++i)
5124 card = cardarray[i];
5125 if(count == ENTITLEMENT_PAGE_SIZE)
5126 { break; }
5127 count++;
5129 if(!apicall)
5131 if(show_global_list)
5132 { rdr = card->origin_reader; }
5133 if(rdr)
5134 { tpl_printf(vars, TPLADD, "HOST", "%s:%d", xml_encode(vars, rdr->device), rdr->r_port); }
5135 tpl_printf(vars, TPLADD, "CAID", "%04X", card->caid);
5136 tpl_printf(vars, TPLADD, "CARDTYPE", "%02X", card->card_type);
5138 else
5140 tpl_printf(vars, TPLADD, "APICARDNUMBER", "%d", cardcount);
5141 tpl_printf(vars, TPLADD, "APICAID", "%04X", card->caid);
5142 tpl_printf(vars, TPLADD, "APICARDTYPE", "%02X", card->card_type);
5145 if(cc_UA_valid(card->hexserial)) //Add UA:
5147 cc_UA_cccam2oscam(card->hexserial, serbuf, card->caid);
5148 char tmp[20];
5149 tpl_printf(vars, TPLAPPEND, "HOST", "<BR>\nUA_OSCam:%s", cs_hexdump(0, serbuf, 8, tmp, 20));
5150 tpl_printf(vars, TPLAPPEND, "HOST", "<BR>\nUA_CCcam:%s", cs_hexdump(0, card->hexserial, 8, tmp, 20));
5152 if(!apicall)
5154 int32_t n;
5155 char channame[CS_SERVICENAME_SIZE];
5156 int8_t sidname = 0;
5157 LL_ITER its = ll_iter_create(card->goodsids);
5158 struct cc_srvid *srv;
5159 n = 0;
5160 if(strcmp(getParam(params, "button"), "Show detail list") == 0)
5161 { sidname = 1; }
5163 tpl_addVar(vars, TPLADD, "SERVICESGOOD", "");
5164 while((srv = ll_iter_next(&its)))
5166 if(sidname)
5168 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))));
5169 } else {
5170 tpl_printf(vars, TPLAPPEND, "SERVICESGOOD", "%04X%s", srv->sid, ++n % 10 == 0 ? "<BR>\n" : " ");
5174 its = ll_iter_create(card->badsids);
5175 n = 0;
5176 tpl_addVar(vars, TPLADD, "SERVICESBAD", "");
5177 while((srv = ll_iter_next(&its)))
5179 if(sidname)
5181 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))));
5182 } else {
5183 tpl_printf(vars, TPLAPPEND, "SERVICESBAD", "%04X%s", srv->sid, ++n % 10 == 0 ? "<BR>\n" : " ");
5188 tpl_addVar(vars, TPLADD, "SYSTEM", get_cardsystem_desc_by_caid(card->caid));
5190 tpl_printf(vars, TPLADD, "SHAREID", "%08X", card->id);
5191 tpl_printf(vars, TPLADD, "REMOTEID", "%08X", card->remote_id);
5192 tpl_printf(vars, TPLADD, "UPHOPS", "%d", card->hop);
5193 tpl_printf(vars, TPLADD, "MAXDOWN", "%d", card->reshare);
5195 LL_ITER pit = ll_iter_create(card->providers);
5196 struct cc_provider *prov;
5198 providercount = 0;
5200 if(!apicall)
5201 { tpl_addVar(vars, TPLADD, "PROVIDERS", ""); }
5202 else
5203 { tpl_addVar(vars, TPLADD, "PROVIDERLIST", ""); }
5205 while((prov = ll_iter_next(&pit)))
5207 provider = xml_encode(vars, get_provider(prov->prov, card->caid, provname, sizeof(provname)));
5209 if(!apicall)
5211 if(prov->sa[0] || prov->sa[1] || prov->sa[2] || prov->sa[3])
5213 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]);
5215 else
5217 tpl_printf(vars, TPLAPPEND, "PROVIDERS", "%s<BR>\n", provider);
5220 else
5222 if(prov->sa[0] || prov->sa[1] || prov->sa[2] || prov->sa[3])
5223 { tpl_printf(vars, TPLADD, "APIPROVIDERSA", "%02X%02X%02X%02X", prov->sa[0], prov->sa[1], prov->sa[2], prov->sa[3]); }
5224 else
5225 { tpl_addVar(vars, TPLADD, "APIPROVIDERSA", ""); }
5226 tpl_printf(vars, TPLADD, "APIPROVIDERCAID", "%04X", card->caid);
5227 tpl_printf(vars, TPLADD, "APIPROVIDERPROVID", "%06X", prov->prov);
5228 tpl_printf(vars, TPLADD, "APIPROVIDERNUMBER", "%d", providercount);
5229 tpl_addVar(vars, TPLADD, "APIPROVIDERNAME", xml_encode(vars, provider));
5230 tpl_addVar(vars, TPLAPPEND, "PROVIDERLIST", tpl_getTpl(vars, "APICCCAMCARDPROVIDERBIT"));
5233 providercount++;
5234 tpl_printf(vars, TPLADD, "APITOTALPROVIDERS", "%d", providercount);
5237 LL_ITER nit = ll_iter_create(card->remote_nodes);
5238 uint8_t *node;
5240 nodecount = 0;
5241 if(!apicall) { tpl_addVar(vars, TPLADD, "NODES", ""); }
5242 else { tpl_addVar(vars, TPLADD, "NODELIST", ""); }
5244 while((node = ll_iter_next(&nit)))
5247 if(!apicall)
5249 tpl_printf(vars, TPLAPPEND, "NODES", "%02X%02X%02X%02X%02X%02X%02X%02X<BR>\n",
5250 node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7]);
5252 else
5254 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]);
5255 tpl_printf(vars, TPLADD, "APINODENUMBER", "%d", nodecount);
5256 tpl_addVar(vars, TPLAPPEND, "NODELIST", tpl_getTpl(vars, "APICCCAMCARDNODEBIT"));
5258 nodecount++;
5259 tpl_printf(vars, TPLADD, "APITOTALNODES", "%d", nodecount);
5262 if(!apicall)
5263 { tpl_addVar(vars, TPLAPPEND, "CCCAMSTATSENTRY", tpl_getTpl(vars, "ENTITLEMENTCCCAMENTRYBIT")); }
5264 else
5265 { tpl_addVar(vars, TPLAPPEND, "CARDLIST", tpl_getTpl(vars, "APICCCAMCARDBIT")); }
5267 cardcount++;
5269 // set previous Link if needed
5270 if(offset >= ENTITLEMENT_PAGE_SIZE)
5272 tpl_printf(vars, TPLAPPEND, "CONTROLS", "<A HREF=\"entitlements.html?offset=%d&globallist=%s&amp;label=%s\"> << PREVIOUS < </A>",
5273 offset - ENTITLEMENT_PAGE_SIZE,
5274 getParam(params, "globallist"),
5275 urlencode(vars, getParam(params, "label")));
5278 // set next link if needed
5279 if(cardsize > count && offset < cardsize)
5281 tpl_printf(vars, TPLAPPEND, "CONTROLS", "<A HREF=\"entitlements.html?offset=%d&globallist=%s&amp;label=%s\"> > NEXT >> </A>",
5282 offset + ENTITLEMENT_PAGE_SIZE,
5283 getParam(params, "globallist"),
5284 urlencode(vars, getParam(params, "label")));
5287 if(!apicall)
5289 tpl_printf(vars, TPLADD, "TOTALS", "card count=%d", cardsize);
5290 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTCCCAMBIT"));
5292 else
5294 tpl_printf(vars, TPLADD, "APITOTALCARDS", "%d", cardsize);
5298 else
5300 if(!apicall)
5302 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTGENERICBIT"));
5303 tpl_addVar(vars, TPLADD, "LOGHISTORY", "no cards found<BR>\n");
5305 else
5307 tpl_printf(vars, TPLADD, "APITOTALCARDS", "%d", 0);
5312 #endif
5314 static char *send_oscam_entitlement(struct templatevars *vars, struct uriparams *params, int32_t apicall)
5316 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
5317 char *reader_ = getParam(params, "label");
5318 #ifdef MODULE_CCCAM
5319 char *sharelist_ = getParam(params, "globallist");
5320 int32_t show_global_list = sharelist_ && sharelist_[0] == '1';
5322 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
5323 if(show_global_list || cs_strlen(reader_) || (rdr && rdr->typ == R_CCCAM))
5326 if(show_global_list || (rdr && rdr->typ == R_CCCAM && rdr->enable))
5329 if(show_global_list)
5331 tpl_addVar(vars, TPLADD, "READERNAME", "GLOBAL");
5332 tpl_addVar(vars, TPLADD, "APIHOST", "GLOBAL");
5333 tpl_addVar(vars, TPLADD, "APIHOSTPORT", "GLOBAL");
5335 else
5337 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
5338 tpl_addVar(vars, TPLADD, "APIHOST", xml_encode(vars, rdr->device));
5339 tpl_printf(vars, TPLADD, "APIHOSTPORT", "%d", rdr->r_port);
5342 #ifdef MODULE_CCCSHARE
5343 int32_t offset = atoi(getParam(params, "offset")); //should be 0 if parameter is missed on very first call
5344 int32_t cardsize;
5345 if(show_global_list)
5347 int32_t i;
5348 LLIST **sharelist = get_and_lock_sharelist();
5349 LLIST *sharelist2 = ll_create("web-sharelist");
5350 for(i = 0; i < CAID_KEY; i++)
5352 if(sharelist[i])
5353 { ll_putall(sharelist2, sharelist[i]); }
5355 unlock_sharelist();
5356 struct cc_card **cardarray = get_sorted_card_copy(sharelist2, 0, &cardsize);
5357 ll_destroy(&sharelist2);
5358 print_cards(vars, params, cardarray, cardsize, 1, NULL, offset, apicall);
5359 NULLFREE(cardarray);
5361 else
5363 struct s_client *rc = rdr->client;
5364 struct cc_data *rcc = (rc) ? rc->cc : NULL;
5365 if(rcc && rcc->cards)
5367 struct cc_card **cardarray = get_sorted_card_copy(rcc->cards, 0, &cardsize);
5368 print_cards(vars, params, cardarray, cardsize, 0, rdr, offset, apicall);
5369 NULLFREE(cardarray);
5372 #endif
5375 else
5377 #else
5378 if(cs_strlen(reader_))
5381 struct s_reader *rdr;
5382 #endif
5383 tpl_addVar(vars, TPLADD, "LOGHISTORY", "->");
5384 // normal non-cccam reader
5386 rdr = get_reader_by_label(reader_);
5388 if(rdr)
5390 struct s_client *cl = rdr->client;
5391 if(rdr->ll_entitlements)
5394 time_t now = time((time_t *)0);
5396 struct tm start_t, end_t;
5397 LL_ITER itr = ll_iter_create(rdr->ll_entitlements);
5398 S_ENTITLEMENT *item;
5400 tpl_addVar(vars, TPLAPPEND, "LOGHISTORY", "<BR><BR>New Structure:<BR>");
5401 char tbuffer[83];
5402 #ifdef WITH_EMU
5403 char keyBuffer[1024];
5404 #endif
5405 int jsondelimiter = 0;
5406 while((item = ll_iter_next(&itr)))
5408 #ifdef WITH_EMU
5409 if(item->isKey)
5411 tpl_addVar(vars, TPLADD, "ENTSTARTDATE", "");
5412 tpl_addVar(vars, TPLADD, "ENTENDDATE", "");
5413 cs_hexdump(0, item->key, item->keyLength, keyBuffer, sizeof(keyBuffer));
5414 tpl_addVar(vars, TPLADD, "ENTEXPIERED", "e_valid");
5415 tpl_printf(vars, TPLADD, "ENTCAID", "%04X", item->caid);
5416 tpl_printf(vars, TPLADD, "ENTPROVID", "%08X", item->provid);
5417 tpl_addVar(vars, TPLADD, "ENTID", item->name);
5418 tpl_addVar(vars, TPLADD, "ENTCLASS", keyBuffer);
5419 if(item->isData) { tpl_addVar(vars, TPLADD, "ENTTYPE", "data"); }
5420 else { tpl_addVar(vars, TPLADD, "ENTTYPE", "key"); }
5421 tpl_addVar(vars, TPLADD, "ENTRESNAME", "");
5423 if((strcmp(getParam(params, "hideexpired"), "1") != 0) || (item->end > now))
5424 { tpl_addVar(vars, TPLAPPEND, "READERENTENTRY", tpl_getTpl(vars, "ENTITLEMENTITEMBIT")); }
5426 continue;
5428 #endif
5430 localtime_r(&item->start, &start_t);
5431 localtime_r(&item->end, &end_t);
5433 if(!apicall)
5434 { strftime(tbuffer, 30, "%Y-%m-%d", &start_t); }
5435 else
5436 { strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &start_t); }
5437 tpl_addVar(vars, TPLADD, "ENTSTARTDATE", tbuffer);
5439 if(!apicall)
5440 { strftime(tbuffer, 30, "%Y-%m-%d", &end_t); }
5441 else
5442 { strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &end_t); }
5443 tpl_addVar(vars, TPLADD, "ENTENDDATE", tbuffer);
5445 tpl_addVar(vars, TPLADD, "ENTEXPIERED", item->end > now ? "e_valid" : "e_expired");
5446 tpl_printf(vars, TPLADD, "ENTCAID", "%04X", item->caid);
5447 tpl_printf(vars, TPLADD, "ENTPROVID", "%06X", item->provid);
5448 tpl_printf(vars, TPLADD, "ENTID", "%08X%08X", (uint32_t)(item->id >> 32), (uint32_t)item->id);
5449 tpl_printf(vars, TPLADD, "ENTCLASS", "%08X", item->class);
5450 tpl_addVar(vars, TPLADD, "ENTTYPE", entitlement_type[item->type]);
5452 char *entresname;
5453 entresname = xml_encode(vars, get_tiername((uint16_t)(item->id & 0xFFFF), item->caid, tbuffer));
5454 if(!tbuffer[0])
5455 { entresname = xml_encode(vars, get_provider(item->provid, item->caid, tbuffer, sizeof(tbuffer))); }
5456 tpl_addVar(vars, TPLADD, "ENTRESNAME", entresname);
5458 if((strcmp(getParam(params, "hideexpired"), "1") != 0) || (item->end > now))
5459 { tpl_addVar(vars, TPLAPPEND, "READERENTENTRY", tpl_getTpl(vars, "ENTITLEMENTITEMBIT")); }
5461 if(apicall==2)
5463 tpl_printf(vars, TPLAPPEND, "APIENTITLEMENTLIST","%s%s",jsondelimiter?",":"", tpl_getTpl(vars, "JSONENTITLEMENTBIT"));
5464 jsondelimiter++;
5469 if(cl && cl->typ)
5470 { tpl_printf(vars, TPLADD, "READERTYPE", "%c", cl->typ); }
5471 else
5472 { tpl_addVar(vars, TPLADD, "READERTYPE", "null"); }
5473 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
5475 int8_t i, j;
5476 for(i = 0; i < 15; i++) { tpl_printf(vars, TPLAPPEND, "READERROM", "%c", rdr->rom[i]); }
5477 if(rdr->hexserial[0] || rdr->hexserial[1]) { i = 0; }
5478 else { i = 2; }
5479 if(rdr->hexserial[6] || rdr->hexserial[7]) { j = 8; }
5480 else { j = 6; }
5481 for(; i < j; i++) { tpl_printf(vars, TPLAPPEND, "READERSERIAL", "%02X%s", rdr->hexserial[i], i < j - 1 ? " " : ""); }
5482 for(i = 0; i < rdr->nprov; i++)
5484 for(j = 0; j < 4; j++) { tpl_printf(vars, TPLAPPEND, "READERPROVIDS", "%02X ", rdr->prid[i][j]); }
5485 tpl_addVar(vars, TPLAPPEND, "READERPROVIDS", i == 0 ? "(sysid)<BR>\n" : "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>\n");
5488 //CountryCode Vg card
5489 char add_nds_line = 0;
5490 if(rdr->VgCountryC[0])
5492 for(i = 0; i < 3; i++) { tpl_printf(vars, TPLAPPEND, "READERCOUNTRYC", "%c", rdr->VgCountryC[i]); }
5493 add_nds_line = 1;
5495 else
5497 tpl_addVar(vars, TPLADD, "READERCOUNTRYC", "n/a");
5500 //regional code for Vg card
5501 if(rdr->VgRegionC[0])
5503 for(i = 0; i < 8; i++) { tpl_printf(vars, TPLAPPEND, "READER_RCODE", "%c", rdr->VgRegionC[i]); }
5504 add_nds_line = 1;
5506 else
5508 tpl_addVar(vars, TPLADD, "READER_RCODE", "n/a");
5511 //Pin Vg card
5512 if(rdr->VgPin)
5514 tpl_printf(vars, TPLAPPEND, "READERPIN", "%04i", rdr->VgPin);
5515 add_nds_line = 1;
5517 else
5519 tpl_addVar(vars, TPLADD, "READERPIN", "n/a");
5522 //Fuse Vg card
5523 if(rdr->VgFuse)
5525 tpl_printf(vars, TPLAPPEND, "READERFUSE", "%02X", rdr->VgFuse);
5526 add_nds_line = 1;
5529 if(caid_is_videoguard(rdr->caid))
5531 tpl_printf(vars, TPLAPPEND, "READERPAYLOAD", "%02X %02X %02X %02X %02X %02X", rdr->VgLastPayload[0],
5532 rdr->VgLastPayload[1], rdr->VgLastPayload[2], rdr->VgLastPayload[3], rdr->VgLastPayload[4], rdr->VgLastPayload[5]);
5533 add_nds_line = 1;
5536 //credit on Vg card
5537 if(rdr->VgCredit)
5539 tpl_printf(vars, TPLAPPEND, "READERCREDIT", "%i", rdr->VgCredit);
5540 add_nds_line = 1;
5542 else
5544 tpl_addVar(vars, TPLADD, "READERCREDIT", "n/a");
5547 if(rdr->card_valid_to)
5549 struct tm vto_t;
5550 char vtobuffer[30];
5551 localtime_r(&rdr->card_valid_to, &vto_t);
5552 strftime(vtobuffer, 30, "%Y-%m-%d", &vto_t);
5553 tpl_addVar(vars, TPLADD, "READERCARDVALIDTO", vtobuffer);
5555 else
5557 tpl_addVar(vars, TPLADD, "READERCARDVALIDTO", "n/a");
5560 if(rdr->irdId[0])
5562 for(i = 0; i < 4; i++) { tpl_printf(vars, TPLAPPEND, "READERIRDID", "%02X ", rdr->irdId[i]); }
5564 else
5566 tpl_addVar(vars, TPLADD, "READERIRDID", "n/a");
5569 if(rdr->card_atr_length)
5570 for(i = 0; i < rdr->card_atr_length; i++) { tpl_printf(vars, TPLAPPEND, "READERATR", "%02X ", rdr->card_atr[i]); }
5572 if(caid_is_seca(rdr->caid) || caid_is_viaccess(rdr->caid))
5574 if(rdr->maturity == 0xF)
5576 tpl_printf(vars, TPLAPPEND, "READERMATURITY", "%s ", "no limit");
5578 else
5580 tpl_printf(vars, TPLAPPEND, "READERMATURITY", "%d+", rdr->maturity);
5583 else
5585 tpl_printf(vars, TPLAPPEND, "READERMATURITY", "%s ", "n/a");
5588 if (rdr->csystem)
5589 tpl_addVar(vars, TPLADD, "READERCSYSTEM", rdr->csystem->desc);
5591 if(add_nds_line)
5593 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENTNDS", tpl_getTpl(vars, "ENTITLEMENTBITNDS"));
5595 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTBIT"));
5597 else
5599 tpl_addMsg(vars, "Reader does not exist or is not started!");
5604 else
5606 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTGENERICBIT"));
5609 if(!apicall)
5610 { return tpl_getTpl(vars, "ENTITLEMENTS"); }
5611 else
5613 if(apicall==1)
5614 { return tpl_getTpl(vars, "APICCCAMCARDLIST"); }
5615 else
5616 { return tpl_getTpl(vars, "JSONENTITLEMENTS"); }
5620 #ifdef WEBIF_LIVELOG
5621 static char *send_oscam_logpoll(struct templatevars * vars, struct uriparams * params)
5624 uint64_t lastid = 0;
5626 #ifdef WITH_DEBUG
5627 tpl_addVar(vars, TPLADD, "LOG_DEBUGMENU", tpl_getTpl(vars, "LOGDEBUGMENU"));
5628 #endif
5629 tpl_addVar(vars, TPLADD, "LOG_SIZEMENU", tpl_getTpl(vars, "LOGSIZEMENU"));
5630 tpl_addVar(vars, TPLADD, "TITLEADD1", "Move mouse over log-window to stop scroll");
5632 if(strcmp(getParam(params, "lastid"), "start") == 0){
5633 setActiveMenu(vars, MNU_LIVELOG);
5634 return tpl_getTpl(vars, "LOGPAGE");
5636 else
5638 lastid = strtoull(getParam(params, "lastid"), NULL, 10);
5641 char *dot = ""; //Delimiter
5643 #ifdef WITH_DEBUG
5644 char *debuglvl = getParam(params, "debug");
5645 if(cs_strlen(debuglvl) > 0) {
5646 int32_t dblvl = atoi(debuglvl);
5647 if(cs_dblevel != dblvl) {
5648 if(dblvl >= 0 && dblvl <= 65535) { cs_dblevel = dblvl; }
5649 cs_log("%s debug_level=%d", "all", cs_dblevel);
5652 tpl_printf(vars, TPLAPPEND, "DATA","%s\"debug\":\"%d\"", dot, cs_dblevel);
5653 dot = ",";
5654 tpl_printf(vars, TPLAPPEND, "DATA","%s\"maxdebug\":\"%d\"",dot, MAX_DEBUG_LEVELS);
5655 #endif
5657 if(cfg.loghistorylines == 0){
5658 tpl_printf(vars, TPLAPPEND, "DATA","%s\"logdisabled\":\"1\"",dot);
5659 return tpl_getTpl(vars, "POLL");
5662 if(log_history)
5664 LL_ITER it = ll_iter_create(log_history);
5665 struct s_log_history *hist;
5667 tpl_printf(vars, TPLAPPEND, "DATA", "%s\"lines\":[", dot);
5669 dot = "";
5671 while((hist = (struct s_log_history*)ll_iter_next(&it)))
5673 char p_usr[32];
5674 size_t pos1 = strcspn(hist->txt, "\t") + 1;
5675 cs_strncpy(p_usr, hist->txt , pos1 > sizeof(p_usr) ? sizeof(p_usr) : pos1);
5677 char *p_txt = hist->txt + pos1;
5679 pos1 = strcspn(p_txt, "\n") + 1;
5680 char str_out[pos1];
5681 cs_strncpy(str_out, p_txt, pos1);
5682 uint64_t id = hist->counter;
5684 size_t b64_str_in = cs_strlen(xml_encode(vars, str_out));
5685 size_t b64_str_out = 32 + BASE64_LENGTH(b64_str_in);
5686 char *b64_str_out_buf;
5687 if(!cs_malloc(&b64_str_out_buf, b64_str_out))
5688 { continue; }
5689 base64_encode(xml_encode(vars, str_out), b64_str_in, b64_str_out_buf, b64_str_out);
5691 if(id > lastid){
5692 tpl_printf(vars, TPLAPPEND, "DATA","%s{\"id\":\"%" PRIu64 "\",\"usr\":\"%s\",\"line\":\"%s\"}",
5693 dot,
5695 urlencode(vars, xml_encode(vars, p_usr)),
5696 b64_str_out_buf);
5697 dot = ","; // next in Array with leading delimiter
5699 NULLFREE(b64_str_out_buf);
5703 tpl_addVar(vars, TPLAPPEND, "DATA", "]");
5704 return tpl_getTpl(vars, "POLL");
5706 #endif
5708 static char *send_oscam_status(struct templatevars * vars, struct uriparams * params, int32_t apicall)
5710 int32_t i;
5711 const char *usr;
5712 int32_t lsec, isec, chsec, con, cau = 0;
5713 time_t now = time((time_t *)0);
5714 struct tm lt;
5715 int delimiter=0;
5717 if(!apicall)
5719 setActiveMenu(vars, MNU_STATUS);
5720 if (config_enabled(WITH_LB))
5721 tpl_addVar(vars, TPLADD, "STATUSCOL14HEAD","LB Value/");
5723 if(strcmp(getParam(params, "action"), "kill") == 0)
5725 char *cptr = getParam(params, "threadid");
5726 struct s_client *cl = NULL;
5727 if(cs_strlen(cptr) > 1)
5728 { sscanf(cptr, "%p", (void **)(void *)&cl); }
5730 if(cl && is_valid_client(cl))
5732 if(is_dvbapi_usr(cl->account->usr))
5734 cs_log("WebIF from %s requests to kill dvbapi client %s -> ignoring!", cs_inet_ntoa(GET_IP()), cl->account->usr);
5736 else
5738 kill_thread(cl);
5739 cs_log("Client %s killed by WebIF from %s", cl->account->usr, cs_inet_ntoa(GET_IP()));
5744 if(strcmp(getParam(params, "action"), "resetuserstats") == 0)
5746 clear_info_clients_stats();
5748 if(strcmp(getParam(params, "action"), "resetreaderstats") == 0)
5750 clear_info_readers_stats();
5752 if(strcmp(getParam(params, "action"), "restart") == 0)
5754 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
5755 if(rdr)
5757 if(rdr->typ != R_GBOX)
5759 add_job(rdr->client, ACTION_READER_RESTART, NULL, 0);
5761 #ifdef MODULE_GBOX
5762 else
5764 restart_gbox_peer(rdr->label, 0, 0);
5766 #endif
5767 cs_log("Reader %s restarted by WebIF from %s", rdr->label, cs_inet_ntoa(GET_IP()));
5771 char *debuglvl = getParam(params, "debug");
5772 if(cs_strlen(debuglvl) > 0)
5774 #ifndef WITH_DEBUG
5775 cs_log("*** Warning: Debug Support not compiled in ***");
5776 #else
5777 int32_t dblvl = atoi(debuglvl);
5778 if(dblvl >= 0 && dblvl <= 65535) { cs_dblevel = dblvl; }
5779 cs_log("%s debug_level=%d", "all", cs_dblevel);
5780 #endif
5783 char *hide = getParam(params, "hide");
5784 if(cs_strlen(hide) > 0)
5786 struct s_client *hideidx = NULL;
5787 sscanf(hide, "%p", (void **)(void *)&hideidx);
5789 if(hideidx && is_valid_client(hideidx))
5790 { hideidx->wihidden = 1; }
5793 char *hideidle = getParam(params, "hideidle");
5794 if(cs_strlen(hideidle) > 0)
5796 if(atoi(hideidle) == 2)
5798 struct s_client *cl;
5799 for(cl = first_client; cl ; cl = cl->next)
5801 if(cl->typ == 's' || cl->typ == 'h' || cl->typ == 'm'){
5802 cl->wihidden = 0;
5806 else if(atoi(hideidle) == 3)
5808 struct s_client *cl;
5809 for(cl = first_client; cl ; cl = cl->next)
5811 if(cl->typ == 'r'){
5812 cl->wihidden = 0;
5816 else if(atoi(hideidle) == 4)
5818 struct s_client *cl;
5819 for(cl = first_client; cl ; cl = cl->next)
5821 if(cl->typ == 'p'){
5822 cl->wihidden = 0;
5826 else if(atoi(hideidle) == 5)
5828 struct s_client *cl;
5829 for(cl = first_client; cl ; cl = cl->next)
5831 if(cl->typ == 'c'){
5832 cl->wihidden = 0;
5836 else
5838 int32_t oldval = cfg.http_hide_idle_clients;
5839 config_set("webif", "httphideidleclients", hideidle);
5840 if(oldval != cfg.http_hide_idle_clients)
5842 refresh_oscam(REFR_SERVER);
5847 if(cfg.http_hide_idle_clients > 0) { tpl_addVar(vars, TPLADD, "HIDEIDLECLIENTSSELECTED1", "selected"); }
5848 else { tpl_addVar(vars, TPLADD, "HIDEIDLECLIENTSSELECTED0", "selected"); }
5850 tpl_addVar(vars, TPLADD, "SRVIDFILE", use_srvid2 ? "oscam.srvid2" : "oscam.srvid");
5852 int32_t user_count_all = 0, user_count_shown = 0, user_count_active = 0;
5853 int32_t reader_count_all = 0, reader_count_conn = 0, reader_count_off = 0;
5854 int32_t proxy_count_all = 0, proxy_count_conn = 0, proxy_count_off = 0;
5855 int32_t server_count_all = 0, server_count_shown = 0, server_count_hidden = 0;
5856 int32_t monitor_count_all = 0, monitor_count_shown = 0;
5857 int32_t shown;
5859 int32_t total_readers = 0;
5860 int32_t active_readers = 0;
5861 int32_t disabled_readers = 0;
5862 int32_t connected_readers = 0;
5864 struct s_client *cl;
5865 int8_t filtered;
5867 cs_readlock(__func__, &readerlist_lock);
5868 cs_readlock(__func__, &clientlist_lock);
5869 for(i = 0, cl = first_client; cl ; cl = cl->next, i++)
5871 #ifdef CS_CACHEEX_AIO
5872 #if defined(MODULE_CCCAM) && defined(CS_CACHEEX)
5873 struct cc_data *cc = cl->cc;
5874 #endif
5875 #endif
5876 if(cl->kill) { continue; }
5877 #ifdef CS_CACHEEX
5878 if(get_module(cl)->listenertype != LIS_CSPUDP)
5880 #endif
5882 // Reset template variables
5883 tpl_addVar(vars, TPLADD, "LBLRPSTRVALUE", "");
5884 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", "");
5885 tpl_addVar(vars, TPLADD, "LASTREADER", "");
5886 tpl_addVar(vars, TPLADD, "CLIENTPROTO", "");
5887 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
5888 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIME", "");
5889 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIMEHIST", "");
5890 tpl_addVar(vars, TPLADD, "UPICMISSING" , "");
5891 tpl_addVar(vars, TPLADD, "ENTITLEMENTS", "");
5893 if(cl->typ == 'c')
5894 { user_count_all++; }
5895 else if(cl->typ == 'p')
5897 proxy_count_all++;
5898 if((cl->reader->typ == R_GBOX && cl->reader->card_status != CARD_INSERTED && cl->reader->card_status != NO_CARD) ||
5899 (cl->reader->typ != R_GBOX && cl->reader->card_status != CARD_INSERTED))
5900 { proxy_count_off++; }
5902 else if(cl->typ == 'r')
5903 { reader_count_all++; if(cl->reader->card_status != CARD_INSERTED) { reader_count_off++; } }
5904 else if(cl->typ == 's' || cl->typ == 'h')
5905 { server_count_all++; if(cl->wihidden) {server_count_hidden++;} }
5906 else if(cl->typ == 'm')
5907 { monitor_count_all++; }
5909 shown = 0;
5910 if(cl->wihidden != 1)
5912 filtered = !(cfg.http_hide_idle_clients != 1 || cl->typ != 'c' || (now - cl->lastecm) <= cfg.hideclient_to);
5913 if(!filtered && cfg.http_hide_type)
5915 char *p = cfg.http_hide_type;
5916 while(*p && !filtered)
5918 char type = *p++;
5919 #ifdef CS_CACHEEX
5920 filtered = (type == cl->typ) || (type == 'x' && (cl->typ == 'p' || cl->typ == 'r') && (cl->reader && cl->reader->cacheex.mode));
5921 #else
5922 filtered = (type == cl->typ);
5923 #endif
5924 #ifdef WITH_EMU
5925 if(type == 'e' && cl->typ == 'r' && cl->reader->typ == R_EMU) filtered = 1;
5926 #endif
5930 if(!filtered)
5932 if(cl->typ == 'c')
5934 user_count_shown++;
5935 if(cfg.http_hide_idle_clients != 1 && cfg.hideclient_to > 0 && (now - cl->lastecm) <= cfg.hideclient_to)
5937 user_count_active++;
5940 else if(cl->typ == 's' || cl->typ == 'h')
5942 server_count_shown++;
5944 else if(cl->typ == 'm')
5946 monitor_count_shown++;
5948 else if(cl->typ == 'r')
5950 reader_count_conn++;
5952 else if(cl->typ == 'p')
5954 proxy_count_conn++;
5957 if(cl->typ == 'c' || cl->typ == 'r' || cl->typ == 'p')
5959 if(cl->lastecm >= cl->login && cl->lastecm >= cl->logout) { isec = now - cl->lastecm; }
5960 else if(cl->logout >= cl->login) { isec = now - cl->logout; }
5961 else { isec = now - cl->login; }
5963 else { isec = now - cl->last; }
5965 shown = 1;
5966 lsec = now - cl->login;
5967 chsec = now - cl->lastswitch;
5968 usr = username(cl);
5970 if((cl->typ == 'r') || (cl->typ == 'p')) { usr = cl->reader->label; }
5972 if(cl->dup) { con = 2; }
5973 else if((cl->tosleep) && (now - cl->lastswitch > cl->tosleep)) { con = 1; }
5974 else { con = 0; }
5976 // no AU reader == 0 / AU ok == 1 / Last EMM > aulow == -1
5977 if(cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r')
5979 if((cl->typ == 'c' && ll_count(cl->aureader_list) == 0) || ((cl->typ == 'p' || cl->typ == 'r') && cl->reader->audisabled)) { cau = 0; }
5980 else if((now - cl->lastemm) / 60 > cfg.aulow) { cau = -1; }
5981 else { cau = 1; }
5983 if(cau == 0)
5985 tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", "OFF");
5987 else
5989 if(cau == -1)
5990 { tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", !apicall?"<A HREF=\"#\" CLASS=\"tooltip\">ON":""); }
5991 else
5992 { tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", !apicall?"<A HREF=\"#\" CLASS=\"tooltip\">ACTIVE":""); }
5993 tpl_addVar(vars, TPLAPPEND, "CLIENTCAUHTTP", !apicall?"<SPAN>":"");
5994 if(cl->typ == 'c')
5996 struct s_reader *rdr;
5997 LL_ITER itr = ll_iter_create(cl->aureader_list);
5998 while((rdr = ll_iter_next(&itr)))
6000 if(rdr->audisabled)
6001 { tpl_printf(vars, TPLAPPEND, "CLIENTCAUHTTP", "(%s)<BR>", xml_encode(vars, rdr->label)); }
6002 else
6003 { tpl_printf(vars, TPLAPPEND, "CLIENTCAUHTTP", "%s<BR>", xml_encode(vars, rdr->label)); }
6006 else { tpl_addVar(vars, TPLAPPEND, "CLIENTCAUHTTP", xml_encode(vars, cl->reader->label)); }
6007 tpl_addVar(vars, TPLAPPEND, "CLIENTCAUHTTP", !apicall?"</SPAN></A>":"");
6010 else
6012 cau = 0;
6013 tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", "");
6015 localtime_r(&cl->login, &lt);
6017 if(cl->typ == 'c' || cl->typ == 'm')
6019 if(cl->account && cl->account->description)
6020 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->account->description));
6021 else
6022 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
6024 else if(cl->typ == 'p' || cl->typ == 'r')
6026 if(cl->reader && cl->reader->description)
6027 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->reader->description));
6028 else
6029 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
6031 if(!apicall)
6033 tpl_addVar(vars, TPLADD, "LBL", xml_encode(vars, usr));
6034 tpl_printf(vars, TPLADD, "CID", "%p", cl);
6035 if(cl->typ == 'c' || cl->typ == 'm')
6037 tpl_addVar(vars, TPLADD, "TARGET", "User");
6038 tpl_addVar(vars, TPLADD, "CSIDX", tpl_getTpl(vars, "STATUSKBUTTON"));
6040 else if(cl->typ == 'p')
6042 tpl_addVar(vars, TPLADD, "TARGET", "Proxy");
6043 tpl_addVar(vars, TPLADD, "LBLENC", urlencode(vars, usr));
6044 tpl_addVar(vars, TPLADD, "CSIDX", tpl_getTpl(vars, "STATUSRBUTTON"));
6046 else if(cl->typ == 'r')
6048 tpl_addVar(vars, TPLADD, "TARGET", "Reader");
6049 tpl_addVar(vars, TPLADD, "LBLENC", urlencode(vars, usr));
6050 tpl_addVar(vars, TPLADD, "CSIDX", tpl_getTpl(vars, "STATUSRBUTTON"));
6052 else if (cl->typ == 'h' || cl->typ == 's')
6054 tpl_addVar(vars, TPLADD, "TARGET", "Server");
6055 tpl_addVar(vars, TPLADD, "CSIDX", "");
6057 tpl_addVar(vars, TPLADD, "HIDEIDX", tpl_getTpl(vars, "STATUSHBUTTON"));
6058 tpl_printf(vars, TPLADD, "CSIDXPLAIN", "id_%p", cl);
6060 else
6062 tpl_printf(vars, TPLADD, "HIDEIDX", "%p", cl);
6063 tpl_printf(vars, TPLADD, "CSIDX", "id_%p", cl);
6065 tpl_printf(vars, TPLADD, "CLIENTTYPE", "%c", cl->typ);
6066 tpl_printf(vars, TPLADD, "CLIENTCNR", "%d", get_threadnum(cl));
6067 tpl_addVar(vars, TPLADD, "CLIENTUSER", xml_encode(vars, usr));
6069 tpl_addVar(vars, TPLADD, "STATUSUSERICON", xml_encode(vars, usr));
6070 if (cl->typ == 'c' || cl->typ == 'm')
6072 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, usr));
6073 tpl_addVar(vars, TPLADD, "USERENC", urlencode(vars, usr));
6075 else if (cl->typ == 'p' || cl->typ == 'r')
6077 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, usr));
6078 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, usr));
6081 bool picon_shown = false;
6082 const char *status_user_icon_tpl = NULL;
6084 char picon_name[32];
6085 if(cfg.http_showpicons)
6087 if(picon_exists(xml_encode(vars, usr)))
6089 switch (cl->typ)
6091 case 'm': // Fall through
6092 case 'c': status_user_icon_tpl = "SUSERICON"; picon_shown = true; break;
6093 case 'p': // Fall through
6094 case 'r': status_user_icon_tpl = "SREADERICON"; picon_shown = true; break;
6097 else
6098 tpl_printf(vars, TPLADD, "UPICMISSING", "%smissing icon: IC_%s.tpl",!apicall?"&#13;":"",xml_encode(vars, usr));
6101 if (!picon_shown)
6103 switch (cl->typ)
6105 case 'm': // Fall through
6106 case 'c': status_user_icon_tpl = "SUSER"; break;
6107 case 'p': // Fall through
6108 case 'r': status_user_icon_tpl = "SREADER"; break;
6112 if (status_user_icon_tpl)
6113 tpl_addVar(vars, TPLADD, "STATUSUSERICON", tpl_getTpl(vars, status_user_icon_tpl));
6115 tpl_printf(vars, TPLADD, "CLIENTCAU", "%d", cau);
6116 if(!apicall)
6118 if(cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r')
6120 if(cl->crypted) { tpl_addVar(vars, TPLADD, "CLIENTCRYPTED", "ON"); }
6121 else { tpl_addVar(vars, TPLADD, "CLIENTCRYPTED", "OFF"); }
6123 else { tpl_addVar(vars, TPLADD, "CLIENTCRYPTED", ""); }
6125 else { tpl_printf(vars, TPLADD, "CLIENTCRYPTED", "%d", cl->crypted); }
6126 tpl_addVar(vars, TPLADD, "CLIENTIP", cs_inet_ntoa(cl->ip));
6127 tpl_printf(vars, TPLADD, "CLIENTPORT", "%d", cl->port);
6128 const char *proto = client_get_proto(cl);
6129 #ifdef CS_CACHEEX_AIO
6130 if(cl &&
6131 ( (cl->typ == 'c' && cl->account && cl->account->cacheex.feature_bitfield)
6132 #if defined(MODULE_CAMD35) || defined (MODULE_CAMD35_TCP)
6133 || (cl->c35_extmode > 1)
6134 #endif
6135 #ifdef MODULE_CCCAM
6136 || (cc && cc->extended_lg_flagged_cws)
6137 #endif
6138 || (cl->typ == 'p' && cl->reader && cl->reader->cacheex.feature_bitfield))
6141 const char *aio_suffix = " (cx-aio)";
6142 char *new_proto;
6143 if(cs_malloc(&new_proto, cs_strlen(proto)+cs_strlen(aio_suffix)+1)) {
6144 new_proto[0] = '\0';
6145 if (!cs_strncat(new_proto, (char *)proto, cs_strlen(proto)+cs_strlen(aio_suffix)+1)) {
6146 cs_log("FIXME!");
6148 if (cs_strncat(new_proto, (char *)aio_suffix, cs_strlen(proto)+cs_strlen(aio_suffix)+1)) {
6149 webif_add_client_proto(vars, cl, (const char*)new_proto, apicall);
6150 } else {
6151 cs_log("FIXME!");
6153 free(new_proto);
6155 } else {
6156 #endif
6157 webif_add_client_proto(vars, cl, proto, apicall);
6158 #ifdef CS_CACHEEX_AIO
6160 #endif
6161 if(!apicall)
6163 if((cl->typ != 'p' && cl->typ != 'r') || cl->reader->card_status == CARD_INSERTED)
6165 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);
6166 tpl_addVar(vars, TPLADD, "CLIENTLOGINSECS", sec2timeformat(vars, lsec));
6168 else
6170 tpl_addVar(vars, TPLADD, "CLIENTLOGINDATE", "");
6171 tpl_addVar(vars, TPLADD, "CLIENTLOGINSECS", "");
6174 else
6176 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);
6177 char tbuffer [30];
6178 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &lt);
6179 tpl_addVar(vars, TPLADD, "CLIENTLOGINDATE", tbuffer);
6180 tpl_printf(vars, TPLADD, "CLIENTLOGINSECS", "%d", lsec);
6183 //load historical values from ringbuffer
6184 char *value = get_ecm_historystring(cl);
6185 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIMEHIST", value);
6186 free_mk_t(value);
6188 if((isec < cfg.hideclient_to || cfg.hideclient_to == 0 || is_dvbapi_usr(cl->account->usr)) && (cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r'))
6190 if(((cl->typ == 'c')) && (cl->lastreader[0]))
6192 tpl_printf(vars, TPLADD, "MSVALUE", PRINTF_LOCAL_D, cl->cwlastresptime);
6193 if(apicall)
6195 tpl_addVar(vars, TPLADD, "LASTREADER", (cl->last_caid == NO_CAID_VALUE || isec > cfg.hideclient_to ) ? "" : cl->lastreader);
6196 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, cl->lastreader));
6198 else
6200 #ifdef WITH_LB
6201 tpl_addVar(vars, TPLADD, "LBLVALUE", xml_encode(vars, cl->lastreader));
6202 if(strstr(cl->lastreader, " (cache)"))
6204 char lastreader_tmp[cs_strlen(cl->lastreader) - 8];
6205 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", tpl_getVar(vars, "LBLRPSTRVALUE"));
6206 cs_strncpy(lastreader_tmp, cl->lastreader, sizeof(lastreader_tmp));
6207 tpl_addVar(vars, TPLADD, "LBLVALUEENC", urlencode(vars, lastreader_tmp));
6208 tpl_addVar(vars, TPLADD, "LBLVALUETITLE", xml_encode(vars, lastreader_tmp));
6210 else
6212 tpl_addVar(vars, TPLADD, "LBLVALUEENC", urlencode(vars, cl->lastreader));
6213 tpl_addVar(vars, TPLADD, "LBLVALUETITLE", xml_encode(vars, cl->lastreader));
6215 tpl_addVar(vars, TPLAPPEND, "CLIENTLBVALUE", tpl_getTpl(vars, "CLIENTLBLVALUEBIT"));
6216 #else
6217 tpl_printf(vars, TPLAPPEND, "CLIENTLBVALUE", "%s (%'d ms)", xml_encode(vars, cl->lastreader), cl->cwlastresptime);
6218 #endif
6220 if(cl->last_caid == NO_CAID_VALUE || isec > cfg.hideclient_to) tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", "");
6222 if(cl->last_caid != NO_CAID_VALUE || cl->last_srvid != NO_SRVID_VALUE)
6224 char channame[CS_SERVICENAME_SIZE];
6225 const char *lastprovidername;
6227 get_servicename_or_null(cl, cl->last_srvid, cl->last_provid, cl->last_caid, channame, sizeof(channame));
6228 if(channame[0] == '\0')
6230 cs_strncpy(channame, "unknown", sizeof(channame));
6233 lastprovidername = get_cl_lastprovidername(cl);
6235 tpl_printf(vars, TPLADD, "CLIENTCAID", "%04X", cl->last_caid);
6236 tpl_printf(vars, TPLADD, "CLIENTPROVID", "%06X", cl->last_provid);
6237 tpl_printf(vars, TPLADD, "CLIENTSRVID", "%04X", cl->last_srvid);
6238 tpl_printf(vars, TPLADD, "CLIENTSRVPROVIDER", "%s%s%s", (lastprovidername[0] != '\0' && strcmp(lastprovidername, " ")) ? " [" : "", xml_encode(vars, lastprovidername), (lastprovidername[0] != '\0' && strcmp(lastprovidername, " ")) ? "]" : "");
6239 tpl_addVar(vars, TPLADD, "CLIENTSRVNAME", xml_encode(vars, channame));
6240 tpl_printf(vars, TPLADD, "CLIENTLASTRESPONSETIME", "%d", cl->cwlastresptime ? cl->cwlastresptime : 1);
6241 tpl_addVar(vars, TPLADD, "CLIENTSRVTYPE", cl->last_srvidptr && cl->last_srvidptr->type ? xml_encode(vars, cl->last_srvidptr->type) : "");
6242 tpl_addVar(vars, TPLADD, "CLIENTSRVDESCRIPTION", cl->last_srvidptr && cl->last_srvidptr->desc ? xml_encode(vars, cl->last_srvidptr->desc) : "");
6243 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", sec2timeformat(vars, chsec));
6244 if(cfg.http_showpicons && cl->last_srvid)
6246 char picon_channame[30];
6247 int8_t picon_ok = 0;
6249 get_picon_servicename_or_null(cl, cl->last_srvid, cl->last_provid, cl->last_caid, picon_channame, sizeof(picon_channame));
6250 if(picon_channame[0])
6252 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", picon_channame);
6253 picon_ok = picon_exists(picon_name);
6254 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
6256 if(!picon_ok && picon_servicename_remve_hd(picon_channame, sizeof(picon_channame)))
6258 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", picon_channame);
6259 picon_ok = picon_exists(picon_name);
6260 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
6263 if(!picon_ok)
6265 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%04X_%06X_%04X", cl->last_caid, cl->last_provid, cl->last_srvid);
6266 tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
6267 picon_ok = picon_exists(picon_name);
6269 if(!picon_ok)
6271 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%04X_%04X", cl->last_caid, cl->last_srvid);
6272 picon_ok = picon_exists(picon_name);
6273 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
6275 if(!picon_ok)
6277 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "0000_%04X", cl->last_srvid);
6278 picon_ok = picon_exists(picon_name);
6279 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
6281 if(picon_ok)
6283 tpl_addVar(vars, TPLADDONCE, "CURRENTPICON", tpl_getTpl(vars, "CLIENTCURRENTCHANNELPIC"));
6285 else
6287 tpl_addVar(vars, TPLADDONCE, "CURRENTPICON", tpl_getTpl(vars, "CLIENTCURRENTCHANNEL"));
6288 tpl_addVar(vars, TPLADD, "PICONNAME", "");
6291 else
6293 tpl_addVar(vars, TPLADDONCE, "CURRENTPICON", tpl_getTpl(vars, "CLIENTCURRENTCHANNELBIT"));
6294 tpl_addVar(vars, TPLADD, "PICONNAME", "0000_0000");
6297 else
6299 tpl_addVar(vars, TPLADD, "CLIENTCAID", "0000");
6300 tpl_addVar(vars, TPLADD, "CLIENTPROVID", "000000");
6301 tpl_printf(vars, TPLADD, "CLIENTSRVID", "0000");
6304 else
6306 tpl_addVar(vars, TPLADD, "CLIENTCAID", "0000");
6307 tpl_addVar(vars, TPLADD, "CLIENTPROVID", "000000");
6308 tpl_addVar(vars, TPLADD, "CLIENTSRVID", "0000");
6309 tpl_addVar(vars, TPLADD, "CURRENTPICON", "");
6310 tpl_addVar(vars, TPLADD, "CLIENTSRVPROVIDER", "");
6311 tpl_addVar(vars, TPLADD, "CLIENTSRVNAME", "");
6312 tpl_addVar(vars, TPLADD, "CLIENTSRVTYPE", "");
6313 tpl_addVar(vars, TPLADD, "CLIENTSRVDESCRIPTION", "");
6314 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", "");
6315 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", "");
6318 if(!apicall)
6320 tpl_addVar(vars, TPLADD, "CLIENTIDLESECS", sec2timeformat(vars, isec));
6322 if((cl->typ != 'p' && cl->typ != 'r') || cl->reader->card_status == CARD_INSERTED)
6323 { tpl_addVar(vars, TPLADD, "CLIENTIDLESECSCLASS", "idlesec_normal"); }
6324 else
6325 { tpl_addVar(vars, TPLADD, "CLIENTIDLESECSCLASS", "idlesec_alert"); }
6327 else
6329 tpl_printf(vars, TPLADD, "CLIENTIDLESECS", "%d", isec);
6332 if(con == 2) { tpl_addVar(vars, TPLADD, "CLIENTCON", "Duplicate"); }
6333 else if(con == 1) { tpl_addVar(vars, TPLADD, "CLIENTCON", "Sleep"); }
6334 else
6336 struct s_reader *rdr = cl->reader;
6337 char *txt = "OK";
6338 if(!rdr && (cl->typ == 'r' || cl->typ == 'p')) { txt = "UNKNOWN"; }
6340 else if(cl->typ == 'r' || cl->typ == 'p') //reader or proxy
6342 #ifdef WITH_LB
6343 if(rdr->lbvalue)
6345 tpl_printf(vars, TPLADD, "LBLRPSTRVALUE", "%d", rdr->lbvalue);
6347 else
6349 tpl_addVar(vars, TPLADD, "LBLRPSTRVALUE", "no data");
6351 tpl_addVar(vars, TPLADD, "LBLRPVALUE", rdr->label);
6352 tpl_addVar(vars, TPLADD, "LBLRPVALUEENC", urlencode(vars, rdr->label));
6353 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", tpl_getTpl(vars, "CLIENTLBLVALUERP"));
6354 #else
6355 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", tpl_getVar(vars, "LBLRPSTRVALUE"));
6356 #endif
6357 switch(rdr->card_status)
6359 case NO_CARD:
6360 if(rdr->typ == R_GBOX)
6361 { txt = "ONL"; }
6362 else
6363 { txt = "OFF"; }
6364 break;
6365 case UNKNOWN:
6366 txt = "UNKNOWN";
6367 break;
6368 case READER_DEVICE_ERROR:
6369 txt = "READER DEVICE ERROR";
6370 break;
6371 case CARD_NEED_INIT:
6372 if(rdr->typ == R_GBOX)
6373 { txt = "OFFLINE"; }
6374 #ifdef CS_CACHEEX
6375 else if (cl->reader->cacheex.mode > 0)
6376 { txt = "CCcam CacheEX"; }
6377 #endif
6378 else
6379 { txt = "NEEDINIT"; }
6380 break;
6381 case CARD_INSERTED:
6382 if(cl->typ == 'p')
6384 if(rdr->typ == R_GBOX)
6385 { txt = "ONL"; }
6386 else
6387 { txt = "CONNECTED"; }
6389 else
6390 { txt = "CARDOK"; }
6391 break;
6392 case CARD_FAILURE:
6393 txt = "ERROR";
6394 break;
6395 default:
6396 txt = "UNDEF";
6398 #ifdef MODULE_GBOX
6399 if(rdr->typ == R_GBOX)
6401 struct gbox_peer *peer = cl->gbox;
6402 char gbx_txt[45];
6403 memset(gbx_txt, 0, sizeof(gbx_txt));
6404 if(!strcmp(txt, "OFFLINE"))
6406 snprintf(gbx_txt, sizeof(gbx_txt), "%s | ID: %04X", txt, peer->gbox.id);
6408 else
6410 snprintf(gbx_txt, sizeof(gbx_txt), "%s | crd: %d | ID: %04X", txt, gbox_count_peer_cards(peer->gbox.id), peer->gbox.id);
6412 txt = gbx_txt;
6414 #endif
6417 tpl_addVar(vars, TPLADD, "CLIENTCON", txt);
6419 if(rdr && (cl->typ == 'r')) //reader
6421 if(rdr->ll_entitlements)
6423 LL_ITER itr = ll_iter_create(rdr->ll_entitlements);
6424 S_ENTITLEMENT *ent;
6425 uint16_t total_ent = 0;
6426 uint16_t active_ent = 0;
6427 struct tm end_t;
6428 tpl_addVar(vars, TPLADD, "TMPSPAN", "<SPAN>");
6429 while((ent = ll_iter_next(&itr)))
6431 total_ent++;
6432 if((ent->end > now) && (ent->type != 7))
6434 if(active_ent) {tpl_addVar(vars, TPLAPPEND, "TMPSPAN", "<BR><BR>");}
6435 active_ent++;
6436 localtime_r(&ent->end, &end_t);
6437 tpl_printf(vars, TPLAPPEND, "TMPSPAN", "%04X@%06X<BR>exp:%04d/%02d/%02d",
6438 ent->caid, ent->provid,
6439 end_t.tm_year + 1900, end_t.tm_mon + 1, end_t.tm_mday);
6440 tpl_printf(vars, TPLAPPEND, "ENTITLEMENTS", "%s{\"caid\":\"%04X\",\"provid\":\"%06X\",\"exp\":\"%04d/%02d/%02d\"}",
6441 active_ent > 1 ? ",": "",
6442 ent->caid, ent->provid,
6443 end_t.tm_year + 1900, end_t.tm_mon + 1, end_t.tm_mday);
6446 tpl_printf(vars, TPLADD, "TOTENTITLEMENTS", "%d", total_ent);
6447 if(((total_ent) && (active_ent == 0)) || (total_ent == 0))
6449 tpl_addVar(vars, TPLAPPEND, "TMPSPAN", "No active entitlements found");
6451 tpl_addVar(vars, TPLAPPEND, "TMPSPAN", "</SPAN>");
6452 if(active_ent)
6454 tpl_printf(vars, TPLADD, "TMP", "(%d entitlement%s)", active_ent, (active_ent != 1) ? "s" : "");
6456 else
6458 tpl_addVar(vars, TPLADD, "TMP", "(no entitlements)");
6460 tpl_addVar(vars, TPLADD, "ENTLABEL", urlencode(vars, cl->reader->label));
6461 tpl_addVar(vars, TPLADD, "ENTVALUE", active_ent > 0 ? "" : "1");
6462 if (!apicall) tpl_addVar(vars, TPLAPPEND, "CLIENTCON", tpl_getTpl(vars, "FOUNDENTITLEMENTS"));
6464 else
6466 tpl_addVar(vars, TPLADD, "ENTLABEL", urlencode(vars, cl->reader->label));
6467 if (!apicall) tpl_addVar(vars, TPLAPPEND, "CLIENTCON", tpl_getTpl(vars, "NOENTITLEMENTS"));
6470 #ifdef MODULE_CCCAM
6471 if(!apicall || apicall == 2)
6473 if(rdr && (cl->typ == 'r' || cl->typ == 'p') && strncmp(proto, "cccam", 5) == 0 && rdr->tcp_connected && rdr->card_status != CARD_FAILURE)
6475 struct cc_data *rcc = cl->cc;
6476 if(rcc)
6478 LLIST *cards = rcc->cards;
6479 if(cards)
6481 int32_t cnt = ll_count(cards);
6482 int32_t locals = rcc->num_hop1;
6483 if(!apicall)
6485 tpl_printf(vars, TPLADD, "TMP", "(%d of %d card%s)", locals, cnt, (cnt > 1) ? "s" : "");
6486 tpl_printf(vars, TPLADD, "CCCOUNT", "%d", cnt);
6487 tpl_printf(vars, TPLADD, "CCCHOP1", "%d", rcc->num_hop1);
6488 tpl_printf(vars, TPLADD, "CCCHOP2", "%d", rcc->num_hop2);
6489 tpl_printf(vars, TPLADD, "CCCHOPX", "%d", rcc->num_hopx);
6490 tpl_printf(vars, TPLADD, "CCCCURR", "%d", cl->reader->currenthops);
6491 tpl_printf(vars, TPLADD, "CCCRES0", "%d", rcc->num_reshare0);
6492 tpl_printf(vars, TPLADD, "CCCRES1", "%d", rcc->num_reshare1);
6493 tpl_printf(vars, TPLADD, "CCCRES2", "%d", rcc->num_reshare2);
6494 tpl_printf(vars, TPLADD, "CCCRESX", "%d", rcc->num_resharex);
6495 tpl_addVar(vars, TPLADD, "TMPSPAN", tpl_getTpl(vars, "CCENTITLEMENTS"));
6496 tpl_addVar(vars, TPLADD, "CCCLABEL", urlencode(vars, cl->reader->label));
6497 tpl_addVar(vars, TPLADD, "CCCRESHARE", rcc->num_reshare0 > 0 ? "1" : "");
6498 tpl_addVar(vars, TPLADD, "CCCTMP", tpl_getVar(vars, "TMP"));
6499 tpl_addVar(vars, TPLADD, "CCCTMPSPAN", tpl_getVar(vars, "TMPSPAN"));
6500 tpl_addVar(vars, TPLAPPEND, "CLIENTCON", tpl_getTpl(vars, "CCENTITLETOOLTIP"));
6502 if (apicall == 2)
6504 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, cl->reader->label));
6505 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\"}",
6506 locals, cnt, rcc->num_hop1, rcc->num_hop2, rcc->num_hopx, cl->reader->currenthops,
6507 rcc->num_reshare0, rcc->num_reshare1, rcc->num_reshare2, rcc->num_resharex,
6508 rcc->num_reshare0 > 0 ? "1" : "");
6510 cs_log_dbg(D_TRACE, "Reader %s has total %d local%s hop1 %d hopx %d from total of %d card%s", cl->reader->label, locals, (locals > 1) ? "s" : "", rcc->num_hop2, rcc->num_hopx, cnt, (cnt > 1) ? "s" : "");
6515 #endif
6519 if(!apicall)
6521 // select right suborder
6522 if(cl->typ == 'c')
6524 if(shown) { tpl_addVar(vars, TPLAPPEND, "CLIENTSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT")); }
6525 if(cfg.http_hide_idle_clients != 1 && cfg.hideclient_to > 0)
6527 tpl_printf(vars, TPLADD, "UCAC", "%d", user_count_active);
6528 tpl_printf(vars, TPLADD, "CFGH", "%d", cfg.hideclient_to);
6529 tpl_addVar(vars, TPLADD, "CHEADADD", tpl_getTpl(vars, "CLIENTHEADLINEADD"));
6532 tpl_printf(vars, TPLADD, "UCS", "%d", user_count_shown);
6533 tpl_printf(vars, TPLADD, "UCA", "%d", user_count_all);
6534 tpl_addVar(vars, TPLADD, "HIDEIDLE", "5");
6535 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "User");
6536 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTHEADLINE"));
6537 tpl_addVar(vars, TPLADD, "CLIENTOPTIONADD", tpl_getTpl(vars, "CLIENTHEADLINEBIT"));
6538 tpl_addVar(vars, TPLADD, "CLIENTHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
6539 tpl_addVar(vars, TPLADD, "CLIENTOPTIONADD", "");
6541 else if(cl->typ == 'r')
6543 if(shown)
6545 tpl_addVar(vars, TPLAPPEND, "READERSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT"));
6548 tpl_printf(vars, TPLADD, "RCC", "%d", reader_count_conn);
6549 tpl_printf(vars, TPLADD, "RCA", "%d", reader_count_all);
6551 if(reader_count_off)
6553 tpl_printf(vars, TPLADD, "RCO", "%d", reader_count_all-reader_count_off);
6554 tpl_addVar(vars, TPLADD, "RHEADADD", tpl_getTpl(vars, "CLIENTRHEADLINEADD"));
6557 tpl_addVar(vars, TPLADD, "HIDEIDLE", "3");
6558 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "Reader");
6559 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTRHEADLINE"));
6560 tpl_addVar(vars, TPLADD, "READERHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
6562 else if(cl->typ == 'p')
6564 if(shown)
6566 tpl_addVar(vars, TPLAPPEND, "PROXYSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT"));
6569 tpl_printf(vars, TPLADD, "PCC", "%d", proxy_count_conn);
6570 tpl_printf(vars, TPLADD, "PCA", "%d", proxy_count_all);
6572 if(proxy_count_off)
6574 tpl_printf(vars, TPLADD, "PCO", "%d", proxy_count_all-proxy_count_off);
6575 tpl_addVar(vars, TPLADD, "PHEADADD", tpl_getTpl(vars, "CLIENTPHEADLINEADD"));
6578 tpl_addVar(vars, TPLADD, "HIDEIDLE", "4");
6579 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "Proxy");
6580 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTPHEADLINE"));
6581 tpl_addVar(vars, TPLADD, "PROXYHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
6583 else if(cl->typ == 'm' || cl->typ == 's' || cl->typ == 'h')
6585 if(shown)
6587 tpl_addVar(vars, TPLAPPEND, "SERVERSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT"));
6590 tpl_addVar(vars, TPLADD, "HIDEIDLE", "2");
6591 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "Server");
6593 if(cl->typ == 's' || cl->typ == 'h')
6595 tpl_printf(vars, TPLADD, "SCS", "%d", server_count_shown);
6596 tpl_printf(vars, TPLADD, "SCA", "%d", server_count_all);
6597 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTSHEADLINE"));
6599 if(shown || cl->wihidden)
6601 tpl_addVar(vars, TPLADD, "SERVERHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
6604 else
6606 tpl_addVar(vars, TPLADD, "SHOWHIDDENADD", " & Monitors");
6607 tpl_printf(vars, TPLADD, "MCS", "%d", monitor_count_shown);
6608 tpl_printf(vars, TPLADD, "MCA", "%d", monitor_count_all);
6609 tpl_addVar(vars, TPLADD, "MHEADADD", tpl_getTpl(vars, "CLIENTMHEADLINE"));
6610 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTSHEADLINE"));
6611 tpl_addVar(vars, TPLADD, "SERVERHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
6612 tpl_addVar(vars, TPLADD, "SHOWHIDDENADD", "");
6616 else
6618 if(shown)
6620 if(apicall == 1)
6622 tpl_addVar(vars, TPLAPPEND, "APISTATUSBITS", tpl_getTpl(vars, "APISTATUSBIT"));
6625 if(apicall == 2)
6627 tpl_addVar(vars, TPLADD, "JSONARRAYDELIMITER", delimiter?",":"");
6628 tpl_addVar(vars, TPLAPPEND, "JSONSTATUSBITS", tpl_getTpl(vars, "JSONSTATUSBIT"));
6629 delimiter++;
6634 #ifdef CS_CACHEEX
6636 #endif
6640 LL_ITER itr = ll_iter_create(configured_readers);
6641 struct s_reader *rdrr;
6642 while((rdrr = ll_iter_next(&itr)))
6644 if(rdrr->label[0] && rdrr->typ)
6646 total_readers += 1;
6648 if(rdrr->enable) { active_readers += 1; }
6649 else { disabled_readers += 1; }
6651 if(rdrr->tcp_connected) { connected_readers += 1; }
6655 cs_readunlock(__func__, &clientlist_lock);
6656 cs_readunlock(__func__, &readerlist_lock);
6658 uint8_t is_touch = 0;
6659 if(config_enabled(TOUCH) && streq(tpl_getVar(vars, "SUBDIR"), TOUCH_SUBDIR))
6660 {is_touch=1;}
6662 if(cfg.http_status_log || (apicall == 1 && strcmp(getParam(params, "appendlog"), "1") == 0) || is_touch)
6664 if(cfg.loghistorylines && log_history)
6666 LL_ITER it = ll_iter_create(log_history);
6667 struct s_log_history *hist;
6669 while((hist = (struct s_log_history*)ll_iter_next(&it)))
6671 char p_usr[32];
6672 size_t pos1 = strcspn(hist->txt, "\t") + 1;
6673 cs_strncpy(p_usr, hist->txt , pos1 > sizeof(p_usr) ? sizeof(p_usr) : pos1);
6675 char *p_txt = hist->txt + pos1;
6677 if(!apicall)
6679 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));
6681 else
6683 tpl_addVar(vars, TPLAPPEND, "LOGHISTORY", p_txt);
6687 else
6689 tpl_addVar(vars, TPLADD, "LOGHISTORY", "loghistorylines is set to 0 in your configuration");
6693 #ifdef CS_CACHEEX
6694 char *getting = "<IMG SRC=\"image?i=ICARRL\" ALT=\"Getting\">";
6695 char *pushing = "<IMG SRC=\"image?i=ICARRR\" ALT=\"Pushing\">";
6697 float cachesum = first_client ? first_client->cwcacheexgot : 1;
6698 if(cachesum < 1)
6700 cachesum = 1;
6702 tpl_printf(vars, TPLADD, "TOTAL_CACHEXPUSH", "%d", first_client ? first_client->cwcacheexpush : 0);
6703 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXPUSH_IMG", pushing);
6704 tpl_printf(vars, TPLADD, "TOTAL_CACHEXGOT", "%d", first_client ? first_client->cwcacheexgot : 0);
6705 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXGOT_IMG", getting);
6706 tpl_printf(vars, TPLADD, "TOTAL_CACHEXHIT", "%d", first_client ? first_client->cwcacheexhit : 0);
6707 tpl_printf(vars, TPLADD, "TOTAL_CACHESIZE", "%d", cache_size());
6708 #ifdef CS_CACHEEX_AIO
6709 tpl_printf(vars, TPLADD, "TOTAL_CACHESIZE_LG", "%d", cache_size_lg());
6710 #endif
6711 tpl_printf(vars, TPLADD, "REL_CACHEXHIT", "%.2f", (first_client ? first_client->cwcacheexhit : 0) * 100 / cachesum);
6712 tpl_addVar(vars, TPLADD, "CACHEEXSTATS", tpl_getTpl(vars, "STATUSCACHEX"));
6713 #endif
6714 //User info
6715 struct s_auth *account;
6716 int32_t total_users = 0;
6717 int32_t disabled_users = 0;
6718 int32_t expired_users = 0;
6719 int32_t expired_or_disabled_users = 0;
6720 int32_t connected_users = 0;
6721 int32_t online_users = 0;
6723 for(account = cfg.account; (account); account = account->next)
6725 total_users++;
6726 if(account->expirationdate && account->expirationdate < now)
6728 expired_users++;
6730 if(account->disabled != 0)
6732 disabled_users++;
6734 if((account->expirationdate && account->expirationdate < now)||account->disabled != 0)
6736 expired_or_disabled_users++;
6738 int32_t latestactivity = 0;
6739 struct s_client *latestclient = NULL;
6740 for(cl = first_client->next; cl ; cl = cl->next)
6742 if(cl->account && !strcmp(cl->account->usr, account->usr))
6744 if(cl->lastecm > latestactivity || cl->login > latestactivity)
6746 if(cl->lastecm > cl->login) { latestactivity = cl->lastecm; }
6747 else { latestactivity = cl->login; }
6748 latestclient = cl;
6753 if(latestclient != NULL)
6755 connected_users++;
6757 if(latestactivity > 0)
6759 if((now - latestactivity) < cfg.hideclient_to)
6761 if(latestclient->cwfound + latestclient->cwnot + latestclient->cwcache > 0)
6763 online_users++;
6769 tpl_printf(vars, TPLADD, "TOTAL_USERS", "%d", total_users);
6770 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE", "%d", total_users - expired_or_disabled_users);
6771 tpl_printf(vars, TPLADD, "TOTAL_EXPIRED", "%d", expired_users);
6772 tpl_printf(vars, TPLADD, "TOTAL_DISABLED", "%d", disabled_users);
6773 tpl_printf(vars, TPLADD, "TOTAL_ONLINE", "%d", online_users);
6774 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED", "%d", connected_users);
6776 tpl_printf(vars, TPLADD, "TOTAL_READERS", "%d", total_readers);
6777 tpl_printf(vars, TPLADD, "TOTAL_DISABLED_READERS", "%d", disabled_readers);
6778 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE_READERS", "%d", active_readers);
6779 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED_READERS", "%d", connected_readers);
6781 //CM info
6782 set_ecm_info(vars);
6784 //copy struct to p_stat_old for cpu_usage calculation
6785 p_stat_old = p_stat_cur;
6788 * check_available Bit mapping
6789 * mem 0 total, 1 used & free, 2 buff, cached & free incl. buff, 3 share
6790 * swap 4 total, 5 used & free,
6791 * proc 6 count
6792 * cpu 7 load
6793 * oscam 8 vsize & rssize, 9 cpu user, 10 cpu sys, 11 cpu sum, 12 cpu refreshtime
6794 * unused 13 - 15
6796 //Memory-CPU Info for linux based systems
6797 #if defined(__linux__)
6798 //get actual stats
6799 if(!get_stats_linux(getpid(),&p_stat_cur)){
6800 if(p_stat_old.cpu_total_time != 0){
6801 calc_cpu_usage_pct(&p_stat_cur, &p_stat_old);
6804 else{
6805 //something went wrong, so fill with "N/A"
6806 p_stat_cur.check_available = 65535;
6808 #else // if not linux, fill with "N/A" but probably in future gets filled also for other platforms
6809 p_stat_cur.check_available = 65535;
6810 #endif
6811 set_status_info(vars, p_stat_cur);
6813 if(cfg.http_showmeminfo || cfg.http_showuserinfo || cfg.http_showreaderinfo || cfg.http_showloadinfo || cfg.http_showecminfo || (cfg.http_showcacheexinfo && config_enabled(CS_CACHEEX)) || (cfg.http_showcacheexinfo && config_enabled(CS_CACHEEX_AIO))){
6814 tpl_addVar(vars, TPLADD, "DISPLAYINFO", "visible");
6816 else{
6817 tpl_addVar(vars, TPLADD, "DISPLAYINFO", "hidden");
6820 tpl_addVar(vars, TPLADD, "DISPLAYSYSINFO", cfg.http_showmeminfo ? "visible" : "hidden");
6821 tpl_addVar(vars, TPLADD, "DISPLAYUSERINFO", cfg.http_showuserinfo ? "visible" : "hidden");
6822 tpl_addVar(vars, TPLADD, "DISPLAYREADERINFO", cfg.http_showreaderinfo ? "visible" : "hidden");
6823 tpl_addVar(vars, TPLADD, "DISPLAYLOADINFO", cfg.http_showloadinfo ?"visible" : "hidden");
6824 tpl_addVar(vars, TPLADD, "DISPLAYECMINFO", cfg.http_showecminfo ? "visible" : "hidden");
6825 tpl_addVar(vars, TPLADD, "DISPLAYECMINFO_READERS", cfg.http_showecminfo ? "visible" : "hidden");
6827 if(cfg.http_showcacheexinfo == 1 && config_enabled(CS_CACHEEX))
6829 if (config_enabled(CS_CACHEEX_AIO))
6831 tpl_addVar(vars, TPLADD, "DISPLAYCACHEEXINFO", "hidden");
6832 tpl_addVar(vars, TPLADD, "DISPLAYCACHEEXAIOINFO", "visible");
6834 else
6836 tpl_addVar(vars, TPLADD, "DISPLAYCACHEEXINFO", "visible");
6837 tpl_addVar(vars, TPLADD, "DISPLAYCACHEEXAIOINFO", "hidden");
6840 else{
6841 tpl_addVar(vars, TPLADD, "DISPLAYCACHEEXINFO", "hidden");
6842 tpl_addVar(vars, TPLADD, "DISPLAYCACHEEXAIOINFO", "hidden");
6845 #ifdef WITH_DEBUG
6846 if(cfg.http_status_log || is_touch)
6848 // Debuglevel Selector
6849 int32_t lvl;
6850 for(i = 0; i < MAX_DEBUG_LEVELS; i++)
6852 lvl = 1 << i;
6853 tpl_printf(vars, TPLADD, "TMPC", "DCLASS%d", lvl);
6854 tpl_printf(vars, TPLADD, "TMPV", "DEBUGVAL%d", lvl);
6855 if(cs_dblevel & lvl)
6857 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugls");
6858 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel - lvl);
6860 else
6862 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugl");
6863 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel + lvl);
6867 if(cs_dblevel == D_ALL_DUMP)
6868 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugls"); }
6869 else
6870 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugl"); }
6872 tpl_addVar(vars, TPLADD, "NEXTPAGE", "status.html");
6873 tpl_addVar(vars, TPLADD, "DCLASS", "debugl"); //default
6874 tpl_printf(vars, TPLADD, "ACTDEBUG", "%d", cs_dblevel);
6875 #ifdef CS_CACHEEX_AIO
6876 tpl_addVar(vars, TPLADD, "SDEBUG", tpl_getTpl(vars, "DEBUGSELECTAIO"));
6877 #else
6878 tpl_addVar(vars, TPLADD, "SDEBUG", tpl_getTpl(vars, "DEBUGSELECT"));
6879 #endif
6881 #endif
6883 if(cfg.http_status_log || is_touch)
6884 tpl_addVar(vars, TPLADDONCE, "LOG_HISTORY", tpl_getTpl(vars, "LOGHISTORYBIT"));
6886 if(apicall)
6888 if(apicall == 1)
6889 { return tpl_getTpl(vars, "APISTATUS"); }
6890 if(apicall == 2)
6892 tpl_printf(vars, TPLADD, "UCS", "%d", user_count_shown);
6893 tpl_printf(vars, TPLADD, "UCA", "%d", user_count_all);
6894 if(cfg.http_hide_idle_clients != 1 && cfg.hideclient_to > 0){
6895 tpl_printf(vars, TPLADD, "UCAC", "%d", user_count_active);
6897 tpl_printf(vars, TPLADD, "CFGH", "%d", cfg.hideclient_to);
6898 tpl_printf(vars, TPLADD, "MCS", "%d", monitor_count_shown);
6899 tpl_printf(vars, TPLADD, "MCA", "%d", monitor_count_all);
6900 tpl_printf(vars, TPLADD, "SCS", "%d", server_count_shown);
6901 tpl_printf(vars, TPLADD, "SCH", "%d", server_count_hidden);
6902 tpl_printf(vars, TPLADD, "SCA", "%d", server_count_all);
6903 tpl_printf(vars, TPLADD, "RCC", "%d", reader_count_conn);
6904 tpl_printf(vars, TPLADD, "RCO", "%d", reader_count_off);
6905 tpl_printf(vars, TPLADD, "RCA", "%d", reader_count_all);
6906 tpl_printf(vars, TPLADD, "PCC", "%d", proxy_count_conn);
6907 tpl_printf(vars, TPLADD, "PCO", "%d", proxy_count_off);
6908 tpl_printf(vars, TPLADD, "PCA", "%d", proxy_count_all);
6909 tpl_printf(vars, TPLADD, "PICONENABLED", "%d", cfg.http_showpicons?1:0);
6910 tpl_printf(vars, TPLADD, "SRVIDFILE", "%s", use_srvid2 ? "oscam.srvid2" : "oscam.srvid");
6911 return tpl_getTpl(vars, "JSONSTATUS");
6915 if(is_touch)
6916 { return tpl_getTpl(vars, "TOUCH_STATUS"); }
6917 else
6918 { return tpl_getTpl(vars, "STATUS"); }
6921 static char *send_oscam_services_edit(struct templatevars * vars, struct uriparams * params)
6923 struct s_sidtab *sidtab, *ptr;
6924 char label[sizeof(cfg.sidtab->label)];
6925 int32_t i;
6927 setActiveMenu(vars, MNU_SERVICES);
6929 cs_strncpy(label, strtolower(getParam(params, "service")), sizeof(label));
6930 ++cfg_sidtab_generation;
6931 for(sidtab = cfg.sidtab; sidtab != NULL && strcmp(label, sidtab->label) != 0; sidtab = sidtab->next) { ; }
6933 if(sidtab == NULL)
6935 i = 1;
6936 while(cs_strlen(label) < 1)
6938 snprintf(label, sizeof(label) / sizeof(char) - 1, "newservice%d", i);
6939 for(sidtab = cfg.sidtab; sidtab != NULL && strcmp(label, sidtab->label) != 0; sidtab = sidtab->next) { ; }
6940 if(sidtab != NULL) { label[0] = '\0'; }
6941 ++i;
6943 if(!cs_malloc(&sidtab, sizeof(struct s_sidtab))) { return "0"; }
6945 if(cfg.sidtab == NULL) { cfg.sidtab = sidtab; }
6946 else
6948 for(ptr = cfg.sidtab; ptr != NULL && ptr->next != NULL; ptr = ptr->next) { ; }
6949 ptr->next = sidtab;
6951 cs_strncpy((char *)sidtab->label, label, sizeof(sidtab->label));
6952 ++cfg_sidtab_generation;
6953 tpl_addMsg(vars, "New service has been added");
6954 // Adding is uncritical as the new service is appended to sidtabs.ok/sidtabs.no and accounts/clients/readers have zeros there
6955 if(write_services() != 0) { tpl_addMsg(vars, "Writing services to disk failed!"); }
6958 if(strcmp(getParam(params, "action"), "Save") == 0)
6960 for(i = 0; i < (*params).paramcount; i++)
6962 if((strcmp((*params).params[i], "action")) && (strcmp((*params).params[i], "service")))
6964 chk_sidtab((*params).params[i], (*params).values[i], sidtab);
6967 ++cfg_sidtab_generation;
6968 tpl_addMsg(vars, "Services updated");
6969 // We don't need any refresh here as accounts/clients/readers sidtabs.ok/sidtabs.no are unaffected!
6970 if(write_services() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
6972 for(sidtab = cfg.sidtab; sidtab != NULL && strcmp(label, sidtab->label) != 0; sidtab = sidtab->next) { ; }
6975 tpl_addVar(vars, TPLADD, "LABEL", xml_encode(vars, sidtab->label));
6976 tpl_addVar(vars, TPLADD, "LABELENC", urlencode(vars, sidtab->label));
6978 if(sidtab)
6980 #ifdef CS_CACHEEX_AIO
6981 tpl_addVar(vars, TPLADD, "DCRCCHECKED", (sidtab->disablecrccws_only_for_exception == 1) ? "checked" : "" );
6982 tpl_addVar(vars, TPLADD, "NWCHECKED", (sidtab->no_wait_time == 1) ? "checked" : "" );
6983 tpl_addVar(vars, TPLADD, "LGOECHECKED", (sidtab->lg_only_exception == 1) ? "checked" : "" );
6984 #endif
6985 for(i = 0; i < sidtab->num_caid; i++)
6987 if(i == 0) { tpl_printf(vars, TPLADD, "CAIDS", "%04X", sidtab->caid[i]); }
6988 else { tpl_printf(vars, TPLAPPEND, "CAIDS", ",%04X", sidtab->caid[i]); }
6990 for(i = 0; i < sidtab->num_provid; i++)
6992 if(i == 0) { tpl_printf(vars, TPLADD, "PROVIDS", "%06X", sidtab->provid[i]); }
6993 else { tpl_printf(vars, TPLAPPEND, "PROVIDS", ",%06X", sidtab->provid[i]); }
6995 for(i = 0; i < sidtab->num_srvid; i++)
6997 if(i == 0) { tpl_printf(vars, TPLADD, "SRVIDS", "%04X", sidtab->srvid[i]); }
6998 else { tpl_printf(vars, TPLAPPEND, "SRVIDS", ",%04X", sidtab->srvid[i]); }
7001 #ifdef CS_CACHEEX_AIO
7002 return tpl_getTpl(vars, "SERVICEEDITAIO");
7003 #else
7004 return tpl_getTpl(vars, "SERVICEEDIT");
7005 #endif
7008 static void delete_from_SIDTABBITS(SIDTABBITS * orgsidtab, int32_t position, int32_t sidtablength)
7010 if(*orgsidtab)
7012 int32_t i;
7013 SIDTABBITS newsidtab = 0;
7014 for(i = 0; i < position; ++i)
7016 if(*orgsidtab & ((SIDTABBITS)1 << i))
7017 { newsidtab |= ((SIDTABBITS)1 << i); }
7019 for(; i < sidtablength; ++i)
7021 if(*orgsidtab & ((SIDTABBITS)1 << (i + 1)))
7022 { newsidtab |= ((SIDTABBITS)1 << i); }
7024 *orgsidtab = newsidtab;
7028 static char *send_oscam_services(struct templatevars * vars, struct uriparams * params)
7030 struct s_sidtab *sidtab;
7031 char *service = getParam(params, "service");
7032 char channame[CS_SERVICENAME_SIZE];
7033 int32_t i, counter = 0;
7035 setActiveMenu(vars, MNU_SERVICES);
7037 if(strcmp(getParam(params, "action"), "delete") == 0)
7039 if(cfg.http_readonly)
7041 tpl_addMsg(vars, "Sorry, Webif is in readonly mode. No deletion will be made!");
7043 else
7045 struct s_sidtab *sidtab_prev = NULL;
7046 int32_t sidtablength = -1;
7047 int32_t position = 0;
7049 // Calculate sidtablength before deletion so that updating sidtabs is faster
7050 for(sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next)
7051 { ++sidtablength; }
7053 for(sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next)
7055 if(strcmp(sidtab->label, service) == 0)
7057 struct s_auth *account;
7058 struct s_client *cl;
7059 struct s_reader *rdr;
7061 if(!sidtab_prev)
7062 { cfg.sidtab = sidtab->next; }
7063 else
7064 { sidtab_prev->next = sidtab->next; }
7066 for(account = cfg.account; (account); account = account->next)
7068 delete_from_SIDTABBITS(&account->sidtabs.ok, position, sidtablength);
7069 delete_from_SIDTABBITS(&account->sidtabs.no, position, sidtablength);
7071 for(cl = first_client->next; cl ; cl = cl->next)
7073 if(account == cl->account)
7075 cl->sidtabs.ok = account->sidtabs.ok;
7076 cl->sidtabs.no = account->sidtabs.no;
7081 LL_ITER itr = ll_iter_create(configured_readers);
7082 while((rdr = ll_iter_next(&itr)))
7084 delete_from_SIDTABBITS(&rdr->sidtabs.ok, position, sidtablength);
7085 delete_from_SIDTABBITS(&rdr->sidtabs.no, position, sidtablength);
7086 delete_from_SIDTABBITS(&rdr->lb_sidtabs.ok, position, sidtablength);
7088 free_sidtab(sidtab);
7089 ++counter;
7090 break;
7092 sidtab_prev = sidtab;
7093 position++;
7095 if(counter > 0)
7097 ++cfg_sidtab_generation;
7098 tpl_addMsg(vars, "Service has been deleted!");
7099 if(write_services() != 0) { tpl_addMsg(vars, "Writing services to disk failed!"); }
7101 else { tpl_addMsg(vars, "Sorry but the specified service doesn't exist. No deletion will be made!"); }
7105 sidtab = cfg.sidtab;
7106 // Show List
7107 counter = 0;
7108 while(sidtab != NULL)
7110 tpl_addVar(vars, TPLADD, "SID", "");
7111 if((strcmp(getParam(params, "service"), sidtab->label) == 0) && (strcmp(getParam(params, "action"), "list") == 0))
7113 tpl_addVar(vars, TPLADD, "SIDCLASS", "sidlist");
7114 tpl_addVar(vars, TPLAPPEND, "SID", "<DIV CLASS=\"sidlistclose\"><A HREF=\"services.html\">X</A></DIV>");
7115 for(i = 0; i < sidtab->num_srvid; i++)
7117 tpl_printf(vars, TPLAPPEND, "SID", "%04X : %s<BR>", sidtab->srvid[i],
7118 xml_encode(vars, get_servicename(cur_client(), sidtab->srvid[i], sidtab->num_provid ? sidtab->provid[0] : 0,
7119 sidtab->num_caid ? sidtab->caid[0] : 0, channame, sizeof(channame))));
7122 else
7124 tpl_addVar(vars, TPLADD, "SIDCLASS", "");
7125 tpl_printf(vars, TPLADD, "SID", "<A HREF=\"services.html?service=%s&amp;action=list\">Show Services</A>", urlencode(vars, sidtab->label));
7127 tpl_addVar(vars, TPLADD, "LABELENC", urlencode(vars, sidtab->label));
7128 tpl_addVar(vars, TPLADD, "LABEL", xml_encode(vars, sidtab->label));
7129 tpl_addVar(vars, TPLADD, "SIDLIST", tpl_getTpl(vars, "SERVICECONFIGSIDBIT"));
7131 tpl_addVar(vars, TPLAPPEND, "SERVICETABS", tpl_getTpl(vars, "SERVICECONFIGLISTBIT"));
7132 sidtab = sidtab->next;
7133 counter++;
7135 if(counter >= MAX_SIDBITS)
7137 tpl_addVar(vars, TPLADD, "BTNDISABLED", "DISABLED");
7138 tpl_addMsg(vars, "Maximum Number of Services is reached");
7140 return tpl_getTpl(vars, "SERVICECONFIGLIST");
7143 static char *send_oscam_savetpls(struct templatevars * vars)
7145 if(cfg.http_tpl)
7147 tpl_printf(vars, TPLADD, "CNT", "%d", tpl_saveIncludedTpls(cfg.http_tpl));
7148 tpl_addVar(vars, TPLADD, "PATH", cfg.http_tpl);
7150 else { tpl_addVar(vars, TPLADD, "CNT", "0"); }
7151 return tpl_getTpl(vars, "SAVETEMPLATES");
7154 static char *send_oscam_shutdown(struct templatevars * vars, FILE * f, struct uriparams * params, int8_t apicall, int8_t *keepalive, char *extraheader)
7156 if(!apicall) { setActiveMenu(vars, MNU_SHUTDOWN); }
7157 if(strcmp(strtolower(getParam(params, "action")), "shutdown") == 0)
7159 *keepalive = 0;
7160 if(!apicall)
7162 char *CSS = tpl_getUnparsedTpl("CSS", 1, "");
7163 tpl_addVar(vars, TPLADD, "STYLESHEET", CSS);
7164 NULLFREE(CSS);
7165 tpl_printf(vars, TPLADD, "REFRESHTIME", "%d", SHUTDOWNREFRESH);
7166 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
7167 tpl_printf(vars, TPLADD, "SECONDS", "%d", SHUTDOWNREFRESH);
7168 char *result = tpl_getTpl(vars, "SHUTDOWN");
7169 send_headers(f, 200, "OK", extraheader, "text/html", 0, cs_strlen(result), NULL, 0);
7170 webif_write(result, f);
7171 cs_log("Shutdown requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
7173 else
7175 tpl_addVar(vars, TPLADD, "APICONFIRMMESSAGE", "shutdown");
7176 cs_log("Shutdown requested by XMLApi from %s", cs_inet_ntoa(GET_IP()));
7178 cs_exit_oscam();
7180 if(!apicall)
7181 { return "1"; }
7182 else
7183 { return tpl_getTpl(vars, "APICONFIRMATION"); }
7186 else if(strcmp(strtolower(getParam(params, "action")), "restart") == 0)
7188 *keepalive = 0;
7189 if(!apicall)
7191 char *CSS = tpl_getUnparsedTpl("CSS", 1, "");
7192 tpl_addVar(vars, TPLADD, "STYLESHEET", CSS);
7193 NULLFREE(CSS);
7194 tpl_addVar(vars, TPLADD, "REFRESHTIME", "5");
7195 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
7196 tpl_addVar(vars, TPLADD, "SECONDS", "5");
7197 char *result = tpl_getTpl(vars, "SHUTDOWN");
7198 send_headers(f, 200, "OK", extraheader, "text/html", 0, cs_strlen(result), NULL, 0);
7199 webif_write(result, f);
7200 cs_log("Restart requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
7202 else
7204 tpl_addVar(vars, TPLADD, "APICONFIRMMESSAGE", "restart");
7205 cs_log("Restart requested by XMLApi from %s", cs_inet_ntoa(GET_IP()));
7207 cs_restart_oscam();
7209 if(!apicall)
7210 { return "1"; }
7211 else
7212 { return tpl_getTpl(vars, "APICONFIRMATION"); }
7215 else
7217 return tpl_getTpl(vars, "PRESHUTDOWN");
7221 static char *send_oscam_script(struct templatevars * vars, struct uriparams * params)
7223 setActiveMenu(vars, MNU_SCRIPT);
7224 tpl_printf(vars, TPLADD, "SCRIPTOPTIONS", "<option value=\"\">----select script----</option>\n");
7226 if(!cfg.http_readonly && cfg.http_script)
7228 struct dirent **namelist;
7229 int count, i;
7230 count = scandir(cfg.http_script, &namelist, 0, alphasort );
7231 if( count >= 0 )
7233 for( i = 0 ; i < count; i++ )
7235 if(is_ext(namelist[i]->d_name, ".script") || is_ext(namelist[i]->d_name, ".sh"))
7237 tpl_printf(vars, TPLAPPEND, "SCRIPTOPTIONS", "<option value=\"script.html?scriptname=%s\">%s</option>\n",namelist[i]->d_name,namelist[i]->d_name);
7239 free( namelist[i] );
7241 free(namelist);
7244 char *scriptname = getParam(params, "scriptname");
7245 char *scriptparam = getParam(params, "scriptparam");
7246 char system_str[256];
7247 struct stat s;
7248 snprintf(system_str, sizeof(system_str), "%s/%s", cfg.http_script, scriptname);
7250 if(!stat(system_str,&s))
7252 if(s.st_mode & S_IFREG)
7254 if(s.st_mode & S_IXUSR)
7256 int32_t rc;
7257 FILE *fp;
7258 char buf[256];
7260 if((scriptparam != NULL) && (sizeof(scriptparam) > 0))
7262 cs_strncat(system_str, " ", sizeof(system_str));
7263 cs_strncat(system_str, scriptparam, sizeof(system_str));
7266 fp = popen(system_str, "r");
7268 while (fgets(buf, sizeof(buf), fp) != NULL)
7270 tpl_addVar(vars, TPLAPPEND, "SCRIPTRESULTOUT", buf);
7273 rc = pclose(fp)/256;
7275 tpl_printf(vars, TPLAPPEND, "CODE", "returncode: %d", rc);
7276 tpl_printf(vars, TPLADD, "SCRIPTNAME", "scriptname: %s", scriptname);
7278 else
7280 tpl_printf(vars, TPLADD, "SCRIPTRESULTOUT", "[Error]: Script \"%s\" not executable!", scriptname);
7284 else
7286 tpl_printf(vars, TPLADD, "SCRIPTRESULTOUT", "[Error]: Script \"%s\" not found!", scriptname);
7290 return tpl_getTpl(vars, "SCRIPT");
7293 static char *send_oscam_scanusb(struct templatevars * vars)
7295 setActiveMenu(vars, MNU_READERS);
7296 #if !defined(__CYGWIN__)
7297 FILE *fp;
7298 char path[1035];
7300 fp = popen("lsusb -v | egrep '^Bus|^ *iSerial|^ *iProduct'", "r");
7301 if(!fgets(path, sizeof(path) - 1, fp) || !fp)
7303 tpl_addVar(vars, TPLADD, "USBENTRY", "<b>lsusb:</b> Failed to run or not installed!");
7304 tpl_addVar(vars, TPLADD, "USBBIT", tpl_getTpl(vars, "SCANUSBBIT"));
7306 else
7309 tpl_addVar(vars, TPLADD, "USBENTRYCLASS", "");
7310 if(strstr(path, "Bus "))
7312 tpl_addVar(vars, TPLADD, "USBENTRY", path);
7313 tpl_addVar(vars, TPLADD, "USBENTRYCLASS", "CLASS=\"scanusbsubhead\"");
7315 else
7317 tpl_printf(vars, TPLADD, "USBENTRY", "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%s", path);
7319 tpl_addVar(vars, TPLAPPEND, "USBBIT", tpl_getTpl(vars, "SCANUSBBIT"));
7321 while(fgets(path, sizeof(path) - 1, fp) != NULL);
7323 pclose(fp);
7324 #else
7325 tpl_addMsg(vars, "Function not supported in CYGWIN environment");
7326 #endif
7327 return tpl_getTpl(vars, "SCANUSB");
7330 static void webif_process_logfile(struct templatevars * vars, struct uriparams * params, char *targetfile, size_t targetfile_len)
7332 snprintf(targetfile, targetfile_len, "%s", cfg.logfile);
7333 if(strcmp(getParam(params, "clear"), "logfile") == 0)
7335 if(cs_strlen(targetfile) > 0)
7337 FILE *file = fopen(targetfile, "w");
7338 fclose(file);
7341 #ifdef WITH_DEBUG
7342 // Debuglevel Selector
7343 int32_t i, lvl;
7344 for(i = 0; i < MAX_DEBUG_LEVELS; i++)
7346 lvl = 1 << i;
7347 tpl_printf(vars, TPLADD, "TMPC", "DCLASS%d", lvl);
7348 tpl_printf(vars, TPLADD, "TMPV", "DEBUGVAL%d", lvl);
7349 if(cs_dblevel & lvl)
7351 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugls");
7352 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel - lvl);
7354 else
7356 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugl");
7357 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel + lvl);
7360 if(cs_dblevel == D_ALL_DUMP)
7361 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugls"); }
7362 else
7363 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugl"); }
7364 tpl_addVar(vars, TPLADD, "CUSTOMPARAM", "&file=logfile");
7365 tpl_printf(vars, TPLADD, "ACTDEBUG", "%d", cs_dblevel);
7366 #ifdef CS_CACHEEX_AIO
7367 tpl_addVar(vars, TPLADD, "SDEBUG", tpl_getTpl(vars, "DEBUGSELECTAIO"));
7368 #else
7369 tpl_addVar(vars, TPLADD, "SDEBUG", tpl_getTpl(vars, "DEBUGSELECT"));
7370 #endif
7371 tpl_addVar(vars, TPLADD, "NEXTPAGE", "files.html");
7372 #endif
7373 if(!cfg.disablelog)
7375 tpl_printf(vars, TPLADD, "SWITCH", "%d", 1);
7376 tpl_addVar(vars, TPLADD, "TEXT", "Stop Log");
7377 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUDISABLELOG"));
7380 else
7382 tpl_printf(vars, TPLADD, "SWITCH", "%d", 0);
7383 tpl_addVar(vars, TPLADD, "TEXT", "Start Log");
7384 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUDISABLELOG"));
7386 tpl_addVar(vars, TPLAPPEND, "LOGMENU", tpl_getTpl(vars, "CLEARLOG"));
7387 return;
7390 static void webif_process_userfile(struct templatevars * vars, struct uriparams * params, char *targetfile, size_t targetfile_len)
7392 snprintf(targetfile, targetfile_len, "%s", cfg.usrfile);
7393 if(strcmp(getParam(params, "clear"), "usrfile") == 0)
7395 if(cs_strlen(targetfile) > 0)
7397 FILE *file = fopen(targetfile, "w");
7398 fclose(file);
7401 if(!cfg.disableuserfile)
7403 tpl_printf(vars, TPLADD, "SWITCH", "%d", 1);
7404 tpl_addVar(vars, TPLADD, "TEXT", "Stop Log");
7405 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUONOFF"));
7407 else
7409 tpl_printf(vars, TPLADD, "SWITCH", "%d", 0);
7410 tpl_addVar(vars, TPLADD, "TEXT", "Start Log");
7411 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUONOFF"));
7413 tpl_addVar(vars, TPLAPPEND, "LOGMENU", tpl_getTpl(vars, "CLEARUSERLOG"));
7414 tpl_addVar(vars, TPLADD, "FFVAL", "all");
7415 tpl_addVar(vars, TPLADD, "FILTERFORMOPTIONS", tpl_getTpl(vars, "LOGMENUFILTERFORM"));
7416 struct s_auth *account;
7417 for(account = cfg.account; account; account = account->next)
7419 tpl_addVar(vars, TPLADD, "FFVAL", xml_encode(vars, account->usr));
7420 tpl_addVar(vars, TPLADD, "FFSEL", strcmp(getParam(params, "filter"), account->usr) ? "" : "selected");
7421 tpl_addVar(vars, TPLAPPEND, "FILTERFORMOPTIONS", tpl_getTpl(vars, "LOGMENUFILTERFORM"));
7423 tpl_addVar(vars, TPLADD, "FILTERFORM", tpl_getTpl(vars, "FILTERFORM"));
7426 enum file_types { FTYPE_CONFIG, FTYPE_VERSION, FTYPE_ANTICASC, FTYPE_LOGFILE, FTYPE_USERFILE , FTYPE_GBOX };
7428 struct files
7430 char *file;
7431 int menu_id;
7432 enum file_types type;
7435 static char *send_oscam_files(struct templatevars * vars, struct uriparams * params, int8_t apicall)
7437 bool writable = false;
7438 const struct files *entry;
7439 static struct files config_files[] =
7441 // id are used
7442 // new entry after last entry before first ifdef entry
7443 // ifdef must be add to end
7444 { "oscam.version", MNU_CFG_FVERSION, FTYPE_VERSION }, // id 0
7445 { "oscam.conf", MNU_CFG_FCONF, FTYPE_CONFIG }, // id 1
7446 { "oscam.user", MNU_CFG_FUSER, FTYPE_CONFIG }, // id 2
7447 { "oscam.server", MNU_CFG_FSERVER, FTYPE_CONFIG }, // id 3
7448 { "oscam.srvid", MNU_CFG_FSRVID, FTYPE_CONFIG }, // id 4
7449 { "oscam.srvid2", MNU_CFG_FSRVID2, FTYPE_CONFIG }, // id 5
7450 { "logfile", MNU_CFG_FLOGFILE, FTYPE_LOGFILE }, // id 6
7451 { "userfile", MNU_CFG_FUSERFILE, FTYPE_USERFILE }, // id 7
7452 { "css_file_name", MNU_CFG_FCSS, FTYPE_CONFIG }, // id 8
7453 { "oscam.services", MNU_CFG_FSERVICES, FTYPE_CONFIG }, // id 9
7454 { "oscam.provid", MNU_CFG_FPROVID, FTYPE_CONFIG }, // id 10
7455 { "oscam.tiers", MNU_CFG_FTIERS, FTYPE_CONFIG }, // id 11
7456 { "oscam.ratelimit", MNU_CFG_FRATELIMIT,FTYPE_CONFIG }, // id 12
7457 { "oscam.whitelist", MNU_CFG_FWHITELIST,FTYPE_CONFIG }, // id 13
7458 #ifdef HAVE_DVBAPI
7459 { "oscam.dvbapi", MNU_CFG_FDVBAPI, FTYPE_CONFIG }, // id 14
7460 #endif
7461 #ifdef CS_CACHEEX
7462 { "oscam.fakecws", MNU_CFG_FFAKECWS, FTYPE_CONFIG }, // id 15
7463 #endif
7464 #ifdef CS_ANTICASC
7465 { "anticasc", MNU_CFG_FACLOG, FTYPE_ANTICASC }, // id 16
7466 #endif
7467 #ifdef MODULE_SERIAL
7468 { "oscam.twin", MNU_CFG_FTWIN, FTYPE_CONFIG }, // id 17
7469 #endif
7470 #ifdef MODULE_CONSTCW
7471 { "constant.cw", MNU_CFG_FKEYCW, FTYPE_CONFIG }, // id 18
7472 #endif
7473 #ifdef MODULE_GBOX
7474 { "sc.info", MNU_GBX_FSCINF, FTYPE_GBOX }, // id 19
7475 { "share.info", MNU_GBX_FSHRINF, FTYPE_GBOX }, // id 20
7476 { "share.onl", MNU_GBX_FSHRONL, FTYPE_GBOX }, // id 21
7477 { "gbox.ver", MNU_GBX_FVERS, FTYPE_GBOX }, // id 22
7478 { "attack.txt", MNU_GBX_FATTACK, FTYPE_GBOX }, // id 23
7479 { "gsms.log", MNU_GBX_FSMSLOG, FTYPE_GBOX }, // id 24
7480 { "gsms.ack", MNU_GBX_FSMSACK, FTYPE_GBOX }, // id 25
7481 { "gsms.nack", MNU_GBX_FSMSNACK, FTYPE_GBOX }, // id 26
7482 { "stats.info", MNU_GBX_FSTAINF, FTYPE_GBOX }, // id 27
7483 { "expired.info", MNU_GBX_FEXPINF, FTYPE_GBOX }, // id 28
7484 { "info.log", MNU_GBX_INFOLOG, FTYPE_GBOX }, // id 29
7485 #endif
7486 #ifdef WITH_EMU
7487 { "SoftCam.Key", MNU_CFG_FSOFTCAMKEY,FTYPE_CONFIG }, // id 30
7488 #endif
7489 { NULL, 0, 0 },
7492 if(use_srvid2)
7494 config_files[4].menu_id = MNU_CFG_FSRVID2;
7495 config_files[5].menu_id = MNU_CFG_FSRVID;
7498 if(cfg.http_css)
7500 if(strchr(cfg.http_css,'/'))
7501 config_files[8].file = strrchr(cfg.http_css, '/')+1;
7502 else if(strchr(cfg.http_css,'\\'))
7503 config_files[8].file = strrchr(cfg.http_css, '\\')+1;
7504 else
7505 config_files[8].file = cfg.http_css;
7506 tpl_addVar(vars, TPLADD, "FILE_USER_CSS", xml_encode(vars, config_files[8].file));
7509 if(!apicall) { setActiveMenu(vars, MNU_FILES); }
7511 tpl_addVar(vars, TPLADD, "APIFILENAME", "null");
7512 tpl_addVar(vars, TPLADD, "APIWRITABLE", "0");
7514 if(use_srvid2)
7516 tpl_printf(vars, TPLADD, "SRVID", "%s", "oscam.srvid2");
7517 tpl_printf(vars, TPLADD, "SRVIDSUB", "%s", "oscam.srvid");
7519 else
7521 tpl_printf(vars, TPLADD, "SRVID", "%s", "oscam.srvid");
7522 tpl_printf(vars, TPLADD, "SRVIDSUB", "%s", "oscam.srvid2");
7525 char *stoplog = getParam(params, "stoplog");
7526 if(cs_strlen(stoplog) > 0)
7527 { cs_disable_log(atoi(stoplog)); }
7529 char *stopusrlog = getParam(params, "stopusrlog");
7530 if(cs_strlen(stopusrlog) > 0)
7531 { cfg.disableuserfile = atoi(stopusrlog); }
7533 char *debuglvl = getParam(params, "debug");
7534 if(cs_strlen(debuglvl) > 0)
7536 #ifndef WITH_DEBUG
7537 cs_log("*** Warning: Debug Support not compiled in ***");
7538 #else
7539 int32_t dblvl = atoi(debuglvl);
7540 if(dblvl >= 0 && dblvl <= 65535) { cs_dblevel = dblvl; }
7541 cs_log("%s debug_level=%d", "all", cs_dblevel);
7542 #endif
7544 // Process config files
7545 char *file = getParam(params, "file");
7546 char targetfile[256] = { 0 };
7547 int menu_id = 0;
7548 for(entry = config_files; entry->file; entry++)
7550 if(streq(file, entry->file))
7552 if(!apicall) { setActiveSubMenu(vars, entry->menu_id); }
7553 menu_id = entry->menu_id;
7554 tpl_addVar(vars, TPLADD, "APIWRITABLE", writable ? "1" : "0");
7555 switch(entry->type)
7557 case FTYPE_CONFIG:
7558 writable = 1;
7559 get_config_filename(targetfile, sizeof(targetfile), entry->file);
7560 break;
7561 case FTYPE_VERSION:
7562 get_tmp_dir_filename(targetfile, sizeof(targetfile), entry->file);
7563 break;
7564 case FTYPE_ANTICASC:
7565 #ifdef CS_ANTICASC
7566 if(!apicall) { snprintf(targetfile, sizeof(targetfile), "%s", ESTR(cfg.ac_logfile)); }
7567 #endif
7568 break;
7569 case FTYPE_LOGFILE:
7570 if(!apicall) { webif_process_logfile(vars, params, targetfile, sizeof(targetfile)); }
7571 break;
7572 case FTYPE_USERFILE:
7573 if(!apicall) { webif_process_userfile(vars, params, targetfile, sizeof(targetfile)); }
7574 break;
7575 case FTYPE_GBOX:
7576 #ifdef MODULE_GBOX
7577 get_gbox_filename(targetfile, sizeof(targetfile), entry->file);
7578 #endif
7579 break;
7581 tpl_addVar(vars, TPLADD, "APIFILENAME", entry->file);
7582 break;
7586 if(cfg.http_css)
7588 tpl_addVar(vars, TPLADD, "VIEW_FILEMENUCSS", tpl_getTpl(vars, "FILEMENUCSS"));
7591 if(!strstr(targetfile, "/dev/"))
7593 if(strcmp(getParam(params, "action"), "Save") == 0)
7595 if((cs_strlen(targetfile) > 0) /*&& (file_exists(targetfile) == 1)*/)
7597 FILE *fpsave;
7598 char *fcontent = getParam(params, "filecontent");
7599 if((fpsave = fopen(targetfile, "w")))
7601 int32_t i, lastpos = 0, len = cs_strlen(fcontent) + 1;
7602 //write submitted file line by line to disk and remove windows linebreaks
7603 for(i = 0; i < len; ++i)
7605 char tmp = fcontent[i];
7606 if(tmp == '\r' || tmp == '\n' || tmp == 0)
7608 fcontent[i] = 0;
7609 fprintf(fpsave, "%s%s", fcontent + lastpos, tmp == 0 ? "" : "\n");
7610 if(tmp == '\r' && fcontent[i + 1] == '\n') { ++i; }
7611 lastpos = i + 1;
7614 fclose(fpsave);
7615 tpl_addVar(vars, TPLAPPEND, "APIFILENAME", " saved!");
7616 // Reinit on save
7617 switch(menu_id)
7619 case MNU_CFG_FSRVID:
7620 case MNU_CFG_FSRVID2:
7621 init_srvid();
7622 break;
7623 case MNU_CFG_FPROVID:
7624 init_provid();
7625 break;
7626 case MNU_CFG_FUSER:
7627 cs_accounts_chk();
7628 break;
7629 case MNU_CFG_FDVBAPI:
7630 dvbapi_read_priority();
7631 break;
7632 case MNU_CFG_FWHITELIST:
7633 global_whitelist_read();
7634 break;
7635 case MNU_CFG_FFAKECWS:
7636 init_fakecws();
7637 break;
7638 default:
7639 break;
7645 if((cs_strlen(targetfile) > 0) && (file_exists(targetfile) == 1))
7647 FILE *fp;
7648 char buffer[256];
7650 if((fp = fopen(targetfile, "r")) == NULL) { return "0"; }
7651 while(fgets(buffer, sizeof(buffer), fp) != NULL)
7652 if(!strcmp(getParam(params, "filter"), "all"))
7653 { tpl_addVar(vars, TPLAPPEND, "FILECONTENT", buffer); }
7654 else if(strstr(buffer, getParam(params, "filter")))
7655 { tpl_addVar(vars, TPLAPPEND, "FILECONTENT", buffer); }
7656 fclose(fp);
7658 else
7660 tpl_addVar(vars, TPLAPPEND, "FILECONTENT", "File does not exist or no file selected!");
7663 else
7665 tpl_addVar(vars, TPLAPPEND, "FILECONTENT", "File not valid!");
7668 tpl_addVar(vars, TPLADD, "PART", file);
7670 if(!writable)
7672 tpl_addVar(vars, TPLADD, "WRITEPROTECTION", tpl_getTpl(vars, "WRITEPROTECTION"));
7673 tpl_addVar(vars, TPLADD, "BTNDISABLED", "DISABLED");
7676 if(!apicall)
7677 { return tpl_getTpl(vars, "FILE"); }
7678 else
7679 { return tpl_getTpl(vars, "APIFILE"); }
7682 static char *send_oscam_failban(struct templatevars * vars, struct uriparams * params, int8_t apicall)
7684 IN_ADDR_T ip2delete;
7685 set_null_ip(&ip2delete);
7686 LL_ITER itr = ll_iter_create(cfg.v_list);
7687 V_BAN *v_ban_entry;
7688 //int8_t apicall = 0; //remove before flight
7690 if(!apicall) { setActiveMenu(vars, MNU_FAILBAN); }
7692 if(strcmp(getParam(params, "action"), "delete") == 0)
7694 if(strcmp(getParam(params, "intip"), "all") == 0)
7696 // clear whole list
7697 while(ll_iter_next(&itr))
7699 ll_iter_remove_data(&itr);
7702 else
7704 //we have a single IP
7705 cs_inet_addr(getParam(params, "intip"), &ip2delete);
7706 while((v_ban_entry = ll_iter_next(&itr)))
7708 if(IP_EQUAL(v_ban_entry->v_ip, ip2delete))
7710 ll_iter_remove_data(&itr);
7711 break;
7716 ll_iter_reset(&itr);
7718 struct timeb now;
7719 cs_ftime(&now);
7721 while((v_ban_entry = ll_iter_next(&itr)))
7723 tpl_printf(vars, TPLADD, "IPADDRESS", "%s@%d", cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port);
7724 tpl_addVar(vars, TPLADD, "VIOLATIONUSER", v_ban_entry->info ? v_ban_entry->info : "unknown");
7725 struct tm st ;
7726 localtime_r(&v_ban_entry->v_time.time, &st); // fix me, we need walltime!
7727 if(!apicall)
7729 tpl_printf(vars, TPLADD, "VIOLATIONDATE", "%02d.%02d.%02d %02d:%02d:%02d",
7730 st.tm_mday, st.tm_mon + 1,
7731 st.tm_year % 100, st.tm_hour,
7732 st.tm_min, st.tm_sec);
7734 else
7736 char tbuffer [30];
7737 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &st);
7738 tpl_addVar(vars, TPLADD, "VIOLATIONDATE", tbuffer);
7741 tpl_printf(vars, TPLADD, "VIOLATIONCOUNT", "%d", v_ban_entry->v_count);
7743 int64_t gone = comp_timeb(&now, &v_ban_entry->v_time);
7744 if(!apicall)
7746 if(!v_ban_entry->acosc_entry)
7747 { tpl_addVar(vars, TPLADD, "LEFTTIME", sec2timeformat(vars, (cfg.failbantime * 60) - (gone / 1000))); }
7748 else
7749 { tpl_addVar(vars, TPLADD, "LEFTTIME", sec2timeformat(vars, v_ban_entry->acosc_penalty_dur - (gone / 1000))); }
7751 else
7753 if(!v_ban_entry->acosc_entry)
7754 { tpl_printf(vars, TPLADD, "LEFTTIME", "%"PRId64"", (cfg.failbantime * 60) - (gone / 1000)); }
7755 else
7756 { tpl_printf(vars, TPLADD, "LEFTTIME", "%"PRId64"", v_ban_entry->acosc_penalty_dur - (gone / 1000)); }
7759 tpl_addVar(vars, TPLADD, "INTIP", cs_inet_ntoa(v_ban_entry->v_ip));
7761 if(!apicall)
7762 { tpl_addVar(vars, TPLAPPEND, "FAILBANROW", tpl_getTpl(vars, "FAILBANBIT")); }
7763 else
7764 { tpl_addVar(vars, TPLAPPEND, "APIFAILBANROW", tpl_getTpl(vars, "APIFAILBANBIT")); }
7766 if(!apicall)
7767 { return tpl_getTpl(vars, "FAILBAN"); }
7768 else
7769 { return tpl_getTpl(vars, "APIFAILBAN"); }
7772 static bool send_EMM(struct s_reader * rdr, uint16_t caid, const struct s_cardsystem *csystem, const uint8_t *emmhex, uint32_t len)
7774 if(NULL != rdr && NULL != emmhex && 0 != len)
7776 EMM_PACKET *emm_pack = NULL;
7778 if(cs_malloc(&emm_pack, sizeof(EMM_PACKET)))
7780 struct s_client *webif_client = cur_client();
7781 webif_client->grp = 0xFF; /* to access to all readers */
7783 memset(emm_pack, '\0', sizeof(EMM_PACKET));
7784 emm_pack->client = webif_client;
7785 emm_pack->emmlen = len;
7786 memcpy(emm_pack->emm, emmhex, len);
7788 emm_pack->caid[0] = (caid >> 8) & 0xFF;
7789 emm_pack->caid[1] = caid & 0xFF;
7791 if(csystem && csystem->get_emm_type)
7793 if(!csystem->get_emm_type(emm_pack, rdr))
7795 rdr_log_dbg(rdr, D_EMM, "get_emm_type() returns error");
7799 cs_log_dbg(D_EMM, "emm is being sent to reader %s.", rdr->label);
7800 add_job(rdr->client, ACTION_READER_EMM, emm_pack, sizeof(EMM_PACKET));
7801 return true;
7805 return false;
7808 static bool process_single_emm(struct templatevars * vars, struct s_reader * rdr, uint16_t caid, const struct s_cardsystem *csystem, const char *ep)
7811 if(NULL != vars && NULL != rdr && NULL != ep)
7813 char emmdata[1025] = {'\0'}; /*1024 + '\0'*/
7814 uint8_t emmhex[513] = {'\0'};
7815 char buff[7] = {'\0'};
7816 uint16_t len = 0;
7817 cs_strncpy(emmdata, ep, sizeof(emmdata));
7818 remove_white_chars(emmdata);
7820 if('\0' != emmdata[0])
7822 len = cs_strlen(emmdata);
7823 tpl_addVar(vars, TPLADD, "EP", strtoupper(emmdata));
7824 if(key_atob_l(emmdata, emmhex, len))
7826 tpl_addMsg(vars, "Single EMM has not been sent due to wrong value!");
7828 else
7830 len /= 2;
7831 snprintf(buff, sizeof(buff), "0x%02X", len);
7832 tpl_addVar(vars, TPLADD, "EP", strtoupper(emmdata));
7833 tpl_addVar(vars, TPLADD, "SIZE", buff);
7835 if(send_EMM(rdr, caid, csystem, emmhex, len))
7837 tpl_addMsg(vars, "Single EMM has been sent.");
7838 return true;
7843 tpl_addVar(vars, TPLADD, "SIZE", "0x00");
7844 return false;
7847 static bool process_emm_file(struct templatevars * vars, struct s_reader * rdr, uint16_t caid, const struct s_cardsystem *csystem, const char *sFilePath)
7850 bool bret = false;
7851 uint32_t fsize = 0;
7852 uint32_t rlines = 0;
7853 uint32_t wemms = 0;
7854 uint32_t errsize = 0;
7855 char numerrl[256] = {'\0'};
7856 char buff[20] = {'\0'};
7858 if(NULL != rdr && NULL != sFilePath && '\0' != sFilePath[0])
7860 char sMessage[128] = {0};
7861 if(true == file_exists(sFilePath))
7863 FILE *fp;
7864 if((fp = fopen(sFilePath, "r")))
7866 char line[2048] = {'\0'};
7867 uint8_t emmhex[513] = {'\0'};
7868 uint32_t len = 0;
7870 tpl_addMsg(vars, "EMM file has been processed.");
7871 while(fgets(line, sizeof(line), fp))
7873 ++rlines;
7874 len = cs_strlen(remove_white_chars(line));
7876 // wrong emm
7877 if(len > (sizeof(emmhex) * 2) ||
7878 key_atob_l(line, emmhex, len))
7880 errsize += snprintf(numerrl + errsize, sizeof(numerrl) - errsize, "%d, ", rlines);
7881 continue;
7883 len /= 2;
7884 if(send_EMM(rdr, caid, csystem, emmhex, len))
7886 ++wemms;
7887 int32_t jcount = ll_count(rdr->client->joblist);
7888 if (jcount > 200)
7890 /* Give more time to process EMMs */
7891 cs_sleepms(1000);
7893 rdr_log_dbg(rdr, D_READER, "pending emm jobs: %i, processed emms: %i", jcount, wemms);
7896 fsize = ftell(fp);
7897 fclose(fp);
7899 else
7901 snprintf(sMessage, sizeof(sMessage), "Cannot open file '%s' (errno=%d: %s)\n", sFilePath, errno, strerror(errno));
7902 tpl_addMsg(vars, sMessage);
7905 else
7907 snprintf(sMessage, sizeof(sMessage), "FILE \"%s\" not found!", sFilePath);
7908 tpl_addMsg(vars, sMessage);
7910 bret = true;
7913 snprintf(buff, sizeof(buff), "%d bytes", fsize);
7914 tpl_addVar(vars, TPLADD, "FSIZE", buff);
7915 snprintf(buff, sizeof(buff), "%d", rlines);
7916 tpl_addVar(vars, TPLADD, "NUMRLINE", buff);
7917 snprintf(buff, sizeof(buff), "%d", wemms);
7918 tpl_addVar(vars, TPLADD, "NUMWEMM", buff);
7919 tpl_addVar(vars, TPLADD, "ERRLINE", numerrl);
7921 return bret;
7924 static char *send_oscam_EMM_running(struct templatevars * vars, struct uriparams * params)
7927 struct s_reader *rdr = NULL;
7929 setActiveMenu(vars, MNU_READERS);
7930 tpl_addVar(vars, TPLADD, "READER", getParam(params, "label"));
7931 tpl_addVar(vars, TPLADD, "FNAME", getParam(params, "emmfile"));
7933 rdr = get_reader_by_label(getParam(params, "label"));
7934 if(rdr)
7936 int32_t tcaid = dyn_word_atob(getParam(params, "emmcaid"));
7937 uint16_t caid = (-1 != tcaid) ? (uint16_t)tcaid : 0;
7938 char buff[7] = "";
7939 const struct s_cardsystem *csystem = NULL;
7940 int32_t proxy = is_cascading_reader(rdr);
7942 if((proxy || !rdr->csystem_active) && caid) // network reader (R_CAMD35 R_NEWCAMD R_CS378X R_CCCAM)
7944 if(proxy && !rdr->ph.c_send_emm)
7946 tpl_addMsg(vars, "The reader does not support EMM's!");
7947 return tpl_getTpl(vars, "EMM_RUNNING");
7950 csystem = get_cardsystem_by_caid(caid);
7951 if(!csystem)
7953 rdr_log_dbg(rdr, D_EMM, "unable to find cardsystem for caid %04X", caid);
7954 caid = 0;
7957 else if(!proxy && rdr->csystem_active) // local active reader
7959 csystem = rdr->csystem;
7961 if(rdr->typ != R_EMU)
7963 caid = rdr->caid;
7967 if(csystem)
7969 tpl_addVar(vars, TPLADD, "SYSTEM", csystem->desc);
7971 else
7973 tpl_addVar(vars, TPLADD, "SYSTEM", "unknown");
7975 if(caid)
7977 snprintf(buff, sizeof(buff), "0x%04X", caid);
7978 tpl_addVar(vars, TPLADD, "CAID", buff);
7980 else
7982 tpl_addVar(vars, TPLADD, "CAID", "unknown");
7985 process_single_emm(vars, rdr, caid, csystem, getParam(params, "ep"));
7986 process_emm_file(vars, rdr, caid, csystem, getParam(params, "emmfile"));
7988 else
7990 char sMessage[128] = {0};
7991 snprintf(sMessage, sizeof(sMessage), "READER \"%s\" not found!", getParam(params, "label"));
7992 tpl_addMsg(vars, sMessage);
7993 tpl_addVar(vars, TPLADD, "READER", "reader not found");
7996 return tpl_getTpl(vars, "EMM_RUNNING");
7999 static char *send_oscam_EMM(struct templatevars * vars, struct uriparams * params)
8002 setActiveMenu(vars, MNU_READERS);
8003 tpl_addVar(vars, TPLADD, "READER", getParam(params, "label"));
8005 struct s_reader *rdr = NULL;
8006 rdr = get_reader_by_label(getParam(params, "label"));
8007 if(rdr && rdr->caid)
8009 char buff[5] = "";
8010 snprintf(buff, sizeof(buff), "%04X", rdr->caid);
8011 tpl_addVar(vars, TPLADD, "CAID", buff);
8012 if(!is_cascading_reader(rdr))
8014 tpl_addVar(vars, TPLADD, "READONLY", "readonly=\"readonly\"");
8018 FILE *fp;
8019 struct stat sb;
8020 char buffer[1024];
8021 char emm_hex[1024];
8022 char filename[128];
8023 char targetfile[256];
8024 char tmpstr[20];
8025 char emm_txt[32];
8026 char emm_title[32];
8027 char *emm_path;
8028 char *emm_types[] = { "unique_emm", "shared_emm", "global_emm" };
8029 char *emm_names[] = { "RDREMMUNIQUE", "RDREMMSHARED", "RDREMMGLOBAL" };
8030 char *emm_cfg_names[] = { "httpemmuclean", "httpemmsclean", "httpemmgclean" };
8031 int32_t emm_max_size[] = { cfg.http_emmu_clean, cfg.http_emms_clean, cfg.http_emmg_clean };
8032 int num_emm_types = 3;
8033 int i;
8035 emm_path = cfg.emmlogdir ? cfg.emmlogdir : cs_confdir;
8037 for( i = 0 ; i < num_emm_types; i++ )
8039 snprintf(filename, sizeof(filename), "%s%s%s%s", getParam(params, "label"), "_", emm_types[i], ".log");
8040 snprintf(targetfile, sizeof(targetfile), "%s%s%s", emm_path, emm_path[cs_strlen(emm_path) - 1] == '/' ? "" : "/", filename);
8041 snprintf(emm_txt, sizeof(emm_txt), "%s_TXT", emm_names[i]);
8042 tpl_addVar(vars, TPLADD, emm_txt, filename);
8044 if((fp = fopen(targetfile, "r")) != NULL)
8046 stat(targetfile, &sb);
8047 tpl_printf(vars, TPLAPPEND, emm_txt, " (Size: %'.2f kB)", (double)sb.st_size/1024);
8049 if(emm_max_size[i]>=0)
8051 snprintf(emm_title, sizeof(emm_title), "%s_TITLE", emm_names[i]);
8052 tpl_addVar(vars, TPLADD, emm_title, "title=\"Click Line to Copy EMM in Single EMM Write Field\"");
8055 if(emm_max_size[i]>0)
8057 uint32_t emms=0, emm_d, emmrs=0;
8058 char *ptr, *saveptr1 = NULL;
8060 while(fgets(buffer, sizeof(buffer), fp) != NULL)
8062 emms++;
8063 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emms);
8064 tpl_addVar(vars, TPLADD, tmpstr, buffer);
8067 for(emm_d=emms;emm_d>0;--emm_d)
8069 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emm_d);
8070 if(sscanf(tpl_getVar(vars, tmpstr), "%*s %*s %*s %s", &emm_hex[0])==1)
8072 if(strstr(tpl_getVar(vars, "EMM_TMP"),emm_hex)==0)
8073 { tpl_addVar(vars, TPLAPPEND, "EMM_TMP", tpl_getVar(vars, tmpstr)); }
8074 tpl_addVar(vars, TPLADD, tmpstr, "");
8078 for(ptr = strtok_r(tpl_getVar(vars, "EMM_TMP"),"\n", &saveptr1); ptr; ptr = strtok_r(NULL,"\n", &saveptr1))
8080 emmrs++;
8081 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emmrs);
8082 tpl_addVar(vars, TPLADD, tmpstr, ptr);
8084 tpl_addVar(vars, TPLADD, "EMM_TMP", "");
8086 tpl_printf(vars, TPLAPPEND, emm_txt, ": %'d different EMM's from a total off %'d Entrys", emmrs,emms);
8087 for(emm_d=emmrs;emm_d>0;--emm_d)
8089 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emm_d);
8090 tpl_printf(vars, TPLAPPEND, emm_names[i], "<a class=\"tosingleemm\" href=\"#\">%s</a>\n", tpl_getVar(vars, tmpstr));
8091 if(sb.st_size>emm_max_size[i]*1024) { tpl_printf(vars, TPLAPPEND, "EMM_TMP", "%s\n", tpl_getVar(vars, tmpstr)); }
8092 tpl_addVar(vars, TPLADD, tmpstr, "");
8095 if(sb.st_size>emm_max_size[i]*1024)
8097 char orgfile[268];
8098 int f=0;
8099 do {
8100 snprintf(orgfile, sizeof(orgfile), "%s.%d", targetfile, f);
8101 f++;
8102 } while(access(orgfile, 0|F_OK) != -1);
8104 if(rename(targetfile, orgfile) == 0)
8106 FILE *fs = fopen(targetfile, "w");
8107 fprintf(fs, "%s", tpl_getVar(vars, "EMM_TMP"));
8108 fclose(fs);
8109 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);
8112 tpl_addVar(vars, TPLADD, "EMM_TMP", "");
8114 else if (emm_max_size[i]==0)
8116 while(fgets(buffer, sizeof(buffer), fp) != NULL)
8118 tpl_printf(vars, TPLAPPEND, emm_names[i], "<a class=\"tosingleemm\" href=\"#\">%s</a>", buffer);
8121 else
8123 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]);
8125 fclose(fp);
8127 if(strcmp(tpl_getVar(vars, emm_names[i]),"")==0) { tpl_addVar(vars, TPLADD, emm_names[i],"no saved EMM's"); }
8130 return tpl_getTpl(vars, "ASKEMM");
8133 #ifdef CS_CACHEEX
8134 static uint64_t get_cacheex_node(struct s_client * cl)
8136 uint64_t node = 0x00;
8137 #if defined(MODULE_CCCAM) || defined(MODULE_CAMD35) || defined(MODULE_CAMD35_TCP)
8138 struct s_module *module = (cl->reader ? &cl->reader->ph : get_module(cl));
8139 #endif
8140 #ifdef MODULE_CCCAM
8141 if(module->num == R_CCCAM && cl->cc)
8143 struct cc_data *cc = cl->cc;
8144 memcpy(&node, cc->peer_node_id, 8);
8146 else
8147 #endif
8148 #ifdef MODULE_CAMD35
8149 if(module->num == R_CAMD35)
8151 memcpy(&node, cl->ncd_skey, 8);
8153 else
8154 #endif
8155 #ifdef MODULE_CAMD35_TCP
8156 if(module->num == R_CS378X)
8158 memcpy(&node, cl->ncd_skey, 8);
8160 else
8161 #endif
8163 return node;
8167 static char *send_oscam_cacheex(struct templatevars * vars, struct uriparams * params, int8_t apicall)
8170 if(!apicall) { setActiveMenu(vars, MNU_CACHEEX); }
8172 if(strcmp(getParam(params, "x"), "x") == 0)
8174 // avoid compilerwarning unused vars
8176 char *level[] = {"NONE", "CACHE PULL", "CACHE PUSH", "REVERSE CACHE PUSH"};
8177 char *getting = "<IMG SRC=\"image?i=ICARRL\" ALT=\"Getting\">";
8178 char *pushing = "<IMG SRC=\"image?i=ICARRR\" ALT=\"Pushing\">";
8179 char *rowvariable = "";
8181 int16_t i, written = 0;
8182 struct s_client *cl;
8183 time_t now = time((time_t *)0);
8184 int delimiter=0;
8186 if(!apicall)
8188 if(strcmp(getParam(params, "action"), "resetallcacheexstats") == 0)
8190 cacheex_clear_all_stats();
8194 tpl_printf(vars, TPLADD, "OWN_CACHEEX_NODEID", "%" PRIu64 "X", cacheex_node_id(cacheex_peer_id));
8196 const char *cacheex_name_link_tpl = NULL;
8197 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
8199 for(i = 0, cl = first_client; cl ; cl = cl->next, i++)
8201 #ifdef CS_CACHEEX_AIO
8202 char classname[9];
8203 snprintf(classname, 8, "class%02d", i) < 0 ? abort() : (void)0;
8204 classname[8] = '\0';
8205 tpl_addVar(vars, TPLADD, "CLASSNAME", classname);
8206 #endif
8208 if(cl->typ == 'c' && cl->account && cl->account->cacheex.mode)
8210 cacheex_name_link_tpl = "SUSER";
8211 tpl_addVar(vars, TPLADD, "TYPE", "Client");
8212 if(!apicall)
8214 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, cl->account->usr));
8215 tpl_addVar(vars, TPLADD, "USERENC", urlencode(vars, cl->account->usr));
8217 if(cl->account->description)
8219 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->account->description));
8221 else
8223 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
8226 else
8228 tpl_addVar(vars, TPLADD, "NAME", cl->account->usr);
8230 if(cl->account->description)
8232 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", cl->account->description);
8234 else
8236 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
8240 tpl_addVar(vars, TPLADD, "IP", cs_inet_ntoa(cl->ip));
8241 tpl_printf(vars, TPLADD, "NODE", "%" PRIu64 "X", get_cacheex_node(cl));
8242 tpl_addVar(vars, TPLADD, "LEVEL", level[cl->account->cacheex.mode]);
8243 tpl_printf(vars, TPLADD, "PUSH", "%d", cl->account->cwcacheexpush);
8244 tpl_printf(vars, TPLADD, "GOT", "%d", cl->account->cwcacheexgot);
8245 tpl_printf(vars, TPLADD, "CWCINFO", "%d", cl->account->cwc_info);
8246 tpl_printf(vars, TPLADD, "HIT", "%d", cl->account->cwcacheexhit);
8247 tpl_printf(vars, TPLADD, "ERR", "%d", cl->account->cwcacheexerr);
8248 tpl_printf(vars, TPLADD, "ERRCW", "%d", cl->account->cwcacheexerrcw);
8249 #ifdef CS_CACHEEX_AIO
8250 tpl_printf(vars, TPLADD, "GOTLG", "%d", cl->account->cwcacheexgotlg);
8251 tpl_printf(vars, TPLADD, "PUSHLG", "%d", cl->account->cwcacheexpushlg);
8252 tpl_printf(vars, TPLADD, "REL_CACHEXHITGOT", "%.2f", (double)(cl->account->cwcacheexhit ? (double)cl->account->cwcacheexhit : 0) * 100 / (double)(cl->account->cwcacheexgot ? cl->account->cwcacheexgot : 1));
8253 #endif
8254 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", (cl->account->cacheex.mode == 3) ? getting : pushing);
8255 rowvariable = "TABLECLIENTROWS";
8256 written = 1;
8258 else if((cl->typ == 'p' || cl->typ == 'r') && (cl->reader && cl->reader->cacheex.mode))
8260 cacheex_name_link_tpl = "SREADER";
8261 tpl_addVar(vars, TPLADD, "TYPE", "Reader");
8263 if(!apicall)
8265 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, cl->reader->label));
8266 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, cl->reader->label));
8268 if(cl->reader->description)
8270 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->reader->description));
8272 else
8274 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
8277 else
8279 tpl_addVar(vars, TPLADD, "NAME", cl->reader->label);
8281 if(cl->reader->description)
8283 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", cl->reader->description);
8285 else
8287 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
8291 tpl_addVar(vars, TPLADD, "IP", cs_inet_ntoa(cl->ip));
8292 tpl_printf(vars, TPLADD, "NODE", "%" PRIu64 "X", get_cacheex_node(cl));
8293 tpl_addVar(vars, TPLADD, "LEVEL", level[cl->reader->cacheex.mode]);
8294 tpl_printf(vars, TPLADD, "PUSH", "%d", cl->cwcacheexpush);
8295 tpl_printf(vars, TPLADD, "CWCINFO", "%d", cl->cwc_info);
8296 tpl_printf(vars, TPLADD, "GOT", "%d", cl->cwcacheexgot);
8297 tpl_printf(vars, TPLADD, "CWCINFO", "%d", cl->cwc_info);
8298 tpl_printf(vars, TPLADD, "HIT", "%d", cl->cwcacheexhit);
8299 tpl_printf(vars, TPLADD, "ERR", "%d", cl->cwcacheexerr);
8300 tpl_printf(vars, TPLADD, "ERRCW", "%d", cl->cwcacheexerrcw);
8301 #ifdef CS_CACHEEX_AIO
8302 tpl_printf(vars, TPLADD, "GOTLG", "%d", cl->cwcacheexgotlg);
8303 tpl_printf(vars, TPLADD, "PUSHLG", "%d", cl->cwcacheexpushlg);
8304 tpl_printf(vars, TPLADD, "REL_CACHEXHITGOT", "%.2f", (double)(cl->cwcacheexhit ? (double)cl->cwcacheexhit : 0) * 100 / (double)(cl->cwcacheexgot ? cl->cwcacheexgot : 1));
8305 #endif
8306 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", (cl->reader->cacheex.mode == 3) ? pushing : getting);
8308 rowvariable = "TABLEREADERROWS";
8309 written = 1;
8311 else if(get_module(cl)->listenertype == LIS_CSPUDP)
8313 cacheex_name_link_tpl = "SREADER";
8314 tpl_addVar(vars, TPLADD, "TYPE", "csp");
8316 if(!apicall)
8318 tpl_addVar(vars, TPLADD, "READERNAME", "csp");
8319 tpl_addVar(vars, TPLADD, "READERNAMEENC", "csp");
8321 else
8323 tpl_addVar(vars, TPLADD, "NAME", "csp");
8326 tpl_addVar(vars, TPLADD, "IP", cs_inet_ntoa(cl->ip));
8327 tpl_addVar(vars, TPLADD, "NODE", "csp");
8329 if(cl->cwcacheexping)
8331 tpl_printf(vars, TPLADD, "LEVEL", "csp (%d ms)", cl->cwcacheexping);
8333 else
8335 tpl_addVar(vars, TPLADD, "LEVEL", "csp");
8338 tpl_printf(vars, TPLADD, "PUSH", "%d", cl->cwcacheexpush);
8339 tpl_printf(vars, TPLADD, "GOT", "%d", cl->cwcacheexgot);
8340 tpl_printf(vars, TPLADD, "HIT", "%d", cl->cwcacheexhit);
8341 tpl_printf(vars, TPLADD, "ERR", "%d", cl->cwcacheexerr);
8342 tpl_printf(vars, TPLADD, "ERRCW", "%d", cl->cwcacheexerrcw);
8343 #ifdef CS_CACHEEX_AIO
8344 tpl_printf(vars, TPLADD, "GOTLG", "%d", cl->cwcacheexgotlg);
8345 tpl_printf(vars, TPLADD, "PUSHLG", "%d", cl->cwcacheexpushlg);
8346 tpl_printf(vars, TPLADD, "REL_CACHEXHITGOT", "%.2f", (double)(cl->cwcacheexhit ? (double)cl->cwcacheexhit : 0) * 100 / (double)(cl->cwcacheexgot ? cl->cwcacheexgot : 1));
8347 #endif
8348 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", getting);
8349 rowvariable = "TABLECLIENTROWS";
8350 written = 1;
8353 if(written)
8355 if(!apicall)
8357 tpl_addVar(vars, TPLADD, "NAME", tpl_getTpl(vars, cacheex_name_link_tpl));
8359 #ifdef CS_CACHEEX_AIO
8360 tpl_addVar(vars, TPLAPPEND, rowvariable, tpl_getTpl(vars, "CACHEEXAIOTABLEROW"));
8361 #else
8362 tpl_addVar(vars, TPLAPPEND, rowvariable, tpl_getTpl(vars, "CACHEEXTABLEROW"));
8363 #endif
8365 if(cl->ll_cacheex_stats)
8367 LL_ITER itr = ll_iter_create(cl->ll_cacheex_stats);
8368 S_CACHEEX_STAT_ENTRY *cacheex_stats_entry;
8370 while((cacheex_stats_entry = ll_iter_next(&itr)))
8372 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", "");
8373 if(now - cacheex_stats_entry->cache_last < 20)
8374 { tpl_addVar(vars, TPLADD, "TYPE", cacheex_stats_entry->cache_direction == 0 ? pushing : getting); }
8375 else
8376 { tpl_addVar(vars, TPLADD, "TYPE", ""); }
8377 tpl_printf(vars, TPLADD, "NAME", "%04X@%06X:%04X", cacheex_stats_entry->cache_caid,
8378 cacheex_stats_entry->cache_prid,
8379 cacheex_stats_entry->cache_srvid);
8380 if(cacheex_stats_entry->cache_direction == 0)
8382 tpl_printf(vars, TPLADD, "PUSH", "%d", cacheex_stats_entry->cache_count);
8383 #ifdef CS_CACHEEX_AIO
8384 tpl_printf(vars, TPLADD, "PUSHLG", "%d", cacheex_stats_entry->cache_count_lg);
8385 #endif
8386 tpl_addVar(vars, TPLADD, "GOT", "");
8388 else
8390 tpl_printf(vars, TPLADD, "GOT", "%d", cacheex_stats_entry->cache_count);
8391 #ifdef CS_CACHEEX_AIO
8392 tpl_printf(vars, TPLADD, "GOTLG", "%d", cacheex_stats_entry->cache_count_lg);
8393 #endif
8394 tpl_addVar(vars, TPLADD, "PUSH", "");
8396 tpl_addVar(vars, TPLADD, "HIT", "");
8397 char channame[CS_SERVICENAME_SIZE];
8398 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)));
8399 tpl_addVar(vars, TPLADD, "LEVEL", lastchan);
8400 if (apicall == 2)
8402 tpl_printf(vars, TPLADD, "JSONDELIMITER", "%s", (delimiter > 1)?",":"");
8403 #ifdef CS_CACHEEX_AIO
8404 tpl_addVar(vars, TPLAPPEND, "JSONCACHEEXBITS", tpl_getTpl(vars, "JSONCACHEEXAIOBIT"));
8405 #else
8406 tpl_addVar(vars, TPLAPPEND, "JSONCACHEEXBITS", tpl_getTpl(vars, "JSONCACHEEXBIT"));
8407 #endif
8408 delimiter++;
8410 else
8412 #ifdef CS_CACHEEX_AIO
8413 tpl_addVar(vars, TPLAPPEND, rowvariable, tpl_getTpl(vars, "CACHEEXAIOTABLEROWSTATS"));
8414 #else
8415 tpl_addVar(vars, TPLAPPEND, rowvariable, tpl_getTpl(vars, "CACHEEXTABLEROW"));
8416 #endif
8420 written = 0;
8424 float cachesum = first_client ? first_client->cwcacheexgot : 1;
8425 if(cachesum < 1)
8427 cachesum = 1;
8429 tpl_printf(vars, TPLADD, "TOTAL_CACHEXPUSH", PRINTF_LOCAL_D, first_client ? first_client->cwcacheexpush : 0);
8430 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXPUSH_IMG", pushing);
8431 tpl_printf(vars, TPLADD, "TOTAL_CACHEXGOT", PRINTF_LOCAL_D, first_client ? first_client->cwcacheexgot : 0);
8432 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXGOT_IMG", getting);
8433 tpl_printf(vars, TPLADD, "TOTAL_CACHEXHIT", PRINTF_LOCAL_D, first_client ? first_client->cwcacheexhit : 0);
8434 tpl_printf(vars, TPLADD, "TOTAL_CACHESIZE", "%d", cache_size());
8435 #ifdef CS_CACHEEX_AIO
8436 tpl_printf(vars, TPLADD, "TOTAL_CACHESIZE_LG", "%d", cache_size_lg());
8437 #endif
8439 tpl_printf(vars, TPLADD, "REL_CACHEXHIT", "%.2f", (first_client ? first_client->cwcacheexhit : 0) * 100 / cachesum);
8441 if(!apicall)
8443 #ifdef CS_CACHEEX_AIO
8444 return tpl_getTpl(vars, "CACHEEXAIOPAGE");
8445 #else
8446 return tpl_getTpl(vars, "CACHEEXPAGE");
8447 #endif
8449 else
8451 return tpl_getTpl(vars, "JSONCACHEEX");
8454 #endif
8456 static char *send_oscam_api(struct templatevars * vars, FILE * f, struct uriparams * params, int8_t *keepalive, int8_t apicall, char *extraheader)
8458 if(strcmp(getParam(params, "part"), "status") == 0)
8460 return send_oscam_status(vars, params, apicall);
8462 else if(strcmp(getParam(params, "part"), "userstats") == 0)
8464 return send_oscam_user_config(vars, params, apicall);
8466 else if(strcmp(getParam(params, "part"), "failban") == 0)
8468 return send_oscam_failban(vars, params, apicall);
8470 #ifdef CS_CACHEEX
8471 else if(strcmp(getParam(params, "part"), "cacheex") == 0)
8473 return send_oscam_cacheex(vars, params, apicall);
8475 #endif
8476 else if(strcmp(getParam(params, "part"), "files") == 0)
8478 return send_oscam_files(vars, params, apicall);
8480 else if(strcmp(getParam(params, "part"), "readerlist") == 0)
8482 return send_oscam_reader(vars, params, apicall);
8484 else if(strcmp(getParam(params, "part"), "serverconfig") == 0)
8486 //Send Errormessage
8487 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "serverconfig not yet avail");
8488 return tpl_getTpl(vars, "APIERROR");
8490 else if(strcmp(getParam(params, "part"), "userconfig") == 0)
8492 if(((strcmp(getParam(params, "action"), "Save") == 0) ||
8493 (strcmp(getParam(params, "action"), "Save As") == 0)) && cfg.http_readonly == 1)
8495 //Send Errormessage
8496 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "API is in readonly mode");
8497 return tpl_getTpl(vars, "APIERROR");
8499 else
8501 struct s_auth *account = get_account_by_name(getParam(params, "user"));
8502 if(!account && strcmp(getParam(params, "action"), "Save"))
8504 //Send Errormessage
8505 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "user not exist");
8506 return tpl_getTpl(vars, "APIERROR");
8508 else
8510 return send_oscam_user_config_edit(vars, params, apicall);
8514 else if(strcmp(getParam(params, "part"), "entitlement") == 0)
8517 if(strcmp(getParam(params, "label"), ""))
8519 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
8520 if(rdr)
8522 if(rdr->enable == 1)
8524 return send_oscam_entitlement(vars, params, apicall);
8526 else
8528 //Send Errormessage
8529 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no cccam reader or disabled");
8530 return tpl_getTpl(vars, "APIERROR");
8533 else
8535 //Send Errormessage
8536 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "reader not exist");
8537 return tpl_getTpl(vars, "APIERROR");
8540 else
8542 //Send Errormessage
8543 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no reader selected");
8544 return tpl_getTpl(vars, "APIERROR");
8547 else if(strcmp(getParam(params, "part"), "ecmhistory") == 0)
8549 int32_t i;
8550 int32_t isec;
8551 int32_t shown;
8552 time_t now = time((time_t *)0);
8553 const char *usr;
8554 struct s_client *cl;
8555 for(i = 0, cl = first_client; cl ; cl = cl->next, i++)
8557 if(cl->wihidden != 1)
8559 isec = now - cl->lastecm;
8560 usr = username(cl);
8561 shown = 0;
8562 if(strcmp(getParam(params, "label"), "") == 0)
8564 if(strcmp(getParam(params, "type"), "servers") == 0)
8566 if(cl->typ == 'p' || cl->typ == 'r')
8567 { shown = 1; }
8569 else if(strcmp(getParam(params, "type"), "users") == 0)
8571 if(cl->typ == 'c')
8572 { shown = 1; }
8574 else
8576 shown = 1;
8579 else if(strcmp(getParam(params, "label"), usr) == 0)
8581 shown = 1;
8583 if(shown == 1)
8585 tpl_printf(vars, TPLADD, "CLIENTTYPE", "%c", cl->typ);
8586 tpl_addVar(vars, TPLADD, "CLIENTUSER", xml_encode(vars, usr));
8587 if(cl->typ == 'c' || cl->typ == 'm')
8589 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", xml_encode(vars, cl->account->description ? cl->account->description : ""));
8591 else if(cl->typ == 'p' || cl->typ == 'r')
8593 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", xml_encode(vars, cl->reader->description ? cl->reader->description : ""));
8595 tpl_printf(vars, TPLADD, "CLIENTLASTRESPONSETIME", "%d", cl->cwlastresptime ? cl->cwlastresptime : -1);
8596 tpl_printf(vars, TPLADD, "CLIENTIDLESECS", "%d", isec);
8598 //load historical values from ringbuffer
8599 char *value = get_ecm_fullhistorystring(cl);
8600 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIMEHIST", value);
8601 free_mk_t(value);
8603 tpl_addVar(vars, TPLAPPEND, "APISTATUSBITS", tpl_getTpl(vars, "APISTATUSBIT"));
8607 return tpl_getTpl(vars, "APISTATUS");
8609 else if(strcmp(getParam(params, "part"), "readerstats") == 0)
8611 if(strcmp(getParam(params, "label"), ""))
8613 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
8614 if(rdr)
8616 return send_oscam_reader_stats(vars, params, apicall);
8618 else
8620 //Send Errormessage
8621 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "reader not exist");
8622 return tpl_getTpl(vars, "APIERROR");
8625 else
8627 //Send Errormessage
8628 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no reader selected");
8629 return tpl_getTpl(vars, "APIERROR");
8632 else if(strcmp(getParam(params, "part"), "sendcmd") == 0)
8634 if(strcmp(getParam(params, "label"), ""))
8636 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
8637 if(rdr)
8639 char api_msg[150];
8640 CMD_PACKET *cmd_pack = NULL;
8641 if(!cs_malloc(&cmd_pack, sizeof(CMD_PACKET)))
8643 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "cs_malloc failed!");
8644 return tpl_getTpl(vars, "APIERROR");
8646 struct s_client *webif_client = cur_client();
8647 webif_client->grp = 0xFF; // access all readers
8649 memset(cmd_pack, '0', sizeof(CMD_PACKET));
8650 cmd_pack->client = webif_client;
8651 cmd_pack->cmdlen = strlen(getParam(params, "cmd")) / 2;
8653 if(cmd_pack->cmdlen > 0 && (unsigned long)abs(cmd_pack->cmdlen) <= sizeof(cmd_pack->cmd))
8655 if(key_atob_l(getParam(params, "cmd"), cmd_pack->cmd, cmd_pack->cmdlen*2))
8657 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "'cmd' has not been sent due to wrong value!");
8658 return tpl_getTpl(vars, "APIERROR");
8661 else
8663 if(cmd_pack->cmdlen)
8665 snprintf(api_msg, sizeof(api_msg), "Command would exceed %lu bytes!", (long unsigned int)sizeof(cmd_pack->cmd));
8666 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", api_msg);
8668 else
8670 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "Missing parameter 'cmd'!");
8672 return tpl_getTpl(vars, "APIERROR");
8675 struct s_client *cl = rdr->client;
8676 if(rdr->enable == 1 && cl && cl->typ == 'r')
8678 add_job(cl, ACTION_READER_SENDCMD, cmd_pack, sizeof(CMD_PACKET));
8679 tpl_addVar(vars, TPLADD, "APICONFIRMMESSAGE", "command sent");
8680 return tpl_getTpl(vars, "APICONFIRMATION");
8682 else
8684 snprintf(api_msg, sizeof(api_msg), "Reader '%s' is not suitable!", xml_encode(vars, rdr->label));
8685 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", api_msg);
8686 return tpl_getTpl(vars, "APIERROR");
8689 else
8691 //Send Errormessage
8692 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no such reader");
8693 return tpl_getTpl(vars, "APIERROR");
8696 else
8698 //Send Errormessage
8699 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no reader selected");
8700 return tpl_getTpl(vars, "APIERROR");
8703 else if(strcmp(getParam(params, "part"), "shutdown") == 0)
8705 if((strcmp(strtolower(getParam(params, "action")), "restart") == 0) ||
8706 (strcmp(strtolower(getParam(params, "action")), "shutdown") == 0))
8708 if(!cfg.http_readonly)
8710 return send_oscam_shutdown(vars, f, params, apicall, keepalive, extraheader);
8712 else
8714 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "webif readonly mode");
8715 return tpl_getTpl(vars, "APIERROR");
8718 else
8720 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "missing parameter action");
8721 return tpl_getTpl(vars, "APIERROR");
8725 else
8727 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "part not found");
8728 return tpl_getTpl(vars, "APIERROR");
8732 static char *send_oscam_image(struct templatevars * vars, FILE * f, struct uriparams * params, char *image, time_t modifiedheader, uint32_t etagheader, char *extraheader)
8734 char *wanted;
8735 if(image == NULL) { wanted = getParam(params, "i"); }
8736 else { wanted = image; }
8737 if(cs_strlen(wanted) > 3 && wanted[0] == 'I' && wanted[1] == 'C')
8739 if(etagheader == 0)
8741 int8_t disktpl = 0;
8742 char *tpl_path;
8743 tpl_path = cfg.http_piconpath? cfg.http_piconpath : cfg.http_tpl;
8745 if(tpl_path)
8747 char path[255];
8748 if(cs_strlen(tpl_getTplPath(wanted, tpl_path, path, 255)) > 0 && file_exists(path))
8750 struct stat st;
8751 disktpl = 1;
8752 stat(path, &st);
8753 if((time_t)st.st_mtime < modifiedheader)
8755 send_header304(f, extraheader);
8756 return "1";
8760 if(disktpl == 0 && first_client->login < modifiedheader)
8762 send_header304(f, extraheader);
8763 return "1";
8766 char *header = strstr(tpl_getTpl(vars, wanted), "data:");
8767 if(header != NULL)
8769 char *ptr = header + 5;
8770 while(ptr[0] != ';' && ptr[0] != '\0') { ++ptr; }
8771 if(ptr[0] != '\0' && ptr[1] != '\0') { ptr[0] = '\0'; }
8772 else { return "0"; }
8773 ptr = strstr(ptr + 1, "base64,");
8774 if(ptr != NULL)
8776 int32_t len = b64decode((uint8_t *)ptr + 7);
8777 if(len > 0)
8779 if((uint32_t)crc32(0L, (uint8_t *)ptr + 7, len) == etagheader)
8781 send_header304(f, extraheader);
8783 else
8785 send_headers(f, 200, "OK", extraheader, header + 5, 1, len, ptr + 7, 0);
8786 webif_write_raw(ptr + 7, f, len);
8788 return "1";
8793 // Return file not found
8794 const char *not_found = "File not found.\n";
8795 send_headers(f, 404, "Not Found", extraheader, "text/plain", 0, cs_strlen(not_found), (char *)not_found, 0);
8796 webif_write_raw((char *)not_found, f, cs_strlen(not_found));
8797 return "1";
8800 static char *send_oscam_robots_txt(FILE * f)
8802 const char *content = "User-agent: *\nDisallow: /\n";
8803 send_headers(f, 200, "OK", NULL, "text/plain", 0, cs_strlen(content), (char *)content, 0);
8804 webif_write_raw((char *)content, f, cs_strlen(content));
8805 return "1";
8808 static char *send_oscam_graph(struct templatevars * vars)
8810 return tpl_getTpl(vars, "GRAPH");
8813 #ifdef MODULE_GHTTP
8814 static bool ghttp_autoconf(struct templatevars * vars, struct uriparams * params)
8816 int8_t i = 0;
8817 struct s_reader *rdr;
8818 char *name = getParam(params, "gacname");
8819 if(cs_strlen(name) < 3)
8821 tpl_addMsg(vars, "Invalid host name!");
8822 return false;
8825 LL_ITER itr = ll_iter_create(configured_readers);
8826 while((rdr = ll_iter_next(&itr)))
8827 if(rdr->ph.num == R_GHTTP) { i++; } // count existing ghttp readers
8829 while(i < 3) // if less than 3, add more
8831 char lbl[128];
8832 snprintf(lbl, sizeof(lbl), "%s%d", "ghttp", i + 1);
8833 cs_log("GHttp autoconf: adding reader %s", lbl);
8834 struct s_reader *newrdr;
8835 if(!cs_malloc(&newrdr, sizeof(struct s_reader)))
8837 tpl_addMsg(vars, "Create reader failed!");
8838 return false;
8840 newrdr->typ = R_GHTTP;
8841 cs_strncpy(newrdr->label, lbl, sizeof(newrdr->label));
8842 module_reader_set(newrdr);
8843 reader_set_defaults(newrdr);
8844 newrdr->enable = 0;
8845 newrdr->grp = 1;
8846 ll_append(configured_readers, newrdr);
8847 i++;
8850 uint16_t port = 0;
8851 char *str = strstr(name, ":");
8852 if(str)
8854 port = atoi(str + 1);
8855 str[0] = '\0';
8858 i = 0;
8859 itr = ll_iter_create(configured_readers);
8860 while((rdr = ll_iter_next(&itr)))
8862 if(rdr->ph.num == R_GHTTP)
8864 if(i > 2) // remove superflous
8866 cs_log("GHttp autoconf: removing reader %s", rdr->label);
8867 inactivate_reader(rdr);
8868 ll_iter_remove(&itr);
8869 free_reader(rdr);
8871 else // reconfigure the 3 first ghttp readers
8873 cs_log("GHttp autoconf: reconfiguring reader %s", rdr->label);
8874 snprintf(rdr->label, sizeof(rdr->label), "%s%d", "ghttp", i + 1);
8875 rdr->r_port = port;
8876 rdr->enable = 1;
8877 rdr->ghttp_use_ssl = 0;
8878 #ifdef WITH_SSL
8879 rdr->ghttp_use_ssl = 1;
8880 #endif
8881 if(rdr->grp < 1) { rdr->grp = 1; }
8882 cs_strncpy(rdr->r_usr, getParam(params, "gacuser"), sizeof(rdr->r_usr));
8883 cs_strncpy(rdr->r_pwd, getParam(params, "gacpasswd"), sizeof(rdr->r_pwd));
8884 if(i == 0) { cs_strncpy(rdr->device, name, sizeof(rdr->device)); }
8885 else
8887 if(!strstr(name, "."))
8888 { snprintf(rdr->device, sizeof(rdr->device), "%s%d", name, i); } // name, name1, name2
8889 else { cs_strncpy(rdr->device, name, sizeof(rdr->device)); }
8890 // . in the name = assume full hostname = use same for all 3 readers
8892 if(i == 2) { rdr->fallback = 1; }
8893 else { rdr->fallback = 0; }
8894 i++;
8898 cs_log("GHttp autoconf: Saving %d readers", i);
8899 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
8900 itr = ll_iter_create(configured_readers);
8901 while((rdr = ll_iter_next(&itr)))
8903 if(rdr->ph.num == R_GHTTP)
8904 { restart_cardreader(rdr, 1); }
8906 return true;
8909 static char *send_oscam_ghttp(struct templatevars * vars, struct uriparams * params, int8_t apicall)
8911 if(strcmp(strtolower(getParam(params, "action")), "autoconf") == 0)
8913 if(!apicall)
8915 bool missing = false;
8916 if(cs_strlen(getParam(params, "gacuser")) == 0)
8918 tpl_addVar(vars, TPLADD, "USERREQ", "<FONT COLOR='red'>(Required)</FONT>");
8919 missing = true;
8921 else { tpl_addVar(vars, TPLADD, "GACUSER", getParam(params, "gacuser")); }
8922 if(cs_strlen(getParam(params, "gacpasswd")) == 0)
8924 tpl_addVar(vars, TPLADD, "PWDREQ", "<FONT COLOR='red'>(Required)</FONT>");
8925 missing = true;
8927 else { tpl_addVar(vars, TPLADD, "GACPASSWD", getParam(params, "gacpasswd")); }
8928 if(cs_strlen(getParam(params, "gacname")) == 0)
8930 tpl_addVar(vars, TPLADD, "NAMEREQ", "<FONT COLOR='red'>(Required)</FONT>");
8931 missing = true;
8933 else { tpl_addVar(vars, TPLADD, "GACNAME", getParam(params, "gacname")); }
8934 if(missing) { return tpl_getTpl(vars, "PREAUTOCONF"); }
8935 cs_log("GHttp autoconf requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
8937 else
8939 tpl_addVar(vars, TPLADD, "APICONFIRMMESSAGE", "autoconf");
8940 cs_log("GHttp autoconf requested by XMLApi from %s", cs_inet_ntoa(GET_IP()));
8943 if(ghttp_autoconf(vars, params))
8945 tpl_printf(vars, TPLADD, "REFRESHTIME", "%d", 3);
8946 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
8947 tpl_printf(vars, TPLADD, "SECONDS", "%d", 3);
8948 if(apicall) { return tpl_getTpl(vars, "APICONFIRMATION"); }
8949 else { return tpl_getTpl(vars, "AUTOCONF"); }
8951 else { return tpl_getTpl(vars, "PREAUTOCONF"); } // something failed
8954 else
8956 if(cs_strlen(getParam(params, "token")) > 0) // parse autoconf token
8958 char *token = getParam(params, "token");
8959 int32_t len = b64decode((uint8_t *)token);
8960 if(len > 0)
8962 struct uriparams tokenprms;
8963 tokenprms.paramcount = 0;
8964 parseParams(&tokenprms, token);
8965 if(cs_strlen(getParam(&tokenprms, "u")) > 0)
8967 tpl_addVar(vars, TPLADD, "GACUSER", getParam(&tokenprms, "u"));
8968 tpl_addVar(vars, TPLADD, "USERRDONLY", "readonly");
8970 if(cs_strlen(getParam(&tokenprms, "p")) > 0)
8972 tpl_addVar(vars, TPLADD, "GACPASSWD", getParam(&tokenprms, "p"));
8973 tpl_addVar(vars, TPLADD, "PWDRDONLY", "readonly");
8975 if(cs_strlen(getParam(&tokenprms, "n")) > 0)
8977 tpl_addVar(vars, TPLADD, "GACNAME", getParam(&tokenprms, "n"));
8978 tpl_addVar(vars, TPLADD, "NAMERDONLY", "readonly");
8982 return tpl_getTpl(vars, "PREAUTOCONF");
8985 #endif
8987 static int8_t check_httpip(IN_ADDR_T addr)
8989 int8_t i = 0;
8990 // check all previously dyndns resolved addresses
8991 for(i = 0; i < MAX_HTTP_DYNDNS; i++)
8993 if(IP_ISSET(cfg.http_dynip[i]) && IP_EQUAL(cfg.http_dynip[i], addr))
8994 { return 1; }
8996 return 0;
8999 static int8_t check_httpdyndns(IN_ADDR_T addr)
9002 // check all previously dyndns resolved addresses
9003 if(check_httpip(addr))
9004 { return 1; }
9006 // we are not ok, so resolve all dyndns entries into IP's - maybe outdated IP's
9008 if(cfg.http_dyndns[0][0])
9010 int8_t i = 0;
9011 for(i = 0; i < MAX_HTTP_DYNDNS; i++)
9013 if(cfg.http_dyndns[i][0])
9015 cs_resolve((const char *)cfg.http_dyndns[i], &cfg.http_dynip[i], NULL, NULL);
9016 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]));
9020 else
9022 cs_log_dbg(D_TRACE, "WebIf: No dyndns addresses found");
9023 return 0;
9026 // again check all dyndns resolved addresses
9027 if(check_httpip(addr))
9028 { return 1; }
9030 return 0;
9033 static int8_t check_valid_origin(IN_ADDR_T addr)
9036 // check whether requesting IP is in allowed IP ranges
9037 if(check_ip(cfg.http_allowed, addr))
9038 { return 1; }
9040 // we havn't found the requesting IP in allowed range. So we check for allowed httpdyndns as last chance
9041 if(cfg.http_dyndns[0][0])
9043 int8_t ok;
9044 ok = check_httpdyndns(addr);
9045 return ok;
9047 return 0;
9050 static int8_t check_request(char *result, int32_t readen)
9052 if(readen < 50) { return 0; }
9053 result[readen] = '\0';
9054 int8_t method;
9055 if(strncmp(result, "POST", 4) == 0) { method = 1; }
9056 else { method = 0; }
9057 char *headerEnd = strstr(result, "\r\n\r\n");
9058 if(headerEnd == NULL) { return 0; }
9059 else if(method == 0) { return 1; }
9060 else
9062 char *ptr = strstr(result, "Content-Length: ");
9063 if(ptr != NULL)
9065 ptr += 16;
9066 if(ptr < result + readen)
9068 uint32_t length = atoi(ptr);
9069 if(cs_strlen(headerEnd + 4) >= length) { return 1; }
9073 return 0;
9076 static int32_t readRequest(FILE * f, IN_ADDR_T in, char **result, int8_t forcePlain)
9078 int32_t n, bufsize = 0, errcount = 0;
9079 char buf2[1024];
9080 struct pollfd pfd2[1];
9081 #ifdef WITH_SSL
9082 int8_t is_ssl = 0;
9083 if(ssl_active && !forcePlain)
9084 { is_ssl = 1; }
9085 #endif
9087 while(1)
9089 errno = 0;
9090 if(forcePlain)
9091 { n = read(fileno(f), buf2, sizeof(buf2)); }
9092 else
9093 { n = webif_read(buf2, sizeof(buf2), f); }
9094 if(n <= 0)
9096 if((errno == 0 || errno == EINTR))
9098 if(errcount++ < 10)
9100 cs_sleepms(5);
9101 continue;
9103 else { return -1; }
9105 #ifdef WITH_SSL
9106 if(is_ssl)
9108 if(errno != ECONNRESET)
9110 int32_t errcode = ERR_peek_error();
9111 char errstring[128];
9112 ERR_error_string_n(errcode, errstring, sizeof(errstring) - 1);
9113 cs_log_dbg(D_TRACE, "WebIf: read error ret=%d (%d%s%s)", n, SSL_get_error(cur_ssl(), n), errcode ? " " : "", errcode ? errstring : "");
9115 return -1;
9117 #else
9118 if(errno != ECONNRESET)
9119 { cs_log_dbg(D_TRACE, "WebIf: read error ret=%d (errno=%d %s)", n, errno, strerror(errno)); }
9120 #endif
9121 return -1;
9123 if(!cs_realloc(result, bufsize + n + 1))
9125 send_error500(f);
9126 NULLFREE(*result);
9127 return -1;
9130 memcpy(*result + bufsize, buf2, n);
9131 bufsize += n;
9133 #ifdef WITH_EMU
9134 if(bufsize > 204800) // max request size 200kb
9135 #else
9136 if(bufsize > 102400) // max request size 100kb
9137 #endif
9139 cs_log("error: too much data received from %s", cs_inet_ntoa(in));
9140 NULLFREE(*result);
9141 *result = NULL;
9142 return -1;
9145 #ifdef WITH_SSL
9146 if(ssl_active && !forcePlain)
9148 int32_t len = 0;
9149 len = SSL_pending((SSL *)f);
9151 if(len > 0)
9152 { continue; }
9154 pfd2[0].fd = SSL_get_fd((SSL *)f);
9157 else
9158 #endif
9159 pfd2[0].fd = fileno(f);
9161 pfd2[0].events = (POLLIN | POLLPRI);
9163 int32_t rc = poll(pfd2, 1, 100);
9164 if(rc > 0 || !check_request(*result, bufsize))
9165 { continue; }
9166 else
9167 { break; }
9169 return bufsize;
9171 static int32_t process_request(FILE * f, IN_ADDR_T in)
9173 int32_t ok = 0;
9174 int8_t *keepalive = (int8_t *)pthread_getspecific(getkeepalive);
9175 IN_ADDR_T addr = GET_IP();
9179 #ifdef WITH_SSL
9180 if(!ssl_active && *keepalive) { fflush(f); }
9181 #else
9182 if(*keepalive) { fflush(f); }
9183 #endif
9185 // at this point we do all checks related origin IP, ranges and dyndns stuff
9186 ok = check_valid_origin(addr);
9187 cs_log_dbg(D_TRACE, "WebIf: Origin checked. Result: access from %s => %s", cs_inet_ntoa(addr), (!ok) ? "forbidden" : "allowed");
9189 // based on the failed origin checks we send a 403 to calling browser
9190 if(!ok)
9192 send_error(f, 403, "Forbidden", NULL, "Access denied.", 0);
9193 cs_log("unauthorized access from %s - invalid ip or dyndns", cs_inet_ntoa(addr));
9194 return 0;
9196 int32_t authok = 0;
9197 char expectednonce[(MD5_DIGEST_LENGTH * 2) + 1], opaque[(MD5_DIGEST_LENGTH * 2) + 1];
9198 char authheadertmp[sizeof(AUTHREALM) + sizeof(expectednonce) + sizeof(opaque) + 100];
9200 char *method, *path, *protocol, *str1, *saveptr1 = NULL, *authheader = NULL, *extraheader = NULL, *filebuf = NULL;
9201 char *pch, *tmp, *buf, *nameInUrl, subdir[32];
9202 /* List of possible pages */
9203 char *pages[] =
9205 "/config.html",
9206 "/readers.html",
9207 "/entitlements.html",
9208 "/status.html",
9209 "/userconfig.html",
9210 "/readerconfig.html",
9211 "/services.html",
9212 "/user_edit.html",
9213 "/site.css",
9214 "/services_edit.html",
9215 "/savetemplates.html",
9216 "/shutdown.html",
9217 "/script.html",
9218 "/scanusb.html",
9219 "/files.html",
9220 "/readerstats.html",
9221 "/failban.html",
9222 "/oscam.js",
9223 "/oscamapi.html",
9224 "/image",
9225 "/favicon.ico",
9226 "/graph.svg",
9227 "/oscamapi.xml",
9228 "/cacheex.html",
9229 "/oscamapi.json",
9230 "/emm.html",
9231 "/emm_running.html",
9232 "/robots.txt",
9233 "/ghttp.html",
9234 "/logpoll.html",
9235 "/jquery.js",
9238 int32_t pagescnt = sizeof(pages) / sizeof(char *); // Calculate the amount of items in array
9239 int32_t i, bufsize, len, pgidx = -1;
9240 uint32_t etagheader = 0;
9241 struct uriparams params;
9242 params.paramcount = 0;
9243 time_t modifiedheader = 0;
9245 bufsize = readRequest(f, in, &filebuf, 0);
9247 if(!filebuf || bufsize < 1)
9249 if(!*keepalive) { cs_log_dbg(D_CLIENT, "WebIf: No data received from client %s. Closing connection.", cs_inet_ntoa(addr)); }
9250 return -1;
9253 buf = filebuf;
9255 if((method = strtok_r(buf, " ", &saveptr1)) != NULL)
9257 if((path = strtok_r(NULL, " ", &saveptr1)) != NULL)
9259 if((protocol = strtok_r(NULL, "\r", &saveptr1)) == NULL)
9261 NULLFREE(filebuf);
9262 return -1;
9265 else
9267 NULLFREE(filebuf);
9268 return -1;
9271 else
9273 NULLFREE(filebuf);
9274 return -1;
9276 tmp = protocol + cs_strlen(protocol) + 2;
9278 pch = path;
9279 /* advance pointer to beginning of query string */
9280 while(pch[0] != '?' && pch[0] != '\0') { ++pch; }
9281 if(pch[0] == '?')
9283 pch[0] = '\0';
9284 ++pch;
9287 nameInUrl = pch - 1;
9288 while(nameInUrl != path && nameInUrl[0] != '/') { --nameInUrl; }
9290 /* allow only alphanumeric sub-folders */
9291 int32_t subdirLen = nameInUrl - path;
9292 subdir[0] = '\0';
9293 if(subdirLen > 0 && subdirLen < 32)
9295 cs_strncpy(subdir, path + 1, subdirLen);
9297 int32_t invalidSubdir = 0;
9298 for(i = 0; i < subdirLen - 1; i++)
9300 if(!((subdir[i] >= '0' && subdir[i] <= '9')
9301 || (subdir[i] >= 'a' && subdir[i] <= 'z')
9302 || (subdir[i] >= 'A' && subdir[i] <= 'Z')))
9305 invalidSubdir = 1;
9306 subdir[0] = '\0';
9307 break;
9311 if(!invalidSubdir)
9313 subdir[subdirLen] = '\0';
9314 #ifdef WIN32
9315 subdir[subdirLen - 1] = '\\';
9316 #else
9317 subdir[subdirLen - 1] = '/';
9318 #endif
9322 /* Map page to our static page definitions */
9323 for(i = 0; i < pagescnt; i++)
9325 if(!strcmp(nameInUrl, pages[i])) { pgidx = i; }
9328 parseParams(&params, pch);
9330 if(!cfg.http_user || !cfg.http_pwd)
9331 { authok = 1; }
9333 for(str1 = strtok_r(tmp, "\n", &saveptr1); str1; str1 = strtok_r(NULL, "\n", &saveptr1))
9335 len = cs_strlen(str1);
9336 if(str1[len - 1] == '\r')
9338 str1[len - 1] = '\0';
9339 --len;
9341 if(len == 0)
9343 if(strcmp(method, "POST") == 0)
9345 parseParams(&params, str1 + 2);
9347 break;
9349 if(!authok && len > 50 && strncasecmp(str1, "Authorization:", 14) == 0 && strstr(str1, "Digest") != NULL)
9351 if(cs_dblevel & D_CLIENT)
9353 if(cs_realloc(&authheader, len + 1))
9354 { cs_strncpy(authheader, str1, len); }
9356 authok = check_auth(str1, method, path, addr, expectednonce, opaque);
9358 else if(len > 40 && strncasecmp(str1, "If-Modified-Since:", 18) == 0)
9360 modifiedheader = parse_modifiedsince(str1);
9362 else if(len > 20 && strncasecmp(str1, "If-None-Match:", 14) == 0)
9364 for(pch = str1 + 14; pch[0] != '"' && pch[0] != '\0'; ++pch) { ; }
9365 if(cs_strlen(pch) > 5) { etagheader = (uint32_t)strtoul(++pch, NULL, 10); }
9367 else if(len > 12 && strncasecmp(str1, "Connection: Keep-Alive", 22) == 0 && strcmp(method, "POST"))
9369 *keepalive = 1;
9373 if(cfg.http_user && cfg.http_pwd)
9375 if (!authok || cs_strlen(opaque) != MD5_DIGEST_LENGTH * 2)
9377 calculate_opaque(addr, opaque);
9380 if (authok != 2)
9382 if(!authok)
9384 if(authheader)
9386 cs_log_dbg(D_CLIENT, "WebIf: Received wrong auth header from %s:", cs_inet_ntoa(addr));
9387 cs_log_dbg(D_CLIENT, "%s", authheader);
9389 else
9390 { cs_log_dbg(D_CLIENT, "WebIf: Received no auth header from %s.", cs_inet_ntoa(addr)); }
9392 calculate_nonce(NULL, expectednonce, opaque);
9395 if (authok != 1)
9397 snprintf(authheadertmp, sizeof(authheadertmp), "WWW-Authenticate: Digest algorithm=\"MD5\", realm=\"%s\", qop=\"auth\", opaque=\"%s\", nonce=\"%s\"", AUTHREALM, opaque, expectednonce);
9398 if (authok == 2)
9400 if (!cs_strncat(authheadertmp, ", stale=true", sizeof(authheadertmp))) {
9401 cs_log("WARNING, bug here!");
9405 else
9407 snprintf(authheadertmp, sizeof(authheadertmp), "Authentication-Info: nextnonce=\"%s\"", expectednonce);
9410 extraheader = authheadertmp;
9412 if (authok != 1)
9414 char *msg = "Access denied.\n";
9415 send_headers(f, 401, "Unauthorized", extraheader, "text/html", 0, cs_strlen(msg), msg, 0);
9416 webif_write(msg, f);
9417 NULLFREE(authheader);
9418 NULLFREE(filebuf);
9419 if (*keepalive) {
9420 continue;
9421 } else {
9422 return 0;
9426 else
9428 NULLFREE(authheader);
9431 /*build page*/
9432 if(pgidx == 8)
9434 send_file(f, "CSS", subdir, modifiedheader, etagheader, extraheader);
9436 else if(pgidx == 17)
9438 send_file(f, "JS", subdir, modifiedheader, etagheader, extraheader);
9440 else if(pgidx == 30)
9442 send_file(f, "JQ", subdir, modifiedheader, etagheader, extraheader);
9444 else
9446 time_t t;
9447 struct templatevars *vars = tpl_create();
9448 if(vars == NULL)
9450 send_error500(f);
9451 NULLFREE(filebuf);
9452 return 0;
9455 tpl_addVar(vars, TPLADD, "SUBDIR", subdir);
9457 struct tm lt, st;
9458 time(&t);
9460 localtime_r(&t, &lt);
9462 tpl_addVar(vars, TPLADD, "CS_VERSION", CS_VERSION);
9463 tpl_addVar(vars, TPLADD, "CS_SVN_VERSION", CS_SVN_VERSION);
9464 tpl_addVar(vars, TPLADD, "CS_TARGET", CS_TARGET);
9465 tpl_addVar(vars, TPLADD, "HTTPOSCAMLABEL", xml_encode(vars,cfg.http_oscam_label));
9466 if (!boxtype_is("generic"))
9468 if (!boxname_is("generic"))
9469 tpl_printf(vars, TPLADD, "DETECTED_BOXTYPE", "%s (%s)", boxtype_get(), boxname_get());
9470 else
9471 tpl_addVar(vars, TPLADD, "DETECTED_BOXTYPE", boxtype_get());
9474 if(cfg.http_locale){
9475 float decimal_point = 0.0;
9476 setlocale(LC_ALL, cfg.http_locale);
9477 tpl_printf(vars, TPLADD, "TMP_DECPOINT", "%.1f", decimal_point);
9478 tpl_addVar(vars, TPLADD, "LOCALE_DECPOINT", strstr(tpl_getVar(vars, "TMP_DECPOINT"), ",") ? ",": ".");
9481 tpl_addVar(vars, TPLADD, "HTTP_CHARSET", cs_http_use_utf8 ? "UTF-8" : "ISO-8859-1");
9482 if(cfg.http_picon_size > 0)
9484 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);
9486 if(cfg.poll_refresh > 0)
9488 tpl_printf(vars, TPLADD, "POLLREFRESHTIME", "%d", cfg.poll_refresh);
9490 if ( cfg.http_refresh > 0 &&
9491 ((( pgidx == 1 || pgidx == 4 ) && !cfg.poll_refresh ) ||
9492 ( pgidx == 3 && ( cfg.http_status_log || !cfg.poll_refresh )) ||
9493 pgidx == 15 || pgidx == 23 || pgidx == -1 )) // wenn polling bei cachex.html eingeführt wird muss die 23 => 2 zeilen höher
9495 tpl_printf(vars, TPLADD, "REFRESHTIME", "%d", cfg.http_refresh);
9496 tpl_addVar(vars, TPLADD, "WITHQUERY", pgidx == 15 ? "1" : "0");
9497 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
9499 #ifdef WEBIF_JQUERY
9500 tpl_printf(vars, TPLADD, "SRCJQUERY", "jquery.js?v=%s", CS_SVN_VERSION);
9501 #else
9502 tpl_addVar(vars, TPLADD, "SRCJQUERY", cfg.http_extern_jquery);
9503 #endif
9505 if(picon_exists("LOGO")||cs_strlen(tpl_getTpl(vars, "IC_LOGO"))>3)
9507 tpl_addVar(vars, TPLADD, "LOGO_INS", tpl_getTpl(vars, "LOGOBITIMG"));
9509 else
9511 tpl_addVar(vars, TPLADD, "LOGO_INS", tpl_getTpl(vars, "LOGOBITSVG"));
9513 tpl_addVar(vars, TPLADD, "LOGO", tpl_getTpl(vars, "LOGOBIT"));
9514 tpl_printf(vars, TPLADD, "CURDATE", "%02d.%02d.%02d", lt.tm_mday, lt.tm_mon + 1, lt.tm_year % 100);
9515 tpl_printf(vars, TPLADD, "CURTIME", "%02d:%02d:%02d", lt.tm_hour, lt.tm_min, lt.tm_sec);
9516 localtime_r(&first_client->login, &st);
9517 tpl_printf(vars, TPLADD, "STARTDATE", "%02d.%02d.%02d", st.tm_mday, st.tm_mon + 1, st.tm_year % 100);
9518 tpl_printf(vars, TPLADD, "STARTTIME", "%02d:%02d:%02d", st.tm_hour, st.tm_min, st.tm_sec);
9519 tpl_printf(vars, TPLADD, "PROCESSID", "%d", getppid());
9520 tpl_addVar(vars, TPLADD, "RUNAS", urlencode(vars, username(first_client)));
9522 time_t now = time((time_t *)0);
9523 // XMLAPI
9524 if(pgidx == 18 || pgidx == 22 || pgidx == 24)
9526 char tbuffer [30];
9527 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &st);
9528 tpl_addVar(vars, TPLADD, "APISTARTTIME", tbuffer);
9529 tpl_printf(vars, TPLADD, "APIRUNTIME", "%ld", now - first_client->login);
9530 tpl_printf(vars, TPLADD, "APIREADONLY", "%d", cfg.http_readonly);
9531 if(strcmp(getParam(&params, "callback"), ""))
9533 tpl_printf(vars, TPLADD, "CALLBACK", "%s%s", getParam(&params, "callback"), "(");
9534 tpl_addVar(vars, TPLADD, "ENDBRACKET", ")");
9539 if (config_enabled(WITH_LB))
9540 tpl_addVar(vars, TPLADD, "LBISDEFINED", "1");
9542 // language code in helplink
9543 tpl_addVar(vars, TPLADD, "LANGUAGE", cfg.http_help_lang);
9544 tpl_addVar(vars, TPLADD, "RUNTIME", sec2timeformat(vars, (now - first_client->login)));
9545 time_t uptime = oscam_get_uptime();
9546 if(uptime > 0){
9547 tpl_printf(vars, TPLADD, "UPTIMETXT", "%s Up Time: ", strcmp(tpl_getVar(vars, "DETECTED_BOXTYPE"),"")==0 ? "System" : tpl_getVar(vars, "DETECTED_BOXTYPE"));
9548 tpl_addVar(vars, TPLADD, "UPTIME", sec2timeformat(vars, uptime));
9550 tpl_addVar(vars, TPLADD, "CURIP", cs_inet_ntoa(addr));
9551 if(cfg.http_readonly)
9552 { tpl_addVar(vars, TPLAPPEND, "BTNDISABLED", "DISABLED"); }
9554 i = ll_count(cfg.v_list);
9555 if(i > 0) { tpl_printf(vars, TPLADD, "FAILBANNOTIFIER", "<SPAN CLASS=\"span_notifier\">%d</SPAN>", i); }
9556 tpl_printf(vars, TPLADD, "FAILBANNOTIFIERPOLL", "%d", i);
9558 char *result = NULL;
9560 // WebIf allows modifying many things. Thus, all pages except images/css/static are expected to be non-threadsafe!
9561 if(pgidx != 19 && pgidx != 20 && pgidx != 21 && pgidx != 27) { cs_writelock(__func__, &http_lock); }
9562 switch(pgidx)
9564 case 0:
9565 tpl_addVar(vars, TPLADD, "CONFIG_CONTENT", send_oscam_config(vars, &params));
9566 result = tpl_getTpl(vars, "CONFIGCONTENT");
9567 break;
9568 case 1:
9569 result = send_oscam_reader(vars, &params, 0);
9570 break;
9571 case 2:
9572 result = send_oscam_entitlement(vars, &params, 0);
9573 break;
9574 case 3:
9575 result = send_oscam_status(vars, &params, 0);
9576 break;
9577 case 4:
9578 result = send_oscam_user_config(vars, &params, 0);
9579 break;
9580 case 5:
9581 result = send_oscam_reader_config(vars, &params);
9582 break;
9583 case 6:
9584 result = send_oscam_services(vars, &params);
9585 break;
9586 case 7:
9587 result = send_oscam_user_config_edit(vars, &params, 0);
9588 break;
9589 //case 8: css file
9590 case 9:
9591 result = send_oscam_services_edit(vars, &params);
9592 break;
9593 case 10:
9594 result = send_oscam_savetpls(vars);
9595 break;
9596 case 11:
9597 result = send_oscam_shutdown(vars, f, &params, 0, keepalive, extraheader);
9598 break;
9599 case 12:
9600 result = send_oscam_script(vars, &params);
9601 break;
9602 case 13:
9603 result = send_oscam_scanusb(vars);
9604 break;
9605 case 14:
9606 result = send_oscam_files(vars, &params, 0);
9607 break;
9608 case 15:
9609 result = send_oscam_reader_stats(vars, &params, 0);
9610 break;
9611 case 16:
9612 result = send_oscam_failban(vars, &params, 0);
9613 break;
9614 //case 17: js file
9615 case 18:
9616 result = send_oscam_api(vars, f, &params, keepalive, 1, extraheader);
9617 break; //oscamapi.html
9618 case 19:
9619 result = send_oscam_image(vars, f, &params, NULL, modifiedheader, etagheader, extraheader);
9620 break;
9621 case 20:
9622 result = send_oscam_image(vars, f, &params, "ICMAI", modifiedheader, etagheader, extraheader);
9623 break;
9624 case 21:
9625 result = send_oscam_graph(vars);
9626 break;
9627 case 22:
9628 result = send_oscam_api(vars, f, &params, keepalive, 1, extraheader);
9629 break; //oscamapi.xml
9630 #ifdef CS_CACHEEX
9631 case 23:
9632 result = send_oscam_cacheex(vars, &params, 0);
9633 break;
9634 #endif
9635 case 24:
9636 result = send_oscam_api(vars, f, &params, keepalive, 2, extraheader);
9637 break; //oscamapi.json
9638 case 25:
9639 result = send_oscam_EMM(vars, &params);
9640 break; //emm.html
9641 case 26:
9642 result = send_oscam_EMM_running(vars, &params);
9643 break; //emm_running.html
9644 case 27:
9645 result = send_oscam_robots_txt(f);
9646 break; //robots.txt
9647 #ifdef MODULE_GHTTP
9648 case 28:
9649 result = send_oscam_ghttp(vars, &params, 0);
9650 break;
9651 #endif
9652 #ifdef WEBIF_LIVELOG
9653 case 29:
9654 result = send_oscam_logpoll(vars, &params);
9655 break;
9656 //case 30: jquery.js
9657 #endif
9658 default:
9659 result = send_oscam_status(vars, &params, 0);
9660 break;
9662 if(pgidx != 19 && pgidx != 20 && pgidx != 21 && pgidx != 27) { cs_writeunlock(__func__, &http_lock); }
9664 if(result == NULL || !strcmp(result, "0") || cs_strlen(result) == 0) { send_error500(f); }
9665 else if(strcmp(result, "1"))
9667 //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
9668 if(pgidx == 18)
9669 { send_headers(f, 200, "OK", extraheader, "text/xml", 0, cs_strlen(result), NULL, 0); }
9670 else if(pgidx == 21)
9671 { send_headers(f, 200, "OK", extraheader, "image/svg+xml", 0, cs_strlen(result), NULL, 0); }
9672 else if(pgidx == 24)
9673 { send_headers(f, 200, "OK", extraheader, "text/javascript", 0, cs_strlen(result), NULL, 0); }
9674 else
9675 { send_headers(f, 200, "OK", extraheader, "text/html", 0, cs_strlen(result), NULL, 0); }
9676 webif_write(result, f);
9678 tpl_clear(vars);
9680 NULLFREE(filebuf);
9682 while(*keepalive == 1 && !exit_oscam);
9683 return 0;
9686 static void *serve_process(void *conn)
9688 struct s_connection *myconn = (struct s_connection *)conn;
9689 int32_t s = myconn->socket;
9690 struct s_client *cl = myconn->cl;
9691 IN_ADDR_T in;
9692 IP_ASSIGN(in, myconn->remote);
9694 set_thread_name(__func__);
9696 #ifdef WITH_SSL
9697 SSL *ssl = myconn->ssl;
9698 SAFE_SETSPECIFIC(getssl, ssl);
9699 #endif
9700 NULLFREE(myconn);
9702 SAFE_SETSPECIFIC(getip, &in);
9703 SAFE_SETSPECIFIC(getclient, cl);
9705 int8_t keepalive = 0;
9706 SAFE_SETSPECIFIC(getkeepalive, &keepalive);
9708 #ifdef WITH_SSL
9709 if(ssl_active)
9711 if(SSL_set_fd(ssl, s))
9713 int32_t ok = (SSL_accept(ssl) != -1);
9714 if(!ok)
9716 int8_t tries = 100;
9717 while(!ok && tries--)
9719 int32_t err = SSL_get_error(ssl, -1);
9720 if(err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
9721 { break; }
9722 else
9724 struct pollfd pfd;
9725 pfd.fd = s;
9726 pfd.events = POLLIN | POLLPRI;
9727 int32_t rc = poll(&pfd, 1, -1);
9728 if(rc < 0)
9730 if(errno == EINTR || errno == EAGAIN) { continue; }
9731 break;
9733 if(rc == 1)
9734 { ok = (SSL_accept(ssl) != -1); }
9738 if(ok)
9740 process_request((FILE *)ssl, in);
9742 else
9744 FILE *f;
9745 f = fdopen(s, "r+");
9746 if(f != NULL)
9748 char *ptr, *filebuf = NULL, *host = NULL;
9749 int32_t bufsize = readRequest(f, in, &filebuf, 1);
9751 if(filebuf)
9753 filebuf[bufsize] = '\0';
9754 host = strstr(filebuf, "Host: ");
9755 if(host)
9757 host += 6;
9758 ptr = strchr(host, '\r');
9759 if(ptr) { ptr[0] = '\0'; }
9762 if(host)
9764 char extra[cs_strlen(host) + 20];
9765 snprintf(extra, sizeof(extra), "Location: https://%s", host);
9766 send_error(f, 301, "Moved Permanently", extra, "This web server is running in SSL mode.", 1);
9768 else
9769 { send_error(f, 200, "Bad Request", NULL, "This web server is running in SSL mode.", 1); }
9770 fflush(f);
9771 fclose(f);
9772 NULLFREE(filebuf);
9774 else
9776 cs_log_dbg(D_TRACE, "WebIf: fdopen(%d) failed. (errno=%d %s)", s, errno, strerror(errno));
9780 else { cs_log("WebIf: Error calling SSL_set_fd()."); }
9781 SSL_shutdown(ssl);
9782 close(s);
9783 SSL_free(ssl);
9785 else
9786 #endif
9788 FILE *f;
9789 f = fdopen(s, "r+");
9790 if(f != NULL)
9792 process_request(f, in);
9793 fflush(f);
9794 fclose(f);
9796 else
9798 cs_log_dbg(D_TRACE, "WebIf: fdopen(%d) failed. (errno=%d %s)", s, errno, strerror(errno));
9800 shutdown(s, SHUT_WR);
9801 close(s);
9804 return NULL;
9807 /* Creates a random string with specified length. Note that dst must be one larger than size to hold the trailing \0*/
9808 static void create_rand_str(char *dst, int32_t size)
9810 int32_t i;
9811 for(i = 0; i < size; ++i)
9813 dst[i] = (rand() % 94) + 32;
9815 dst[i] = '\0';
9818 static void *http_server(void *UNUSED(d))
9820 struct s_client *cl = create_client(first_client->ip);
9821 if(cl == NULL) { return NULL; }
9822 SAFE_SETSPECIFIC(getclient, cl);
9823 cl->typ = 'h';
9824 int32_t s, reuse = 1;
9825 struct s_connection *conn;
9827 set_thread_name(__func__);
9829 /* Create random string for nonce value generation */
9830 create_rand_str(noncekey, 32);
9832 /* Prepare base64 decoding array */
9833 b64prepare();
9834 webif_tpls_prepare();
9836 tpl_checkDiskRevisions();
9838 cs_lock_create(__func__, &http_lock, "http_lock", 10000);
9839 init_noncelocks();
9841 memset(&p_stat_cur, 0x0, sizeof(p_stat_cur));
9843 if(pthread_key_create(&getip, NULL))
9845 cs_log("Could not create getip");
9846 return NULL;
9848 if(pthread_key_create(&getkeepalive, NULL))
9850 cs_log("Could not create getkeepalive");
9851 return NULL;
9854 struct SOCKADDR sin;
9855 socklen_t len = 0;
9856 memset(&sin, 0, sizeof(sin));
9858 bool do_ipv6 = config_enabled(IPV6SUPPORT);
9859 #ifdef IPV6SUPPORT
9860 if(do_ipv6)
9862 len = sizeof(struct sockaddr_in6);
9863 if((sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0)
9865 cs_log("HTTP Server: ERROR: Creating IPv6 socket failed! (errno=%d %s)", errno, strerror(errno));
9866 cs_log("HTTP Server: Falling back to IPv4.");
9867 do_ipv6 = false;
9869 else
9871 struct sockaddr_in6 *ia = (struct sockaddr_in6 *)&sin;
9872 ia->sin6_family = AF_INET6;
9873 ia->sin6_addr = in6addr_any;
9874 ia->sin6_port = htons(cfg.http_port);
9877 #endif
9878 if(!do_ipv6)
9880 len = sizeof(struct sockaddr_in);
9881 if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
9883 cs_log("HTTP Server: ERROR: Creating socket failed! (errno=%d %s)", errno, strerror(errno));
9884 return NULL;
9886 SIN_GET_FAMILY(sin) = AF_INET;
9887 if(IP_ISSET(cfg.http_srvip))
9888 { IP_ASSIGN(SIN_GET_ADDR(sin), cfg.http_srvip); }
9889 else if(IP_ISSET(cfg.srvip))
9890 { IP_ASSIGN(SIN_GET_ADDR(sin), cfg.srvip); }
9891 // The default is INADDR_ANY (0)
9892 SIN_GET_PORT(sin) = htons(cfg.http_port);
9895 if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
9897 cs_log("HTTP Server: Setting SO_REUSEADDR via setsockopt failed! (errno=%d %s)", errno, strerror(errno));
9900 if(bind(sock, (struct sockaddr *)&sin, len) < 0)
9902 cs_log("HTTP Server couldn't bind on port %d (errno=%d %s). Not starting HTTP!", cfg.http_port, errno, strerror(errno));
9903 close(sock);
9904 return NULL;
9907 if(listen(sock, SOMAXCONN) < 0)
9909 cs_log("HTTP Server: Call to listen() failed! (errno=%d %s)", errno, strerror(errno));
9910 close(sock);
9911 return NULL;
9914 #ifdef WITH_SSL
9915 if(pthread_key_create(&getssl, NULL))
9917 cs_log("Could not create getssl");
9920 SSL_CTX *ctx = NULL;
9921 if(cfg.http_use_ssl)
9923 ctx = SSL_Webif_Init();
9924 if(ctx == NULL)
9925 { cs_log("SSL could not be initialized. Starting WebIf in plain mode."); }
9926 else { ssl_active = 1; }
9928 else { ssl_active = 0; }
9929 cs_log("HTTP Server running. ip=%s port=%d%s", cs_inet_ntoa(SIN_GET_ADDR(sin)), cfg.http_port, ssl_active ? " (SSL)" : "");
9930 #else
9931 cs_log("HTTP Server running. ip=%s port=%d", cs_inet_ntoa(SIN_GET_ADDR(sin)), cfg.http_port);
9932 #endif
9934 struct SOCKADDR remote;
9935 memset(&remote, 0, sizeof(remote));
9937 while(!exit_oscam)
9939 if((s = accept(sock, (struct sockaddr *) &remote, &len)) < 0)
9941 if(exit_oscam)
9942 { break; }
9943 if(errno != EAGAIN && errno != EINTR)
9945 cs_log("HTTP Server: Error calling accept() (errno=%d %s)", errno, strerror(errno));
9946 cs_sleepms(100);
9948 else { cs_sleepms(5); }
9949 continue;
9951 else
9953 getpeername(s, (struct sockaddr *) &remote, &len);
9954 if(!cs_malloc(&conn, sizeof(struct s_connection)))
9956 close(s);
9957 continue;
9959 setTCPTimeouts(s);
9960 cur_client()->last = time((time_t *)0); //reset last busy time
9961 conn->cl = cur_client();
9962 #ifdef IPV6SUPPORT
9963 if(do_ipv6)
9965 struct sockaddr_in6 *ra = (struct sockaddr_in6 *)&remote;
9966 memcpy(&conn->remote, &ra->sin6_addr, sizeof(struct in6_addr));
9968 else
9970 struct sockaddr_in *fba = (struct sockaddr_in *)&remote;
9971 struct in6_addr taddr;
9972 memset(&taddr, 0, sizeof(taddr));
9973 taddr.s6_addr32[3] = fba->sin_addr.s_addr;
9974 memcpy(&conn->remote, &taddr, sizeof(struct in6_addr));
9976 #else
9977 memcpy(&conn->remote, &remote.sin_addr, sizeof(struct in_addr));
9978 #endif
9979 conn->socket = s;
9980 #ifdef WITH_SSL
9981 conn->ssl = NULL;
9982 if(ssl_active)
9984 conn->ssl = SSL_new(ctx);
9985 if(conn->ssl == NULL)
9987 close(s);
9988 cs_log("WebIf: Error calling SSL_new().");
9989 continue;
9992 #endif
9994 int32_t ret = start_thread("webif workthread", serve_process, (void *)conn, NULL, 1, 1);
9995 if(ret)
9997 NULLFREE(conn);
10001 // Wait a bit so that we don't close ressources while http threads are active
10002 cs_sleepms(300);
10003 #ifdef WITH_SSL
10004 SSL_CTX_free(ctx);
10005 CRYPTO_set_dynlock_create_callback(NULL);
10006 CRYPTO_set_dynlock_lock_callback(NULL);
10007 CRYPTO_set_dynlock_destroy_callback(NULL);
10008 CRYPTO_set_locking_callback(NULL);
10009 CRYPTO_set_id_callback(NULL);
10010 OPENSSL_free(lock_cs);
10011 lock_cs = NULL;
10012 #endif
10013 cs_log("HTTP Server stopped");
10014 free_client(cl);
10015 close(sock);
10016 return NULL;
10019 void webif_client_reset_lastresponsetime(struct s_client * cl)
10021 int32_t i;
10022 for(i = 0; i < CS_ECM_RINGBUFFER_MAX; i++)
10024 cl->cwlastresptimes[i].duration = 0;
10025 cl->cwlastresptimes[i].timestamp = time((time_t *)0);
10026 cl->cwlastresptimes[i].rc = 0;
10028 cl->cwlastresptimes_last = 0;
10031 void webif_client_add_lastresponsetime(struct s_client * cl, int32_t ltime, time_t timestamp, int32_t rc)
10033 int32_t last = cl->cwlastresptimes_last = (cl->cwlastresptimes_last + 1) & (CS_ECM_RINGBUFFER_MAX - 1);
10034 cl->cwlastresptimes[last].duration = ltime > 9999 ? 9999 : ltime;
10035 cl->cwlastresptimes[last].timestamp = timestamp;
10036 cl->cwlastresptimes[last].rc = rc;
10039 void webif_client_init_lastreader(struct s_client * client, ECM_REQUEST * er, struct s_reader * er_reader, const char *stxt[])
10041 if(er_reader)
10043 if(er->rc == E_FOUND)
10044 { cs_strncpy(client->lastreader, er_reader->label, sizeof(client->lastreader)); }
10045 else if(er->rc == E_CACHEEX)
10046 { cs_strncpy(client->lastreader, "cache3", sizeof(client->lastreader)); }
10047 else if(er->rc < E_NOTFOUND)
10048 { snprintf(client->lastreader, sizeof(client->lastreader) - 1, "%.54s (cache)", er_reader->label); }
10049 else
10050 { cs_strncpy(client->lastreader, stxt[er->rc], sizeof(client->lastreader)); }
10052 else
10054 cs_strncpy(client->lastreader, stxt[er->rc], sizeof(client->lastreader));
10058 void webif_init(void)
10060 char buf[8], fname[256];
10061 snprintf(buf, 8, "%'d", 7);
10062 if(strcmp(buf, "7"))
10064 useLocal = 0;
10067 if(cfg.http_port == 0)
10069 cs_log("http disabled");
10070 return;
10073 get_config_filename(fname, sizeof(fname), "oscam.srvid2");
10074 use_srvid2 = file_exists(fname);
10076 if(start_thread("http", http_server, NULL, &httpthread, 0, 1) == 0)
10078 httpthread_running = 1;
10082 void webif_close(void)
10084 if(!sock)
10085 { return; }
10087 shutdown(sock, 2);
10088 close(sock);
10090 if(httpthread_running)
10091 { SAFE_THREAD_JOIN(httpthread, NULL); }
10094 #endif