added Streamrelay libdvbcsa - thanks to lpm11 <lpm11@lpm11>, fegol, icb, loka, kitte8...
[oscam.git] / module-webif.c
blob1e62ca2def4e06bfd6af217fd25059abbfee23d9
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);
1321 tpl_printf(vars, TPLADD, "TMP", "STREAMRELAYENABLEDSELECTED%d", cfg.stream_relay_enabled);
1322 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1324 value = mk_t_caidtab(&cfg.stream_relay_ctab);
1325 tpl_addVar(vars, TPLADD, "STREAM_RELAY_CTAB", value);
1326 free_mk_t(value);
1328 return tpl_getTpl(vars, "CONFIGSTREAMRELAY");
1330 #endif
1332 #ifdef MODULE_CCCAM
1333 static char *send_oscam_config_cccam(struct templatevars *vars, struct uriparams *params)
1336 setActiveSubMenu(vars, MNU_CFG_CCCAM);
1338 if(strcmp(getParam(params, "button"), "Refresh list") == 0)
1340 cs_log_dbg(D_TRACE, "Entitlements: Refresh Shares start");
1341 #ifdef MODULE_CCCSHARE
1342 refresh_shares();
1343 #endif
1344 cs_log_dbg(D_TRACE, "Entitlements: Refresh Shares finished");
1345 tpl_addMsg(vars, "Refresh Shares started");
1348 webif_save_config("cccam", vars, params);
1350 if(streq(getParam(params, "action"), "execute") && !cfg.http_readonly)
1351 { cc_update_nodeid(); }
1353 char *value = mk_t_cccam_port();
1354 tpl_addVar(vars, TPLAPPEND, "PORT", value);
1355 free_mk_t(value);
1357 if(IP_ISSET(cfg.cc_srvip))
1358 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.cc_srvip)); }
1360 tpl_printf(vars, TPLADD, "RESHARE", "%d", cfg.cc_reshare);
1362 if(!strcmp((char *)cfg.cc_version, "2.0.11"))
1364 tpl_addVar(vars, TPLADD, "VERSIONSELECTED0", "selected");
1366 else if(!strcmp((char *)cfg.cc_version, "2.1.1"))
1368 tpl_addVar(vars, TPLADD, "VERSIONSELECTED1", "selected");
1370 else if(!strcmp((char *)cfg.cc_version, "2.1.2"))
1372 tpl_addVar(vars, TPLADD, "VERSIONSELECTED2", "selected");
1374 else if(!strcmp((char *)cfg.cc_version, "2.1.3"))
1376 tpl_addVar(vars, TPLADD, "VERSIONSELECTED3", "selected");
1378 else if(!strcmp((char *)cfg.cc_version, "2.1.4"))
1380 tpl_addVar(vars, TPLADD, "VERSIONSELECTED4", "selected");
1382 else if(!strcmp((char *)cfg.cc_version, "2.2.0"))
1384 tpl_addVar(vars, TPLADD, "VERSIONSELECTED5", "selected");
1386 else if(!strcmp((char *)cfg.cc_version, "2.2.1"))
1388 tpl_addVar(vars, TPLADD, "VERSIONSELECTED6", "selected");
1390 else if(!strcmp((char *)cfg.cc_version, "2.3.0"))
1392 tpl_addVar(vars, TPLADD, "VERSIONSELECTED7", "selected");
1394 else if(!strcmp((char *)cfg.cc_version, "2.3.1"))
1396 tpl_addVar(vars, TPLADD, "VERSIONSELECTED8", "selected");
1398 else if(!strcmp((char *)cfg.cc_version, "2.3.2"))
1400 tpl_addVar(vars, TPLADD, "VERSIONSELECTED9", "selected");
1403 tpl_printf(vars, TPLADD, "UPDATEINTERVAL", "%d", cfg.cc_update_interval);
1404 tpl_printf(vars, TPLADD, "RECV_TIMEOUT", "%u", cfg.cc_recv_timeout);
1406 tpl_addVar(vars, TPLADD, "STEALTH", (cfg.cc_stealth == 1) ? "checked" : "");
1408 tpl_printf(vars, TPLADD, "NODEID", "%02X%02X%02X%02X%02X%02X%02X%02X",
1409 cfg.cc_fixed_nodeid[0], cfg.cc_fixed_nodeid[1], cfg.cc_fixed_nodeid[2], cfg.cc_fixed_nodeid[3],
1410 cfg.cc_fixed_nodeid[4], cfg.cc_fixed_nodeid[5], cfg.cc_fixed_nodeid[6], cfg.cc_fixed_nodeid[7]);
1412 tpl_printf(vars, TPLADD, "TMP", "MINIMIZECARDSELECTED%d", cfg.cc_minimize_cards);
1413 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1415 tpl_printf(vars, TPLADD, "TMP", "RESHAREMODE%d", cfg.cc_reshare_services);
1416 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1418 tpl_printf(vars, TPLADD, "TMP", "IGNRSHRSELECTED%d", cfg.cc_ignore_reshare);
1419 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1421 tpl_addVar(vars, TPLADD, "FORWARDORIGINCARD", (cfg.cc_forward_origin_card == 1) ? "checked" : "");
1423 tpl_addVar(vars, TPLADD, "KEEPCONNECTED", (cfg.cc_keep_connected == 1) ? "checked" : "");
1425 tpl_addVar(vars, TPLADDONCE, "CONFIG_CONTROL", tpl_getTpl(vars, "CONFIGCCCAMCTRL"));
1427 return tpl_getTpl(vars, "CONFIGCCCAM");
1429 #endif
1431 static bool is_ext(const char *path, const char *ext)
1433 size_t lenpath = cs_strlen(path);
1434 size_t lenext = cs_strlen(ext);
1435 if(lenext > lenpath)
1436 { return 0; }
1437 return memcmp(path + lenpath - lenext, ext, lenext) == 0;
1440 static char *send_oscam_config_webif(struct templatevars *vars, struct uriparams *params)
1442 int32_t i;
1444 setActiveSubMenu(vars, MNU_CFG_WEBIF);
1446 webif_save_config("webif", vars, params);
1448 tpl_printf(vars, TPLADD, "HTTPPORT", "%s%d", cfg.http_use_ssl ? "+" : "", cfg.http_port);
1449 if(IP_ISSET(cfg.http_srvip))
1450 { tpl_addVar(vars, TPLAPPEND, "SERVERIP", cs_inet_ntoa(cfg.http_srvip)); }
1452 tpl_addVar(vars, TPLADD, "HTTPUSER", cfg.http_user);
1453 tpl_addVar(vars, TPLADD, "HTTPPASSWORD", cfg.http_pwd);
1454 tpl_addVar(vars, TPLADD, "HTTPOSCAMLABEL", cfg.http_oscam_label);
1456 // css style selector
1457 tpl_printf(vars, TPLADD, "CSSOPTIONS", "\t\t\t\t\t\t<option value=\"\"%s>embedded</option>\n",
1458 !cfg.http_css ? " selected" : "");
1460 if(cfg.http_tpl)
1462 char path[255];
1463 tpl_getFilePathInSubdir(cfg.http_tpl, "", "style", ".css", path, 255);
1464 if(file_exists(path))
1465 tpl_printf(vars, TPLAPPEND, "CSSOPTIONS", "\t\t\t\t\t\t<option value=\"%s\"%s>%s (template)</option>\n",
1466 path,
1467 cfg.http_css && strstr(cfg.http_css, path) ? " selected" : "",
1468 path);
1471 struct dirent **namelist;
1472 int count;
1473 count = scandir(cs_confdir, &namelist, 0, alphasort );
1475 if( count >= 0 )
1477 for( i = 0 ; i < count; i++ )
1479 if(is_ext(namelist[i]->d_name, ".css"))
1481 tpl_printf(vars, TPLAPPEND, "CSSOPTIONS", "\t\t\t\t\t\t<option value=\"%s%s\"%s>%s%s</option>\n",
1482 cs_confdir,
1483 namelist[i]->d_name,
1484 cfg.http_css && strstr(cfg.http_css, namelist[i]->d_name) ? " selected" : "",
1485 cs_confdir, namelist[i]->d_name);
1487 free( namelist[i] );
1489 free(namelist);
1492 if(cfg.http_prepend_embedded_css)
1493 { tpl_addVar(vars, TPLADD, "HTTPPREPENDEMBEDDEDCSS", "checked"); }
1495 tpl_addVar(vars, TPLADD, "HTTPHELPLANG", cfg.http_help_lang);
1496 tpl_addVar(vars, TPLADD, "HTTPLOCALE", cfg.http_locale);
1497 tpl_printf(vars, TPLADD, "HTTPEMMUCLEAN", "%d", cfg.http_emmu_clean);
1498 tpl_printf(vars, TPLADD, "HTTPEMMSCLEAN", "%d", cfg.http_emms_clean);
1499 tpl_printf(vars, TPLADD, "HTTPEMMGCLEAN", "%d", cfg.http_emmg_clean);
1500 tpl_printf(vars, TPLADD, "HTTPREFRESH", "%d", cfg.http_refresh);
1501 tpl_printf(vars, TPLADD, "HTTPPOLLREFRESH", "%d", cfg.poll_refresh);
1502 tpl_addVar(vars, TPLADD, "HTTPTPL", cfg.http_tpl);
1503 tpl_addVar(vars, TPLADD, "HTTPPICONPATH", cfg.http_piconpath);
1504 tpl_addVar(vars, TPLADD, "HTTPSCRIPT", cfg.http_script);
1505 tpl_addVar(vars, TPLADD, "HTTPJSCRIPT", cfg.http_jscript);
1506 #ifndef WEBIF_JQUERY
1507 tpl_addVar(vars, TPLADD, "HTTPEXTERNJQUERY", cfg.http_extern_jquery);
1508 #endif
1509 tpl_printf(vars, TPLADD, "HTTPPICONSIZE", "%d", cfg.http_picon_size);
1511 if(cfg.http_hide_idle_clients > 0) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
1512 tpl_addVar(vars, TPLADD, "HTTPHIDETYPE", cfg.http_hide_type);
1513 if(cfg.http_status_log > 0) { tpl_addVar(vars, TPLADD, "SHOWLOGCHECKED", "checked"); }
1514 if(cfg.http_showpicons > 0) { tpl_addVar(vars, TPLADD, "SHOWPICONSCHECKED", "checked"); }
1515 if(cfg.http_showmeminfo > 0) { tpl_addVar(vars, TPLADD, "SHOWMEMINFOCHECKED", "checked"); }
1516 if(cfg.http_showuserinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWUSERINFOCHECKED", "checked"); }
1517 if(cfg.http_showreaderinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWREADERINFOCHECKED", "checked"); }
1518 if(cfg.http_showcacheexinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWCACHEEXINFOCHECKED", "checked"); }
1519 if(cfg.http_showloadinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWLOADINFOCHECKED", "checked"); }
1520 if(cfg.http_showecminfo > 0) { tpl_addVar(vars, TPLADD, "SHOWECMINFOCHECKED", "checked"); }
1522 char *value = mk_t_iprange(cfg.http_allowed);
1523 tpl_addVar(vars, TPLADD, "HTTPALLOW", value);
1524 free_mk_t(value);
1526 for(i = 0; i < MAX_HTTP_DYNDNS; i++)
1528 if(cfg.http_dyndns[i][0])
1530 tpl_addVar(vars, TPLAPPEND, "HTTPDYNDNS", i > 0 ? "," : "");
1531 tpl_addVar(vars, TPLAPPEND, "HTTPDYNDNS", (char *)cfg.http_dyndns[i]);
1535 tpl_addVar(vars, TPLADD, "HTTPSAVEFULLSELECT", (cfg.http_full_cfg == 1) ? "checked" : "");
1536 tpl_addVar(vars, TPLADD, "HTTPOVERWRITEBAKFILE", (cfg.http_overwrite_bak_file == 1) ? "checked" : "");
1537 tpl_addVar(vars, TPLADD, "HTTPREADONLY", (cfg.http_readonly == 1) ? "checked" : "");
1540 #ifdef WITH_SSL
1541 if(cfg.http_cert != NULL) { tpl_addVar(vars, TPLADD, "HTTPCERT", cfg.http_cert); }
1542 tpl_addVar(vars, TPLADD, "HTTPFORCESECUREMODESELECT", (cfg.https_force_secure_mode == 1) ? "checked" : "");
1543 #endif
1545 #ifndef WEBIF_JQUERY
1546 tpl_addVar(vars, TPLADDONCE, "CONFIGWEBIFJQUERY", tpl_getTpl(vars, "CONFIGWEBIFJQUERYBIT"));
1547 #endif
1549 tpl_printf(vars, TPLADD, "AULOW", "%d", cfg.aulow);
1550 tpl_printf(vars, TPLADD, "HIDECLIENTTO", "%d", cfg.hideclient_to);
1552 return tpl_getTpl(vars, "CONFIGWEBIF");
1555 #ifdef LCDSUPPORT
1556 static char *send_oscam_config_lcd(struct templatevars *vars, struct uriparams *params)
1558 setActiveSubMenu(vars, MNU_CFG_LCD);
1560 webif_save_config("lcd", vars, params);
1562 tpl_addVar(vars, TPLADD, "ENABLELCDSELECTED", (cfg.enablelcd == 1) ? "checked" : "");
1564 if(cfg.lcd_output_path != NULL)
1565 { tpl_addVar(vars, TPLADD, "LCDOUTPUTPATH", cfg.lcd_output_path); }
1567 tpl_addVar(vars, TPLADD, "LCDHIDEIDLE", (cfg.lcd_hide_idle == 1) ? "checked" : "");
1569 tpl_printf(vars, TPLADD, "LCDREFRESHINTERVAL", "%d", cfg.lcd_write_intervall);
1571 return tpl_getTpl(vars, "CONFIGLCD");
1573 #endif
1575 #ifdef MODULE_MONITOR
1576 static char *send_oscam_config_monitor(struct templatevars *vars, struct uriparams *params)
1578 setActiveSubMenu(vars, MNU_CFG_MONITOR);
1580 webif_save_config("monitor", vars, params);
1582 tpl_printf(vars, TPLADD, "MONPORT", "%d", cfg.mon_port);
1583 if(IP_ISSET(cfg.mon_srvip))
1584 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.mon_srvip)); }
1586 tpl_printf(vars, TPLADD, "AULOW", "%d", cfg.aulow);
1587 tpl_printf(vars, TPLADD, "HIDECLIENTTO", "%d", cfg.hideclient_to);
1589 char *value = mk_t_iprange(cfg.mon_allowed);
1590 tpl_addVar(vars, TPLADD, "NOCRYPT", value);
1591 free_mk_t(value);
1593 //Monlevel selector
1594 tpl_printf(vars, TPLADD, "TMP", "MONSELECTED%d", cfg.mon_level);
1595 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1597 return tpl_getTpl(vars, "CONFIGMONITOR");
1599 #endif
1601 #ifdef MODULE_SERIAL
1602 static char *send_oscam_config_serial(struct templatevars *vars, struct uriparams *params)
1604 setActiveSubMenu(vars, MNU_CFG_SERIAL);
1606 webif_save_config("serial", vars, params);
1608 if(cfg.ser_device)
1610 char sdevice[cs_strlen(cfg.ser_device)];
1611 cs_strncpy(sdevice, cfg.ser_device, sizeof(sdevice));
1612 char *ptr, *saveptr1 = NULL;
1613 char delimiter[2];
1614 delimiter[0] = 1;
1615 delimiter[1] = '\0';
1616 for(ptr = strtok_r(sdevice, delimiter, &saveptr1); ptr; ptr = strtok_r(NULL, delimiter, &saveptr1))
1618 tpl_addVar(vars, TPLADD, "SERIALDEVICE", xml_encode(vars, ptr));
1619 tpl_addVar(vars, TPLAPPEND, "DEVICES", tpl_getTpl(vars, "CONFIGSERIALDEVICEBIT"));
1623 tpl_addVar(vars, TPLADD, "SERIALDEVICE", "");
1624 tpl_addVar(vars, TPLAPPEND, "DEVICES", tpl_getTpl(vars, "CONFIGSERIALDEVICEBIT"));
1626 return tpl_getTpl(vars, "CONFIGSERIAL");
1628 #endif
1630 #ifdef HAVE_DVBAPI
1631 extern const char *boxdesc[];
1633 static char *send_oscam_config_dvbapi(struct templatevars *vars, struct uriparams *params)
1635 int32_t i;
1637 setActiveSubMenu(vars, MNU_CFG_DVBAPI);
1639 webif_save_config("dvbapi", vars, params);
1641 if(cfg.dvbapi_enabled > 0)
1642 { tpl_addVar(vars, TPLADD, "ENABLEDCHECKED", "checked"); }
1644 if(cfg.dvbapi_au > 0)
1645 { tpl_addVar(vars, TPLADD, "AUCHECKED", "checked"); }
1647 if(cfg.dvbapi_delayer > 0)
1648 { tpl_printf(vars, TPLADD, "DELAYER", "%d", cfg.dvbapi_delayer); }
1650 tpl_printf(vars, TPLADD, "BOXTYPE", "<option value=\"\"%s>None</option>\n", cfg.dvbapi_boxtype == 0 ? " selected" : "");
1651 for(i = 1; i <= BOXTYPES; i++)
1653 tpl_printf(vars, TPLAPPEND, "BOXTYPE", "<option%s>%s</option>\n", cfg.dvbapi_boxtype == i ? " selected" : "", boxdesc[i]);
1656 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, cfg.dvbapi_usr));
1658 //PMT Mode
1659 tpl_printf(vars, TPLADD, "TMP", "PMTMODESELECTED%d", cfg.dvbapi_pmtmode);
1660 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1662 //Request Mode
1663 tpl_printf(vars, TPLADD, "TMP", "REQMODESELECTED%d", cfg.dvbapi_requestmode);
1664 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1666 //ecminfo_file
1667 if(cfg.dvbapi_ecminfo_file > 0)
1668 { tpl_addVar(vars, TPLADD, "ECMINFOFILECHECKED", "checked"); }
1670 //ecminfo_type
1671 tpl_printf(vars, TPLADD, "TMP", "ECMINFOTYPESELECTED%d", cfg.dvbapi_ecminfo_type);
1672 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1674 //read_sdt
1675 tpl_printf(vars, TPLADD, "TMP", "READSDTSELECTED%d", cfg.dvbapi_read_sdt);
1676 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1678 //extended_cw_api
1679 tpl_printf(vars, TPLADD, "TMP", "EXTENDEDCWAPISELECTED%d", cfg.dvbapi_extended_cw_api);
1680 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1682 //write_sdt_prov
1683 if(cfg.dvbapi_write_sdt_prov > 0)
1684 { tpl_addVar(vars, TPLADD, "WRITESDTPROVCHECKED", "checked"); }
1686 #ifdef MODULE_STREAMRELAY
1687 //demuxer_fix
1688 if(cfg.dvbapi_demuxer_fix > 0)
1689 { tpl_addVar(vars, TPLADD, "DEMUXERFIXCHECKED", "checked"); }
1690 #endif
1692 //TCP listen port
1693 if(cfg.dvbapi_listenport > 0)
1694 { tpl_printf(vars, TPLADD, "LISTENPORT", "%d", cfg.dvbapi_listenport); }
1696 return tpl_getTpl(vars, "CONFIGDVBAPI");
1698 #endif
1700 #ifdef CS_ANTICASC
1701 static char *send_oscam_config_anticasc(struct templatevars *vars, struct uriparams *params)
1703 setActiveSubMenu(vars, MNU_CFG_ANTICASC);
1705 webif_save_config("anticasc", vars, params);
1707 if(cfg.ac_enabled > 0) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
1708 tpl_printf(vars, TPLADD, "NUMUSERS", "%d", cfg.ac_users);
1709 tpl_printf(vars, TPLADD, "SAMPLETIME", "%d", cfg.ac_stime);
1710 tpl_printf(vars, TPLADD, "SAMPLES", "%d", cfg.ac_samples);
1712 tpl_printf(vars, TPLADD, "TMP", "PENALTY%d", cfg.ac_penalty);
1713 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1715 if(cfg.ac_logfile)
1716 { tpl_addVar(vars, TPLADD, "ACLOGFILE", cfg.ac_logfile); }
1717 tpl_printf(vars, TPLADD, "FAKEDELAY", "%d", cfg.ac_fakedelay);
1718 tpl_printf(vars, TPLADD, "DENYSAMPLES", "%d", cfg.ac_denysamples);
1720 if(cfg.acosc_enabled == 1)
1721 { tpl_addVar(vars, TPLADD, "ACOSC_CHECKED", "checked"); }
1722 tpl_printf(vars, TPLADD, "ACOSC_MAX_ECMS_PER_MINUTE", "%d", cfg.acosc_max_ecms_per_minute);
1723 tpl_printf(vars, TPLADD, "ACOSC_MAX_ACTIVE_SIDS", "%d", cfg.acosc_max_active_sids);
1724 tpl_printf(vars, TPLADD, "ACOSC_ZAP_LIMIT", "%d", cfg.acosc_zap_limit);
1725 tpl_printf(vars, TPLADD, "TMP", "ACOSC_PENALTY%d", cfg.acosc_penalty);
1726 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1727 tpl_printf(vars, TPLADD, "ACOSC_PENALTY_DURATION", "%d", cfg.acosc_penalty_duration);
1728 tpl_printf(vars, TPLADD, "ACOSC_DELAY", "%d", cfg.acosc_delay);
1730 return tpl_getTpl(vars, "CONFIGANTICASC");
1732 #endif
1734 static char *send_oscam_config(struct templatevars *vars, struct uriparams *params)
1737 setActiveMenu(vars, MNU_CONFIG);
1739 char *part = getParam(params, "part");
1740 if(!strcmp(part, "webif")) { return send_oscam_config_webif(vars, params); }
1741 #ifdef MODULE_MONITOR
1742 else if(!strcmp(part, "monitor")) { return send_oscam_config_monitor(vars, params); }
1743 #endif
1744 #ifdef LCDSUPPORT
1745 else if(!strcmp(part, "lcd")) { return send_oscam_config_lcd(vars, params); }
1746 #endif
1747 #ifdef MODULE_CAMD33
1748 else if(!strcmp(part, "camd33")) { return send_oscam_config_camd33(vars, params); }
1749 #endif
1750 #ifdef MODULE_CAMD35
1751 else if(!strcmp(part, "camd35")) { return send_oscam_config_camd35(vars, params); }
1752 #endif
1753 #ifdef MODULE_CAMD35_TCP
1754 else if(!strcmp(part, "camd35tcp")) { return send_oscam_config_camd35tcp(vars, params); }
1755 #endif
1756 else if(!strcmp(part, "cache")) { return send_oscam_config_cache(vars, params); }
1757 #ifdef MODULE_NEWCAMD
1758 else if(!strcmp(part, "newcamd")) { return send_oscam_config_newcamd(vars, params); }
1759 #endif
1760 #ifdef MODULE_RADEGAST
1761 else if(!strcmp(part, "radegast")) { return send_oscam_config_radegast(vars, params); }
1762 #endif
1763 #ifdef MODULE_SCAM
1764 else if(!strcmp(part, "scam")) { return send_oscam_config_scam(vars, params); }
1765 #endif
1766 #ifdef MODULE_STREAMRELAY
1767 else if(!strcmp(part, "streamrelay")) { return send_oscam_config_streamrelay(vars, params); }
1768 #endif
1769 #ifdef MODULE_CCCAM
1770 else if(!strcmp(part, "cccam")) { return send_oscam_config_cccam(vars, params); }
1771 #endif
1772 #ifdef MODULE_GBOX
1773 else if(!strcmp(part, "gbox")) { return send_oscam_config_gbox(vars, params); }
1774 #endif
1775 #ifdef HAVE_DVBAPI
1776 else if(!strcmp(part, "dvbapi")) { return send_oscam_config_dvbapi(vars, params); }
1777 #endif
1778 #ifdef CS_ANTICASC
1779 else if(!strcmp(part, "anticasc")) { return send_oscam_config_anticasc(vars, params); }
1780 #endif
1781 #ifdef MODULE_SERIAL
1782 else if(!strcmp(part, "serial")) { return send_oscam_config_serial(vars, params); }
1783 #endif
1784 #ifdef WITH_LB
1785 else if(!strcmp(part, "loadbalancer")) { return send_oscam_config_loadbalancer(vars, params); }
1786 #endif
1787 else { return send_oscam_config_global(vars, params); }
1790 static void inactivate_reader(struct s_reader *rdr)
1792 struct s_client *cl = rdr->client;
1793 if(cl)
1794 { kill_thread(cl); }
1797 static bool picon_exists(char *name)
1799 char picon_name[255], path[255];
1800 char *tpl_path;
1801 tpl_path = cfg.http_piconpath ? cfg.http_piconpath : cfg.http_tpl;
1802 if(!tpl_path)
1803 { return false; }
1804 snprintf(picon_name, sizeof(picon_name) - 1, "IC_%s", name);
1805 return cs_strlen(tpl_getTplPath(picon_name, tpl_path, path, sizeof(path) - 1)) && file_exists(path);
1808 static void clear_rdr_stats(struct s_reader *rdr)
1810 int i;
1811 for(i = 0; i < 4; i++)
1813 rdr->emmerror[i] = 0;
1814 rdr->emmwritten[i] = 0;
1815 rdr->emmskipped[i] = 0;
1816 rdr->emmblocked[i] = 0;
1818 rdr->ecmsok = 0;
1819 #ifdef CS_CACHEEX_AIO
1820 rdr->ecmsoklg = 0;
1821 #endif
1822 rdr->ecmsnok = 0;
1823 rdr->ecmstout = 0;
1824 rdr->ecmshealthok = 0;
1825 #ifdef CS_CACHEEX_AIO
1826 rdr->ecmshealthoklg = 0;
1827 #endif
1828 rdr->ecmshealthnok = 0;
1829 rdr->ecmshealthtout = 0;
1830 rdr->ecmsfilteredhead = 0;
1831 rdr->ecmsfilteredlen = 0;
1834 static void clear_all_rdr_stats(void)
1836 struct s_reader *rdr;
1837 LL_ITER itr = ll_iter_create(configured_readers);
1838 while((rdr = ll_iter_next(&itr)))
1840 clear_rdr_stats(rdr);
1844 static char *send_oscam_reader(struct templatevars *vars, struct uriparams *params, int32_t apicall)
1846 struct s_reader *rdr;
1847 int32_t i;
1848 uint8_t md5tmp[MD5_DIGEST_LENGTH];
1849 char *status;
1851 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
1852 if(!apicall)
1854 if(strcmp(getParam(params, "action"), "resetallrdrstats") == 0)
1856 clear_all_rdr_stats();
1860 tpl_addVar(vars, TPLADD, "READERACTIONCOLS", config_enabled(WITH_LB) ? "6" : "5");
1862 if(strcmp(getParam(params, "action"), "resetuserstats") == 0)
1864 clear_info_clients_stats();
1866 if(strcmp(getParam(params, "action"), "resetreaderstats") == 0)
1868 clear_info_readers_stats();
1870 if(strcmp(getParam(params, "action"), "reloadreaders") == 0)
1872 if(!cfg.http_readonly)
1873 { refresh_oscam(REFR_READERS); }
1875 if((strcmp(getParam(params, "action"), "disable") == 0) || (strcmp(getParam(params, "action"), "enable") == 0))
1877 if(cfg.http_readonly)
1879 tpl_addMsg(vars, "WebIf is in readonly mode. Enabling or disabling readers is not possible!");
1881 else
1883 rdr = get_reader_by_label(getParam(params, "label"));
1884 if(rdr)
1886 if(strcmp(getParam(params, "action"), "enable") == 0)
1888 if(!rdr->enable)
1890 rdr->enable = 1;
1893 else
1895 if(rdr->enable)
1897 rdr->enable = 0;
1900 if(rdr->typ != R_GBOX)
1902 restart_cardreader(rdr, 1);
1904 #ifdef MODULE_GBOX
1905 else
1907 restart_gbox_peer(rdr->label, 0, 0);
1908 cs_log("gbox -> you must restart oscam so that setting becomes effective");
1910 #endif
1912 cs_log("reader %s %s by WebIf", rdr->label, rdr->enable == 1 ? "enabled":"disabled");
1914 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
1916 #ifdef MODULE_GBOX
1917 if(!is_network_reader(rdr) && !rdr->enable)
1919 gbx_local_card_stat(LOCALCARDDISABLED, 0);
1921 #endif
1926 if(strcmp(getParam(params, "action"), "delete") == 0)
1928 if(cfg.http_readonly)
1930 tpl_addMsg(vars, "WebIf is in readonly mode. No deletion will be made!");
1932 else
1934 rdr = get_reader_by_label(getParam(params, "label"));
1935 if(rdr)
1937 inactivate_reader(rdr);
1938 ll_remove(configured_readers, rdr);
1940 free_reader(rdr);
1942 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
1947 if(strcmp(getParam(params, "action"), "reread") == 0)
1949 rdr = get_reader_by_label(getParam(params, "label"));
1950 if(rdr)
1952 struct s_client *cl = rdr->client;
1953 //reset the counters
1954 for(i = 0; i < 4; i++)
1956 rdr->emmerror[i] = 0;
1957 rdr->emmwritten[i] = 0;
1958 rdr->emmskipped[i] = 0;
1959 rdr->emmblocked[i] = 0;
1962 if(rdr->enable == 1 && cl && cl->typ == 'r')
1964 add_job(cl, ACTION_READER_CARDINFO, NULL, 0);
1969 LL_ITER itr = ll_iter_create(configured_readers);
1971 if(!apicall)
1973 for(i = 0, rdr = ll_iter_next(&itr); rdr && rdr->label[0]; rdr = ll_iter_next(&itr), i++) { ; }
1974 tpl_printf(vars, TPLADD, "NEXTREADER", "Reader-%d", i); //Next Readername
1977 int jsondelimiter = 0;
1978 int existing_insert = 0;
1980 int32_t total_readers = 0;
1981 int32_t disabled_readers = 0;
1982 int32_t active_readers = 0;
1983 int32_t connected_readers = 0;
1985 ll_iter_reset(&itr); //going to iterate all configured readers
1986 while((rdr = ll_iter_next(&itr)))
1988 #ifdef CS_CACHEEX_AIO
1989 const char *proto = reader_get_type_desc(rdr, 0);
1990 #endif
1991 struct s_client *cl = rdr->client;
1992 if(rdr->label[0] && rdr->typ)
1994 #ifdef CS_CACHEEX_AIO
1995 char *new_proto;
1996 #if defined(MODULE_CAMD35) || defined (MODULE_CAMD35_TCP)
1997 if(rdr->cacheex.feature_bitfield || (cl && cl->c35_extmode > 1))
1998 #else
1999 if(rdr->cacheex.feature_bitfield)
2000 #endif
2002 const char *aio_suffix = " (cx-aio)";
2004 if(cs_malloc(&new_proto, cs_strlen(proto)+cs_strlen(aio_suffix)+1)) {
2005 if (!cs_strncat(new_proto, (char *)proto, cs_strlen(proto)+cs_strlen(aio_suffix)+1)) {
2006 cs_log("FIXME!");
2008 if (!cs_strncat(new_proto, (char *)aio_suffix, cs_strlen(proto)+cs_strlen(aio_suffix)+1)) {
2009 cs_log("FIXME!");
2013 #endif
2014 total_readers += 1;
2016 // used for API and WebIf
2017 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
2019 MD5((uint8_t *)rdr->label, cs_strlen(rdr->label), md5tmp);
2020 int z;
2021 tpl_addVar(vars, TPLADD, "LABELMD5","id_");
2022 for (z = 0; z < MD5_DIGEST_LENGTH; z++)
2024 tpl_printf(vars, TPLAPPEND, "LABELMD5", "%02x", md5tmp[z]);
2026 #ifdef MODULE_GBOX
2027 if(apicall)
2029 tpl_addVar(vars, TPLADD, "LASTGSMS", "");
2030 tpl_addVar(vars, TPLADD, "LASTGSMS", rdr->last_gsms);
2032 #endif
2033 if(apicall)
2035 tpl_printf(vars, TPLADD, "PICONENABLED", "%d", cfg.http_showpicons?1:0);
2037 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, rdr->label));
2038 if(!existing_insert)
2040 tpl_printf(vars, TPLADD, "EXISTING_INS", "'%s'", urlencode(vars, rdr->label));
2041 existing_insert++;
2042 }else
2044 tpl_printf(vars, TPLAPPEND, "EXISTING_INS", ",'%s'", urlencode(vars, rdr->label));
2046 tpl_addVar(vars, TPLADD, "READERCLASS", rdr->enable ? "enabledreader" : "disabledreader");
2048 if(rdr->enable) { active_readers += 1; }
2049 else { disabled_readers += 1; }
2051 if(rdr->tcp_connected)
2053 connected_readers += 1;
2055 #ifdef CS_CACHEEX_AIO
2056 if(rdr->cacheex.feature_bitfield)
2058 tpl_addVar(vars, TPLADD, "CLIENTPROTOSORT", (const char*)new_proto);
2059 tpl_addVar(vars, TPLADD, "CLIENTPROTO", (const char*)new_proto);
2060 if(cfg.http_showpicons)
2062 char picon_name[32];
2063 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", new_proto);
2064 if(picon_exists(picon_name))
2066 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s",(char*)new_proto);
2070 if(rdr->cacheex.feature_bitfield & 32)
2071 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", rdr->cacheex.aio_version);
2072 else if(cl->reader->cacheex.feature_bitfield)
2073 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", "[cx-aio < 9.2.3]");
2075 else
2077 tpl_addVar(vars, TPLADD, "CLIENTPROTOSORT", proto);
2078 tpl_addVar(vars, TPLADD, "CLIENTPROTO", proto);
2079 if(cfg.http_showpicons)
2081 char picon_name[32];
2082 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", proto);
2083 if(picon_exists(picon_name))
2085 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s",(char *)proto);
2089 #else
2090 tpl_addVar(vars, TPLADD, "CLIENTPROTO", reader_get_type_desc(rdr, 0));
2091 tpl_addVar(vars, TPLADD, "CLIENTPROTOSORT", reader_get_type_desc(rdr, 0));
2092 if(cfg.http_showpicons)
2094 char picon_name[32];
2095 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", reader_get_type_desc(rdr, 0));
2096 if(picon_exists(picon_name))
2098 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s", reader_get_type_desc(rdr, 0));
2101 #endif
2102 switch(rdr->card_status)
2104 case CARD_INSERTED:
2105 status = "<B>online</B>";
2106 tpl_addVar(vars, TPLADD, "RSTATUS", status);
2107 tpl_addVar(vars, TPLADD, "READERCLASS", "r_connected");
2108 break;
2110 case NO_CARD:
2111 case UNKNOWN:
2112 case READER_DEVICE_ERROR:
2113 case CARD_NEED_INIT:
2114 case CARD_FAILURE:
2115 default:
2116 status = "<B>connected</B>";
2117 tpl_addVar(vars, TPLADD, "RSTATUS", status);
2118 tpl_addVar(vars, TPLADD, "READERCLASS", "r_undefined");
2119 break;
2122 tpl_addVar(vars, TPLADD, "READERIP", cs_inet_ntoa(rdr->client->ip));
2124 else
2126 /* default initial values */
2127 tpl_addVar(vars, TPLADDONCE, "RSTATUS", "offline");
2128 tpl_addVar(vars, TPLADDONCE, "READERIP", "");
2129 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTO", "");
2130 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOSORT", "");
2131 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOTITLE", "");
2132 tpl_addVar(vars, TPLADDONCE, "PROTOICON", "");
2134 if(!is_network_reader(rdr) && rdr->enable)
2136 switch(rdr->card_status)
2138 case CARD_INSERTED:
2139 status = "<B>active</B>";
2140 tpl_addVar(vars, TPLADD, "RSTATUS", status);
2141 tpl_addVar(vars, TPLADD, "READERCLASS", "r_connected");
2142 break;
2144 case NO_CARD:
2145 case UNKNOWN:
2146 case READER_DEVICE_ERROR:
2147 case CARD_NEED_INIT:
2148 case CARD_FAILURE:
2149 default:
2150 status = "<B>connected</B>";
2151 tpl_addVar(vars, TPLADD, "RSTATUS", status);
2152 tpl_addVar(vars, TPLADD, "READERCLASS", "r_undefined");
2153 break;
2156 tpl_addVar(vars, TPLADD, "CLIENTPROTO", reader_get_type_desc(rdr, 0));
2157 tpl_addVar(vars, TPLADD, "CLIENTPROTOSORT", reader_get_type_desc(rdr, 0));
2158 if(cfg.http_showpicons)
2160 char picon_name[32];
2161 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", reader_get_type_desc(rdr, 0));
2162 if(picon_exists(picon_name))
2164 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s", reader_get_type_desc(rdr, 0));
2170 if(rdr->description)
2171 tpl_printf(vars, TPLADD, "DESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, rdr->description));
2172 else
2173 tpl_addVar(vars, TPLADD, "DESCRIPTION", "");
2175 if(cfg.http_showpicons && !apicall)
2177 tpl_addVar(vars, TPLADD, "READERBIT", tpl_getTpl(vars, picon_exists(xml_encode(vars, rdr->label)) ? "READERNAMEBIT" : "READERNOICON"));
2178 #ifdef CS_CACHEEX_AIO
2179 if(rdr->cacheex.feature_bitfield)
2181 tpl_addVar(vars, TPLADD, "CLIENTPROTO", picon_exists(xml_encode(vars, (const char*)new_proto)) ? tpl_getTpl(vars, "READERCTYPBIT") : tpl_getTpl(vars, "READERCTYPNOICON"));
2183 else
2185 #endif
2186 tpl_addVar(vars, TPLADD, "CLIENTPROTO", picon_exists(xml_encode(vars, reader_get_type_desc(rdr, 0))) ? tpl_getTpl(vars, "READERCTYPBIT") : tpl_getTpl(vars, "READERCTYPNOICON"));
2187 #ifdef CS_CACHEEX_AIO
2189 #endif
2191 else
2192 tpl_addVar(vars, TPLADD, "READERBIT", tpl_getTpl(vars, "READERLABEL"));
2194 char *value = mk_t_group(rdr->grp);
2195 tpl_addVar(vars, TPLADD, "GROUPS", value);
2196 free_mk_t(value);
2197 tpl_printf(vars, TPLADD, "EMMERRORUK", PRINTF_LOCAL_D, rdr->emmerror[UNKNOWN]);
2198 tpl_printf(vars, TPLADD, "EMMERRORG", PRINTF_LOCAL_D, rdr->emmerror[GLOBAL]);
2199 tpl_printf(vars, TPLADD, "EMMERRORS", PRINTF_LOCAL_D, rdr->emmerror[SHARED]);
2200 tpl_printf(vars, TPLADD, "EMMERRORUQ", PRINTF_LOCAL_D, rdr->emmerror[UNIQUE]);
2202 tpl_printf(vars, TPLADD, "EMMWRITTENUK", PRINTF_LOCAL_D, rdr->emmwritten[UNKNOWN]);
2203 tpl_printf(vars, TPLADD, "EMMWRITTENG", PRINTF_LOCAL_D, rdr->emmwritten[GLOBAL]);
2204 tpl_printf(vars, TPLADD, "EMMWRITTENS", PRINTF_LOCAL_D, rdr->emmwritten[SHARED]);
2205 tpl_printf(vars, TPLADD, "EMMWRITTENUQ", PRINTF_LOCAL_D, rdr->emmwritten[UNIQUE]);
2207 tpl_printf(vars, TPLADD, "EMMSKIPPEDUK", PRINTF_LOCAL_D, rdr->emmskipped[UNKNOWN]);
2208 tpl_printf(vars, TPLADD, "EMMSKIPPEDG", PRINTF_LOCAL_D, rdr->emmskipped[GLOBAL]);
2209 tpl_printf(vars, TPLADD, "EMMSKIPPEDS", PRINTF_LOCAL_D, rdr->emmskipped[SHARED]);
2210 tpl_printf(vars, TPLADD, "EMMSKIPPEDUQ", PRINTF_LOCAL_D, rdr->emmskipped[UNIQUE]);
2212 tpl_printf(vars, TPLADD, "EMMBLOCKEDUK", PRINTF_LOCAL_D, rdr->emmblocked[UNKNOWN]);
2213 tpl_printf(vars, TPLADD, "EMMBLOCKEDG", PRINTF_LOCAL_D, rdr->emmblocked[GLOBAL]);
2214 tpl_printf(vars, TPLADD, "EMMBLOCKEDS", PRINTF_LOCAL_D, rdr->emmblocked[SHARED]);
2215 tpl_printf(vars, TPLADD, "EMMBLOCKEDUQ", PRINTF_LOCAL_D, rdr->emmblocked[UNIQUE]);
2217 tpl_printf(vars, TPLADD, "ECMSOK", PRINTF_LOCAL_D, rdr->ecmsok);
2218 tpl_printf(vars, TPLADD, "ECMSOKREL", " (%.2f %%)", rdr->ecmshealthok);
2219 #ifdef CS_CACHEEX_AIO
2220 tpl_printf(vars, TPLADD, "ECMSOKLG", PRINTF_LOCAL_D, rdr->ecmsoklg);
2221 tpl_printf(vars, TPLADD, "ECMSOKLGREL", " (%.2f %%)", rdr->ecmshealthoklg);
2222 #endif
2223 tpl_printf(vars, TPLADD, "ECMSNOK", PRINTF_LOCAL_D, rdr->ecmsnok);
2224 tpl_printf(vars, TPLADD, "ECMSNOKREL", " (%.2f %%)",rdr->ecmshealthnok);
2225 tpl_printf(vars, TPLADD, "ECMSTOUT", PRINTF_LOCAL_D, rdr->ecmstout);
2226 tpl_printf(vars, TPLADD, "ECMSTOUTREL", " (%.2f %%)",rdr->ecmshealthtout);
2227 tpl_printf(vars, TPLADD, "ECMSFILTEREDHEAD", PRINTF_LOCAL_D, rdr->ecmsfilteredhead);
2228 tpl_printf(vars, TPLADD, "ECMSFILTEREDLEN", PRINTF_LOCAL_D, rdr->ecmsfilteredlen);
2229 #ifdef WITH_LB
2230 tpl_printf(vars, TPLADD, "LBWEIGHT", "%d", rdr->lb_weight);
2231 #endif
2232 if(!is_network_reader(rdr)) //reader is physical
2234 tpl_addVar(vars, TPLADD, "REFRICO", "image?i=ICREF");
2235 tpl_addVar(vars, TPLADD, "READERREFRESH", tpl_getTpl(vars, "READERREFRESHBIT"));
2236 tpl_addVar(vars, TPLADD, "ENTICO", "image?i=ICENT");
2237 tpl_addVar(vars, TPLADD, "ENTITLEMENT", tpl_getTpl(vars, "READERENTITLEBIT"));
2239 else
2241 tpl_addVar(vars, TPLADD, "READERREFRESH", "");
2242 if(rdr->typ == R_CCCAM)
2244 tpl_addVar(vars, TPLADD, "ENTICO", "image?i=ICENT");
2245 tpl_addVar(vars, TPLADD, "ENTITLEMENT", tpl_getTpl(vars, "READERENTITLEBIT"));
2247 else
2249 tpl_addVar(vars, TPLADD, "ENTITLEMENT", "");
2253 if(rdr->enable == 0)
2255 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICENA");
2256 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Enable");
2257 tpl_addVar(vars, TPLADD, "SWITCH", "enable");
2258 tpl_addVar(vars, TPLADD, "WRITEEMM", "");
2260 else
2262 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICDIS");
2263 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Disable");
2264 tpl_addVar(vars, TPLADD, "SWITCH", "disable");
2266 tpl_addVar(vars, TPLADD, "EMMICO", "image?i=ICEMM");
2267 tpl_addVar(vars, TPLADD, "WRITEEMM", tpl_getTpl(vars, "READERWRITEEMMBIT"));
2270 if(!apicall)
2272 // Add to WebIf Template
2273 #ifdef CS_CACHEEX_AIO
2274 tpl_addVar(vars, TPLAPPEND, "READERLIST", tpl_getTpl(vars, "READERSBITAIO"));
2275 #else
2276 tpl_addVar(vars, TPLAPPEND, "READERLIST", tpl_getTpl(vars, "READERSBIT"));
2277 #endif
2279 else
2282 // used only for API
2283 tpl_addVar(vars, TPLADD, "APIREADERENABLED", !rdr->enable ? "0" : "1");
2284 if(cl)
2286 tpl_printf(vars, TPLADD, "APIREADERTYPE", "%c", cl->typ ? cl->typ : 'x');
2289 if(apicall==1)
2291 // Add to API Template
2292 tpl_addVar(vars, TPLAPPEND, "APIREADERLIST", tpl_getTpl(vars, "APIREADERSBIT"));
2294 if(apicall==2)
2296 tpl_printf(vars, TPLAPPEND, "APIREADERLIST","%s%s",jsondelimiter?",":"", tpl_getTpl(vars, "JSONREADERBIT"));
2297 jsondelimiter++;
2300 #ifdef CS_CACHEEX_AIO
2301 if(rdr->cacheex.feature_bitfield)
2303 free(new_proto);
2305 #endif
2309 tpl_printf(vars, TPLADD, "TOTAL_READERS", "%d", total_readers);
2310 tpl_printf(vars, TPLADD, "TOTAL_DISABLED_READERS", "%d", disabled_readers);
2311 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE_READERS", "%d", active_readers);
2312 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED_READERS", "%d", connected_readers);
2314 //CM info
2315 tpl_addVar(vars, TPLADD, "DISPLAYUSERINFO", "hidden"); // no userinfo in readers
2316 set_ecm_info(vars);
2318 if(!apicall)
2320 #ifdef MODULE_CAMD33
2321 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>camd33</option>\n");
2322 #endif
2323 #ifdef MODULE_CAMD35
2324 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>cs357x</option>\n");
2325 #endif
2326 #ifdef MODULE_CAMD35_TCP
2327 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>cs378x</option>\n");
2328 #endif
2329 #ifdef MODULE_NEWCAMD
2330 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>newcamd</option>\n");
2331 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>newcamd524</option>\n");
2332 #endif
2333 #ifdef MODULE_CCCAM
2334 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>cccam</option>\n");
2335 #endif
2336 #ifdef MODULE_GBOX
2337 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>gbox</option>\n");
2338 #endif
2339 #ifdef MODULE_RADEGAST
2340 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>radegast</option>\n");
2341 #endif
2342 #ifdef MODULE_SERIAL
2343 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>serial</option>\n");
2344 #endif
2345 #ifdef MODULE_CONSTCW
2346 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>constcw</option>\n");
2347 #endif
2348 #ifdef MODULE_SCAM
2349 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>scam</option>\n");
2350 #endif
2352 for(i = 0; cardreaders[i]; i++)
2354 tpl_printf(vars, TPLAPPEND, "ADDPROTOCOL", "<option>%s</option>\n", xml_encode(vars, cardreaders[i]->desc));
2356 #ifdef CS_CACHEEX_AIO
2357 return tpl_getTpl(vars, "READERSAIO");
2358 #else
2359 return tpl_getTpl(vars, "READERS");
2360 #endif
2362 else
2364 if(apicall == 1)
2366 return tpl_getTpl(vars, "APIREADERS");
2368 else
2370 return tpl_getTpl(vars, "JSONREADER");
2375 static char *send_oscam_reader_config(struct templatevars *vars, struct uriparams *params)
2377 int32_t i;
2378 int32_t apicall = 0;
2379 char *reader_ = getParam(params, "label");
2380 char *value;
2382 struct s_reader *rdr;
2384 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
2386 if(strcmp(getParam(params, "action"), "Add") == 0)
2388 // Add new reader
2389 struct s_reader *newrdr;
2390 if(!cs_malloc(&newrdr, sizeof(struct s_reader))) { return "0"; }
2391 for(i = 0; i < (*params).paramcount; ++i)
2393 if(strcmp((*params).params[i], "action"))
2394 { chk_reader((*params).params[i], (*params).values[i], newrdr); }
2396 module_reader_set(newrdr);
2397 reader_ = newrdr->label;
2398 reader_set_defaults(newrdr);
2399 newrdr->enable = 0; // do not start the reader because must configured before
2400 ll_append(configured_readers, newrdr);
2401 tpl_addMsg(vars, "New Reader has been added with default settings");
2403 else if(strcmp(getParam(params, "action"), "Save") == 0)
2406 rdr = get_reader_by_label(getParam(params, "label"));
2407 if(!rdr)
2408 { return NULL; }
2409 //if (is_network_reader(rdr))
2410 // inactivate_reader(rdr); //Stop reader before reinitialization
2411 char servicelabels[1024] = "";
2412 char servicelabelslb[1024] = "";
2414 for(i = 0; i < (*params).paramcount; ++i)
2416 if((strcmp((*params).params[i], "reader")) && (strcmp((*params).params[i], "action")))
2418 if(!strcmp((*params).params[i], "services"))
2419 { snprintf(servicelabels + cs_strlen(servicelabels), sizeof(servicelabels) - cs_strlen(servicelabels), "%s,", (*params).values[i]); }
2420 else if(!strcmp((*params).params[i], "lb_whitelist_services"))
2421 { snprintf(servicelabelslb + cs_strlen(servicelabelslb), sizeof(servicelabelslb) - cs_strlen(servicelabelslb), "%s,", (*params).values[i]); }
2422 else
2423 /*if(cs_strlen((*params).values[i]) > 0)*/
2424 { chk_reader((*params).params[i], (*params).values[i], rdr); }
2426 //printf("param %s value %s\n",(*params).params[i], (*params).values[i]);
2428 chk_reader("services", servicelabels, rdr);
2429 chk_reader("lb_whitelist_services", servicelabelslb, rdr);
2431 if(is_network_reader(rdr) || rdr->typ == R_EMU) //physical readers make trouble if re-started
2433 if(rdr)
2435 if(rdr->typ != R_GBOX)
2437 restart_cardreader(rdr, 1);
2439 #ifdef MODULE_GBOX
2440 else
2442 //cs_log("SAVE - single gbox reader %s restarted by WebIf", rdr->label);
2443 restart_gbox_peer(rdr->label, 0, 0);
2445 #endif
2449 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); } else { tpl_addMsg(vars, "Reader config updated and saved"); }
2453 rdr = get_reader_by_label(reader_);
2454 if(!rdr)
2455 { return NULL; }
2457 // Label, Description
2458 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
2459 tpl_addVar(vars, TPLADD, "DESCRIPTION", xml_encode(vars, rdr->description));
2461 // enabled
2462 if(!apicall)
2464 tpl_addVar(vars, TPLADD, "ENABLED", (rdr->enable == 1) ? "checked" : "");
2466 else
2468 tpl_addVar(vars, TPLADD, "ENABLEDVALUE", (rdr->enable == 1) ? "1" : "0");
2471 tpl_addVar(vars, TPLADD, "PASSWORD", xml_encode(vars, rdr->r_pwd));
2472 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, rdr->r_usr));
2473 tpl_addVar(vars, TPLADD, "PASS", xml_encode(vars, rdr->r_pwd));
2475 // Key Newcamd
2476 for(i = 0; i < (int32_t)sizeof(rdr->ncd_key); i++)
2477 { tpl_printf(vars, TPLAPPEND, "NCD_KEY", "%02X", rdr->ncd_key[i]); }
2479 // Pincode
2480 tpl_addVar(vars, TPLADD, "PINCODE", rdr->pincode);
2482 // Emmfile Path
2483 if(rdr->emmfile) { tpl_addVar(vars, TPLADD, "EMMFILE", (char *)rdr->emmfile); }
2485 // Inactivity timeout
2486 tpl_printf(vars, TPLADD, "INACTIVITYTIMEOUT", "%d", rdr->tcp_ito);
2488 // Receive timeout
2489 tpl_printf(vars, TPLADD, "RECEIVETIMEOUT", "%d", rdr->tcp_rto);
2491 // keepalive
2492 tpl_addVar(vars, TPLADD, "RDRKEEPALIVE", (rdr->keepalive == 1) ? "checked" : "");
2494 // Connect on init (newcamd)
2495 if(!apicall)
2497 tpl_addVar(vars, TPLADD, "CONNECTONINITCHECKED", (rdr->ncd_connect_on_init == 1) ? "checked" : "");
2499 else
2501 tpl_addVar(vars, TPLADD, "CONNECTONINITCHECKED", (rdr->ncd_connect_on_init == 1) ? "1" : "0");
2504 // Reset Cycle
2505 tpl_printf(vars, TPLADD, "RESETCYCLE", "%d", rdr->resetcycle);
2507 // Disable Serverfilter
2508 if(!apicall)
2510 tpl_addVar(vars, TPLADD, "DISABLESERVERFILTERCHECKED", (rdr->ncd_disable_server_filt == 1) ? "checked" : "");
2512 else
2514 tpl_addVar(vars, TPLADD, "DISABLESERVERFILTERVALUE", (rdr->ncd_disable_server_filt == 1) ? "1" : "0");
2517 #ifdef MODULE_GHTTP
2518 // Use SSL
2519 if(!apicall)
2521 tpl_addVar(vars, TPLADD, "USESSLCHECKED", (rdr->ghttp_use_ssl == 1) ? "checked" : "");
2523 else
2525 tpl_addVar(vars, TPLADD, "USESSLVALUE", (rdr->ghttp_use_ssl == 1) ? "1" : "0");
2527 #endif
2529 // Fallback
2530 if(!apicall)
2532 tpl_addVar(vars, TPLADD, "FALLBACKCHECKED", (rdr->fallback == 1) ? "checked" : "");
2534 else
2536 tpl_addVar(vars, TPLADD, "FALLBACKVALUE", (rdr->fallback == 1) ? "1" : "0");
2539 // Fallback per caid
2540 value = mk_t_ftab(&rdr->fallback_percaid);
2541 tpl_addVar(vars, TPLADD, "FALLBACK_PERCAID", value);
2542 free_mk_t(value);
2544 // disable checksum test only for selected caid/provid
2545 value = mk_t_ftab(&rdr->disablecrccws_only_for);
2546 tpl_addVar(vars, TPLADD, "IGN_CHKSUM_ONLYFOR", value);
2547 free_mk_t(value);
2549 #ifdef WITH_LB
2550 tpl_addVar(vars, TPLADD, "LBFORCEFALLBACK", (rdr->lb_force_fallback == 1) ? "checked" : "");
2551 #endif
2553 #ifdef CS_CACHEEX
2554 // Cacheex
2555 if(!apicall)
2557 tpl_printf(vars, TPLADD, "TMP", "CACHEEXSELECTED%d", rdr->cacheex.mode);
2558 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
2560 else
2562 tpl_printf(vars, TPLADD, "CACHEEX", "%d", rdr->cacheex.mode);
2564 tpl_printf(vars, TPLADD, "CACHEEX_MAXHOP", "%d", rdr->cacheex.maxhop);
2565 #ifdef CS_CACHEEX_AIO
2566 tpl_printf(vars, TPLADD, "CACHEEX_MAXHOP_LG", "%d", rdr->cacheex.maxhop_lg);
2567 #endif
2568 value = mk_t_cacheex_hitvaluetab(&rdr->cacheex.filter_caidtab);
2569 //if (cs_strlen(value) > 0)
2570 tpl_printf(vars, TPLADD, "CACHEEX_ECM_FILTER", "%s", value);
2571 free_mk_t(value);
2573 tpl_addVar(vars, TPLADD, "DCCHECKED", (rdr->cacheex.drop_csp == 1) ? "checked" : "");
2574 tpl_addVar(vars, TPLADD, "ARCHECKED", (rdr->cacheex.allow_request == 1) ? "checked" : "");
2575 tpl_addVar(vars, TPLADD, "AFCHECKED", (rdr->cacheex.allow_filter == 1) ? "checked" : "");
2576 #ifdef CS_CACHEEX_AIO
2577 tpl_addVar(vars, TPLADD, "AMCHECKED", (rdr->cacheex.allow_maxhop == 1) ? "checked" : "");
2578 #endif
2579 tpl_addVar(vars, TPLADD, "BLOCKFAKECWSCHECKED", (rdr->cacheex.block_fakecws == 1) ? "checked" : "");
2580 #ifdef CS_CACHEEX_AIO
2581 tpl_addVar(vars, TPLADD, "USECWCHECKFORPUSHCHECKED", (rdr->cacheex.cw_check_for_push == 1) ? "checked" : "");
2582 tpl_addVar(vars, TPLADD, "LGONLYREMOTESETTINGSCHECKED", (rdr->cacheex.lg_only_remote_settings == 1) ? "checked" : "");
2583 tpl_addVar(vars, TPLADD, "LOCALGENERATEDONLYCHECKED", (rdr->cacheex.localgenerated_only == 1) ? "checked" : "");
2585 value = mk_t_ftab(&rdr->cacheex.lg_only_tab);
2586 tpl_addVar(vars, TPLADD, "LGONLYTAB", value);
2587 free_mk_t(value);
2589 tpl_addVar(vars, TPLADD, "LOCALGENERATEDONLYINCHECKED", (rdr->cacheex.localgenerated_only_in == 1) ? "checked" : "");
2591 tpl_addVar(vars, TPLADD, "LGONLYINAIOONLYCHECKED", (rdr->cacheex.lg_only_in_aio_only == 1) ? "checked" : "");
2593 value = mk_t_ftab(&rdr->cacheex.lg_only_in_tab);
2594 tpl_addVar(vars, TPLADD, "LGONLYINTAB", value);
2595 free_mk_t(value);
2597 value = mk_t_caidvaluetab(&rdr->cacheex.cacheex_nopushafter_tab);
2598 tpl_addVar(vars, TPLADD, "CACHEEXNOPUSHAFTER", value);
2599 free_mk_t(value);
2600 #endif
2601 #endif
2603 // BoxID
2604 if(rdr->boxid)
2605 { tpl_printf(vars, TPLADD, "BOXID", "%08X", rdr->boxid); }
2607 // Filt 07
2608 if(!apicall)
2610 tpl_addVar(vars, TPLADD, "FIX07CHECKED", (rdr->fix_07 == 1) ? "checked" : "");
2612 else
2614 tpl_addVar(vars, TPLADD, "FIX07VALUE", (rdr->fix_07 == 1) ? "1" : "0");
2618 // Fix 9993
2619 if(!apicall)
2621 tpl_addVar(vars, TPLADD, "FIX9993CHECKED", (rdr->fix_9993 == 1) ? "checked" : "");
2623 else
2625 tpl_addVar(vars, TPLADD, "FIX9993VALUE", (rdr->fix_9993 == 1) ? "1" : "0");
2628 // Drop CWs with wrong checksum:
2629 if(!apicall)
2631 tpl_addVar(vars, TPLADD, "DROPBADCWSCHECKED", (rdr->dropbadcws == 1) ? "checked" : "");
2633 else
2635 tpl_addVar(vars, TPLADD, "DROPBADCWSVALUE", (rdr->dropbadcws == 1) ? "1" : "0");
2638 // Disable CWs checksum test:
2639 if(!apicall)
2641 tpl_addVar(vars, TPLADD, "DISABLECRCCWSCHECKED", (rdr->disablecrccws == 1) ? "checked" : "");
2643 else
2645 tpl_addVar(vars, TPLADD, "DISABLECRCCWSVALUE", (rdr->disablecrccws == 1) ? "1" : "0");
2648 // Set reader to use GPIO
2649 if(!apicall)
2651 tpl_addVar(vars, TPLADD, "USE_GPIOCHECKED", rdr->use_gpio ? "checked" : "");
2653 else
2655 tpl_addVar(vars, TPLADD, "USE_GPIOVALUE", rdr->use_gpio ? "1" : "0");
2658 // AUdisabled
2659 if(!apicall)
2661 tpl_addVar(vars, TPLADD, "AUDISABLED", (rdr->audisabled == 1) ? "checked" : "");
2663 else
2665 tpl_addVar(vars, TPLADD, "AUDISABLEDVALUE", (rdr->audisabled == 1) ? "1" : "0");
2668 tpl_printf(vars, TPLADD, "TMP", "AUTYPE%d", rdr->autype);
2669 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
2671 // AUprovid
2672 if(rdr->auprovid)
2673 { tpl_printf(vars, TPLADD, "AUPROVID", "%06X", rdr->auprovid); }
2675 if(rdr->ecmnotfoundlimit)
2676 { tpl_printf(vars, TPLADD, "ECMNOTFOUNDLIMIT", "%u", rdr->ecmnotfoundlimit); }
2678 // Force Irdeto
2679 if(!apicall)
2681 tpl_addVar(vars, TPLADD, "FORCEIRDETOCHECKED", (rdr->force_irdeto == 1) ? "checked" : "");
2683 else
2685 tpl_addVar(vars, TPLADD, "FORCEIRDETOVALUE", (rdr->force_irdeto == 1) ? "1" : "0");
2688 // needsemmfirst
2690 if(!apicall)
2692 tpl_addVar(vars, TPLADD, "NEEDSEMMFIRST", (rdr->needsemmfirst == 1) ? "checked" : "");
2694 else
2696 tpl_addVar(vars, TPLADD, "NEEDSEMMFIRST", (rdr->needsemmfirst == 1) ? "1" : "0");
2699 #ifdef READER_CRYPTOWORKS
2700 // needsglobalfirst
2701 if(!apicall)
2703 tpl_addVar(vars, TPLADD, "NEEDSGLOBALFIRST", (rdr->needsglobalfirst == 1) ? "checked" : "");
2705 else
2707 tpl_addVar(vars, TPLADD, "NEEDSGLOBALFIRST", (rdr->needsglobalfirst == 1) ? "1" : "0");
2709 #endif
2711 // RSA Key
2712 int32_t len = rdr->rsa_mod_length;
2713 if(len > 0)
2715 for(i = 0; i < len; i++) { tpl_printf(vars, TPLAPPEND, "RSAKEY", "%02X", rdr->rsa_mod[i]); }
2718 // 3DES Key
2719 len = rdr->des_key_length;
2720 if(len > 0)
2722 for(i = 0; i < len; i++) { tpl_printf(vars, TPLAPPEND, "DESKEY", "%02X", rdr->des_key[i]); }
2725 // BoxKey
2726 len = rdr->boxkey_length;
2727 if(len > 0)
2729 for(i = 0; i < len ; i++)
2730 { tpl_printf(vars, TPLAPPEND, "BOXKEY", "%02X", rdr->boxkey[i]); }
2733 #ifdef READER_CONAX
2734 // CWPK Key
2735 len = rdr->cwpk_mod_length;
2736 if(len > 0)
2738 for(i = 0; i < len; i++) { tpl_printf(vars, TPLAPPEND, "CWPKKEY", "%02X", rdr->cwpk_mod[i]); }
2740 #endif
2742 #ifdef READER_NAGRA
2743 // nuid (CAK6.3)
2744 len = rdr->cak63nuid_length;
2745 if(len > 0)
2747 for(i = 0; i < len ; i++)
2748 { tpl_printf(vars, TPLAPPEND, "CAK63NUID", "%02X", rdr->cak63nuid[i]); }
2751 // cwekey (CAK6.3)
2752 len = rdr->cak63cwekey_length;
2753 if(len > 0)
2755 for(i = 0; i < len ; i++)
2756 { tpl_printf(vars, TPLAPPEND, "CAK63CWEKEY", "%02X", rdr->cak63cwekey[i]); }
2758 #endif
2760 #ifdef READER_NAGRA_MERLIN
2761 // idird (CAK7)
2762 len = rdr->idird_length;
2763 if(len > 0)
2765 for(i = 0; i < len ; i++)
2766 { tpl_printf(vars, TPLAPPEND, "IDIRD", "%02X", rdr->idird[i]); }
2769 // cmd0e_provider (CAK7)
2770 len = rdr->cmd0eprov_length;
2771 if(len > 0)
2773 for(i = 0; i < len ; i++)
2774 { tpl_printf(vars, TPLAPPEND, "CMD0EPROV", "%02X", rdr->cmd0eprov[i]); }
2777 // mod1 (CAK7)
2778 len = rdr->mod1_length;
2779 if(len > 0)
2781 for(i = 0; i < len ; i++)
2782 { tpl_printf(vars, TPLAPPEND, "MOD1", "%02X", rdr->mod1[i]); }
2785 // mod2 (CAK7)
2786 len = rdr->mod2_length;
2787 if(len > 0)
2789 for(i = 0; i < len ; i++)
2790 { tpl_printf(vars, TPLAPPEND, "MOD2", "%02X", rdr->mod2[i]); }
2793 // key3588 (CAK7)
2794 len = rdr->key3588_length;
2795 if(len > 0)
2797 for(i = 0; i < len ; i++)
2798 { tpl_printf(vars, TPLAPPEND, "KEY3588", "%02X", rdr->key3588[i]); }
2801 // key3310 (CAK7)
2802 len = rdr->key3310_length;
2803 if(len > 0)
2805 for(i = 0; i < len ; i++)
2806 { tpl_printf(vars, TPLAPPEND, "KEY3310", "%02X", rdr->key3310[i]); }
2809 // key3460 (CAK7)
2810 len = rdr->key3460_length;
2811 if(len > 0)
2813 for(i = 0; i < len ; i++)
2814 { tpl_printf(vars, TPLAPPEND, "KEY3460", "%02X", rdr->key3460[i]); }
2817 // data50 (CAK7)
2818 len = rdr->data50_length;
2819 if(len > 0)
2821 for(i = 0; i < len ; i++)
2822 { tpl_printf(vars, TPLAPPEND, "DATA50", "%02X", rdr->data50[i]); }
2825 // mod50 (CAK7)
2826 len = rdr->mod50_length;
2827 if(len > 0)
2829 for(i = 0; i < len ; i++)
2830 { tpl_printf(vars, TPLAPPEND, "MOD50", "%02X", rdr->mod50[i]); }
2833 // nuid (CAK7)
2834 len = rdr->nuid_length;
2835 if(len > 0)
2837 for(i = 0; i < len ; i++)
2838 { tpl_printf(vars, TPLAPPEND, "NUID", "%02X", rdr->nuid[i]); }
2841 // OTP CSC (CAK7)
2842 len = rdr->otpcsc_length;
2843 if(len > 0)
2845 for(i = 0; i < len ; i++)
2846 { tpl_printf(vars, TPLAPPEND, "OTPCSC", "%02X", rdr->otpcsc[i]); }
2849 // OTA CSC (CAK7)
2850 len = rdr->otacsc_length;
2851 if(len > 0)
2853 for(i = 0; i < len ; i++)
2854 { tpl_printf(vars, TPLAPPEND, "OTACSC", "%02X", rdr->otacsc[i]); }
2857 // Force Pairing Type (CAK7)
2858 len = rdr->forcepair_length;
2859 if(len > 0)
2861 for(i = 0; i < len ; i++)
2862 { tpl_printf(vars, TPLAPPEND, "FORCEPAIR", "%02X", rdr->forcepair[i]); }
2865 // cwekey0 (CAK7)
2866 len = rdr->cwekey0_length;
2867 if(len > 0)
2869 for(i = 0; i < len ; i++)
2870 { tpl_printf(vars, TPLAPPEND, "CWEKEY0", "%02X", rdr->cwekey0[i]); }
2873 // cwekey1 (CAK7)
2874 len = rdr->cwekey1_length;
2875 if(len > 0)
2877 for(i = 0; i < len ; i++)
2878 { tpl_printf(vars, TPLAPPEND, "CWEKEY1", "%02X", rdr->cwekey1[i]); }
2881 // cwekey2 (CAK7)
2882 len = rdr->cwekey2_length;
2883 if(len > 0)
2885 for(i = 0; i < len ; i++)
2886 { tpl_printf(vars, TPLAPPEND, "CWEKEY2", "%02X", rdr->cwekey2[i]); }
2889 // cwekey3 (CAK7)
2890 len = rdr->cwekey3_length;
2891 if(len > 0)
2893 for(i = 0; i < len ; i++)
2894 { tpl_printf(vars, TPLAPPEND, "CWEKEY3", "%02X", rdr->cwekey3[i]); }
2897 // cwekey4 (CAK7)
2898 len = rdr->cwekey4_length;
2899 if(len > 0)
2901 for(i = 0; i < len ; i++)
2902 { tpl_printf(vars, TPLAPPEND, "CWEKEY4", "%02X", rdr->cwekey4[i]); }
2905 // cwekey5 (CAK7)
2906 len = rdr->cwekey5_length;
2907 if(len > 0)
2909 for(i = 0; i < len ; i++)
2910 { tpl_printf(vars, TPLAPPEND, "CWEKEY5", "%02X", rdr->cwekey5[i]); }
2913 // cwekey6 (CAK7)
2914 len = rdr->cwekey6_length;
2915 if(len > 0)
2917 for(i = 0; i < len ; i++)
2918 { tpl_printf(vars, TPLAPPEND, "CWEKEY6", "%02X", rdr->cwekey6[i]); }
2921 // cwekey7 (CAK7)
2922 len = rdr->cwekey7_length;
2923 if(len > 0)
2925 for(i = 0; i < len ; i++)
2926 { tpl_printf(vars, TPLAPPEND, "CWEKEY7", "%02X", rdr->cwekey7[i]); }
2929 // force_cw_swap
2930 if(rdr->forcecwswap)
2931 { tpl_addVar(vars, TPLADD, "FORCECWSWAPCHECKED", "checked"); }
2933 // only_even_SA
2934 if(rdr->evensa)
2935 { tpl_addVar(vars, TPLADD, "EVENSACHECKED", "checked"); }
2937 // force_EMM_82
2938 if(rdr->forceemmg)
2939 { tpl_addVar(vars, TPLADD, "FORCEEMMGCHECKED", "checked"); }
2941 // OTA_CWPKs
2942 if(rdr->cwpkota)
2943 { tpl_addVar(vars, TPLADD, "CWPKOTACHECKED", "checked"); }
2944 #endif
2946 // CWPK CaID (CAK7)
2947 len = rdr->cwpkcaid_length;
2948 if(len > 0)
2950 for(i = 0; i < len ; i++)
2951 { tpl_printf(vars, TPLAPPEND, "CWPKCAID", "%02X", rdr->cwpkcaid[i]); }
2954 // cak7_mode
2955 if(rdr->cak7_mode)
2956 { tpl_addVar(vars, TPLADD, "NAGRACAK7MODECHECKED", "checked"); }
2958 // ins7E
2959 if(rdr->ins7E[0x1A])
2961 for(i = 0; i < 26 ; i++) { tpl_printf(vars, TPLAPPEND, "INS7E", "%02X", rdr->ins7E[i]); }
2963 // ins42
2964 if(rdr->ins42[0x25])
2966 for(i = 0; i < 37 ; i++) { tpl_printf(vars, TPLAPPEND, "INS42", "%02X", rdr->ins42[i]); }
2969 // ins7E11
2970 if(rdr->ins7E11[0x01])
2972 tpl_printf(vars, TPLAPPEND, "INS7E11", "%02X", rdr->ins7E11[0]);
2975 // ins2e06
2976 if(rdr->ins2e06[0x04])
2978 for(i = 0; i < 4 ; i++) { tpl_printf(vars, TPLAPPEND, "INS2E06", "%02X", rdr->ins2e06[i]); }
2981 // k1 for generic pairing mode
2982 if(rdr->k1_generic[0x10])
2984 for(i = 0; i < rdr->k1_generic[0x10] ; i++) { tpl_printf(vars, TPLAPPEND, "K1_GENERIC", "%02X", rdr->k1_generic[i]); }
2987 // k1 for unique pairing mode
2988 if(rdr->k1_unique[0x10])
2990 for(i = 0; i < rdr->k1_unique[0x10] ; i++) { tpl_printf(vars, TPLAPPEND, "K1_UNIQUE", "%02X", rdr->k1_unique[i]); }
2993 // ATR
2994 if(rdr->atr[0])
2995 for(i = 0; i < rdr->atrlen / 2; i++)
2996 { tpl_printf(vars, TPLAPPEND, "ATR", "%02X", rdr->atr[i]); }
2998 // ECM Whitelist
2999 value = mk_t_ecm_whitelist(&rdr->ecm_whitelist);
3000 tpl_addVar(vars, TPLADD, "ECMWHITELIST", value);
3001 free_mk_t(value);
3003 // ECM Header Whitelist
3004 value = mk_t_ecm_hdr_whitelist(&rdr->ecm_hdr_whitelist);
3005 tpl_addVar(vars, TPLADD, "ECMHEADERWHITELIST", value);
3006 free_mk_t(value);
3008 // Deprecated
3009 if(!apicall)
3011 tpl_addVar(vars, TPLADD, "DEPRECATEDCHECKED", (rdr->deprecated == 1) ? "checked" : "");
3013 else
3015 tpl_addVar(vars, TPLADD, "DEPRECATEDVALUE", (rdr->deprecated == 1) ? "1" : "0");
3018 // Smargopatch
3019 if(!apicall)
3021 tpl_addVar(vars, TPLADD, "SMARGOPATCHCHECKED", (rdr->smargopatch == 1) ? "checked" : "");
3023 else
3025 tpl_addVar(vars, TPLADD, "SMARGOPATCHVALUE", (rdr->smargopatch == 1) ? "1" : "0");
3028 // Autospeed
3029 if(!apicall)
3031 tpl_addVar(vars, TPLADD, "AUTOSPEEDCHECKED", (rdr->autospeed == 1) ? "checked" : "");
3033 else
3035 tpl_addVar(vars, TPLADD, "AUTOSPEEDVALUE", (rdr->autospeed == 1) ? "1" : "0");
3037 // sc8in1 dtrrts patch
3038 if(!apicall)
3040 tpl_addVar(vars, TPLADD, "SC8IN1DTRRTSPATCHCHECKED", (rdr->sc8in1_dtrrts_patch == 1) ? "checked" : "");
3042 else
3044 tpl_addVar(vars, TPLADD, "SC8IN1DTRRTSPATCHVALUE", (rdr->sc8in1_dtrrts_patch == 1) ? "1" : "0");
3047 if(!apicall)
3049 tpl_addVar(vars, TPLADD, "READOLDCLASSES", (rdr->read_old_classes == 1) ? "checked" : "");
3051 else
3053 tpl_addVar(vars, TPLADD, "READOLDCLASSES", (rdr->read_old_classes == 1) ? "1" : "0");
3056 // Detect
3057 if(rdr->detect & 0x80)
3058 { tpl_printf(vars, TPLADD, "DETECT", "!%s", RDR_CD_TXT[rdr->detect & 0x7f]); }
3059 else
3060 { tpl_addVar(vars, TPLADD, "DETECT", RDR_CD_TXT[rdr->detect & 0x7f]); }
3062 // Ratelimit
3063 if(rdr->ratelimitecm)
3065 tpl_printf(vars, TPLADD, "RATELIMITECM", "%d", rdr->ratelimitecm);
3066 // ECMUNIQUE
3067 if(!apicall)
3069 tpl_addVar(vars, TPLADD, "ECMUNIQUECHECKED", (rdr->ecmunique == 1) ? "checked" : "");
3071 else
3073 tpl_addVar(vars, TPLADD, "ECMUNIQUE", (rdr->ecmunique == 1) ? "1" : "0");
3075 tpl_printf(vars, TPLADD, "RATELIMITTIME", "%d", rdr->ratelimittime);
3076 tpl_printf(vars, TPLADD, "SRVIDHOLDTIME", "%d", rdr->srvidholdtime);
3078 // Cooldown
3079 if(rdr->cooldown[0] && rdr->cooldown[1])
3081 tpl_printf(vars, TPLADD, "COOLDOWNDELAY", "%d", rdr->cooldown[0]);
3082 tpl_printf(vars, TPLADD, "COOLDOWNTIME", "%d", rdr->cooldown[1]);
3084 // Frequencies
3085 tpl_printf(vars, TPLADD, "MHZ", "%d", rdr->mhz);
3086 tpl_printf(vars, TPLADD, "CARDMHZ", "%d", rdr->cardmhz);
3088 // Device
3089 if(!apicall)
3091 tpl_addVar(vars, TPLADD, "DEVICE", xml_encode(vars, rdr->device));
3093 else
3095 tpl_addVar(vars, TPLADD, "DEVICE", rdr->device);
3098 if(rdr->r_port)
3099 { tpl_printf(vars, TPLAPPEND, "DEVICE", ",%d", rdr->r_port); }
3100 if(rdr->l_port)
3102 if(rdr->r_port)
3103 { tpl_printf(vars, TPLAPPEND, "DEVICE", ",%d", rdr->l_port); }
3104 else
3105 { tpl_printf(vars, TPLAPPEND, "DEVICE", ",,%d", rdr->l_port); }
3108 // Group
3109 value = mk_t_group(rdr->grp);
3110 tpl_addVar(vars, TPLADD, "GRP", value);
3111 free_mk_t(value);
3113 #ifdef WITH_LB
3114 if(rdr->lb_weight)
3115 { tpl_printf(vars, TPLADD, "LBWEIGHT", "%d", rdr->lb_weight); }
3116 #endif
3118 //services
3119 if(!apicall)
3121 struct s_sidtab *sidtab = cfg.sidtab;
3122 //build matrix
3123 i = 0;
3124 while(sidtab != NULL)
3126 tpl_addVar(vars, TPLADD, "SIDLABEL", xml_encode(vars, sidtab->label));
3127 if(rdr->sidtabs.ok & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
3128 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
3129 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "READERCONFIGSIDOKBIT"));
3130 if(rdr->sidtabs.no & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
3131 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
3132 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "READERCONFIGSIDNOBIT"));
3133 if(rdr->lb_sidtabs.ok & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
3134 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
3135 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "READERCONFIGSIDLBOKBIT"));
3136 sidtab = sidtab->next;
3137 i++;
3139 if(i){
3140 tpl_addVar(vars, TPLADD, "READERCONFIGSIDINS", tpl_getTpl(vars, "READERCONFIGSID"));
3143 else
3145 value = mk_t_service(&rdr->sidtabs);
3146 if(cs_strlen(value) > 0)
3147 { tpl_addVar(vars, TPLADD, "SERVICES", value); }
3148 free_mk_t(value);
3151 // CAID
3152 value = mk_t_caidtab(&rdr->ctab);
3153 tpl_addVar(vars, TPLADD, "CAIDS", value);
3154 free_mk_t(value);
3156 // AESkeys
3157 value = mk_t_aeskeys(rdr);
3158 tpl_addVar(vars, TPLADD, "AESKEYS", value);
3159 free_mk_t(value);
3161 //ident
3162 value = mk_t_ftab(&rdr->ftab);
3163 tpl_addVar(vars, TPLADD, "IDENTS", value);
3164 free_mk_t(value);
3166 //CHID
3167 value = mk_t_ftab(&rdr->fchid);
3168 tpl_addVar(vars, TPLADD, "CHIDS", value);
3169 free_mk_t(value);
3171 //Local cards
3172 value = mk_t_ftab(&rdr->localcards);
3173 tpl_addVar(vars, TPLADD, "LOCALCARDS", value);
3174 free_mk_t(value);
3176 //class
3177 value = mk_t_cltab(&rdr->cltab);
3178 tpl_addVar(vars, TPLADD, "CLASS", value);
3179 free_mk_t(value);
3181 if(rdr->cachemm || rdr->logemm)
3182 { tpl_printf(vars, TPLADD, "EMMCACHE", "%d,%d,%d,%d", rdr->cachemm, rdr->rewritemm, rdr->logemm, rdr->deviceemm); }
3184 //savenano
3185 value = mk_t_nano(rdr->s_nano);
3186 tpl_addVar(vars, TPLADD, "SAVENANO", value);
3187 free_mk_t(value);
3189 //blocknano
3190 value = mk_t_nano(rdr->b_nano);
3191 tpl_addVar(vars, TPLADD, "BLOCKNANO", value);
3192 free_mk_t(value);
3194 // Blocke EMM
3195 if(!apicall)
3197 tpl_addVar(vars, TPLADD, "BLOCKEMMUNKNOWNCHK", (rdr->blockemm & EMM_UNKNOWN) ? "checked" : "");
3198 tpl_addVar(vars, TPLADD, "BLOCKEMMUNIQCHK", (rdr->blockemm & EMM_UNIQUE) ? "checked" : "");
3199 tpl_addVar(vars, TPLADD, "BLOCKEMMSHAREDCHK", (rdr->blockemm & EMM_SHARED) ? "checked" : "");
3200 tpl_addVar(vars, TPLADD, "BLOCKEMMGLOBALCHK", (rdr->blockemm & EMM_GLOBAL) ? "checked" : "");
3202 else
3204 tpl_addVar(vars, TPLADD, "BLOCKEMMUNKNOWNVALUE", (rdr->blockemm & EMM_UNKNOWN) ? "1" : "0");
3205 tpl_addVar(vars, TPLADD, "BLOCKEMMUNIQVALUE", (rdr->blockemm & EMM_UNIQUE) ? "1" : "0");
3206 tpl_addVar(vars, TPLADD, "BLOCKEMMSHAREDVALUE", (rdr->blockemm & EMM_SHARED) ? "1" : "0");
3207 tpl_addVar(vars, TPLADD, "BLOCKEMMGLOBALVALUE", (rdr->blockemm & EMM_GLOBAL) ? "1" : "0");
3210 // Save EMM
3211 if(!apicall)
3213 tpl_addVar(vars, TPLADD, "SAVEEMMUNKNOWNCHK", (rdr->saveemm & EMM_UNKNOWN) ? "checked" : "");
3214 tpl_addVar(vars, TPLADD, "SAVEEMMUNIQCHK", (rdr->saveemm & EMM_UNIQUE) ? "checked" : "");
3215 tpl_addVar(vars, TPLADD, "SAVEEMMSHAREDCHK", (rdr->saveemm & EMM_SHARED) ? "checked" : "");
3216 tpl_addVar(vars, TPLADD, "SAVEEMMGLOBALCHK", (rdr->saveemm & EMM_GLOBAL) ? "checked" : "");
3218 else
3220 tpl_addVar(vars, TPLADD, "SAVEEMMUNKNOWNVALUE", (rdr->saveemm & EMM_UNKNOWN) ? "1" : "0");
3221 tpl_addVar(vars, TPLADD, "SAVEEMMUNIQVALUE", (rdr->saveemm & EMM_UNIQUE) ? "1" : "0");
3222 tpl_addVar(vars, TPLADD, "SAVEEMMSHAREDVALUE", (rdr->saveemm & EMM_SHARED) ? "1" : "0");
3223 tpl_addVar(vars, TPLADD, "SAVEEMMGLOBALVALUE", (rdr->saveemm & EMM_GLOBAL) ? "1" : "0");
3226 value = mk_t_emmbylen(rdr);
3227 if(cs_strlen(value) > 0)
3228 { tpl_addVar(vars, TPLADD, "BLOCKEMMBYLEN", value); }
3229 free_mk_t(value);
3231 #ifdef MODULE_CCCAM
3232 if(!strcmp(rdr->cc_version, "2.0.11"))
3234 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED0", "selected");
3236 else if(!strcmp(rdr->cc_version, "2.1.1"))
3238 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED1", "selected");
3240 else if(!strcmp(rdr->cc_version, "2.1.2"))
3242 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED2", "selected");
3244 else if(!strcmp(rdr->cc_version, "2.1.3"))
3246 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED3", "selected");
3248 else if(!strcmp(rdr->cc_version, "2.1.4"))
3250 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED4", "selected");
3252 else if(!strcmp(rdr->cc_version, "2.2.0"))
3254 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED5", "selected");
3256 else if(!strcmp(rdr->cc_version, "2.2.1"))
3258 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED6", "selected");
3260 else if(!strcmp(rdr->cc_version, "2.3.0"))
3262 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED7", "selected");
3264 else if(!strcmp(rdr->cc_version, "2.3.1"))
3266 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED8", "selected");
3268 else if(!strcmp(rdr->cc_version, "2.3.2"))
3270 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED9", "selected");
3272 #endif
3274 tpl_printf(vars, TPLADD, "TMP", "NDSVERSION%d", rdr->ndsversion);
3275 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3277 tpl_printf(vars, TPLADD, "TMP", "NDSREADTIERS%d", rdr->readtiers);
3278 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3280 tpl_printf(vars, TPLADD, "TMP", "NAGRAREAD%d", rdr->nagra_read);
3281 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3283 if(rdr->detect_seca_nagra_tunneled_card)
3284 { tpl_addVar(vars, TPLADD, "NAGRADETECTSECACARDCHECKED", "checked"); }
3286 #ifdef MODULE_CCCAM
3287 tpl_printf(vars, TPLADD, "CCCMAXHOPS", "%d", rdr->cc_maxhops);
3288 tpl_printf(vars, TPLADD, "CCCMINDOWN", "%d", rdr->cc_mindown);
3289 tpl_printf(vars, TPLADD, "CCCRESHARE", "%d", rdr->cc_reshare);
3290 tpl_printf(vars, TPLADD, "RESHARE", "%d", cfg.cc_reshare);
3291 tpl_printf(vars, TPLADD, "CCCRECONNECT", "%d", rdr->cc_reconnect);
3293 if(rdr->cc_want_emu)
3294 { tpl_addVar(vars, TPLADD, "CCCWANTEMUCHECKED", "checked"); }
3295 if(rdr->cc_keepalive)
3296 { tpl_addVar(vars, TPLADD, "KEEPALIVECHECKED", "checked"); }
3297 #endif
3299 #ifdef MODULE_GBOX
3300 tpl_printf(vars, TPLADD, "GBOXMAXDISTANCE", "%d", rdr->gbox_maxdist);
3301 tpl_printf(vars, TPLADD, "GBOXMAXECMSEND", "%d", rdr->gbox_maxecmsend);
3302 tpl_printf(vars, TPLADD, "GBOXRESHARE", "%d", rdr->gbox_reshare);
3303 tpl_printf(vars, TPLADD, "PEERGBOXID", "%04X", gbox_convert_password_to_id((uint32_t)a2i(rdr->r_pwd, 4)));
3304 tpl_addVar(vars, TPLADD, "PEERONLSTAT", (get_peer_onl_status(gbox_convert_password_to_id((uint32_t)a2i(rdr->r_pwd, 4)))) ? "checked" : "");
3305 tpl_printf(vars, TPLADD, "FORCEREMM", "%d", rdr->gbox_force_remm);
3306 tpl_printf(vars, TPLADD, "CMDHERE", rdr->send_offline_cmd ? "checked" : "");
3308 if(rdr->blockemm & 0x80)
3310 tpl_addVar(vars, TPLADD, "REMMCNLDCHK", "checked");
3311 tpl_printf(vars, TPLADD, "GBOXREMMPEER", "%04X", rdr->gbox_remm_peer);
3312 tpl_addVar(vars, TPLADD, "REMMUNIQCHK", (rdr->blockemm & EMM_UNIQUE) ? "" : "checked");
3313 tpl_addVar(vars, TPLADD, "REMMSHAREDCHK", (rdr->blockemm & EMM_SHARED) ? "" : "checked");
3314 tpl_addVar(vars, TPLADD, "REMMGLOBALCHK", (rdr->blockemm & EMM_GLOBAL) ? "" : "checked");
3315 tpl_addVar(vars, TPLADD, "REMMEMMUNKNOWNCHK", (rdr->blockemm & EMM_UNKNOWN) ? "" : "checked");
3317 if(rdr->gbox_gsms_peer)
3319 tpl_printf(vars, TPLADD, "LASTGSMS", "%s", rdr->last_gsms);
3320 tpl_printf(vars, TPLADD, "GBOXGSMSPEER", "%04X", rdr->gbox_gsms_peer);
3322 #endif
3324 #ifdef READER_DRECAS
3325 tpl_addVar(vars, TPLADD, "STMKEYS", rdr->stmkeys);
3326 #endif
3328 #if defined(READER_DRE) || defined(READER_DRECAS)
3329 tpl_addVar(vars, TPLADD, "USERSCRIPT", rdr->userscript);
3330 #endif
3332 #ifdef WITH_EMU
3333 //emu_auproviders
3334 value = mk_t_ftab(&rdr->emu_auproviders);
3335 tpl_addVar(vars, TPLADD, "EMUAUPROVIDERS", value);
3336 free_mk_t(value);
3338 // Date-coded BISS keys
3339 if(!apicall)
3341 tpl_addVar(vars, TPLADD, "EMUDATECODEDENABLED", (rdr->emu_datecodedenabled == 1) ? "checked" : "");
3343 else
3345 tpl_addVar(vars, TPLADD, "EMUDATECODEDENABLED", (rdr->emu_datecodedenabled == 1) ? "1" : "0");
3347 #endif
3349 tpl_addVar(vars, TPLADD, "PROTOCOL", reader_get_type_desc(rdr, 0));
3351 // Show only parameters which needed for the reader
3352 switch(rdr->typ)
3354 case R_CONSTCW:
3355 case R_DB2COM1:
3356 case R_DB2COM2:
3357 case R_MOUSE :
3358 case R_DRECAS :
3359 case R_MP35:
3360 case R_SC8in1 :
3361 case R_SMART :
3362 case R_INTERNAL:
3363 case R_SERIAL :
3364 case R_PCSC :
3365 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGSTDHWREADERBIT"));
3366 break;
3367 case R_CAMD35 :
3368 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGCAMD35BIT"));
3369 break;
3370 case R_EMU :
3371 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGEMUBIT"));
3372 break;
3373 case R_CS378X :
3374 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGCS378XBIT"));
3375 break;
3376 case R_RADEGAST:
3377 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGRADEGASTBIT"));
3378 break;
3379 case R_SCAM:
3380 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGSCAMBIT"));
3381 break;
3382 case R_GHTTP:
3383 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGGHTTPBIT"));
3384 break;
3385 case R_GBOX:
3386 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGGBOXBIT"));
3387 #if defined (MODULE_CCCAM) && defined (MODULE_GBOX)
3388 if(cfg.cc_gbx_reshare_en)
3390 tpl_printf(vars, TPLADD, "GBOXCCCAMRESHARE", "%d", rdr->gbox_cccam_reshare);
3391 value = mk_t_ftab(&rdr->ccc_gbx_reshare_ident);
3392 tpl_addVar(vars, TPLADD, "CCCGBXRESHAREIDENT", value);
3393 free_mk_t(value);
3394 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "GBOXCCCAMRESHAREBIT"));
3396 #endif
3397 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERINFOGBOXREMM"));
3398 break;
3399 case R_NEWCAMD:
3400 if(rdr->ncd_proto == NCD_525)
3402 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGNCD525BIT"));
3404 else if(rdr->ncd_proto == NCD_524)
3406 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGNCD524BIT"));
3408 break;
3409 #ifdef MODULE_CCCAM
3410 case R_CCCAM :
3411 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGCCCAMBIT"));
3412 break;
3413 #endif
3414 default :
3415 tpl_addMsg(vars, "Error: protocol not resolvable");
3416 break;
3420 #ifdef MODULE_CCCAM
3421 if(rdr->typ != R_CCCAM && rdr->typ != R_GBOX)
3423 tpl_printf(vars, TPLADD, "CCCHOP", "%d", rdr->cc_hop);
3424 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGHOPBIT"));
3426 #endif
3428 #ifdef CS_CACHEEX_AIO
3429 return tpl_getTpl(vars, "READERCONFIGAIO");
3430 #else
3431 return tpl_getTpl(vars, "READERCONFIG");
3432 #endif
3435 static char *send_oscam_reader_stats(struct templatevars *vars, struct uriparams *params, int32_t apicall)
3438 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
3440 int8_t error;
3441 struct s_client *cl = NULL;
3442 struct s_reader *rdr;
3444 rdr = get_reader_by_label(getParam(params, "label"));
3445 error = (rdr ? 0 : 1);
3447 if(!error && rdr)
3449 cl = rdr->client;
3450 error = (cl ? 0 : 1);
3453 if(error)
3455 tpl_addVar(vars, TPLAPPEND, "READERSTATSROW", tpl_getTpl(vars, "READERSTATSROWBIT"));
3456 if(!apicall)
3457 { return tpl_getTpl(vars, "READERSTATS"); }
3458 else
3459 { return tpl_getTpl(vars, "APIREADERSTATS"); }
3462 #ifdef WITH_LB
3463 char *stxt[] = {"found", "cache1", "cache2", "cache3",
3464 "not found", "timeout", "sleeping",
3465 "fake", "invalid", "corrupt", "no card", "expdate",
3466 "disabled", "stopped"
3469 if(strcmp(getParam(params, "action"), "resetstat") == 0)
3471 char *rcs = getParam(params, "rc");
3472 int32_t retval = 0;
3473 if(cs_strlen(rcs) > 0)
3475 int8_t rc;
3476 rc = atoi(rcs);
3477 retval = clean_stat_by_rc(rdr, rc, 0);
3478 cs_log("Reader %s stats %d %s entr%s deleted by WebIF from %s",
3479 rdr->label, retval, stxt[rc],
3480 retval == 1 ? "y" : "ies",
3481 cs_inet_ntoa(GET_IP()));
3483 else
3485 clear_reader_stat(rdr);
3486 cs_log("Reader %s stats resetted by WebIF from %s", rdr->label, cs_inet_ntoa(GET_IP()));
3491 if(strcmp(getParam(params, "action"), "deleterecord") == 0)
3493 char *record = getParam(params, "record");
3494 if(cs_strlen(record) > 0)
3496 int32_t retval = 0;
3497 uint32_t caid, provid, sid, cid, len;
3498 sscanf(record, "%4x@%6x:%4x:%4x:%4x", &caid, &provid, &sid, &cid, &len);
3499 retval = clean_stat_by_id(rdr, caid, provid, sid, cid, len);
3500 cs_log("Reader %s stats %d entr%s deleted by WebIF from %s",
3501 rdr->label, retval,
3502 retval == 1 ? "y" : "ies",
3503 cs_inet_ntoa(GET_IP()));
3507 if(strcmp(getParam(params, "action"), "updateecmlen") == 0)
3509 update_ecmlen_from_stat(rdr);
3510 write_server();
3513 #endif
3515 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
3516 tpl_addVar(vars, TPLADD, "LABEL", xml_encode(vars, rdr->label));
3517 tpl_addVar(vars, TPLADD, "ENCODEDLABEL", urlencode(vars, rdr->label));
3519 if(apicall)
3521 int32_t i, emmcount = 0;
3522 char *ttxt[] = {"unknown", "unique", "shared", "global"};
3524 for(i = 0; i < 4; i++)
3526 tpl_addVar(vars, TPLADD, "EMMRESULT", "error");
3527 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
3528 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmerror[i]);
3529 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
3530 emmcount += rdr->emmerror[i];
3531 tpl_printf(vars, TPLADD, "TOTALERROR", "%d", emmcount);
3533 emmcount = 0;
3534 for(i = 0; i < 4; i++)
3536 tpl_addVar(vars, TPLADD, "EMMRESULT", "written");
3537 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
3538 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmwritten[i]);
3539 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
3540 emmcount += rdr->emmwritten[i];
3541 tpl_printf(vars, TPLADD, "TOTALWRITTEN", "%d", emmcount);
3543 emmcount = 0;
3544 for(i = 0; i < 4; i++)
3546 tpl_addVar(vars, TPLADD, "EMMRESULT", "skipped");
3547 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
3548 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmskipped[i]);
3549 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
3550 emmcount += rdr->emmskipped[i];
3551 tpl_printf(vars, TPLADD, "TOTALSKIPPED", "%d", emmcount);
3553 emmcount = 0;
3554 for(i = 0; i < 4; i++)
3556 tpl_addVar(vars, TPLADD, "EMMRESULT", "blocked");
3557 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
3558 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmblocked[i]);
3559 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
3560 emmcount += rdr->emmblocked[i];
3561 tpl_printf(vars, TPLADD, "TOTALBLOCKED", "%d", emmcount);
3565 if(apicall)
3567 char *txt = "UNDEF";
3568 switch(rdr->card_status)
3570 case NO_CARD:
3571 if(rdr->typ == R_GBOX)
3572 { txt = "ONL no crd"; }
3573 else
3574 { txt = "OFF"; }
3575 break;
3576 case UNKNOWN:
3577 txt = "UNKNOWN";
3578 break;
3579 case READER_DEVICE_ERROR:
3580 txt = "READER DEVICE ERROR";
3581 break;
3582 case CARD_NEED_INIT:
3583 if(rdr->typ == R_GBOX)
3584 { txt = "OFFLINE"; }
3585 else
3586 { txt = "NEEDINIT"; }
3587 break;
3588 case CARD_INSERTED:
3589 if(cl->typ == 'p')
3591 if(rdr->typ == R_GBOX)
3592 { txt = "ONL w/crd"; }
3593 else
3594 { txt = "CONNECTED"; }
3596 else
3597 { txt = "CARDOK"; }
3598 break;
3599 case CARD_FAILURE:
3600 txt = "ERROR";
3601 break;
3602 default:
3603 txt = "UNDEF";
3605 tpl_addVar(vars, TPLADD, "READERSTATUS", txt);
3606 tpl_printf(vars, TPLADD, "READERCAID", "%04X", rdr->caid);
3609 int32_t rowcount = 0;
3610 uint64_t ecmcount = 0;
3611 time_t lastaccess = 0;
3613 #ifdef WITH_LB
3614 int32_t rc2hide = (-1);
3615 if(cs_strlen(getParam(params, "hide")) > 0)
3616 { rc2hide = atoi(getParam(params, "hide")); }
3618 int32_t rc2show = (-1);
3619 if(cs_strlen(getParam(params, "show")) > 0)
3620 { rc2show = atoi(getParam(params, "show")); }
3622 if(rdr->lb_stat)
3624 int32_t statsize;
3625 // @todo alno: sort by click, 0=ascending, 1=descending (maybe two buttons or reverse on second click)
3626 READER_STAT **statarray = get_sorted_stat_copy(rdr, 0, &statsize);
3627 char channame[CS_SERVICENAME_SIZE];
3628 for(; rowcount < statsize; ++rowcount)
3630 READER_STAT *s = statarray[rowcount];
3631 if(!(s->rc == rc2hide) && ((rc2show == -1) || (s->rc == rc2show)))
3633 struct tm lt;
3634 localtime_r(&s->last_received.time, &lt); // fixme we need walltime!
3635 ecmcount += s->ecm_count;
3636 if(!apicall)
3638 tpl_printf(vars, TPLADD, "CHANNEL", "%04X@%06X:%04X:%04X", s->caid, s->prid, s->srvid, s->chid);
3639 tpl_addVar(vars, TPLADD, "CHANNELNAME", xml_encode(vars, get_servicename(cur_client(), s->srvid, s->prid, s->caid, channame, sizeof(channame))));
3640 tpl_printf(vars, TPLADD, "ECMLEN", "%04hX", s->ecmlen);
3641 tpl_addVar(vars, TPLADD, "RC", stxt[s->rc]);
3642 tpl_printf(vars, TPLADD, "TIME", PRINTF_LOCAL_D " ms", s->time_avg);
3643 if(s->time_stat[s->time_idx])
3644 { tpl_printf(vars, TPLADD, "TIMELAST", PRINTF_LOCAL_D " ms", s->time_stat[s->time_idx]); }
3645 else
3646 { tpl_addVar(vars, TPLADD, "TIMELAST", ""); }
3647 tpl_printf(vars, TPLADD, "COUNT", PRINTF_LOCAL_D, s->ecm_count);
3649 if(s->last_received.time)
3651 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);
3654 else
3656 tpl_addVar(vars, TPLADD, "LAST", "never");
3659 else
3661 tpl_printf(vars, TPLADD, "ECMCAID", "%04X", s->caid);
3662 tpl_printf(vars, TPLADD, "ECMPROVID", "%06X", s->prid);
3663 tpl_printf(vars, TPLADD, "ECMSRVID", "%04X", s->srvid);
3664 tpl_printf(vars, TPLADD, "ECMLEN", "%04hX", s->ecmlen);
3665 tpl_addVar(vars, TPLADD, "ECMCHANNELNAME", xml_encode(vars, get_servicename(cur_client(), s->srvid, s->prid, s->caid, channame, sizeof(channame))));
3666 tpl_printf(vars, TPLADD, "ECMTIME", PRINTF_LOCAL_D, s->time_avg);
3667 tpl_printf(vars, TPLADD, "ECMTIMELAST", PRINTF_LOCAL_D, s->time_stat[s->time_idx]);
3668 tpl_printf(vars, TPLADD, "ECMRC", "%d", s->rc);
3669 tpl_addVar(vars, TPLADD, "ECMRCS", stxt[s->rc]);
3670 if(s->last_received.time)
3672 char tbuffer [30];
3673 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &lt);
3674 tpl_addVar(vars, TPLADD, "ECMLAST", tbuffer);
3676 else
3678 tpl_addVar(vars, TPLADD, "ECMLAST", "");
3680 tpl_printf(vars, TPLADD, "ECMCOUNT", PRINTF_LOCAL_D, s->ecm_count);
3682 if(s->last_received.time > lastaccess)
3683 { lastaccess = s->last_received.time; }
3686 if(!apicall)
3688 if(s->rc == E_NOTFOUND)
3690 tpl_addVar(vars, TPLAPPEND, "READERSTATSROWNOTFOUND", tpl_getTpl(vars, "READERSTATSBIT"));
3691 tpl_addVar(vars, TPLADD, "RESETA", urlencode(vars, rdr->label));
3692 tpl_addVar(vars, TPLADD, "READERSTATSNFHEADLINE", tpl_getTpl(vars, "READERSTATSROWNOTFOUNDBIT"));
3694 else if(s->rc == E_TIMEOUT)
3696 tpl_addVar(vars, TPLAPPEND, "READERSTATSROWTIMEOUT", tpl_getTpl(vars, "READERSTATSBIT"));
3697 tpl_addVar(vars, TPLADD, "RESETB", urlencode(vars, rdr->label));
3698 tpl_addVar(vars, TPLADD, "READERSTATSTOHEADLINE", tpl_getTpl(vars, "READERSTATSROWTIMEOUTBIT"));
3700 else if(s->rc == E_INVALID)
3702 tpl_addVar(vars, TPLAPPEND, "READERSTATSROWINVALID", tpl_getTpl(vars, "READERSTATSBIT"));
3703 tpl_addVar(vars, TPLADD, "RESETC", urlencode(vars, rdr->label));
3704 tpl_addVar(vars, TPLADD, "READERSTATSIVHEADLINE", tpl_getTpl(vars, "READERSTATSROWINVALIDBIT"));
3706 else
3707 { tpl_addVar(vars, TPLAPPEND, "READERSTATSROWFOUND", tpl_getTpl(vars, "READERSTATSBIT")); }
3709 else
3712 tpl_addVar(vars, TPLAPPEND, "ECMSTATS", tpl_getTpl(vars, "APIREADERSTATSECMBIT"));
3716 NULLFREE(statarray);
3718 else
3719 #endif
3720 tpl_addVar(vars, TPLAPPEND, "READERSTATSROW", tpl_getTpl(vars, "READERSTATSNOSTATS"));
3722 tpl_printf(vars, TPLADD, "ROWCOUNT", "%d", rowcount);
3724 if(lastaccess > 0)
3726 char tbuffer [30];
3727 struct tm lt;
3728 localtime_r(&lastaccess, &lt);
3729 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &lt);
3730 tpl_addVar(vars, TPLADD, "LASTACCESS", tbuffer);
3732 else
3734 tpl_addVar(vars, TPLADD, "LASTACCESS", "");
3737 if(apicall)
3739 if(cl)
3741 char *value = get_ecm_historystring(cl);
3742 tpl_addVar(vars, TPLADD, "ECMHISTORY", value);
3743 free_mk_t(value);
3747 tpl_printf(vars, TPLADD, "TOTALECM", "%'" PRIu64, ecmcount);
3749 if(!apicall)
3750 { return tpl_getTpl(vars, "READERSTATS"); }
3751 else
3752 { return tpl_getTpl(vars, "APIREADERSTATS"); }
3755 static char *send_oscam_user_config_edit(struct templatevars *vars, struct uriparams *params, int32_t apicall)
3757 struct s_auth *account, *ptr, *chk;
3758 char user[sizeof(first_client->account->usr)];
3760 int32_t i;
3761 int existing_insert = 0;
3763 if(!apicall) { setActiveMenu(vars, MNU_USERS); }
3765 if(strcmp(getParam(params, "action"), "Save As") == 0) { cs_strncpy(user, getParam(params, "newuser"), sizeof(user)); }
3766 else { cs_strncpy(user, getParam(params, "user"), sizeof(user)); }
3768 account = NULL;
3769 for(chk = cfg.account; chk != NULL; chk = chk->next)
3771 if(strcmp(user, chk->usr) == 0)
3772 { account = chk; }
3773 if(!existing_insert)
3775 tpl_printf(vars, TPLADD, "EXISTING_INS", "'%s'", urlencode(vars, chk->usr));
3776 existing_insert++;
3778 else
3780 tpl_printf(vars, TPLAPPEND, "EXISTING_INS", ",'%s'", urlencode(vars, chk->usr));
3784 // Create a new user if it doesn't yet
3785 if(account == NULL)
3787 i = 1;
3788 while(cs_strlen(user) < 1)
3790 snprintf(user, sizeof(user) / sizeof(char) - 1, "NEWUSER%d", i);
3791 for(account = cfg.account; account != NULL && strcmp(user, account->usr) != 0; account = account->next) { ; }
3792 if(account != NULL) { user[0] = '\0'; }
3793 ++i;
3795 if(!cs_malloc(&account, sizeof(struct s_auth))) { return "0"; }
3796 if(cfg.account == NULL) { cfg.account = account; }
3797 else
3799 for(ptr = cfg.account; ptr != NULL && ptr->next != NULL; ptr = ptr->next) { ; }
3800 ptr->next = account;
3802 account_set_defaults(account);
3803 account->disabled = 1;
3804 cs_strncpy((char *)account->usr, user, sizeof(account->usr));
3805 if(!account->grp)
3806 { account->grp = 1; }
3807 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
3808 else if(strcmp(getParam(params, "action"), "Save As") == 0) { tpl_addMsg(vars, "New user has been added with cloned settings"); }
3809 else { tpl_addMsg(vars, "New user has been added with default settings"); }
3810 // no need to refresh anything here as the account is disabled by default and there's no client with this new account anyway!
3813 if((strcmp(getParam(params, "action"), "Save") == 0) || (strcmp(getParam(params, "action"), "Save As") == 0))
3815 char servicelabels[1024] = "";
3817 for(i = 0; i < (*params).paramcount; i++)
3819 if((strcmp((*params).params[i], "action")) &&
3820 (strcmp((*params).params[i], "user")) &&
3821 (strcmp((*params).params[i], "newuser")) &&
3822 (strcmp((*params).params[i], "part")))
3825 if(!strcmp((*params).params[i], "services"))
3826 { snprintf(servicelabels + cs_strlen(servicelabels), sizeof(servicelabels) - cs_strlen(servicelabels), "%s,", (*params).values[i]); }
3827 else
3828 { chk_account((*params).params[i], (*params).values[i], account); }
3831 chk_account("services", servicelabels, account);
3833 refresh_oscam(REFR_CLIENTS);
3835 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
3836 else if(strcmp(getParam(params, "action"), "Save As") != 0) { tpl_addMsg(vars, "User Account updated and saved"); }
3839 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, account->usr));
3840 tpl_addVar(vars, TPLADD, "PASSWORD", xml_encode(vars, account->pwd));
3841 tpl_addVar(vars, TPLADD, "DESCRIPTION", xml_encode(vars, account->description));
3843 //Disabled
3844 if(!apicall)
3846 if(account->disabled)
3847 { tpl_addVar(vars, TPLADD, "DISABLEDCHECKED", "checked"); }
3849 else
3851 tpl_printf(vars, TPLADD, "DISABLEDVALUE", "%d", account->disabled);
3854 //Expirationdate
3855 struct tm timeinfo;
3856 cs_gmtime_r(&account->expirationdate, &timeinfo);
3857 char buf [80];
3858 strftime(buf, 80, "%Y-%m-%d", &timeinfo);
3859 if(strcmp(buf, "1970-01-01")) { tpl_addVar(vars, TPLADD, "EXPDATE", buf); }
3861 //Allowed TimeFrame
3862 char *allowedtf = mk_t_allowedtimeframe(account);
3863 tpl_printf(vars, TPLADD, "ALLOWEDTIMEFRAME", "%s", allowedtf);
3864 free_mk_t(allowedtf);
3866 //Group
3867 char *value = mk_t_group(account->grp);
3868 tpl_addVar(vars, TPLADD, "GROUPS", value);
3869 free_mk_t(value);
3871 // allowed protocols
3872 value = mk_t_allowedprotocols(account);
3873 tpl_addVar(vars, TPLADD, "ALLOWEDPROTOCOLS", value);
3874 free_mk_t(value);
3876 //Hostname
3877 tpl_addVar(vars, TPLADD, "DYNDNS", xml_encode(vars, account->dyndns));
3879 //Uniq
3880 if(!apicall)
3882 tpl_printf(vars, TPLADD, "TMP", "UNIQSELECTED%d", account->uniq);
3883 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3885 else
3887 tpl_printf(vars, TPLADD, "UNIQVALUE", "%d", account->uniq);
3890 //Sleep
3891 if(!account->tosleep) { tpl_addVar(vars, TPLADD, "SLEEP", "0"); }
3892 else { tpl_printf(vars, TPLADD, "SLEEP", "%d", account->tosleep); }
3894 //Monlevel selector
3895 if(!apicall)
3897 tpl_printf(vars, TPLADD, "TMP", "MONSELECTED%d", account->monlvl);
3898 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3900 else
3902 tpl_printf(vars, TPLADD, "MONVALUE", "%d", account->monlvl);
3905 //Au
3906 if(account->autoau == 1)
3907 { tpl_addVar(vars, TPLADD, "AUREADER", "1"); }
3908 else if(account->aureader_list)
3910 value = mk_t_aureader(account);
3911 tpl_addVar(vars, TPLADD, "AUREADER", value);
3912 free_mk_t(value);
3915 if(!apicall)
3917 /* SERVICES */
3918 struct s_sidtab *sidtab = cfg.sidtab;
3919 //build matrix
3920 i = 0;
3921 while(sidtab != NULL)
3923 tpl_addVar(vars, TPLADD, "SIDLABEL", xml_encode(vars, sidtab->label));
3924 if(account->sidtabs.ok & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
3925 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
3926 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "USEREDITSIDOKBIT"));
3927 if(account->sidtabs.no & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
3928 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
3929 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "USEREDITSIDNOBIT"));
3930 sidtab = sidtab->next;
3931 i++;
3933 if(i){
3934 tpl_addVar(vars, TPLADD, "USEREDITSIDINS", tpl_getTpl(vars, "USEREDITSID"));
3937 else
3939 value = mk_t_service(&account->sidtabs);
3940 if(cs_strlen(value) > 0)
3941 { tpl_addVar(vars, TPLADD, "SERVICES", value); }
3942 free_mk_t(value);
3945 // CAID
3946 value = mk_t_caidtab(&account->ctab);
3947 tpl_addVar(vars, TPLADD, "CAIDS", value);
3948 free_mk_t(value);
3950 //ident
3951 value = mk_t_ftab(&account->ftab);
3952 tpl_addVar(vars, TPLADD, "IDENTS", value);
3953 free_mk_t(value);
3955 //CHID
3956 value = mk_t_ftab(&account->fchid);
3957 tpl_addVar(vars, TPLADD, "CHIDS", value);
3958 free_mk_t(value);
3960 //class
3961 value = mk_t_cltab(&account->cltab);
3962 tpl_addVar(vars, TPLADD, "CLASS", value);
3963 free_mk_t(value);
3965 //Betatunnel
3966 value = mk_t_tuntab(&account->ttab);
3967 tpl_addVar(vars, TPLADD, "BETATUNNELS", value);
3968 free_mk_t(value);
3970 //SUPPRESSCMD08
3971 if(!apicall)
3973 if(account->c35_suppresscmd08)
3974 { tpl_addVar(vars, TPLADD, "SUPPRESSCMD08", "selected"); }
3976 else
3978 tpl_printf(vars, TPLADD, "SUPPRESSCMD08VALUE", "%d", account->c35_suppresscmd08);
3981 //Sleepsend
3982 if(account->c35_sleepsend)
3984 tpl_printf(vars, TPLADD, "SLEEPSEND", "selected");
3987 //max_connections
3988 tpl_printf(vars, TPLADD, "MAXCONNECTIONS", "%d", account->max_connections);
3990 //User Max Idle
3991 tpl_printf(vars, TPLADD, "UMAXIDLE", "%d", account->umaxidle);
3993 //EMM Reassembly selector
3994 if(!apicall)
3996 tpl_printf(vars, TPLADD, "TMP", "EMMRSELECTED%d", account->emm_reassembly);
3997 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3999 else
4001 tpl_printf(vars, TPLADD, "EMMRVALUE", "%d", account->emm_reassembly);
4004 //Prefer local cards
4005 if(!apicall)
4007 tpl_printf(vars, TPLADD, "TMP", "PREFERLOCALCARDS%d", account->preferlocalcards);
4008 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
4009 char *tmp = NULL;
4010 switch(cfg.preferlocalcards)
4012 case -1:
4013 tmp = "-1 - Use Global prefer local cards";
4014 break;
4015 case 0:
4016 tmp = "0 - local cards like proxied";
4017 break;
4018 case 1:
4019 tmp = "1 - prefer cache-ex then local cards";
4020 break;
4021 case 2:
4022 tmp = "2 - prefer local cards above cache-ex";
4023 break;
4025 tpl_addVar(vars, TPLADD, "CFGPREFERLOCALCARDS", tmp);
4027 else
4029 tpl_printf(vars, TPLADD, "PREFERLOCALCARDSVALUE", "%d", account->preferlocalcards);
4032 #ifdef CS_CACHEEX
4033 // Cacheex
4034 if(!apicall)
4036 tpl_printf(vars, TPLADD, "TMP", "CACHEEXSELECTED%d", account->cacheex.mode);
4037 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
4040 else
4042 tpl_printf(vars, TPLADD, "CACHEEX", "%d", account->cacheex.mode);
4044 tpl_printf(vars, TPLADD, "CACHEEX_MAXHOP", "%d", account->cacheex.maxhop);
4045 #ifdef CS_CACHEEX_AIO
4046 tpl_printf(vars, TPLADD, "CACHEEX_MAXHOP_LG", "%d", account->cacheex.maxhop_lg);
4047 #endif
4049 value = mk_t_cacheex_hitvaluetab(&account->cacheex.filter_caidtab);
4050 //if (cs_strlen(value) > 0)
4051 tpl_printf(vars, TPLADD, "CACHEEX_ECM_FILTER", "%s", value);
4052 free_mk_t(value);
4054 tpl_addVar(vars, TPLADD, "DCCHECKED", (account->cacheex.drop_csp == 1) ? "checked" : "");
4055 tpl_addVar(vars, TPLADD, "ARCHECKED", (account->cacheex.allow_request == 1) ? "checked" : "");
4056 tpl_addVar(vars, TPLADD, "AFCHECKED", (account->cacheex.allow_filter == 1) ? "checked" : "");
4057 #ifdef CS_CACHEEX_AIO
4058 tpl_addVar(vars, TPLADD, "AMCHECKED", (account->cacheex.allow_maxhop == 1) ? "checked" : "");
4059 #endif
4060 tpl_addVar(vars, TPLADD, "BLOCKFAKECWSCHECKED", (account->cacheex.block_fakecws == 1) ? "checked" : "");
4061 #ifdef CS_CACHEEX_AIO
4062 tpl_addVar(vars, TPLADD, "USECWCHECKFORPUSHCHECKED", (account->cacheex.cw_check_for_push == 1) ? "checked" : "");
4063 tpl_addVar(vars, TPLADD, "LGONLYREMOTESETTINGSCHECKED", (account->cacheex.lg_only_remote_settings == 1) ? "checked" : "");
4064 tpl_addVar(vars, TPLADD, "LOCALGENERATEDONLYCHECKED", (account->cacheex.localgenerated_only == 1) ? "checked" : "");
4066 value = mk_t_ftab(&account->cacheex.lg_only_tab);
4067 tpl_addVar(vars, TPLADD, "LGONLYTAB", value);
4068 free_mk_t(value);
4070 tpl_addVar(vars, TPLADD, "LOCALGENERATEDONLYINCHECKED", (account->cacheex.localgenerated_only_in == 1) ? "checked" : "");
4072 tpl_addVar(vars, TPLADD, "LGONLYINAIOONLYCHECKED", (account->cacheex.lg_only_in_aio_only == 1) ? "checked" : "");
4074 value = mk_t_ftab(&account->cacheex.lg_only_in_tab);
4075 tpl_addVar(vars, TPLADD, "LGONLYINTAB", value);
4076 free_mk_t(value);
4078 value = mk_t_caidvaluetab(&account->cacheex.cacheex_nopushafter_tab);
4079 tpl_addVar(vars, TPLADD, "CACHEEXNOPUSHAFTER", value);
4080 free_mk_t(value);
4081 #endif
4082 tpl_addVar(vars, TPLADD, "NWTCHECKED", (account->no_wait_time == 1) ? "checked" : "");
4083 tpl_addVar(vars, TPLADD, "DISABLECRCCEX4USER", (account->disablecrccacheex == 1) ? "checked" : "");
4084 value = mk_t_ftab(&account->disablecrccacheex_only_for);
4085 tpl_addVar(vars, TPLADD, "IGNCRCCEX4USERONLYFOR", value);
4086 free_mk_t(value);
4088 #endif
4090 #ifdef CW_CYCLE_CHECK
4091 tpl_addVar(vars, TPLADD, "USERCWCYCLEDISABLE", (account->cwc_disable == 1) ? "checked" : "");
4092 #endif
4094 //Keepalive
4095 if(!apicall)
4097 if(account->ncd_keepalive)
4098 { tpl_addVar(vars, TPLADD, "KEEPALIVE", "checked"); }
4100 else
4102 tpl_printf(vars, TPLADD, "KEEPALIVEVALUE", "%d", account->ncd_keepalive);
4105 #ifdef CS_ANTICASC
4106 tpl_printf(vars, TPLADD, "AC_USERS", "%d", account->ac_users);
4107 tpl_printf(vars, TPLADD, "CFGNUMUSERS", "%d", cfg.ac_users);
4108 if(!apicall)
4110 tpl_printf(vars, TPLADD, "TMP", "PENALTY%d", account->ac_penalty);
4111 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
4112 char *tmp = NULL;
4113 switch(cfg.ac_penalty)
4115 case 0:
4116 tmp = "(0) Only write to log";
4117 break;
4118 case 1:
4119 tmp = "(1) NULL CW";
4120 break;
4121 case 2:
4122 tmp = "(2) Ban";
4123 break;
4124 case 3:
4125 tmp = "(3) Real CW delayed";
4126 break;
4128 tpl_addVar(vars, TPLADD, "CFGPENALTY", tmp);
4130 else
4132 tpl_printf(vars, TPLADD, "PENALTYVALUE", "%d", account->ac_penalty);
4134 tpl_printf(vars, TPLADD, "ACOSC_MAX_ECMS_PER_MINUTE", "%d", account->acosc_max_ecms_per_minute);
4135 tpl_printf(vars, TPLADD, "ACOSC_MAX_ACTIVE_SIDS", "%d", account->acosc_max_active_sids);
4136 tpl_printf(vars, TPLADD, "CFG_ACOSC_MAX_ECMS_PER_MINUTE", "%d", cfg.acosc_max_ecms_per_minute);
4137 tpl_printf(vars, TPLADD, "CFG_ACOSC_MAX_ACTIVE_SIDS", "%d", cfg.acosc_max_active_sids);
4138 tpl_printf(vars, TPLADD, "ACOSC_ZAP_LIMIT", "%d", account->acosc_zap_limit);
4139 tpl_printf(vars, TPLADD, "CFG_ACOSC_ZAP_LIMIT", "%d", cfg.acosc_zap_limit);
4140 if(!apicall)
4142 tpl_printf(vars, TPLADD, "TMP", "ACOSC_PENALTY%d", account->acosc_penalty);
4143 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
4144 char *tmp = NULL;
4145 switch(cfg.acosc_penalty)
4147 case -1:
4148 tmp = "(-1) Use Global Value";
4149 break;
4150 case 0:
4151 tmp = "(0) Only write to log";
4152 break;
4153 case 1:
4154 tmp = "(1) NULL CW";
4155 break;
4156 case 2:
4157 tmp = "(2) Ban";
4158 break;
4159 case 3:
4160 tmp = "(3) CW delayed";
4161 break;
4162 case 4:
4163 tmp = "(4) Hidecards";
4164 break;
4166 tpl_addVar(vars, TPLADD, "CFG_ACOSC_PENALTY", tmp);
4167 } else
4169 tpl_printf(vars, TPLADD, "ACOSC_PENALTYVALUE", "%d", account->acosc_penalty);
4172 tpl_printf(vars, TPLADD, "ACOSC_PENALTY_DURATION", "%d", account->acosc_penalty_duration);
4173 tpl_printf(vars, TPLADD, "CFG_ACOSC_PENALTY_DURATION", "%d", cfg.acosc_penalty_duration);
4174 tpl_printf(vars, TPLADD, "ACOSC_DELAY", "%d", account->acosc_delay);
4175 tpl_printf(vars, TPLADD, "CFG_ACOSC_DELAY", "%d", cfg.acosc_delay);
4176 #endif
4178 #ifdef MODULE_CCCAM
4179 tpl_printf(vars, TPLADD, "CCCMAXHOPS", "%d", account->cccmaxhops);
4180 tpl_printf(vars, TPLADD, "CCCRESHARE", "%d", account->cccreshare);
4181 tpl_printf(vars, TPLADD, "RESHARE", "%d", cfg.cc_reshare);
4183 //CCcam Ignore Reshare
4184 tpl_printf(vars, TPLADD, "TMP", "CCCIGNRSHRSELECTED%d", account->cccignorereshare);
4185 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
4186 tpl_addVar(vars, TPLADD, "CFGIGNORERESHARE",
4187 cfg.cc_ignore_reshare == 0 ?
4188 "0 - use reshare level of Server" : "1 - use reshare level of Reader or User");
4190 //CCcam Stealth Mode
4191 tpl_printf(vars, TPLADD, "TMP", "CCCSTEALTHSELECTED%d", account->cccstealth);
4192 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
4194 tpl_addVar(vars, TPLADD, "STEALTH", cfg.cc_stealth ? "enable" : "disable");
4195 #endif
4197 //Failban
4198 tpl_printf(vars, TPLADD, "FAILBAN", "%d", account->failban);
4200 if(!apicall)
4202 #ifdef CS_CACHEEX_AIO
4203 return tpl_getTpl(vars, "USEREDITAIO");
4204 #else
4205 return tpl_getTpl(vars, "USEREDIT");
4206 #endif
4208 else
4210 return tpl_getTpl(vars, "APIUSEREDIT");
4215 static void webif_add_client_proto(struct templatevars *vars, struct s_client *cl, const char *proto, int8_t apicall)
4217 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTO", "");
4218 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOSORT", "");
4219 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOTITLE", "");
4220 tpl_addVar(vars, TPLADDONCE, "PROTOICON", "");
4221 if(!cl) { return; }
4222 #ifdef MODULE_NEWCAMD
4223 if(streq(proto, "newcamd") && cl->typ == 'c')
4225 tpl_printf(vars, TPLADD, "CLIENTPROTO", "%s (%s)", proto, newcamd_get_client_name(cl->ncd_client_id));
4226 tpl_printf(vars, TPLADD, "CLIENTPROTOSORT", "%s (%s)", proto, newcamd_get_client_name(cl->ncd_client_id));
4227 if(cfg.http_showpicons )
4229 char picon_name[32];
4230 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s_%s", (char *)proto, newcamd_get_client_name(cl->ncd_client_id));
4231 if(picon_exists(picon_name))
4233 if (!apicall)
4235 tpl_addVar(vars, TPLADD, "NCMDA", (char *)proto);
4236 tpl_addVar(vars, TPLADD, "NCMDB", (char *)newcamd_get_client_name(cl->ncd_client_id));
4237 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTONEWCAMDPIC"));
4239 else
4241 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s_%s",(char *)proto, (char *)newcamd_get_client_name(cl->ncd_client_id));
4244 else
4246 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s_%s.tpl", proto, newcamd_get_client_name(cl->ncd_client_id));
4249 return;
4251 #endif
4252 #ifdef MODULE_CCCAM
4253 if(strncmp(proto, "cccam", 5) == 0)
4255 struct cc_data *cc = cl->cc;
4256 if(cc && *cc->remote_version && *cc->remote_build)
4258 tpl_printf(vars, TPLADD, "CLIENTPROTO", "%s (%s-%s)", proto, cc->remote_version, cc->remote_build);
4259 tpl_printf(vars, TPLADD, "CLIENTPROTOSORT", "%s (%s-%s)", proto, cc->remote_version, cc->remote_build);
4260 if(cccam_client_multics_mode(cl))
4262 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "Multics, revision r%d", cc->multics_version[0] | (cc->multics_version[1] << 8));
4264 else
4266 #endif
4267 #ifdef CS_CACHEEX_AIO
4268 #if defined(MODULE_CCCAM) && defined(CS_CACHEEX)
4269 if(cl->reader && cl->reader->cacheex.feature_bitfield)
4271 if(cl->reader->cacheex.feature_bitfield & 32)
4273 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "%s [cx-aio %s]", (cc->extended_mode ? cc->remote_oscam : ""), cl->reader->cacheex.aio_version);
4275 else if(cl->reader->cacheex.feature_bitfield)
4277 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "%s [cx-aio < 9.2.3]", (cc->extended_mode ? cc->remote_oscam : ""));
4280 else if(cl->account && cl->account->cacheex.feature_bitfield)
4282 if(cl->account->cacheex.feature_bitfield & 32)
4284 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "%s [cx-aio %s]", (cc->extended_mode ? cc->remote_oscam : ""), cl->account->cacheex.aio_version);
4286 else if(cl->account->cacheex.feature_bitfield)
4288 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "%s [cx-aio < 9.2.3]", (cc->extended_mode ? cc->remote_oscam : ""));
4291 else
4293 #endif
4294 #endif
4295 #ifdef MODULE_CCCAM
4296 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", cc->extended_mode ? cc->remote_oscam : "");
4297 #endif
4298 #ifdef CS_CACHEEX_AIO
4299 #if defined(MODULE_CCCAM) && defined(CS_CACHEEX)
4301 #endif
4302 #endif
4303 #ifdef MODULE_CCCAM
4306 if(cfg.http_showpicons)
4308 char picon_name[32];
4310 int8_t is_other_proto = 0;
4311 if(cccam_client_multics_mode(cl)) { is_other_proto = 1; }
4313 switch(is_other_proto)
4315 case 1:
4316 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s_r_%d", proto, cc->multics_version[0] | (cc->multics_version[1] << 8));
4317 if(picon_exists(picon_name))
4319 if (!apicall)
4321 tpl_addVar(vars, TPLADD, "CCA", (char *)proto);
4322 tpl_addVar(vars, TPLADD, "CCB", "r");
4323 tpl_printf(vars, TPLADD, "CCC", "%d", cc->multics_version[0] | (cc->multics_version[1] << 8));
4324 tpl_addVar(vars, TPLADD, "CCD", "");
4325 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTOCCCAMPIC"));
4327 else
4329 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s_r_%d",(char *)proto, cc->multics_version[0] | (cc->multics_version[1] << 8));
4332 else
4334 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "Multics, revision r%d missing icon: IC_%s_r_%d.tpl",
4335 cc->multics_version[0] | (cc->multics_version[1] << 8), proto, cc->multics_version[0] | (cc->multics_version[1] << 8));
4337 break;
4339 default:
4340 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s_%s_%s", proto, cc->remote_version, cc->remote_build);
4341 if(picon_exists(picon_name))
4343 if (!apicall)
4345 tpl_addVar(vars, TPLADD, "CCA", (char *)proto);
4346 tpl_addVar(vars, TPLADD, "CCB", cc->remote_version);
4347 tpl_addVar(vars, TPLADD, "CCC", cc->remote_build);
4348 #ifdef CS_CACHEEX_AIO
4349 #if defined(MODULE_CCCAM) && defined(CS_CACHEEX)
4350 if(cl->reader && cl->reader->cacheex.feature_bitfield)
4352 if(cl->reader->cacheex.feature_bitfield & 32)
4354 tpl_printf(vars, TPLADD, "CCD", "%s [cx-aio %s]", (cc->extended_mode ? cc->remote_oscam : ""), cl->reader->cacheex.aio_version);
4356 else if(cl->reader->cacheex.feature_bitfield)
4358 tpl_printf(vars, TPLADD, "CCD", "%s [cx-aio < 9.2.3]", (cc->extended_mode ? cc->remote_oscam : ""));
4361 else if(cl->account && cl->account->cacheex.feature_bitfield)
4363 if(cl->account->cacheex.feature_bitfield & 32)
4365 tpl_printf(vars, TPLADD, "CCD", "%s [cx-aio %s]", (cc->extended_mode ? cc->remote_oscam : ""), cl->account->cacheex.aio_version);
4367 else if(cl->account->cacheex.feature_bitfield)
4369 tpl_printf(vars, TPLADD, "CCD", "%s [cx-aio < 9.2.3]", (cc->extended_mode ? cc->remote_oscam : ""));
4372 else
4374 #endif
4375 #endif
4376 tpl_addVar(vars, TPLADD, "CCD", cc->extended_mode ? cc->remote_oscam : "");
4377 #ifdef CS_CACHEEX_AIO
4378 #if defined(MODULE_CCCAM) && defined(CS_CACHEEX)
4380 #endif
4381 #endif
4382 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTOCCCAMPIC"));
4384 else
4386 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s_%s_%s",(char *)proto, cc->remote_version, cc->remote_build);
4389 else
4391 #endif
4392 #ifdef CS_CACHEEX_AIO
4393 #if defined(MODULE_CCCAM) && defined(CS_CACHEEX)
4394 if(cl->reader && cl->reader->cacheex.feature_bitfield)
4396 if(cl->reader->cacheex.feature_bitfield & 32)
4398 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);
4400 else if(cl->reader->cacheex.feature_bitfield)
4402 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);
4405 else if(cl->account && cl->account->cacheex.feature_bitfield)
4407 if(cl->account->cacheex.feature_bitfield & 32)
4409 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);
4411 else if(cl->account->cacheex.feature_bitfield)
4413 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);
4416 else
4418 #endif
4419 #endif
4420 #ifdef MODULE_CCCAM
4421 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "%s missing icon: IC_%s_%s_%s.tpl",
4422 cc->extended_mode ? cc->remote_oscam : "", proto, cc->remote_version, cc->remote_build);
4423 #ifdef CS_CACHEEX_AIO
4424 #if defined(MODULE_CCCAM) && defined(CS_CACHEEX)
4426 #endif
4427 #endif
4429 break;
4433 return;
4435 #endif
4436 #ifdef CS_CACHEEX_AIO
4437 #if (defined(MODULE_CAMD35) || defined(MODULE_CAMD35_TCP)) && defined(CS_CACHEEX)
4438 if(strncmp(proto, "cs3", 3) == 0)
4440 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTO", (char *)proto);
4442 char aiover[32];
4443 aiover[0] = '\0';
4445 if(cl->account && cl->cacheex_aio_checked)
4447 if(cl->account->cacheex.feature_bitfield & 32)
4449 snprintf(aiover, sizeof(aiover) / sizeof(char) -1, "%s", cl->account->cacheex.aio_version);
4450 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", aiover);
4452 else if(cl->account->cacheex.feature_bitfield)
4454 snprintf(aiover, sizeof(aiover) / sizeof(char) -1, "%s", "[cx-aio: < 9.2.3]");
4455 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", aiover);
4457 else
4459 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", "");
4463 if(cl->reader && cl->cacheex_aio_checked)
4465 if(cl->reader->cacheex.feature_bitfield & 32)
4467 snprintf(aiover, sizeof(aiover) / sizeof(char) -1, "%s", cl->reader->cacheex.aio_version);
4468 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", aiover);
4470 else if(cl->reader->cacheex.feature_bitfield)
4472 snprintf(aiover, sizeof(aiover) / sizeof(char) -1, "%s", "[cx-aio: < 9.2.3]");
4473 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", aiover);
4475 else
4477 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", "");
4481 if(cfg.http_showpicons)
4483 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTO", (char *)proto);
4485 char picon_name[32];
4486 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", proto);
4487 if(picon_exists(picon_name))
4489 if (!apicall)
4491 tpl_addVar(vars, TPLADD, "CAMD3A", (char *)proto);
4492 if(aiover[0] == '\0')
4493 tpl_addVar(vars, TPLADD, "AIOVER", "");
4494 else
4495 tpl_printf(vars, TPLADD, "AIOVER", "[cx-aio %s]", aiover);
4497 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTOCAMD3AIOPIC"));
4499 else
4501 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s",(char *)proto);
4504 else
4506 if(cl->account && cl->cacheex_aio_checked)
4508 if(cl->account->cacheex.feature_bitfield & 32)
4509 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s.tpl [cx-aio %s]", proto, cl->account->cacheex.aio_version);
4510 else if(cl->account->cacheex.feature_bitfield)
4511 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s.tpl [cx-aio < 9.2.3]", proto);
4512 else
4513 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s.tpl", proto);
4516 if(cl->reader && cl->cacheex_aio_checked)
4518 if(cl->reader->cacheex.feature_bitfield & 32)
4519 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s.tpl [cx-aio %s]", proto, cl->reader->cacheex.aio_version);
4520 else if(cl->reader->cacheex.feature_bitfield)
4521 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s.tpl [cx-aio < 9.2.3]", proto);
4522 else
4523 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s.tpl", proto);
4527 return;
4529 #endif
4530 #endif
4532 #ifdef HAVE_DVBAPI
4533 if(streq(proto, "dvbapi") && cl->typ == 'c' && strcmp(dvbapi_get_client_name(), ""))
4535 if (!apicall)
4536 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());
4537 else
4538 tpl_printf(vars, TPLADD, "CLIENTPROTO", "%s (client: %s, protocol version: %d)", proto, dvbapi_get_client_name(), dvbapi_get_client_proto_version());
4539 tpl_printf(vars, TPLADD, "CLIENTPROTOSORT", "%s", proto);
4540 return;
4542 #endif
4543 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTO", (char *)proto);
4544 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOSORT", (char *)proto);
4545 if(cfg.http_showpicons)
4547 char picon_name[32];
4548 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", proto);
4549 if(picon_exists(picon_name))
4551 if (!apicall)
4553 tpl_addVar(vars, TPLADD, "OTHER", (char *)proto);
4554 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTOOTHERPIC"));
4556 else
4558 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s",(char *)proto);
4561 else
4563 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s.tpl", proto);
4568 static void kill_account_thread(struct s_auth *account)
4570 struct s_client *cl;
4571 for(cl = first_client->next; cl ; cl = cl->next)
4573 if(cl->account == account)
4575 if(get_module(cl)->type & MOD_CONN_NET)
4577 kill_thread(cl);
4579 else
4581 cl->account = first_client->account;
4587 static char *send_oscam_user_config(struct templatevars *vars, struct uriparams *params, int32_t apicall)
4589 struct s_auth *account;
4590 struct s_client *cl;
4591 char *user = getParam(params, "user");
4592 int32_t found = 0;
4593 uint8_t md5tmp[MD5_DIGEST_LENGTH];
4595 if(!apicall)
4597 setActiveMenu(vars, MNU_USERS);
4599 if(strcmp(getParam(params, "action"), "reinit") == 0)
4601 if(!cfg.http_readonly)
4602 { refresh_oscam(REFR_ACCOUNTS); }
4604 if(strcmp(getParam(params, "action"), "delete") == 0)
4606 if(cfg.http_readonly)
4608 tpl_addMsg(vars, "WebIf is in readonly mode. No deletion will be made!");
4610 else
4612 struct s_auth *account_prev = NULL;
4614 for(account = cfg.account; (account); account = account->next)
4616 if(strcmp(account->usr, user) == 0)
4618 if(account_prev == NULL)
4619 { cfg.account = account->next; }
4620 else
4621 { account_prev->next = account->next; }
4622 ll_clear(account->aureader_list);
4623 kill_account_thread(account);
4624 add_garbage(account);
4625 found = 1;
4626 break;
4628 account_prev = account;
4630 if(found > 0)
4632 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
4634 else { tpl_addMsg(vars, "Sorry but the specified user doesn't exist. No deletion will be made!"); }
4638 if((strcmp(getParam(params, "action"), "disable") == 0) || (strcmp(getParam(params, "action"), "enable") == 0))
4640 account = get_account_by_name(getParam(params, "user"));
4641 if(account)
4643 if(strcmp(getParam(params, "action"), "disable") == 0)
4645 account->disabled = 1;
4646 kill_account_thread(account);
4648 else
4649 { account->disabled = 0; }
4650 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
4652 else
4654 tpl_addMsg(vars, "Sorry but the specified user doesn't exist. No deletion will be made!");
4658 if(strcmp(getParam(params, "action"), "resetstats") == 0)
4660 account = get_account_by_name(getParam(params, "user"));
4661 if(account) { clear_account_stats(account); }
4664 if(strcmp(getParam(params, "action"), "resetuserstats") == 0)
4666 clear_info_clients_stats();
4669 if(strcmp(getParam(params, "action"), "resetreaderstats") == 0)
4671 clear_info_readers_stats();
4674 if(strcmp(getParam(params, "action"), "resetalluserstats") == 0)
4676 clear_all_account_stats();
4679 if((strcmp(getParam(params, "part"), "adduser") == 0) && (!cfg.http_readonly))
4681 tpl_addVar(vars, TPLAPPEND, "NEWUSERFORM", tpl_getTpl(vars, "ADDNEWUSER"));
4684 /* List accounts*/
4685 char *status, *expired, *classname, *lastchan;
4686 time_t now = time((time_t *)0);
4687 int32_t isec = 0, chsec = 0;
4689 char *filter = NULL;
4690 int32_t clientcount = 0;
4691 if(apicall)
4693 filter = getParam(params, "label");
4695 int8_t grp_set = 0;
4696 int8_t expdate_set = 0;
4697 int32_t total_users = 0;
4698 int32_t disabled_users = 0;
4699 int32_t expired_users = 0;
4700 int32_t expired_or_disabled_users = 0;
4701 int32_t connected_users = 0;
4702 int32_t online_users = 0;
4703 int32_t casc_users = 0;
4704 int32_t casc_users2 = 0;
4705 int32_t n_request = 0;
4706 int existing_insert = 0;
4708 for(account = cfg.account; (account); account = account->next)
4710 if(account->expirationdate){
4711 expdate_set = 1;
4714 if(account->next){
4715 if(account->grp != account->next->grp){
4716 grp_set = 1;
4719 if(expdate_set && grp_set)
4720 break;
4723 for(account = cfg.account; (account); account = account->next)
4725 //clear for next client
4726 total_users++;
4727 isactive = 1;
4729 status = "offline";
4730 classname = "offline";
4731 isec = 0;
4732 chsec = 0;
4734 //reset caid/srevid template variables
4735 tpl_addVar(vars, TPLADD, "CLIENTCAID", "");
4736 tpl_addVar(vars, TPLADD, "CLIENTPROVID", "");
4737 tpl_addVar(vars, TPLADD, "CLIENTSRVID", "");
4738 tpl_addVar(vars, TPLADD, "LASTCHANNEL", "");
4739 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", "");
4740 tpl_addVar(vars, TPLADD, "USERMD5", "");
4741 tpl_addVar(vars, TPLADD, "CWLASTRESPONSET", "");
4742 tpl_addVar(vars, TPLADD, "CWLASTRESPONSETMS", "");
4743 tpl_addVar(vars, TPLADD, "CLIENTIP", "");
4744 tpl_addVar(vars, TPLADD, "LASTCHANNELTITLE", "");
4745 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", "");
4746 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNELAPI", "");
4747 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", "");
4748 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEP", "");
4749 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEPAPI", "");
4750 tpl_addVar(vars, TPLADD, "IDLESECS", "");
4751 tpl_addVar(vars, TPLADD, "UNOTIFY", "");
4753 if(account->expirationdate && account->expirationdate < now)
4755 expired = " (expired)";
4756 classname = "expired";
4757 expired_users++;
4758 isactive = 0;
4760 else
4762 expired = "";
4765 if(account->disabled != 0)
4767 expired = " (disabled)";
4768 classname = "disabled";
4769 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICENA");
4770 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Enable");
4771 tpl_addVar(vars, TPLADD, "SWITCH", "enable");
4772 disabled_users++;
4773 isactive = 0;
4775 else
4777 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICDIS");
4778 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Disable");
4779 tpl_addVar(vars, TPLADD, "SWITCH", "disable");
4781 if((account->expirationdate && account->expirationdate < now)||account->disabled != 0)
4783 expired_or_disabled_users++;
4786 int32_t lastresponsetm = 0, latestactivity = 0;
4787 const char *proto = "";
4788 double cwrate = 0.0, cwrate2 = 0.0;
4790 //search account in active clients
4791 isactive = 0;
4792 int16_t nrclients = 0;
4793 struct s_client *latestclient = NULL;
4794 for(cl = first_client->next; cl ; cl = cl->next)
4796 if(cl->account && !strcmp(cl->account->usr, account->usr))
4798 if(cl->lastecm > latestactivity || cl->login > latestactivity)
4800 if(cl->lastecm > cl->login) { latestactivity = cl->lastecm; }
4801 else { latestactivity = cl->login; }
4802 latestclient = cl;
4804 nrclients++;
4807 if(account->cwfound + account->cwnot + account->cwcache > 0)
4809 cwrate = now - account->firstlogin;
4810 cwrate /= (account->cwfound + account->cwnot + account->cwcache);
4813 casc_users = 0;
4814 casc_users2 = 0;
4815 int8_t conn = 0;
4816 if(latestclient != NULL)
4818 char channame[CS_SERVICENAME_SIZE];
4819 status = (!apicall) ? "<B>connected</B>" : "connected";
4820 if(account->expirationdate && account->expirationdate < now) { classname = "expired"; }
4821 else { classname = "connected";conn = 1; }
4823 proto = client_get_proto(latestclient);
4824 int clientcaid = latestclient->last_caid;
4825 int clientsrvid = latestclient->last_srvid;
4826 int clientprovid = latestclient->last_provid;
4827 tpl_printf(vars, TPLADD, "CLIENTCAID", "%04X", clientcaid);
4828 tpl_printf(vars, TPLADD, "CLIENTPROVID", "%06X", clientprovid);
4829 tpl_printf(vars, TPLADD, "CLIENTSRVID", "%04X", clientsrvid);
4831 if(clientsrvid != NO_SRVID_VALUE || clientcaid != NO_CAID_VALUE)
4833 lastchan = xml_encode(vars, get_servicename(latestclient, clientsrvid, clientprovid, clientcaid, channame, sizeof(channame)));
4834 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", lastchan);
4836 else
4838 lastchan = "";
4839 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", "~~~~~");
4842 tpl_addVar(vars, TPLADDONCE, "LASTCHANNEL", lastchan);
4843 tpl_addVar(vars, TPLADD, "LASTCHANNELTITLE", lastchan);
4845 if(cfg.http_showpicons )
4847 char picon_name[128];
4848 char picon_channame[128];
4849 int8_t picon_ok = 0;
4851 get_picon_servicename_or_null(latestclient, clientsrvid, clientprovid, clientcaid, picon_channame, sizeof(picon_channame));
4852 if(picon_channame[0])
4854 snprintf(picon_name, sizeof(picon_name) / sizeof(char), "%s", picon_channame);
4855 picon_ok = picon_exists(picon_name);
4857 if(!picon_ok && picon_servicename_remve_hd(picon_channame, sizeof(picon_channame)))
4859 snprintf(picon_name, sizeof(picon_name) / sizeof(char), "%s", picon_channame);
4860 picon_ok = picon_exists(picon_name);
4863 if(!picon_ok)
4865 snprintf(picon_name, sizeof(picon_name) / sizeof(char), "%04X_%06X_%04X", clientcaid, clientprovid, clientsrvid);
4866 picon_ok = picon_exists(picon_name);
4868 if(!picon_ok)
4870 snprintf(picon_name, sizeof(picon_name) / sizeof(char), "%04X_%04X", clientcaid, clientsrvid);
4871 picon_ok = picon_exists(picon_name);
4873 if(!picon_ok)
4875 snprintf(picon_name, sizeof(picon_name) / sizeof(char), "0000_%04X", clientsrvid);
4876 picon_ok = picon_exists(picon_name);
4878 if(picon_ok)
4880 tpl_addVar(vars, TPLADDONCE, "LCA", picon_name);
4881 tpl_addVar(vars, TPLADDONCE, "LCB", lastchan);
4882 if(!apicall)
4884 tpl_addVar(vars, TPLADDONCE, "LASTCHANNEL", tpl_getTpl(vars, "USERCONFIGLASTCHANEL"));
4887 else
4889 tpl_printf(vars, TPLADD, "LASTCHANNELTITLE", "missing icon: IC_%s.tpl", picon_name);
4893 lastresponsetm = latestclient->cwlastresptime;
4894 tpl_addVar(vars, TPLADD, "CLIENTIP", cs_inet_ntoa(latestclient->ip));
4895 connected_users++;
4896 casc_users = ll_count(latestclient->cascadeusers);
4897 LL_ITER it = ll_iter_create(latestclient->cascadeusers);
4898 struct s_cascadeuser *cu;
4899 while((cu = ll_iter_next(&it)))
4901 if(cu->cwrate > 0)
4902 { casc_users2++; }
4904 if(latestactivity > 0)
4906 isec = now - latestactivity;
4907 chsec = latestclient->lastswitch ? now - latestclient->lastswitch : 0;
4908 if(isec < cfg.hideclient_to)
4910 isactive = 1;
4911 status = (!apicall) ? "<B>online</B>" : "online";
4912 if(account->expirationdate && account->expirationdate < now) { classname = "expired"; }
4913 else { classname = "online"; }
4914 if(latestclient->cwfound + latestclient->cwnot + latestclient->cwcache > 0)
4916 cwrate2 = now - latestclient->login;
4917 cwrate2 /= (latestclient->cwfound + latestclient->cwnot + latestclient->cwcache);
4918 tpl_printf(vars, TPLADDONCE, "CWRATE2", " (%.2f)", cwrate2);
4919 online_users++;
4925 n_request = 0;
4926 if(latestclient != NULL){
4927 n_request = latestclient->n_request[0];
4930 tpl_addVar(vars, TPLADD, "EXPIREVIEW", expdate_set ? "" : "exp");
4931 tpl_addVar(vars, TPLADD, "GRPVIEW", grp_set ? "" : "grp");
4932 #ifdef CS_ANTICASC
4933 tpl_addVar(vars, TPLADD, "ANTICASCVIEW", cfg.ac_enabled ? "" : "acas");
4934 #endif
4935 tpl_printf(vars, TPLADD, "CWOK", PRINTF_LOCAL_D, account->cwfound);
4936 tpl_printf(vars, TPLADD, "CWNOK", PRINTF_LOCAL_D, account->cwnot);
4937 tpl_printf(vars, TPLADD, "CWIGN", PRINTF_LOCAL_D, account->cwignored);
4938 tpl_printf(vars, TPLADD, "CWTOUT", PRINTF_LOCAL_D, account->cwtout);
4939 #ifdef CW_CYCLE_CHECK
4940 tpl_addVar(vars, TPLADD, "CWCCYCVIEW", cfg.cwcycle_check_enable ? "" : "cwc");
4941 tpl_printf(vars, TPLADD, "CWCYCLECHECKED", "%d", account->cwcycledchecked);
4942 tpl_printf(vars, TPLADD, "CWCYCLEOK", "%d", account->cwcycledok);
4943 tpl_printf(vars, TPLADD, "CWCYCLENOK", "%d", account->cwcyclednok);
4944 tpl_printf(vars, TPLADD, "CWCYCLEIGN", "%d", account->cwcycledign);
4945 #endif
4946 tpl_printf(vars, TPLADD, "CWCACHE", PRINTF_LOCAL_D, account->cwcache);
4947 tpl_printf(vars, TPLADD, "CWTUN", PRINTF_LOCAL_D, account->cwtun);
4948 tpl_printf(vars, TPLADD, "EMMOK", PRINTF_LOCAL_D, account->emmok);
4949 tpl_printf(vars, TPLADD, "EMMNOK", PRINTF_LOCAL_D, account->emmnok);
4950 tpl_printf(vars, TPLADD, "CWRATE", "%.2f", cwrate);
4951 tpl_printf(vars, TPLADD, "CASCUSERS", "%d", casc_users);
4952 tpl_printf(vars, TPLADD, "CASCUSERS2", "%d", casc_users2);
4953 tpl_printf(vars, TPLADD, "CASCUSERSCOMB", "%d/%d", casc_users, casc_users2);
4954 tpl_printf(vars, TPLADD, "N_REQUEST_MIN", "%d", n_request);
4956 if(isactive > 0 || conn > 0)
4958 if(casc_users+casc_users2>0)
4960 tpl_printf(vars, TPLADD, "CWLASTRESPONSET", "%d", lastresponsetm);
4961 tpl_printf(vars, TPLADD, "CWLASTRESPONSETMS", PRINTF_LOCAL_D " ms", lastresponsetm);
4963 tpl_addVar(vars, TPLADD, "IDLESECS", sec2timeformat(vars, isec));
4966 if(isactive > 0)
4968 tpl_printf(vars, TPLADD, "CLIENTTIMEONCHANNELAPI", "%d", chsec);
4969 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", sec2timeformat(vars, chsec));
4971 if(account->tosleep)
4973 if(account->tosleep >0){
4974 tpl_printf(vars, TPLADD, "CLIENTTIMETOSLEEP", "Sleeping in %d minutes", account->tosleep - (chsec / 60));
4975 } else {
4976 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEP", "Sleeping");
4978 tpl_printf(vars, TPLADD, "CLIENTTIMETOSLEEPAPI", "%d", account->tosleep - (chsec / 60));
4979 } else {
4980 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEPAPI", "undefined");
4983 #ifdef CS_CACHEEX_AIO
4984 #if defined(MODULE_CAMD35) || defined (MODULE_CAMD35_TCP)
4985 if(latestclient != NULL && (latestclient->account->cacheex.feature_bitfield || latestclient->c35_extmode > 1))
4986 #else
4987 if(latestclient != NULL && (latestclient->account->cacheex.feature_bitfield))
4988 #endif
4990 const char *aio_suffix = " (cx-aio)";
4991 char *new_proto;
4992 if(cs_malloc(&new_proto, cs_strlen(proto)+cs_strlen(aio_suffix)+1)) {
4993 if (!cs_strncat(new_proto, (char *)proto, cs_strlen(proto)+cs_strlen(aio_suffix)+1)) {
4994 cs_log("FIXME!");
4996 if (cs_strncat(new_proto, (char *)aio_suffix, cs_strlen(proto)+cs_strlen(aio_suffix)+1)) {
4997 webif_add_client_proto(vars, latestclient, (const char *)new_proto, apicall);
4998 } else {
4999 cs_log("FIXME!");
5001 free(new_proto);
5003 } else {
5004 #endif
5005 webif_add_client_proto(vars, latestclient, proto, apicall);
5006 #ifdef CS_CACHEEX_AIO
5008 #endif
5010 tpl_addVar(vars, TPLADD, "CLASSNAME", classname);
5011 MD5((uint8_t *)account->usr, cs_strlen(account->usr), md5tmp);
5012 int z;
5013 tpl_addVar(vars, TPLADD, "USERMD5","id_");
5014 for (z = 0; z < MD5_DIGEST_LENGTH; z++)
5016 tpl_printf(vars, TPLAPPEND, "USERMD5", "%02x", md5tmp[z]);
5018 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, account->usr));
5019 tpl_addVar(vars, TPLADD, "USERNAMEENC", urlencode(vars, account->usr));
5020 if(!existing_insert)
5022 tpl_printf(vars, TPLADD, "EXISTING_INS", "'%s'", urlencode(vars, account->usr));
5023 existing_insert++;
5024 }else
5026 tpl_printf(vars, TPLAPPEND, "EXISTING_INS", ",'%s'", urlencode(vars, account->usr));
5029 if(account->description)
5030 tpl_printf(vars, TPLADD, "DESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, account->description));
5031 else
5032 tpl_addVar(vars, TPLADD, "DESCRIPTION", "");
5034 if(cfg.http_showpicons && !apicall)
5035 tpl_addVar(vars, TPLADD, "USERBIT", tpl_getTpl(vars, picon_exists(xml_encode(vars, account->usr)) ? "USERICON" : "USERNOICON"));
5036 else
5037 tpl_addVar(vars, TPLADD, "USERBIT", tpl_getTpl(vars, "USERLABEL"));
5039 char *value = mk_t_group(account->grp);
5040 tpl_addVar(vars, TPLADD, "GROUPS", value);
5041 free_mk_t(value);
5042 tpl_addVar(vars, TPLADD, "STATUS", status);
5043 tpl_addVar(vars, TPLAPPEND, "STATUS", expired);
5045 if(nrclients > 1)
5047 tpl_printf(vars, TPLADD, "UNOTIFY", "%d", nrclients);
5048 tpl_addVar(vars, TPLADDONCE, "CLIENTCOUNTNOTIFIER", tpl_getTpl(vars, "CLIENTCOUNTNOTIFIERBIT"));
5051 //Expirationdate
5052 struct tm timeinfo;
5053 cs_gmtime_r(&account->expirationdate, &timeinfo);
5054 char buf [80];
5055 strftime(buf, 80, "%Y-%m-%d", &timeinfo);
5056 if(strcmp(buf, "1970-01-01")) { tpl_addVar(vars, TPLADD, "EXPDATE", buf); }
5057 else { tpl_addVar(vars, TPLADD, "EXPDATE", ""); }
5059 // append row to table template
5060 if(!apicall)
5061 { tpl_addVar(vars, TPLAPPEND, "USERCONFIGS", tpl_getTpl(vars, "USERCONFIGLISTBIT")); }
5062 else if(!filter || strcmp(filter, account->usr) == 0 || strcmp(filter, "all") == 0 || cs_strlen(filter) == 0)
5064 if(apicall == 1){
5065 tpl_addVar(vars, TPLAPPEND, "APIUSERCONFIGS", tpl_getTpl(vars, "APIUSERCONFIGLISTBIT"));
5066 } else if (apicall == 2){
5067 tpl_printf(vars, TPLADD, "JSONDELIMITER", "%s", (total_users > 1)?",":"");
5068 tpl_addVar(vars, TPLAPPEND, "APIUSERCONFIGS", tpl_getTpl(vars, "JSONUSERBIT"));
5070 ++clientcount;
5074 tpl_printf(vars, TPLADD, "TOTAL_USERS", "%d", total_users);
5075 tpl_printf(vars, TPLADD, "TOTAL_DISABLED", "%d", disabled_users);
5076 tpl_printf(vars, TPLADD, "TOTAL_EXPIRED", "%d", expired_users);
5077 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE", "%d", total_users - expired_or_disabled_users);
5078 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED", "%d", connected_users);
5079 tpl_printf(vars, TPLADD, "TOTAL_ONLINE", "%d", online_users);
5081 //CM info
5082 tpl_addVar(vars, TPLADD, "DISPLAYREADERINFO", "hidden"); // no readerinfo in users
5083 set_ecm_info(vars);
5085 if(!apicall)
5086 { return tpl_getTpl(vars, "USERCONFIGLIST"); }
5087 else
5089 if(!filter || clientcount > 0)
5091 return tpl_getTpl(vars, (apicall==1)?"APIUSERCONFIGLIST":"JSONUSER");
5093 else
5095 tpl_printf(vars, TPLADD, "APIERRORMESSAGE", "Invalid client %s", xml_encode(vars, filter));
5096 return tpl_getTpl(vars, "APIERROR");
5102 #define ENTITLEMENT_PAGE_SIZE 500
5104 #ifdef MODULE_CCCSHARE
5105 static void print_cards(struct templatevars *vars, struct uriparams *params, struct cc_card **cardarray, int32_t cardsize,
5106 int8_t show_global_list, struct s_reader *rdr, int32_t offset, int32_t apicall)
5108 if(cardarray)
5110 uint8_t serbuf[8];
5111 int32_t i, count = 0;
5112 char provname[83];
5113 struct cc_card *card;
5114 int32_t cardcount = 0;
5115 int32_t providercount = 0;
5116 int32_t nodecount = 0;
5118 char *provider = "";
5120 // @todo alno: sort by click, 0=ascending, 1=descending (maybe two buttons or reverse on second click)
5121 for(i = offset; i < cardsize; ++i)
5123 card = cardarray[i];
5124 if(count == ENTITLEMENT_PAGE_SIZE)
5125 { break; }
5126 count++;
5128 if(!apicall)
5130 if(show_global_list)
5131 { rdr = card->origin_reader; }
5132 if(rdr)
5133 { tpl_printf(vars, TPLADD, "HOST", "%s:%d", xml_encode(vars, rdr->device), rdr->r_port); }
5134 tpl_printf(vars, TPLADD, "CAID", "%04X", card->caid);
5135 tpl_printf(vars, TPLADD, "CARDTYPE", "%02X", card->card_type);
5137 else
5139 tpl_printf(vars, TPLADD, "APICARDNUMBER", "%d", cardcount);
5140 tpl_printf(vars, TPLADD, "APICAID", "%04X", card->caid);
5141 tpl_printf(vars, TPLADD, "APICARDTYPE", "%02X", card->card_type);
5144 if(cc_UA_valid(card->hexserial)) //Add UA:
5146 cc_UA_cccam2oscam(card->hexserial, serbuf, card->caid);
5147 char tmp[20];
5148 tpl_printf(vars, TPLAPPEND, "HOST", "<BR>\nUA_OSCam:%s", cs_hexdump(0, serbuf, 8, tmp, 20));
5149 tpl_printf(vars, TPLAPPEND, "HOST", "<BR>\nUA_CCcam:%s", cs_hexdump(0, card->hexserial, 8, tmp, 20));
5151 if(!apicall)
5153 int32_t n;
5154 char channame[CS_SERVICENAME_SIZE];
5155 int8_t sidname = 0;
5156 LL_ITER its = ll_iter_create(card->goodsids);
5157 struct cc_srvid *srv;
5158 n = 0;
5159 if(strcmp(getParam(params, "button"), "Show detail list") == 0)
5160 { sidname = 1; }
5162 tpl_addVar(vars, TPLADD, "SERVICESGOOD", "");
5163 while((srv = ll_iter_next(&its)))
5165 if(sidname)
5167 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))));
5168 } else {
5169 tpl_printf(vars, TPLAPPEND, "SERVICESGOOD", "%04X%s", srv->sid, ++n % 10 == 0 ? "<BR>\n" : " ");
5173 its = ll_iter_create(card->badsids);
5174 n = 0;
5175 tpl_addVar(vars, TPLADD, "SERVICESBAD", "");
5176 while((srv = ll_iter_next(&its)))
5178 if(sidname)
5180 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))));
5181 } else {
5182 tpl_printf(vars, TPLAPPEND, "SERVICESBAD", "%04X%s", srv->sid, ++n % 10 == 0 ? "<BR>\n" : " ");
5187 tpl_addVar(vars, TPLADD, "SYSTEM", get_cardsystem_desc_by_caid(card->caid));
5189 tpl_printf(vars, TPLADD, "SHAREID", "%08X", card->id);
5190 tpl_printf(vars, TPLADD, "REMOTEID", "%08X", card->remote_id);
5191 tpl_printf(vars, TPLADD, "UPHOPS", "%d", card->hop);
5192 tpl_printf(vars, TPLADD, "MAXDOWN", "%d", card->reshare);
5194 LL_ITER pit = ll_iter_create(card->providers);
5195 struct cc_provider *prov;
5197 providercount = 0;
5199 if(!apicall)
5200 { tpl_addVar(vars, TPLADD, "PROVIDERS", ""); }
5201 else
5202 { tpl_addVar(vars, TPLADD, "PROVIDERLIST", ""); }
5204 while((prov = ll_iter_next(&pit)))
5206 provider = xml_encode(vars, get_provider(prov->prov, card->caid, provname, sizeof(provname)));
5208 if(!apicall)
5210 if(prov->sa[0] || prov->sa[1] || prov->sa[2] || prov->sa[3])
5212 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]);
5214 else
5216 tpl_printf(vars, TPLAPPEND, "PROVIDERS", "%s<BR>\n", provider);
5219 else
5221 if(prov->sa[0] || prov->sa[1] || prov->sa[2] || prov->sa[3])
5222 { tpl_printf(vars, TPLADD, "APIPROVIDERSA", "%02X%02X%02X%02X", prov->sa[0], prov->sa[1], prov->sa[2], prov->sa[3]); }
5223 else
5224 { tpl_addVar(vars, TPLADD, "APIPROVIDERSA", ""); }
5225 tpl_printf(vars, TPLADD, "APIPROVIDERCAID", "%04X", card->caid);
5226 tpl_printf(vars, TPLADD, "APIPROVIDERPROVID", "%06X", prov->prov);
5227 tpl_printf(vars, TPLADD, "APIPROVIDERNUMBER", "%d", providercount);
5228 tpl_addVar(vars, TPLADD, "APIPROVIDERNAME", xml_encode(vars, provider));
5229 tpl_addVar(vars, TPLAPPEND, "PROVIDERLIST", tpl_getTpl(vars, "APICCCAMCARDPROVIDERBIT"));
5232 providercount++;
5233 tpl_printf(vars, TPLADD, "APITOTALPROVIDERS", "%d", providercount);
5236 LL_ITER nit = ll_iter_create(card->remote_nodes);
5237 uint8_t *node;
5239 nodecount = 0;
5240 if(!apicall) { tpl_addVar(vars, TPLADD, "NODES", ""); }
5241 else { tpl_addVar(vars, TPLADD, "NODELIST", ""); }
5243 while((node = ll_iter_next(&nit)))
5246 if(!apicall)
5248 tpl_printf(vars, TPLAPPEND, "NODES", "%02X%02X%02X%02X%02X%02X%02X%02X<BR>\n",
5249 node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7]);
5251 else
5253 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]);
5254 tpl_printf(vars, TPLADD, "APINODENUMBER", "%d", nodecount);
5255 tpl_addVar(vars, TPLAPPEND, "NODELIST", tpl_getTpl(vars, "APICCCAMCARDNODEBIT"));
5257 nodecount++;
5258 tpl_printf(vars, TPLADD, "APITOTALNODES", "%d", nodecount);
5261 if(!apicall)
5262 { tpl_addVar(vars, TPLAPPEND, "CCCAMSTATSENTRY", tpl_getTpl(vars, "ENTITLEMENTCCCAMENTRYBIT")); }
5263 else
5264 { tpl_addVar(vars, TPLAPPEND, "CARDLIST", tpl_getTpl(vars, "APICCCAMCARDBIT")); }
5266 cardcount++;
5268 // set previous Link if needed
5269 if(offset >= ENTITLEMENT_PAGE_SIZE)
5271 tpl_printf(vars, TPLAPPEND, "CONTROLS", "<A HREF=\"entitlements.html?offset=%d&globallist=%s&amp;label=%s\"> << PREVIOUS < </A>",
5272 offset - ENTITLEMENT_PAGE_SIZE,
5273 getParam(params, "globallist"),
5274 urlencode(vars, getParam(params, "label")));
5277 // set next link if needed
5278 if(cardsize > count && offset < cardsize)
5280 tpl_printf(vars, TPLAPPEND, "CONTROLS", "<A HREF=\"entitlements.html?offset=%d&globallist=%s&amp;label=%s\"> > NEXT >> </A>",
5281 offset + ENTITLEMENT_PAGE_SIZE,
5282 getParam(params, "globallist"),
5283 urlencode(vars, getParam(params, "label")));
5286 if(!apicall)
5288 tpl_printf(vars, TPLADD, "TOTALS", "card count=%d", cardsize);
5289 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTCCCAMBIT"));
5291 else
5293 tpl_printf(vars, TPLADD, "APITOTALCARDS", "%d", cardsize);
5297 else
5299 if(!apicall)
5301 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTGENERICBIT"));
5302 tpl_addVar(vars, TPLADD, "LOGHISTORY", "no cards found<BR>\n");
5304 else
5306 tpl_printf(vars, TPLADD, "APITOTALCARDS", "%d", 0);
5311 #endif
5313 static char *send_oscam_entitlement(struct templatevars *vars, struct uriparams *params, int32_t apicall)
5315 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
5316 char *reader_ = getParam(params, "label");
5317 #ifdef MODULE_CCCAM
5318 char *sharelist_ = getParam(params, "globallist");
5319 int32_t show_global_list = sharelist_ && sharelist_[0] == '1';
5321 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
5322 if(show_global_list || cs_strlen(reader_) || (rdr && rdr->typ == R_CCCAM))
5325 if(show_global_list || (rdr && rdr->typ == R_CCCAM && rdr->enable))
5328 if(show_global_list)
5330 tpl_addVar(vars, TPLADD, "READERNAME", "GLOBAL");
5331 tpl_addVar(vars, TPLADD, "APIHOST", "GLOBAL");
5332 tpl_addVar(vars, TPLADD, "APIHOSTPORT", "GLOBAL");
5334 else
5336 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
5337 tpl_addVar(vars, TPLADD, "APIHOST", xml_encode(vars, rdr->device));
5338 tpl_printf(vars, TPLADD, "APIHOSTPORT", "%d", rdr->r_port);
5341 #ifdef MODULE_CCCSHARE
5342 int32_t offset = atoi(getParam(params, "offset")); //should be 0 if parameter is missed on very first call
5343 int32_t cardsize;
5344 if(show_global_list)
5346 int32_t i;
5347 LLIST **sharelist = get_and_lock_sharelist();
5348 LLIST *sharelist2 = ll_create("web-sharelist");
5349 for(i = 0; i < CAID_KEY; i++)
5351 if(sharelist[i])
5352 { ll_putall(sharelist2, sharelist[i]); }
5354 unlock_sharelist();
5355 struct cc_card **cardarray = get_sorted_card_copy(sharelist2, 0, &cardsize);
5356 ll_destroy(&sharelist2);
5357 print_cards(vars, params, cardarray, cardsize, 1, NULL, offset, apicall);
5358 NULLFREE(cardarray);
5360 else
5362 struct s_client *rc = rdr->client;
5363 struct cc_data *rcc = (rc) ? rc->cc : NULL;
5364 if(rcc && rcc->cards)
5366 struct cc_card **cardarray = get_sorted_card_copy(rcc->cards, 0, &cardsize);
5367 print_cards(vars, params, cardarray, cardsize, 0, rdr, offset, apicall);
5368 NULLFREE(cardarray);
5371 #endif
5374 else
5376 #else
5377 if(cs_strlen(reader_))
5380 struct s_reader *rdr;
5381 #endif
5382 tpl_addVar(vars, TPLADD, "LOGHISTORY", "->");
5383 // normal non-cccam reader
5385 rdr = get_reader_by_label(reader_);
5387 if(rdr)
5389 struct s_client *cl = rdr->client;
5390 if(rdr->ll_entitlements)
5393 time_t now = time((time_t *)0);
5395 struct tm start_t, end_t;
5396 LL_ITER itr = ll_iter_create(rdr->ll_entitlements);
5397 S_ENTITLEMENT *item;
5399 tpl_addVar(vars, TPLAPPEND, "LOGHISTORY", "<BR><BR>New Structure:<BR>");
5400 char tbuffer[83];
5401 #ifdef WITH_EMU
5402 char keyBuffer[1024];
5403 #endif
5404 int jsondelimiter = 0;
5405 while((item = ll_iter_next(&itr)))
5407 #ifdef WITH_EMU
5408 if(item->isKey)
5410 tpl_addVar(vars, TPLADD, "ENTSTARTDATE", "");
5411 tpl_addVar(vars, TPLADD, "ENTENDDATE", "");
5412 cs_hexdump(0, item->key, item->keyLength, keyBuffer, sizeof(keyBuffer));
5413 tpl_addVar(vars, TPLADD, "ENTEXPIERED", "e_valid");
5414 tpl_printf(vars, TPLADD, "ENTCAID", "%04X", item->caid);
5415 tpl_printf(vars, TPLADD, "ENTPROVID", "%08X", item->provid);
5416 tpl_addVar(vars, TPLADD, "ENTID", item->name);
5417 tpl_addVar(vars, TPLADD, "ENTCLASS", keyBuffer);
5418 if(item->isData) { tpl_addVar(vars, TPLADD, "ENTTYPE", "data"); }
5419 else { tpl_addVar(vars, TPLADD, "ENTTYPE", "key"); }
5420 tpl_addVar(vars, TPLADD, "ENTRESNAME", "");
5422 if((strcmp(getParam(params, "hideexpired"), "1") != 0) || (item->end > now))
5423 { tpl_addVar(vars, TPLAPPEND, "READERENTENTRY", tpl_getTpl(vars, "ENTITLEMENTITEMBIT")); }
5425 continue;
5427 #endif
5429 localtime_r(&item->start, &start_t);
5430 localtime_r(&item->end, &end_t);
5432 if(!apicall)
5433 { strftime(tbuffer, 30, "%Y-%m-%d", &start_t); }
5434 else
5435 { strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &start_t); }
5436 tpl_addVar(vars, TPLADD, "ENTSTARTDATE", tbuffer);
5438 if(!apicall)
5439 { strftime(tbuffer, 30, "%Y-%m-%d", &end_t); }
5440 else
5441 { strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &end_t); }
5442 tpl_addVar(vars, TPLADD, "ENTENDDATE", tbuffer);
5444 tpl_addVar(vars, TPLADD, "ENTEXPIERED", item->end > now ? "e_valid" : "e_expired");
5445 tpl_printf(vars, TPLADD, "ENTCAID", "%04X", item->caid);
5446 tpl_printf(vars, TPLADD, "ENTPROVID", "%06X", item->provid);
5447 tpl_printf(vars, TPLADD, "ENTID", "%08X%08X", (uint32_t)(item->id >> 32), (uint32_t)item->id);
5448 tpl_printf(vars, TPLADD, "ENTCLASS", "%08X", item->class);
5449 tpl_addVar(vars, TPLADD, "ENTTYPE", entitlement_type[item->type]);
5451 char *entresname;
5452 entresname = xml_encode(vars, get_tiername((uint16_t)(item->id & 0xFFFF), item->caid, tbuffer));
5453 if(!tbuffer[0])
5454 { entresname = xml_encode(vars, get_provider(item->provid, item->caid, tbuffer, sizeof(tbuffer))); }
5455 tpl_addVar(vars, TPLADD, "ENTRESNAME", entresname);
5457 if((strcmp(getParam(params, "hideexpired"), "1") != 0) || (item->end > now))
5458 { tpl_addVar(vars, TPLAPPEND, "READERENTENTRY", tpl_getTpl(vars, "ENTITLEMENTITEMBIT")); }
5460 if(apicall==2)
5462 tpl_printf(vars, TPLAPPEND, "APIENTITLEMENTLIST","%s%s",jsondelimiter?",":"", tpl_getTpl(vars, "JSONENTITLEMENTBIT"));
5463 jsondelimiter++;
5468 if(cl && cl->typ)
5469 { tpl_printf(vars, TPLADD, "READERTYPE", "%c", cl->typ); }
5470 else
5471 { tpl_addVar(vars, TPLADD, "READERTYPE", "null"); }
5472 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
5474 int8_t i, j;
5475 for(i = 0; i < 15; i++) { tpl_printf(vars, TPLAPPEND, "READERROM", "%c", rdr->rom[i]); }
5476 if(rdr->hexserial[0] || rdr->hexserial[1]) { i = 0; }
5477 else { i = 2; }
5478 if(rdr->hexserial[6] || rdr->hexserial[7]) { j = 8; }
5479 else { j = 6; }
5480 for(; i < j; i++) { tpl_printf(vars, TPLAPPEND, "READERSERIAL", "%02X%s", rdr->hexserial[i], i < j - 1 ? " " : ""); }
5481 for(i = 0; i < rdr->nprov; i++)
5483 for(j = 0; j < 4; j++) { tpl_printf(vars, TPLAPPEND, "READERPROVIDS", "%02X ", rdr->prid[i][j]); }
5484 tpl_addVar(vars, TPLAPPEND, "READERPROVIDS", i == 0 ? "(sysid)<BR>\n" : "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>\n");
5487 //CountryCode Vg card
5488 char add_nds_line = 0;
5489 if(rdr->VgCountryC[0])
5491 for(i = 0; i < 3; i++) { tpl_printf(vars, TPLAPPEND, "READERCOUNTRYC", "%c", rdr->VgCountryC[i]); }
5492 add_nds_line = 1;
5494 else
5496 tpl_addVar(vars, TPLADD, "READERCOUNTRYC", "n/a");
5499 //regional code for Vg card
5500 if(rdr->VgRegionC[0])
5502 for(i = 0; i < 8; i++) { tpl_printf(vars, TPLAPPEND, "READER_RCODE", "%c", rdr->VgRegionC[i]); }
5503 add_nds_line = 1;
5505 else
5507 tpl_addVar(vars, TPLADD, "READER_RCODE", "n/a");
5510 //Pin Vg card
5511 if(rdr->VgPin)
5513 tpl_printf(vars, TPLAPPEND, "READERPIN", "%04i", rdr->VgPin);
5514 add_nds_line = 1;
5516 else
5518 tpl_addVar(vars, TPLADD, "READERPIN", "n/a");
5521 //Fuse Vg card
5522 if(rdr->VgFuse)
5524 tpl_printf(vars, TPLAPPEND, "READERFUSE", "%02X", rdr->VgFuse);
5525 add_nds_line = 1;
5528 if(caid_is_videoguard(rdr->caid))
5530 tpl_printf(vars, TPLAPPEND, "READERPAYLOAD", "%02X %02X %02X %02X %02X %02X", rdr->VgLastPayload[0],
5531 rdr->VgLastPayload[1], rdr->VgLastPayload[2], rdr->VgLastPayload[3], rdr->VgLastPayload[4], rdr->VgLastPayload[5]);
5532 add_nds_line = 1;
5535 //credit on Vg card
5536 if(rdr->VgCredit)
5538 tpl_printf(vars, TPLAPPEND, "READERCREDIT", "%i", rdr->VgCredit);
5539 add_nds_line = 1;
5541 else
5543 tpl_addVar(vars, TPLADD, "READERCREDIT", "n/a");
5546 if(rdr->card_valid_to)
5548 struct tm vto_t;
5549 char vtobuffer[30];
5550 localtime_r(&rdr->card_valid_to, &vto_t);
5551 strftime(vtobuffer, 30, "%Y-%m-%d", &vto_t);
5552 tpl_addVar(vars, TPLADD, "READERCARDVALIDTO", vtobuffer);
5554 else
5556 tpl_addVar(vars, TPLADD, "READERCARDVALIDTO", "n/a");
5559 if(rdr->irdId[0])
5561 for(i = 0; i < 4; i++) { tpl_printf(vars, TPLAPPEND, "READERIRDID", "%02X ", rdr->irdId[i]); }
5563 else
5565 tpl_addVar(vars, TPLADD, "READERIRDID", "n/a");
5568 if(rdr->card_atr_length)
5569 for(i = 0; i < rdr->card_atr_length; i++) { tpl_printf(vars, TPLAPPEND, "READERATR", "%02X ", rdr->card_atr[i]); }
5571 if(caid_is_seca(rdr->caid) || caid_is_viaccess(rdr->caid))
5573 if(rdr->maturity == 0xF)
5575 tpl_printf(vars, TPLAPPEND, "READERMATURITY", "%s ", "no limit");
5577 else
5579 tpl_printf(vars, TPLAPPEND, "READERMATURITY", "%d+", rdr->maturity);
5582 else
5584 tpl_printf(vars, TPLAPPEND, "READERMATURITY", "%s ", "n/a");
5587 if (rdr->csystem)
5588 tpl_addVar(vars, TPLADD, "READERCSYSTEM", rdr->csystem->desc);
5590 if(add_nds_line)
5592 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENTNDS", tpl_getTpl(vars, "ENTITLEMENTBITNDS"));
5594 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTBIT"));
5596 else
5598 tpl_addMsg(vars, "Reader does not exist or is not started!");
5603 else
5605 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTGENERICBIT"));
5608 if(!apicall)
5609 { return tpl_getTpl(vars, "ENTITLEMENTS"); }
5610 else
5612 if(apicall==1)
5613 { return tpl_getTpl(vars, "APICCCAMCARDLIST"); }
5614 else
5615 { return tpl_getTpl(vars, "JSONENTITLEMENTS"); }
5619 #ifdef WEBIF_LIVELOG
5620 static char *send_oscam_logpoll(struct templatevars * vars, struct uriparams * params)
5623 uint64_t lastid = 0;
5625 #ifdef WITH_DEBUG
5626 tpl_addVar(vars, TPLADD, "LOG_DEBUGMENU", tpl_getTpl(vars, "LOGDEBUGMENU"));
5627 #endif
5628 tpl_addVar(vars, TPLADD, "LOG_SIZEMENU", tpl_getTpl(vars, "LOGSIZEMENU"));
5629 tpl_addVar(vars, TPLADD, "TITLEADD1", "Move mouse over log-window to stop scroll");
5631 if(strcmp(getParam(params, "lastid"), "start") == 0){
5632 setActiveMenu(vars, MNU_LIVELOG);
5633 return tpl_getTpl(vars, "LOGPAGE");
5635 else
5637 lastid = strtoull(getParam(params, "lastid"), NULL, 10);
5640 char *dot = ""; //Delimiter
5642 #ifdef WITH_DEBUG
5643 char *debuglvl = getParam(params, "debug");
5644 if(cs_strlen(debuglvl) > 0) {
5645 int32_t dblvl = atoi(debuglvl);
5646 if(cs_dblevel != dblvl) {
5647 if(dblvl >= 0 && dblvl <= 65535) { cs_dblevel = dblvl; }
5648 cs_log("%s debug_level=%d", "all", cs_dblevel);
5651 tpl_printf(vars, TPLAPPEND, "DATA","%s\"debug\":\"%d\"", dot, cs_dblevel);
5652 dot = ",";
5653 tpl_printf(vars, TPLAPPEND, "DATA","%s\"maxdebug\":\"%d\"",dot, MAX_DEBUG_LEVELS);
5654 #endif
5656 if(cfg.loghistorylines == 0){
5657 tpl_printf(vars, TPLAPPEND, "DATA","%s\"logdisabled\":\"1\"",dot);
5658 return tpl_getTpl(vars, "POLL");
5661 if(log_history)
5663 LL_ITER it = ll_iter_create(log_history);
5664 struct s_log_history *hist;
5666 tpl_printf(vars, TPLAPPEND, "DATA", "%s\"lines\":[", dot);
5668 dot = "";
5670 while((hist = (struct s_log_history*)ll_iter_next(&it)))
5672 char p_usr[32];
5673 size_t pos1 = strcspn(hist->txt, "\t") + 1;
5674 cs_strncpy(p_usr, hist->txt , pos1 > sizeof(p_usr) ? sizeof(p_usr) : pos1);
5676 char *p_txt = hist->txt + pos1;
5678 pos1 = strcspn(p_txt, "\n") + 1;
5679 char str_out[pos1];
5680 cs_strncpy(str_out, p_txt, pos1);
5681 uint64_t id = hist->counter;
5683 size_t b64_str_in = cs_strlen(xml_encode(vars, str_out));
5684 size_t b64_str_out = 32 + BASE64_LENGTH(b64_str_in);
5685 char *b64_str_out_buf;
5686 if(!cs_malloc(&b64_str_out_buf, b64_str_out))
5687 { continue; }
5688 base64_encode(xml_encode(vars, str_out), b64_str_in, b64_str_out_buf, b64_str_out);
5690 if(id > lastid){
5691 tpl_printf(vars, TPLAPPEND, "DATA","%s{\"id\":\"%" PRIu64 "\",\"usr\":\"%s\",\"line\":\"%s\"}",
5692 dot,
5694 urlencode(vars, xml_encode(vars, p_usr)),
5695 b64_str_out_buf);
5696 dot = ","; // next in Array with leading delimiter
5698 NULLFREE(b64_str_out_buf);
5702 tpl_addVar(vars, TPLAPPEND, "DATA", "]");
5703 return tpl_getTpl(vars, "POLL");
5705 #endif
5707 static char *send_oscam_status(struct templatevars * vars, struct uriparams * params, int32_t apicall)
5709 int32_t i;
5710 const char *usr;
5711 int32_t lsec, isec, chsec, con, cau = 0;
5712 time_t now = time((time_t *)0);
5713 struct tm lt;
5714 int delimiter=0;
5716 if(!apicall)
5718 setActiveMenu(vars, MNU_STATUS);
5719 if (config_enabled(WITH_LB))
5720 tpl_addVar(vars, TPLADD, "STATUSCOL14HEAD","LB Value/");
5722 if(strcmp(getParam(params, "action"), "kill") == 0)
5724 char *cptr = getParam(params, "threadid");
5725 struct s_client *cl = NULL;
5726 if(cs_strlen(cptr) > 1)
5727 { sscanf(cptr, "%p", (void **)(void *)&cl); }
5729 if(cl && is_valid_client(cl))
5731 if(is_dvbapi_usr(cl->account->usr))
5733 cs_log("WebIF from %s requests to kill dvbapi client %s -> ignoring!", cs_inet_ntoa(GET_IP()), cl->account->usr);
5735 else
5737 kill_thread(cl);
5738 cs_log("Client %s killed by WebIF from %s", cl->account->usr, cs_inet_ntoa(GET_IP()));
5743 if(strcmp(getParam(params, "action"), "resetuserstats") == 0)
5745 clear_info_clients_stats();
5747 if(strcmp(getParam(params, "action"), "resetreaderstats") == 0)
5749 clear_info_readers_stats();
5751 if(strcmp(getParam(params, "action"), "restart") == 0)
5753 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
5754 if(rdr)
5756 if(rdr->typ != R_GBOX)
5758 add_job(rdr->client, ACTION_READER_RESTART, NULL, 0);
5760 #ifdef MODULE_GBOX
5761 else
5763 restart_gbox_peer(rdr->label, 0, 0);
5765 #endif
5766 cs_log("Reader %s restarted by WebIF from %s", rdr->label, cs_inet_ntoa(GET_IP()));
5770 char *debuglvl = getParam(params, "debug");
5771 if(cs_strlen(debuglvl) > 0)
5773 #ifndef WITH_DEBUG
5774 cs_log("*** Warning: Debug Support not compiled in ***");
5775 #else
5776 int32_t dblvl = atoi(debuglvl);
5777 if(dblvl >= 0 && dblvl <= 65535) { cs_dblevel = dblvl; }
5778 cs_log("%s debug_level=%d", "all", cs_dblevel);
5779 #endif
5782 char *hide = getParam(params, "hide");
5783 if(cs_strlen(hide) > 0)
5785 struct s_client *hideidx = NULL;
5786 sscanf(hide, "%p", (void **)(void *)&hideidx);
5788 if(hideidx && is_valid_client(hideidx))
5789 { hideidx->wihidden = 1; }
5792 char *hideidle = getParam(params, "hideidle");
5793 if(cs_strlen(hideidle) > 0)
5795 if(atoi(hideidle) == 2)
5797 struct s_client *cl;
5798 for(cl = first_client; cl ; cl = cl->next)
5800 if(cl->typ == 's' || cl->typ == 'h' || cl->typ == 'm'){
5801 cl->wihidden = 0;
5805 else if(atoi(hideidle) == 3)
5807 struct s_client *cl;
5808 for(cl = first_client; cl ; cl = cl->next)
5810 if(cl->typ == 'r'){
5811 cl->wihidden = 0;
5815 else if(atoi(hideidle) == 4)
5817 struct s_client *cl;
5818 for(cl = first_client; cl ; cl = cl->next)
5820 if(cl->typ == 'p'){
5821 cl->wihidden = 0;
5825 else if(atoi(hideidle) == 5)
5827 struct s_client *cl;
5828 for(cl = first_client; cl ; cl = cl->next)
5830 if(cl->typ == 'c'){
5831 cl->wihidden = 0;
5835 else
5837 int32_t oldval = cfg.http_hide_idle_clients;
5838 config_set("webif", "httphideidleclients", hideidle);
5839 if(oldval != cfg.http_hide_idle_clients)
5841 refresh_oscam(REFR_SERVER);
5846 if(cfg.http_hide_idle_clients > 0) { tpl_addVar(vars, TPLADD, "HIDEIDLECLIENTSSELECTED1", "selected"); }
5847 else { tpl_addVar(vars, TPLADD, "HIDEIDLECLIENTSSELECTED0", "selected"); }
5849 tpl_addVar(vars, TPLADD, "SRVIDFILE", use_srvid2 ? "oscam.srvid2" : "oscam.srvid");
5851 int32_t user_count_all = 0, user_count_shown = 0, user_count_active = 0;
5852 int32_t reader_count_all = 0, reader_count_conn = 0, reader_count_off = 0;
5853 int32_t proxy_count_all = 0, proxy_count_conn = 0, proxy_count_off = 0;
5854 int32_t server_count_all = 0, server_count_shown = 0, server_count_hidden = 0;
5855 int32_t monitor_count_all = 0, monitor_count_shown = 0;
5856 int32_t shown;
5858 int32_t total_readers = 0;
5859 int32_t active_readers = 0;
5860 int32_t disabled_readers = 0;
5861 int32_t connected_readers = 0;
5863 struct s_client *cl;
5864 int8_t filtered;
5866 cs_readlock(__func__, &readerlist_lock);
5867 cs_readlock(__func__, &clientlist_lock);
5868 for(i = 0, cl = first_client; cl ; cl = cl->next, i++)
5870 #ifdef CS_CACHEEX_AIO
5871 #if defined(MODULE_CCCAM) && defined(CS_CACHEEX)
5872 struct cc_data *cc = cl->cc;
5873 #endif
5874 #endif
5875 if(cl->kill) { continue; }
5876 #ifdef CS_CACHEEX
5877 if(get_module(cl)->listenertype != LIS_CSPUDP)
5879 #endif
5881 // Reset template variables
5882 tpl_addVar(vars, TPLADD, "LBLRPSTRVALUE", "");
5883 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", "");
5884 tpl_addVar(vars, TPLADD, "LASTREADER", "");
5885 tpl_addVar(vars, TPLADD, "CLIENTPROTO", "");
5886 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
5887 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIME", "");
5888 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIMEHIST", "");
5889 tpl_addVar(vars, TPLADD, "UPICMISSING" , "");
5890 tpl_addVar(vars, TPLADD, "ENTITLEMENTS", "");
5892 if(cl->typ == 'c')
5893 { user_count_all++; }
5894 else if(cl->typ == 'p')
5896 proxy_count_all++;
5897 if((cl->reader->typ == R_GBOX && cl->reader->card_status != CARD_INSERTED && cl->reader->card_status != NO_CARD) ||
5898 (cl->reader->typ != R_GBOX && cl->reader->card_status != CARD_INSERTED))
5899 { proxy_count_off++; }
5901 else if(cl->typ == 'r')
5902 { reader_count_all++; if(cl->reader->card_status != CARD_INSERTED) { reader_count_off++; } }
5903 else if(cl->typ == 's' || cl->typ == 'h')
5904 { server_count_all++; if(cl->wihidden) {server_count_hidden++;} }
5905 else if(cl->typ == 'm')
5906 { monitor_count_all++; }
5908 shown = 0;
5909 if(cl->wihidden != 1)
5911 filtered = !(cfg.http_hide_idle_clients != 1 || cl->typ != 'c' || (now - cl->lastecm) <= cfg.hideclient_to);
5912 if(!filtered && cfg.http_hide_type)
5914 char *p = cfg.http_hide_type;
5915 while(*p && !filtered)
5917 char type = *p++;
5918 #ifdef CS_CACHEEX
5919 filtered = (type == cl->typ) || (type == 'x' && (cl->typ == 'p' || cl->typ == 'r') && (cl->reader && cl->reader->cacheex.mode));
5920 #else
5921 filtered = (type == cl->typ);
5922 #endif
5923 #ifdef WITH_EMU
5924 if(type == 'e' && cl->typ == 'r' && cl->reader->typ == R_EMU) filtered = 1;
5925 #endif
5929 if(!filtered)
5931 if(cl->typ == 'c')
5933 user_count_shown++;
5934 if(cfg.http_hide_idle_clients != 1 && cfg.hideclient_to > 0 && (now - cl->lastecm) <= cfg.hideclient_to)
5936 user_count_active++;
5939 else if(cl->typ == 's' || cl->typ == 'h')
5941 server_count_shown++;
5943 else if(cl->typ == 'm')
5945 monitor_count_shown++;
5947 else if(cl->typ == 'r')
5949 reader_count_conn++;
5951 else if(cl->typ == 'p')
5953 proxy_count_conn++;
5956 if(cl->typ == 'c' || cl->typ == 'r' || cl->typ == 'p')
5958 if(cl->lastecm >= cl->login && cl->lastecm >= cl->logout) { isec = now - cl->lastecm; }
5959 else if(cl->logout >= cl->login) { isec = now - cl->logout; }
5960 else { isec = now - cl->login; }
5962 else { isec = now - cl->last; }
5964 shown = 1;
5965 lsec = now - cl->login;
5966 chsec = now - cl->lastswitch;
5967 usr = username(cl);
5969 if((cl->typ == 'r') || (cl->typ == 'p')) { usr = cl->reader->label; }
5971 if(cl->dup) { con = 2; }
5972 else if((cl->tosleep) && (now - cl->lastswitch > cl->tosleep)) { con = 1; }
5973 else { con = 0; }
5975 // no AU reader == 0 / AU ok == 1 / Last EMM > aulow == -1
5976 if(cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r')
5978 if((cl->typ == 'c' && ll_count(cl->aureader_list) == 0) || ((cl->typ == 'p' || cl->typ == 'r') && cl->reader->audisabled)) { cau = 0; }
5979 else if((now - cl->lastemm) / 60 > cfg.aulow) { cau = -1; }
5980 else { cau = 1; }
5982 if(cau == 0)
5984 tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", "OFF");
5986 else
5988 if(cau == -1)
5989 { tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", !apicall?"<A HREF=\"#\" CLASS=\"tooltip\">ON":""); }
5990 else
5991 { tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", !apicall?"<A HREF=\"#\" CLASS=\"tooltip\">ACTIVE":""); }
5992 tpl_addVar(vars, TPLAPPEND, "CLIENTCAUHTTP", !apicall?"<SPAN>":"");
5993 if(cl->typ == 'c')
5995 struct s_reader *rdr;
5996 LL_ITER itr = ll_iter_create(cl->aureader_list);
5997 while((rdr = ll_iter_next(&itr)))
5999 if(rdr->audisabled)
6000 { tpl_printf(vars, TPLAPPEND, "CLIENTCAUHTTP", "(%s)<BR>", xml_encode(vars, rdr->label)); }
6001 else
6002 { tpl_printf(vars, TPLAPPEND, "CLIENTCAUHTTP", "%s<BR>", xml_encode(vars, rdr->label)); }
6005 else { tpl_addVar(vars, TPLAPPEND, "CLIENTCAUHTTP", xml_encode(vars, cl->reader->label)); }
6006 tpl_addVar(vars, TPLAPPEND, "CLIENTCAUHTTP", !apicall?"</SPAN></A>":"");
6009 else
6011 cau = 0;
6012 tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", "");
6014 localtime_r(&cl->login, &lt);
6016 if(cl->typ == 'c' || cl->typ == 'm')
6018 if(cl->account && cl->account->description)
6019 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->account->description));
6020 else
6021 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
6023 else if(cl->typ == 'p' || cl->typ == 'r')
6025 if(cl->reader && cl->reader->description)
6026 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->reader->description));
6027 else
6028 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
6030 if(!apicall)
6032 tpl_addVar(vars, TPLADD, "LBL", xml_encode(vars, usr));
6033 tpl_printf(vars, TPLADD, "CID", "%p", cl);
6034 if(cl->typ == 'c' || cl->typ == 'm')
6036 tpl_addVar(vars, TPLADD, "TARGET", "User");
6037 tpl_addVar(vars, TPLADD, "CSIDX", tpl_getTpl(vars, "STATUSKBUTTON"));
6039 else if(cl->typ == 'p')
6041 tpl_addVar(vars, TPLADD, "TARGET", "Proxy");
6042 tpl_addVar(vars, TPLADD, "LBLENC", urlencode(vars, usr));
6043 tpl_addVar(vars, TPLADD, "CSIDX", tpl_getTpl(vars, "STATUSRBUTTON"));
6045 else if(cl->typ == 'r')
6047 tpl_addVar(vars, TPLADD, "TARGET", "Reader");
6048 tpl_addVar(vars, TPLADD, "LBLENC", urlencode(vars, usr));
6049 tpl_addVar(vars, TPLADD, "CSIDX", tpl_getTpl(vars, "STATUSRBUTTON"));
6051 else if (cl->typ == 'h' || cl->typ == 's')
6053 tpl_addVar(vars, TPLADD, "TARGET", "Server");
6054 tpl_addVar(vars, TPLADD, "CSIDX", "");
6056 tpl_addVar(vars, TPLADD, "HIDEIDX", tpl_getTpl(vars, "STATUSHBUTTON"));
6057 tpl_printf(vars, TPLADD, "CSIDXPLAIN", "id_%p", cl);
6059 else
6061 tpl_printf(vars, TPLADD, "HIDEIDX", "%p", cl);
6062 tpl_printf(vars, TPLADD, "CSIDX", "id_%p", cl);
6064 tpl_printf(vars, TPLADD, "CLIENTTYPE", "%c", cl->typ);
6065 tpl_printf(vars, TPLADD, "CLIENTCNR", "%d", get_threadnum(cl));
6066 tpl_addVar(vars, TPLADD, "CLIENTUSER", xml_encode(vars, usr));
6068 tpl_addVar(vars, TPLADD, "STATUSUSERICON", xml_encode(vars, usr));
6069 if (cl->typ == 'c' || cl->typ == 'm')
6071 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, usr));
6072 tpl_addVar(vars, TPLADD, "USERENC", urlencode(vars, usr));
6074 else if (cl->typ == 'p' || cl->typ == 'r')
6076 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, usr));
6077 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, usr));
6080 bool picon_shown = false;
6081 const char *status_user_icon_tpl = NULL;
6083 char picon_name[32];
6084 if(cfg.http_showpicons)
6086 if(picon_exists(xml_encode(vars, usr)))
6088 switch (cl->typ)
6090 case 'm': // Fall through
6091 case 'c': status_user_icon_tpl = "SUSERICON"; picon_shown = true; break;
6092 case 'p': // Fall through
6093 case 'r': status_user_icon_tpl = "SREADERICON"; picon_shown = true; break;
6096 else
6097 tpl_printf(vars, TPLADD, "UPICMISSING", "%smissing icon: IC_%s.tpl",!apicall?"&#13;":"",xml_encode(vars, usr));
6100 if (!picon_shown)
6102 switch (cl->typ)
6104 case 'm': // Fall through
6105 case 'c': status_user_icon_tpl = "SUSER"; break;
6106 case 'p': // Fall through
6107 case 'r': status_user_icon_tpl = "SREADER"; break;
6111 if (status_user_icon_tpl)
6112 tpl_addVar(vars, TPLADD, "STATUSUSERICON", tpl_getTpl(vars, status_user_icon_tpl));
6114 tpl_printf(vars, TPLADD, "CLIENTCAU", "%d", cau);
6115 if(!apicall)
6117 if(cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r')
6119 if(cl->crypted) { tpl_addVar(vars, TPLADD, "CLIENTCRYPTED", "ON"); }
6120 else { tpl_addVar(vars, TPLADD, "CLIENTCRYPTED", "OFF"); }
6122 else { tpl_addVar(vars, TPLADD, "CLIENTCRYPTED", ""); }
6124 else { tpl_printf(vars, TPLADD, "CLIENTCRYPTED", "%d", cl->crypted); }
6125 tpl_addVar(vars, TPLADD, "CLIENTIP", cs_inet_ntoa(cl->ip));
6126 tpl_printf(vars, TPLADD, "CLIENTPORT", "%d", cl->port);
6127 const char *proto = client_get_proto(cl);
6128 #ifdef CS_CACHEEX_AIO
6129 if(cl &&
6130 ( (cl->typ == 'c' && cl->account && cl->account->cacheex.feature_bitfield)
6131 #if defined(MODULE_CAMD35) || defined (MODULE_CAMD35_TCP)
6132 || (cl->c35_extmode > 1)
6133 #endif
6134 #ifdef MODULE_CCCAM
6135 || (cc && cc->extended_lg_flagged_cws)
6136 #endif
6137 || (cl->typ == 'p' && cl->reader && cl->reader->cacheex.feature_bitfield))
6140 const char *aio_suffix = " (cx-aio)";
6141 char *new_proto;
6142 if(cs_malloc(&new_proto, cs_strlen(proto)+cs_strlen(aio_suffix)+1)) {
6143 new_proto[0] = '\0';
6144 if (!cs_strncat(new_proto, (char *)proto, cs_strlen(proto)+cs_strlen(aio_suffix)+1)) {
6145 cs_log("FIXME!");
6147 if (cs_strncat(new_proto, (char *)aio_suffix, cs_strlen(proto)+cs_strlen(aio_suffix)+1)) {
6148 webif_add_client_proto(vars, cl, (const char*)new_proto, apicall);
6149 } else {
6150 cs_log("FIXME!");
6152 free(new_proto);
6154 } else {
6155 #endif
6156 webif_add_client_proto(vars, cl, proto, apicall);
6157 #ifdef CS_CACHEEX_AIO
6159 #endif
6160 if(!apicall)
6162 if((cl->typ != 'p' && cl->typ != 'r') || cl->reader->card_status == CARD_INSERTED)
6164 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);
6165 tpl_addVar(vars, TPLADD, "CLIENTLOGINSECS", sec2timeformat(vars, lsec));
6167 else
6169 tpl_addVar(vars, TPLADD, "CLIENTLOGINDATE", "");
6170 tpl_addVar(vars, TPLADD, "CLIENTLOGINSECS", "");
6173 else
6175 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);
6176 char tbuffer [30];
6177 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &lt);
6178 tpl_addVar(vars, TPLADD, "CLIENTLOGINDATE", tbuffer);
6179 tpl_printf(vars, TPLADD, "CLIENTLOGINSECS", "%d", lsec);
6182 //load historical values from ringbuffer
6183 char *value = get_ecm_historystring(cl);
6184 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIMEHIST", value);
6185 free_mk_t(value);
6187 if((isec < cfg.hideclient_to || cfg.hideclient_to == 0 || is_dvbapi_usr(cl->account->usr)) && (cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r'))
6189 if(((cl->typ == 'c')) && (cl->lastreader[0]))
6191 tpl_printf(vars, TPLADD, "MSVALUE", PRINTF_LOCAL_D, cl->cwlastresptime);
6192 if(apicall)
6194 tpl_addVar(vars, TPLADD, "LASTREADER", (cl->last_caid == NO_CAID_VALUE || isec > cfg.hideclient_to ) ? "" : cl->lastreader);
6195 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, cl->lastreader));
6197 else
6199 #ifdef WITH_LB
6200 tpl_addVar(vars, TPLADD, "LBLVALUE", xml_encode(vars, cl->lastreader));
6201 if(strstr(cl->lastreader, " (cache)"))
6203 char lastreader_tmp[cs_strlen(cl->lastreader) - 8];
6204 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", tpl_getVar(vars, "LBLRPSTRVALUE"));
6205 cs_strncpy(lastreader_tmp, cl->lastreader, sizeof(lastreader_tmp));
6206 tpl_addVar(vars, TPLADD, "LBLVALUEENC", urlencode(vars, lastreader_tmp));
6207 tpl_addVar(vars, TPLADD, "LBLVALUETITLE", xml_encode(vars, lastreader_tmp));
6209 else
6211 tpl_addVar(vars, TPLADD, "LBLVALUEENC", urlencode(vars, cl->lastreader));
6212 tpl_addVar(vars, TPLADD, "LBLVALUETITLE", xml_encode(vars, cl->lastreader));
6214 tpl_addVar(vars, TPLAPPEND, "CLIENTLBVALUE", tpl_getTpl(vars, "CLIENTLBLVALUEBIT"));
6215 #else
6216 tpl_printf(vars, TPLAPPEND, "CLIENTLBVALUE", "%s (%'d ms)", xml_encode(vars, cl->lastreader), cl->cwlastresptime);
6217 #endif
6219 if(cl->last_caid == NO_CAID_VALUE || isec > cfg.hideclient_to) tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", "");
6221 if(cl->last_caid != NO_CAID_VALUE || cl->last_srvid != NO_SRVID_VALUE)
6223 char channame[CS_SERVICENAME_SIZE];
6224 const char *lastprovidername;
6226 get_servicename_or_null(cl, cl->last_srvid, cl->last_provid, cl->last_caid, channame, sizeof(channame));
6227 if(channame[0] == '\0')
6229 cs_strncpy(channame, "unknown", sizeof(channame));
6232 lastprovidername = get_cl_lastprovidername(cl);
6234 tpl_printf(vars, TPLADD, "CLIENTCAID", "%04X", cl->last_caid);
6235 tpl_printf(vars, TPLADD, "CLIENTPROVID", "%06X", cl->last_provid);
6236 tpl_printf(vars, TPLADD, "CLIENTSRVID", "%04X", cl->last_srvid);
6237 tpl_printf(vars, TPLADD, "CLIENTSRVPROVIDER", "%s%s%s", (lastprovidername[0] != '\0' && strcmp(lastprovidername, " ")) ? " [" : "", xml_encode(vars, lastprovidername), (lastprovidername[0] != '\0' && strcmp(lastprovidername, " ")) ? "]" : "");
6238 tpl_addVar(vars, TPLADD, "CLIENTSRVNAME", xml_encode(vars, channame));
6239 tpl_printf(vars, TPLADD, "CLIENTLASTRESPONSETIME", "%d", cl->cwlastresptime ? cl->cwlastresptime : 1);
6240 tpl_addVar(vars, TPLADD, "CLIENTSRVTYPE", cl->last_srvidptr && cl->last_srvidptr->type ? xml_encode(vars, cl->last_srvidptr->type) : "");
6241 tpl_addVar(vars, TPLADD, "CLIENTSRVDESCRIPTION", cl->last_srvidptr && cl->last_srvidptr->desc ? xml_encode(vars, cl->last_srvidptr->desc) : "");
6242 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", sec2timeformat(vars, chsec));
6243 if(cfg.http_showpicons && cl->last_srvid)
6245 char picon_channame[30];
6246 int8_t picon_ok = 0;
6248 get_picon_servicename_or_null(cl, cl->last_srvid, cl->last_provid, cl->last_caid, picon_channame, sizeof(picon_channame));
6249 if(picon_channame[0])
6251 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", picon_channame);
6252 picon_ok = picon_exists(picon_name);
6253 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
6255 if(!picon_ok && picon_servicename_remve_hd(picon_channame, sizeof(picon_channame)))
6257 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", picon_channame);
6258 picon_ok = picon_exists(picon_name);
6259 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
6262 if(!picon_ok)
6264 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%04X_%06X_%04X", cl->last_caid, cl->last_provid, cl->last_srvid);
6265 tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
6266 picon_ok = picon_exists(picon_name);
6268 if(!picon_ok)
6270 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%04X_%04X", cl->last_caid, cl->last_srvid);
6271 picon_ok = picon_exists(picon_name);
6272 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
6274 if(!picon_ok)
6276 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "0000_%04X", cl->last_srvid);
6277 picon_ok = picon_exists(picon_name);
6278 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
6280 if(picon_ok)
6282 tpl_addVar(vars, TPLADDONCE, "CURRENTPICON", tpl_getTpl(vars, "CLIENTCURRENTCHANNELPIC"));
6284 else
6286 tpl_addVar(vars, TPLADDONCE, "CURRENTPICON", tpl_getTpl(vars, "CLIENTCURRENTCHANNEL"));
6287 tpl_addVar(vars, TPLADD, "PICONNAME", "");
6290 else
6292 tpl_addVar(vars, TPLADDONCE, "CURRENTPICON", tpl_getTpl(vars, "CLIENTCURRENTCHANNELBIT"));
6293 tpl_addVar(vars, TPLADD, "PICONNAME", "0000_0000");
6296 else
6298 tpl_addVar(vars, TPLADD, "CLIENTCAID", "0000");
6299 tpl_addVar(vars, TPLADD, "CLIENTPROVID", "000000");
6300 tpl_printf(vars, TPLADD, "CLIENTSRVID", "0000");
6303 else
6305 tpl_addVar(vars, TPLADD, "CLIENTCAID", "0000");
6306 tpl_addVar(vars, TPLADD, "CLIENTPROVID", "000000");
6307 tpl_addVar(vars, TPLADD, "CLIENTSRVID", "0000");
6308 tpl_addVar(vars, TPLADD, "CURRENTPICON", "");
6309 tpl_addVar(vars, TPLADD, "CLIENTSRVPROVIDER", "");
6310 tpl_addVar(vars, TPLADD, "CLIENTSRVNAME", "");
6311 tpl_addVar(vars, TPLADD, "CLIENTSRVTYPE", "");
6312 tpl_addVar(vars, TPLADD, "CLIENTSRVDESCRIPTION", "");
6313 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", "");
6314 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", "");
6317 if(!apicall)
6319 tpl_addVar(vars, TPLADD, "CLIENTIDLESECS", sec2timeformat(vars, isec));
6321 if((cl->typ != 'p' && cl->typ != 'r') || cl->reader->card_status == CARD_INSERTED)
6322 { tpl_addVar(vars, TPLADD, "CLIENTIDLESECSCLASS", "idlesec_normal"); }
6323 else
6324 { tpl_addVar(vars, TPLADD, "CLIENTIDLESECSCLASS", "idlesec_alert"); }
6326 else
6328 tpl_printf(vars, TPLADD, "CLIENTIDLESECS", "%d", isec);
6331 if(con == 2) { tpl_addVar(vars, TPLADD, "CLIENTCON", "Duplicate"); }
6332 else if(con == 1) { tpl_addVar(vars, TPLADD, "CLIENTCON", "Sleep"); }
6333 else
6335 struct s_reader *rdr = cl->reader;
6336 char *txt = "OK";
6337 if(!rdr && (cl->typ == 'r' || cl->typ == 'p')) { txt = "UNKNOWN"; }
6339 else if(cl->typ == 'r' || cl->typ == 'p') //reader or proxy
6341 #ifdef WITH_LB
6342 if(rdr->lbvalue)
6344 tpl_printf(vars, TPLADD, "LBLRPSTRVALUE", "%d", rdr->lbvalue);
6346 else
6348 tpl_addVar(vars, TPLADD, "LBLRPSTRVALUE", "no data");
6350 tpl_addVar(vars, TPLADD, "LBLRPVALUE", rdr->label);
6351 tpl_addVar(vars, TPLADD, "LBLRPVALUEENC", urlencode(vars, rdr->label));
6352 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", tpl_getTpl(vars, "CLIENTLBLVALUERP"));
6353 #else
6354 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", tpl_getVar(vars, "LBLRPSTRVALUE"));
6355 #endif
6356 switch(rdr->card_status)
6358 case NO_CARD:
6359 if(rdr->typ == R_GBOX)
6360 { txt = "ONL"; }
6361 else
6362 { txt = "OFF"; }
6363 break;
6364 case UNKNOWN:
6365 txt = "UNKNOWN";
6366 break;
6367 case READER_DEVICE_ERROR:
6368 txt = "READER DEVICE ERROR";
6369 break;
6370 case CARD_NEED_INIT:
6371 if(rdr->typ == R_GBOX)
6372 { txt = "OFFLINE"; }
6373 #ifdef CS_CACHEEX
6374 else if (cl->reader->cacheex.mode > 0)
6375 { txt = "CCcam CacheEX"; }
6376 #endif
6377 else
6378 { txt = "NEEDINIT"; }
6379 break;
6380 case CARD_INSERTED:
6381 if(cl->typ == 'p')
6383 if(rdr->typ == R_GBOX)
6384 { txt = "ONL"; }
6385 else
6386 { txt = "CONNECTED"; }
6388 else
6389 { txt = "CARDOK"; }
6390 break;
6391 case CARD_FAILURE:
6392 txt = "ERROR";
6393 break;
6394 default:
6395 txt = "UNDEF";
6397 #ifdef MODULE_GBOX
6398 if(rdr->typ == R_GBOX)
6400 struct gbox_peer *peer = cl->gbox;
6401 char gbx_txt[45];
6402 memset(gbx_txt, 0, sizeof(gbx_txt));
6403 if(!strcmp(txt, "OFFLINE"))
6405 snprintf(gbx_txt, sizeof(gbx_txt), "%s | ID: %04X", txt, peer->gbox.id);
6407 else
6409 snprintf(gbx_txt, sizeof(gbx_txt), "%s | crd: %d | ID: %04X", txt, gbox_count_peer_cards(peer->gbox.id), peer->gbox.id);
6411 txt = gbx_txt;
6413 #endif
6416 tpl_addVar(vars, TPLADD, "CLIENTCON", txt);
6418 if(rdr && (cl->typ == 'r')) //reader
6420 if(rdr->ll_entitlements)
6422 LL_ITER itr = ll_iter_create(rdr->ll_entitlements);
6423 S_ENTITLEMENT *ent;
6424 uint16_t total_ent = 0;
6425 uint16_t active_ent = 0;
6426 struct tm end_t;
6427 tpl_addVar(vars, TPLADD, "TMPSPAN", "<SPAN>");
6428 while((ent = ll_iter_next(&itr)))
6430 total_ent++;
6431 if((ent->end > now) && (ent->type != 7))
6433 if(active_ent) {tpl_addVar(vars, TPLAPPEND, "TMPSPAN", "<BR><BR>");}
6434 active_ent++;
6435 localtime_r(&ent->end, &end_t);
6436 tpl_printf(vars, TPLAPPEND, "TMPSPAN", "%04X@%06X<BR>exp:%04d/%02d/%02d",
6437 ent->caid, ent->provid,
6438 end_t.tm_year + 1900, end_t.tm_mon + 1, end_t.tm_mday);
6439 tpl_printf(vars, TPLAPPEND, "ENTITLEMENTS", "%s{\"caid\":\"%04X\",\"provid\":\"%06X\",\"exp\":\"%04d/%02d/%02d\"}",
6440 active_ent > 1 ? ",": "",
6441 ent->caid, ent->provid,
6442 end_t.tm_year + 1900, end_t.tm_mon + 1, end_t.tm_mday);
6445 tpl_printf(vars, TPLADD, "TOTENTITLEMENTS", "%d", total_ent);
6446 if(((total_ent) && (active_ent == 0)) || (total_ent == 0))
6448 tpl_addVar(vars, TPLAPPEND, "TMPSPAN", "No active entitlements found");
6450 tpl_addVar(vars, TPLAPPEND, "TMPSPAN", "</SPAN>");
6451 if(active_ent)
6453 tpl_printf(vars, TPLADD, "TMP", "(%d entitlement%s)", active_ent, (active_ent != 1) ? "s" : "");
6455 else
6457 tpl_addVar(vars, TPLADD, "TMP", "(no entitlements)");
6459 tpl_addVar(vars, TPLADD, "ENTLABEL", urlencode(vars, cl->reader->label));
6460 tpl_addVar(vars, TPLADD, "ENTVALUE", active_ent > 0 ? "" : "1");
6461 if (!apicall) tpl_addVar(vars, TPLAPPEND, "CLIENTCON", tpl_getTpl(vars, "FOUNDENTITLEMENTS"));
6463 else
6465 tpl_addVar(vars, TPLADD, "ENTLABEL", urlencode(vars, cl->reader->label));
6466 if (!apicall) tpl_addVar(vars, TPLAPPEND, "CLIENTCON", tpl_getTpl(vars, "NOENTITLEMENTS"));
6469 #ifdef MODULE_CCCAM
6470 if(!apicall || apicall == 2)
6472 if(rdr && (cl->typ == 'r' || cl->typ == 'p') && strncmp(proto, "cccam", 5) == 0 && rdr->tcp_connected && rdr->card_status != CARD_FAILURE)
6474 struct cc_data *rcc = cl->cc;
6475 if(rcc)
6477 LLIST *cards = rcc->cards;
6478 if(cards)
6480 int32_t cnt = ll_count(cards);
6481 int32_t locals = rcc->num_hop1;
6482 if(!apicall)
6484 tpl_printf(vars, TPLADD, "TMP", "(%d of %d card%s)", locals, cnt, (cnt > 1) ? "s" : "");
6485 tpl_printf(vars, TPLADD, "CCCOUNT", "%d", cnt);
6486 tpl_printf(vars, TPLADD, "CCCHOP1", "%d", rcc->num_hop1);
6487 tpl_printf(vars, TPLADD, "CCCHOP2", "%d", rcc->num_hop2);
6488 tpl_printf(vars, TPLADD, "CCCHOPX", "%d", rcc->num_hopx);
6489 tpl_printf(vars, TPLADD, "CCCCURR", "%d", cl->reader->currenthops);
6490 tpl_printf(vars, TPLADD, "CCCRES0", "%d", rcc->num_reshare0);
6491 tpl_printf(vars, TPLADD, "CCCRES1", "%d", rcc->num_reshare1);
6492 tpl_printf(vars, TPLADD, "CCCRES2", "%d", rcc->num_reshare2);
6493 tpl_printf(vars, TPLADD, "CCCRESX", "%d", rcc->num_resharex);
6494 tpl_addVar(vars, TPLADD, "TMPSPAN", tpl_getTpl(vars, "CCENTITLEMENTS"));
6495 tpl_addVar(vars, TPLADD, "CCCLABEL", urlencode(vars, cl->reader->label));
6496 tpl_addVar(vars, TPLADD, "CCCRESHARE", rcc->num_reshare0 > 0 ? "1" : "");
6497 tpl_addVar(vars, TPLADD, "CCCTMP", tpl_getVar(vars, "TMP"));
6498 tpl_addVar(vars, TPLADD, "CCCTMPSPAN", tpl_getVar(vars, "TMPSPAN"));
6499 tpl_addVar(vars, TPLAPPEND, "CLIENTCON", tpl_getTpl(vars, "CCENTITLETOOLTIP"));
6501 if (apicall == 2)
6503 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, cl->reader->label));
6504 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\"}",
6505 locals, cnt, rcc->num_hop1, rcc->num_hop2, rcc->num_hopx, cl->reader->currenthops,
6506 rcc->num_reshare0, rcc->num_reshare1, rcc->num_reshare2, rcc->num_resharex,
6507 rcc->num_reshare0 > 0 ? "1" : "");
6509 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" : "");
6514 #endif
6518 if(!apicall)
6520 // select right suborder
6521 if(cl->typ == 'c')
6523 if(shown) { tpl_addVar(vars, TPLAPPEND, "CLIENTSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT")); }
6524 if(cfg.http_hide_idle_clients != 1 && cfg.hideclient_to > 0)
6526 tpl_printf(vars, TPLADD, "UCAC", "%d", user_count_active);
6527 tpl_printf(vars, TPLADD, "CFGH", "%d", cfg.hideclient_to);
6528 tpl_addVar(vars, TPLADD, "CHEADADD", tpl_getTpl(vars, "CLIENTHEADLINEADD"));
6531 tpl_printf(vars, TPLADD, "UCS", "%d", user_count_shown);
6532 tpl_printf(vars, TPLADD, "UCA", "%d", user_count_all);
6533 tpl_addVar(vars, TPLADD, "HIDEIDLE", "5");
6534 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "User");
6535 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTHEADLINE"));
6536 tpl_addVar(vars, TPLADD, "CLIENTOPTIONADD", tpl_getTpl(vars, "CLIENTHEADLINEBIT"));
6537 tpl_addVar(vars, TPLADD, "CLIENTHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
6538 tpl_addVar(vars, TPLADD, "CLIENTOPTIONADD", "");
6540 else if(cl->typ == 'r')
6542 if(shown)
6544 tpl_addVar(vars, TPLAPPEND, "READERSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT"));
6547 tpl_printf(vars, TPLADD, "RCC", "%d", reader_count_conn);
6548 tpl_printf(vars, TPLADD, "RCA", "%d", reader_count_all);
6550 if(reader_count_off)
6552 tpl_printf(vars, TPLADD, "RCO", "%d", reader_count_all-reader_count_off);
6553 tpl_addVar(vars, TPLADD, "RHEADADD", tpl_getTpl(vars, "CLIENTRHEADLINEADD"));
6556 tpl_addVar(vars, TPLADD, "HIDEIDLE", "3");
6557 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "Reader");
6558 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTRHEADLINE"));
6559 tpl_addVar(vars, TPLADD, "READERHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
6561 else if(cl->typ == 'p')
6563 if(shown)
6565 tpl_addVar(vars, TPLAPPEND, "PROXYSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT"));
6568 tpl_printf(vars, TPLADD, "PCC", "%d", proxy_count_conn);
6569 tpl_printf(vars, TPLADD, "PCA", "%d", proxy_count_all);
6571 if(proxy_count_off)
6573 tpl_printf(vars, TPLADD, "PCO", "%d", proxy_count_all-proxy_count_off);
6574 tpl_addVar(vars, TPLADD, "PHEADADD", tpl_getTpl(vars, "CLIENTPHEADLINEADD"));
6577 tpl_addVar(vars, TPLADD, "HIDEIDLE", "4");
6578 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "Proxy");
6579 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTPHEADLINE"));
6580 tpl_addVar(vars, TPLADD, "PROXYHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
6582 else if(cl->typ == 'm' || cl->typ == 's' || cl->typ == 'h')
6584 if(shown)
6586 tpl_addVar(vars, TPLAPPEND, "SERVERSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT"));
6589 tpl_addVar(vars, TPLADD, "HIDEIDLE", "2");
6590 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "Server");
6592 if(cl->typ == 's' || cl->typ == 'h')
6594 tpl_printf(vars, TPLADD, "SCS", "%d", server_count_shown);
6595 tpl_printf(vars, TPLADD, "SCA", "%d", server_count_all);
6596 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTSHEADLINE"));
6598 if(shown || cl->wihidden)
6600 tpl_addVar(vars, TPLADD, "SERVERHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
6603 else
6605 tpl_addVar(vars, TPLADD, "SHOWHIDDENADD", " & Monitors");
6606 tpl_printf(vars, TPLADD, "MCS", "%d", monitor_count_shown);
6607 tpl_printf(vars, TPLADD, "MCA", "%d", monitor_count_all);
6608 tpl_addVar(vars, TPLADD, "MHEADADD", tpl_getTpl(vars, "CLIENTMHEADLINE"));
6609 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTSHEADLINE"));
6610 tpl_addVar(vars, TPLADD, "SERVERHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
6611 tpl_addVar(vars, TPLADD, "SHOWHIDDENADD", "");
6615 else
6617 if(shown)
6619 if(apicall == 1)
6621 tpl_addVar(vars, TPLAPPEND, "APISTATUSBITS", tpl_getTpl(vars, "APISTATUSBIT"));
6624 if(apicall == 2)
6626 tpl_addVar(vars, TPLADD, "JSONARRAYDELIMITER", delimiter?",":"");
6627 tpl_addVar(vars, TPLAPPEND, "JSONSTATUSBITS", tpl_getTpl(vars, "JSONSTATUSBIT"));
6628 delimiter++;
6633 #ifdef CS_CACHEEX
6635 #endif
6639 LL_ITER itr = ll_iter_create(configured_readers);
6640 struct s_reader *rdrr;
6641 while((rdrr = ll_iter_next(&itr)))
6643 if(rdrr->label[0] && rdrr->typ)
6645 total_readers += 1;
6647 if(rdrr->enable) { active_readers += 1; }
6648 else { disabled_readers += 1; }
6650 if(rdrr->tcp_connected) { connected_readers += 1; }
6654 cs_readunlock(__func__, &clientlist_lock);
6655 cs_readunlock(__func__, &readerlist_lock);
6657 uint8_t is_touch = 0;
6658 if(config_enabled(TOUCH) && streq(tpl_getVar(vars, "SUBDIR"), TOUCH_SUBDIR))
6659 {is_touch=1;}
6661 if(cfg.http_status_log || (apicall == 1 && strcmp(getParam(params, "appendlog"), "1") == 0) || is_touch)
6663 if(cfg.loghistorylines && log_history)
6665 LL_ITER it = ll_iter_create(log_history);
6666 struct s_log_history *hist;
6668 while((hist = (struct s_log_history*)ll_iter_next(&it)))
6670 char p_usr[32];
6671 size_t pos1 = strcspn(hist->txt, "\t") + 1;
6672 cs_strncpy(p_usr, hist->txt , pos1 > sizeof(p_usr) ? sizeof(p_usr) : pos1);
6674 char *p_txt = hist->txt + pos1;
6676 if(!apicall)
6678 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));
6680 else
6682 tpl_addVar(vars, TPLAPPEND, "LOGHISTORY", p_txt);
6686 else
6688 tpl_addVar(vars, TPLADD, "LOGHISTORY", "loghistorylines is set to 0 in your configuration");
6692 #ifdef CS_CACHEEX
6693 char *getting = "<IMG SRC=\"image?i=ICARRL\" ALT=\"Getting\">";
6694 char *pushing = "<IMG SRC=\"image?i=ICARRR\" ALT=\"Pushing\">";
6696 float cachesum = first_client ? first_client->cwcacheexgot : 1;
6697 if(cachesum < 1)
6699 cachesum = 1;
6701 tpl_printf(vars, TPLADD, "TOTAL_CACHEXPUSH", "%d", first_client ? first_client->cwcacheexpush : 0);
6702 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXPUSH_IMG", pushing);
6703 tpl_printf(vars, TPLADD, "TOTAL_CACHEXGOT", "%d", first_client ? first_client->cwcacheexgot : 0);
6704 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXGOT_IMG", getting);
6705 tpl_printf(vars, TPLADD, "TOTAL_CACHEXHIT", "%d", first_client ? first_client->cwcacheexhit : 0);
6706 tpl_printf(vars, TPLADD, "TOTAL_CACHESIZE", "%d", cache_size());
6707 #ifdef CS_CACHEEX_AIO
6708 tpl_printf(vars, TPLADD, "TOTAL_CACHESIZE_LG", "%d", cache_size_lg());
6709 #endif
6710 tpl_printf(vars, TPLADD, "REL_CACHEXHIT", "%.2f", (first_client ? first_client->cwcacheexhit : 0) * 100 / cachesum);
6711 tpl_addVar(vars, TPLADD, "CACHEEXSTATS", tpl_getTpl(vars, "STATUSCACHEX"));
6712 #endif
6713 //User info
6714 struct s_auth *account;
6715 int32_t total_users = 0;
6716 int32_t disabled_users = 0;
6717 int32_t expired_users = 0;
6718 int32_t expired_or_disabled_users = 0;
6719 int32_t connected_users = 0;
6720 int32_t online_users = 0;
6722 for(account = cfg.account; (account); account = account->next)
6724 total_users++;
6725 if(account->expirationdate && account->expirationdate < now)
6727 expired_users++;
6729 if(account->disabled != 0)
6731 disabled_users++;
6733 if((account->expirationdate && account->expirationdate < now)||account->disabled != 0)
6735 expired_or_disabled_users++;
6737 int32_t latestactivity = 0;
6738 struct s_client *latestclient = NULL;
6739 for(cl = first_client->next; cl ; cl = cl->next)
6741 if(cl->account && !strcmp(cl->account->usr, account->usr))
6743 if(cl->lastecm > latestactivity || cl->login > latestactivity)
6745 if(cl->lastecm > cl->login) { latestactivity = cl->lastecm; }
6746 else { latestactivity = cl->login; }
6747 latestclient = cl;
6752 if(latestclient != NULL)
6754 connected_users++;
6756 if(latestactivity > 0)
6758 if((now - latestactivity) < cfg.hideclient_to)
6760 if(latestclient->cwfound + latestclient->cwnot + latestclient->cwcache > 0)
6762 online_users++;
6768 tpl_printf(vars, TPLADD, "TOTAL_USERS", "%d", total_users);
6769 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE", "%d", total_users - expired_or_disabled_users);
6770 tpl_printf(vars, TPLADD, "TOTAL_EXPIRED", "%d", expired_users);
6771 tpl_printf(vars, TPLADD, "TOTAL_DISABLED", "%d", disabled_users);
6772 tpl_printf(vars, TPLADD, "TOTAL_ONLINE", "%d", online_users);
6773 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED", "%d", connected_users);
6775 tpl_printf(vars, TPLADD, "TOTAL_READERS", "%d", total_readers);
6776 tpl_printf(vars, TPLADD, "TOTAL_DISABLED_READERS", "%d", disabled_readers);
6777 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE_READERS", "%d", active_readers);
6778 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED_READERS", "%d", connected_readers);
6780 //CM info
6781 set_ecm_info(vars);
6783 //copy struct to p_stat_old for cpu_usage calculation
6784 p_stat_old = p_stat_cur;
6787 * check_available Bit mapping
6788 * mem 0 total, 1 used & free, 2 buff, cached & free incl. buff, 3 share
6789 * swap 4 total, 5 used & free,
6790 * proc 6 count
6791 * cpu 7 load
6792 * oscam 8 vsize & rssize, 9 cpu user, 10 cpu sys, 11 cpu sum, 12 cpu refreshtime
6793 * unused 13 - 15
6795 //Memory-CPU Info for linux based systems
6796 #if defined(__linux__)
6797 //get actual stats
6798 if(!get_stats_linux(getpid(),&p_stat_cur)){
6799 if(p_stat_old.cpu_total_time != 0){
6800 calc_cpu_usage_pct(&p_stat_cur, &p_stat_old);
6803 else{
6804 //something went wrong, so fill with "N/A"
6805 p_stat_cur.check_available = 65535;
6807 #else // if not linux, fill with "N/A" but probably in future gets filled also for other platforms
6808 p_stat_cur.check_available = 65535;
6809 #endif
6810 set_status_info(vars, p_stat_cur);
6812 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))){
6813 tpl_addVar(vars, TPLADD, "DISPLAYINFO", "visible");
6815 else{
6816 tpl_addVar(vars, TPLADD, "DISPLAYINFO", "hidden");
6819 tpl_addVar(vars, TPLADD, "DISPLAYSYSINFO", cfg.http_showmeminfo ? "visible" : "hidden");
6820 tpl_addVar(vars, TPLADD, "DISPLAYUSERINFO", cfg.http_showuserinfo ? "visible" : "hidden");
6821 tpl_addVar(vars, TPLADD, "DISPLAYREADERINFO", cfg.http_showreaderinfo ? "visible" : "hidden");
6822 tpl_addVar(vars, TPLADD, "DISPLAYLOADINFO", cfg.http_showloadinfo ?"visible" : "hidden");
6823 tpl_addVar(vars, TPLADD, "DISPLAYECMINFO", cfg.http_showecminfo ? "visible" : "hidden");
6824 tpl_addVar(vars, TPLADD, "DISPLAYECMINFO_READERS", cfg.http_showecminfo ? "visible" : "hidden");
6826 if(cfg.http_showcacheexinfo == 1 && config_enabled(CS_CACHEEX))
6828 if (config_enabled(CS_CACHEEX_AIO))
6830 tpl_addVar(vars, TPLADD, "DISPLAYCACHEEXINFO", "hidden");
6831 tpl_addVar(vars, TPLADD, "DISPLAYCACHEEXAIOINFO", "visible");
6833 else
6835 tpl_addVar(vars, TPLADD, "DISPLAYCACHEEXINFO", "visible");
6836 tpl_addVar(vars, TPLADD, "DISPLAYCACHEEXAIOINFO", "hidden");
6839 else{
6840 tpl_addVar(vars, TPLADD, "DISPLAYCACHEEXINFO", "hidden");
6841 tpl_addVar(vars, TPLADD, "DISPLAYCACHEEXAIOINFO", "hidden");
6844 #ifdef WITH_DEBUG
6845 if(cfg.http_status_log || is_touch)
6847 // Debuglevel Selector
6848 int32_t lvl;
6849 for(i = 0; i < MAX_DEBUG_LEVELS; i++)
6851 lvl = 1 << i;
6852 tpl_printf(vars, TPLADD, "TMPC", "DCLASS%d", lvl);
6853 tpl_printf(vars, TPLADD, "TMPV", "DEBUGVAL%d", lvl);
6854 if(cs_dblevel & lvl)
6856 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugls");
6857 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel - lvl);
6859 else
6861 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugl");
6862 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel + lvl);
6866 if(cs_dblevel == D_ALL_DUMP)
6867 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugls"); }
6868 else
6869 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugl"); }
6871 tpl_addVar(vars, TPLADD, "NEXTPAGE", "status.html");
6872 tpl_addVar(vars, TPLADD, "DCLASS", "debugl"); //default
6873 tpl_printf(vars, TPLADD, "ACTDEBUG", "%d", cs_dblevel);
6874 #ifdef CS_CACHEEX_AIO
6875 tpl_addVar(vars, TPLADD, "SDEBUG", tpl_getTpl(vars, "DEBUGSELECTAIO"));
6876 #else
6877 tpl_addVar(vars, TPLADD, "SDEBUG", tpl_getTpl(vars, "DEBUGSELECT"));
6878 #endif
6880 #endif
6882 if(cfg.http_status_log || is_touch)
6883 tpl_addVar(vars, TPLADDONCE, "LOG_HISTORY", tpl_getTpl(vars, "LOGHISTORYBIT"));
6885 if(apicall)
6887 if(apicall == 1)
6888 { return tpl_getTpl(vars, "APISTATUS"); }
6889 if(apicall == 2)
6891 tpl_printf(vars, TPLADD, "UCS", "%d", user_count_shown);
6892 tpl_printf(vars, TPLADD, "UCA", "%d", user_count_all);
6893 if(cfg.http_hide_idle_clients != 1 && cfg.hideclient_to > 0){
6894 tpl_printf(vars, TPLADD, "UCAC", "%d", user_count_active);
6896 tpl_printf(vars, TPLADD, "CFGH", "%d", cfg.hideclient_to);
6897 tpl_printf(vars, TPLADD, "MCS", "%d", monitor_count_shown);
6898 tpl_printf(vars, TPLADD, "MCA", "%d", monitor_count_all);
6899 tpl_printf(vars, TPLADD, "SCS", "%d", server_count_shown);
6900 tpl_printf(vars, TPLADD, "SCH", "%d", server_count_hidden);
6901 tpl_printf(vars, TPLADD, "SCA", "%d", server_count_all);
6902 tpl_printf(vars, TPLADD, "RCC", "%d", reader_count_conn);
6903 tpl_printf(vars, TPLADD, "RCO", "%d", reader_count_off);
6904 tpl_printf(vars, TPLADD, "RCA", "%d", reader_count_all);
6905 tpl_printf(vars, TPLADD, "PCC", "%d", proxy_count_conn);
6906 tpl_printf(vars, TPLADD, "PCO", "%d", proxy_count_off);
6907 tpl_printf(vars, TPLADD, "PCA", "%d", proxy_count_all);
6908 tpl_printf(vars, TPLADD, "PICONENABLED", "%d", cfg.http_showpicons?1:0);
6909 tpl_printf(vars, TPLADD, "SRVIDFILE", "%s", use_srvid2 ? "oscam.srvid2" : "oscam.srvid");
6910 return tpl_getTpl(vars, "JSONSTATUS");
6914 if(is_touch)
6915 { return tpl_getTpl(vars, "TOUCH_STATUS"); }
6916 else
6917 { return tpl_getTpl(vars, "STATUS"); }
6920 static char *send_oscam_services_edit(struct templatevars * vars, struct uriparams * params)
6922 struct s_sidtab *sidtab, *ptr;
6923 char label[sizeof(cfg.sidtab->label)];
6924 int32_t i;
6926 setActiveMenu(vars, MNU_SERVICES);
6928 cs_strncpy(label, strtolower(getParam(params, "service")), sizeof(label));
6929 ++cfg_sidtab_generation;
6930 for(sidtab = cfg.sidtab; sidtab != NULL && strcmp(label, sidtab->label) != 0; sidtab = sidtab->next) { ; }
6932 if(sidtab == NULL)
6934 i = 1;
6935 while(cs_strlen(label) < 1)
6937 snprintf(label, sizeof(label) / sizeof(char) - 1, "newservice%d", i);
6938 for(sidtab = cfg.sidtab; sidtab != NULL && strcmp(label, sidtab->label) != 0; sidtab = sidtab->next) { ; }
6939 if(sidtab != NULL) { label[0] = '\0'; }
6940 ++i;
6942 if(!cs_malloc(&sidtab, sizeof(struct s_sidtab))) { return "0"; }
6944 if(cfg.sidtab == NULL) { cfg.sidtab = sidtab; }
6945 else
6947 for(ptr = cfg.sidtab; ptr != NULL && ptr->next != NULL; ptr = ptr->next) { ; }
6948 ptr->next = sidtab;
6950 cs_strncpy((char *)sidtab->label, label, sizeof(sidtab->label));
6951 ++cfg_sidtab_generation;
6952 tpl_addMsg(vars, "New service has been added");
6953 // Adding is uncritical as the new service is appended to sidtabs.ok/sidtabs.no and accounts/clients/readers have zeros there
6954 if(write_services() != 0) { tpl_addMsg(vars, "Writing services to disk failed!"); }
6957 if(strcmp(getParam(params, "action"), "Save") == 0)
6959 for(i = 0; i < (*params).paramcount; i++)
6961 if((strcmp((*params).params[i], "action")) && (strcmp((*params).params[i], "service")))
6963 chk_sidtab((*params).params[i], (*params).values[i], sidtab);
6966 ++cfg_sidtab_generation;
6967 tpl_addMsg(vars, "Services updated");
6968 // We don't need any refresh here as accounts/clients/readers sidtabs.ok/sidtabs.no are unaffected!
6969 if(write_services() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
6971 for(sidtab = cfg.sidtab; sidtab != NULL && strcmp(label, sidtab->label) != 0; sidtab = sidtab->next) { ; }
6974 tpl_addVar(vars, TPLADD, "LABEL", xml_encode(vars, sidtab->label));
6975 tpl_addVar(vars, TPLADD, "LABELENC", urlencode(vars, sidtab->label));
6977 if(sidtab)
6979 #ifdef CS_CACHEEX_AIO
6980 tpl_addVar(vars, TPLADD, "DCRCCHECKED", (sidtab->disablecrccws_only_for_exception == 1) ? "checked" : "" );
6981 tpl_addVar(vars, TPLADD, "NWCHECKED", (sidtab->no_wait_time == 1) ? "checked" : "" );
6982 tpl_addVar(vars, TPLADD, "LGOECHECKED", (sidtab->lg_only_exception == 1) ? "checked" : "" );
6983 #endif
6984 for(i = 0; i < sidtab->num_caid; i++)
6986 if(i == 0) { tpl_printf(vars, TPLADD, "CAIDS", "%04X", sidtab->caid[i]); }
6987 else { tpl_printf(vars, TPLAPPEND, "CAIDS", ",%04X", sidtab->caid[i]); }
6989 for(i = 0; i < sidtab->num_provid; i++)
6991 if(i == 0) { tpl_printf(vars, TPLADD, "PROVIDS", "%06X", sidtab->provid[i]); }
6992 else { tpl_printf(vars, TPLAPPEND, "PROVIDS", ",%06X", sidtab->provid[i]); }
6994 for(i = 0; i < sidtab->num_srvid; i++)
6996 if(i == 0) { tpl_printf(vars, TPLADD, "SRVIDS", "%04X", sidtab->srvid[i]); }
6997 else { tpl_printf(vars, TPLAPPEND, "SRVIDS", ",%04X", sidtab->srvid[i]); }
7000 #ifdef CS_CACHEEX_AIO
7001 return tpl_getTpl(vars, "SERVICEEDITAIO");
7002 #else
7003 return tpl_getTpl(vars, "SERVICEEDIT");
7004 #endif
7007 static void delete_from_SIDTABBITS(SIDTABBITS * orgsidtab, int32_t position, int32_t sidtablength)
7009 if(*orgsidtab)
7011 int32_t i;
7012 SIDTABBITS newsidtab = 0;
7013 for(i = 0; i < position; ++i)
7015 if(*orgsidtab & ((SIDTABBITS)1 << i))
7016 { newsidtab |= ((SIDTABBITS)1 << i); }
7018 for(; i < sidtablength; ++i)
7020 if(*orgsidtab & ((SIDTABBITS)1 << (i + 1)))
7021 { newsidtab |= ((SIDTABBITS)1 << i); }
7023 *orgsidtab = newsidtab;
7027 static char *send_oscam_services(struct templatevars * vars, struct uriparams * params)
7029 struct s_sidtab *sidtab;
7030 char *service = getParam(params, "service");
7031 char channame[CS_SERVICENAME_SIZE];
7032 int32_t i, counter = 0;
7034 setActiveMenu(vars, MNU_SERVICES);
7036 if(strcmp(getParam(params, "action"), "delete") == 0)
7038 if(cfg.http_readonly)
7040 tpl_addMsg(vars, "Sorry, Webif is in readonly mode. No deletion will be made!");
7042 else
7044 struct s_sidtab *sidtab_prev = NULL;
7045 int32_t sidtablength = -1;
7046 int32_t position = 0;
7048 // Calculate sidtablength before deletion so that updating sidtabs is faster
7049 for(sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next)
7050 { ++sidtablength; }
7052 for(sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next)
7054 if(strcmp(sidtab->label, service) == 0)
7056 struct s_auth *account;
7057 struct s_client *cl;
7058 struct s_reader *rdr;
7060 if(!sidtab_prev)
7061 { cfg.sidtab = sidtab->next; }
7062 else
7063 { sidtab_prev->next = sidtab->next; }
7065 for(account = cfg.account; (account); account = account->next)
7067 delete_from_SIDTABBITS(&account->sidtabs.ok, position, sidtablength);
7068 delete_from_SIDTABBITS(&account->sidtabs.no, position, sidtablength);
7070 for(cl = first_client->next; cl ; cl = cl->next)
7072 if(account == cl->account)
7074 cl->sidtabs.ok = account->sidtabs.ok;
7075 cl->sidtabs.no = account->sidtabs.no;
7080 LL_ITER itr = ll_iter_create(configured_readers);
7081 while((rdr = ll_iter_next(&itr)))
7083 delete_from_SIDTABBITS(&rdr->sidtabs.ok, position, sidtablength);
7084 delete_from_SIDTABBITS(&rdr->sidtabs.no, position, sidtablength);
7085 delete_from_SIDTABBITS(&rdr->lb_sidtabs.ok, position, sidtablength);
7087 free_sidtab(sidtab);
7088 ++counter;
7089 break;
7091 sidtab_prev = sidtab;
7092 position++;
7094 if(counter > 0)
7096 ++cfg_sidtab_generation;
7097 tpl_addMsg(vars, "Service has been deleted!");
7098 if(write_services() != 0) { tpl_addMsg(vars, "Writing services to disk failed!"); }
7100 else { tpl_addMsg(vars, "Sorry but the specified service doesn't exist. No deletion will be made!"); }
7104 sidtab = cfg.sidtab;
7105 // Show List
7106 counter = 0;
7107 while(sidtab != NULL)
7109 tpl_addVar(vars, TPLADD, "SID", "");
7110 if((strcmp(getParam(params, "service"), sidtab->label) == 0) && (strcmp(getParam(params, "action"), "list") == 0))
7112 tpl_addVar(vars, TPLADD, "SIDCLASS", "sidlist");
7113 tpl_addVar(vars, TPLAPPEND, "SID", "<DIV CLASS=\"sidlistclose\"><A HREF=\"services.html\">X</A></DIV>");
7114 for(i = 0; i < sidtab->num_srvid; i++)
7116 tpl_printf(vars, TPLAPPEND, "SID", "%04X : %s<BR>", sidtab->srvid[i],
7117 xml_encode(vars, get_servicename(cur_client(), sidtab->srvid[i], sidtab->num_provid ? sidtab->provid[0] : 0,
7118 sidtab->num_caid ? sidtab->caid[0] : 0, channame, sizeof(channame))));
7121 else
7123 tpl_addVar(vars, TPLADD, "SIDCLASS", "");
7124 tpl_printf(vars, TPLADD, "SID", "<A HREF=\"services.html?service=%s&amp;action=list\">Show Services</A>", urlencode(vars, sidtab->label));
7126 tpl_addVar(vars, TPLADD, "LABELENC", urlencode(vars, sidtab->label));
7127 tpl_addVar(vars, TPLADD, "LABEL", xml_encode(vars, sidtab->label));
7128 tpl_addVar(vars, TPLADD, "SIDLIST", tpl_getTpl(vars, "SERVICECONFIGSIDBIT"));
7130 tpl_addVar(vars, TPLAPPEND, "SERVICETABS", tpl_getTpl(vars, "SERVICECONFIGLISTBIT"));
7131 sidtab = sidtab->next;
7132 counter++;
7134 if(counter >= MAX_SIDBITS)
7136 tpl_addVar(vars, TPLADD, "BTNDISABLED", "DISABLED");
7137 tpl_addMsg(vars, "Maximum Number of Services is reached");
7139 return tpl_getTpl(vars, "SERVICECONFIGLIST");
7142 static char *send_oscam_savetpls(struct templatevars * vars)
7144 if(cfg.http_tpl)
7146 tpl_printf(vars, TPLADD, "CNT", "%d", tpl_saveIncludedTpls(cfg.http_tpl));
7147 tpl_addVar(vars, TPLADD, "PATH", cfg.http_tpl);
7149 else { tpl_addVar(vars, TPLADD, "CNT", "0"); }
7150 return tpl_getTpl(vars, "SAVETEMPLATES");
7153 static char *send_oscam_shutdown(struct templatevars * vars, FILE * f, struct uriparams * params, int8_t apicall, int8_t *keepalive, char *extraheader)
7155 if(!apicall) { setActiveMenu(vars, MNU_SHUTDOWN); }
7156 if(strcmp(strtolower(getParam(params, "action")), "shutdown") == 0)
7158 *keepalive = 0;
7159 if(!apicall)
7161 char *CSS = tpl_getUnparsedTpl("CSS", 1, "");
7162 tpl_addVar(vars, TPLADD, "STYLESHEET", CSS);
7163 NULLFREE(CSS);
7164 tpl_printf(vars, TPLADD, "REFRESHTIME", "%d", SHUTDOWNREFRESH);
7165 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
7166 tpl_printf(vars, TPLADD, "SECONDS", "%d", SHUTDOWNREFRESH);
7167 char *result = tpl_getTpl(vars, "SHUTDOWN");
7168 send_headers(f, 200, "OK", extraheader, "text/html", 0, cs_strlen(result), NULL, 0);
7169 webif_write(result, f);
7170 cs_log("Shutdown requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
7172 else
7174 tpl_addVar(vars, TPLADD, "APICONFIRMMESSAGE", "shutdown");
7175 cs_log("Shutdown requested by XMLApi from %s", cs_inet_ntoa(GET_IP()));
7177 cs_exit_oscam();
7179 if(!apicall)
7180 { return "1"; }
7181 else
7182 { return tpl_getTpl(vars, "APICONFIRMATION"); }
7185 else if(strcmp(strtolower(getParam(params, "action")), "restart") == 0)
7187 *keepalive = 0;
7188 if(!apicall)
7190 char *CSS = tpl_getUnparsedTpl("CSS", 1, "");
7191 tpl_addVar(vars, TPLADD, "STYLESHEET", CSS);
7192 NULLFREE(CSS);
7193 tpl_addVar(vars, TPLADD, "REFRESHTIME", "5");
7194 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
7195 tpl_addVar(vars, TPLADD, "SECONDS", "5");
7196 char *result = tpl_getTpl(vars, "SHUTDOWN");
7197 send_headers(f, 200, "OK", extraheader, "text/html", 0, cs_strlen(result), NULL, 0);
7198 webif_write(result, f);
7199 cs_log("Restart requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
7201 else
7203 tpl_addVar(vars, TPLADD, "APICONFIRMMESSAGE", "restart");
7204 cs_log("Restart requested by XMLApi from %s", cs_inet_ntoa(GET_IP()));
7206 cs_restart_oscam();
7208 if(!apicall)
7209 { return "1"; }
7210 else
7211 { return tpl_getTpl(vars, "APICONFIRMATION"); }
7214 else
7216 return tpl_getTpl(vars, "PRESHUTDOWN");
7220 static char *send_oscam_script(struct templatevars * vars, struct uriparams * params)
7222 setActiveMenu(vars, MNU_SCRIPT);
7223 tpl_printf(vars, TPLADD, "SCRIPTOPTIONS", "<option value=\"\">----select script----</option>\n");
7225 if(!cfg.http_readonly && cfg.http_script)
7227 struct dirent **namelist;
7228 int count, i;
7229 count = scandir(cfg.http_script, &namelist, 0, alphasort );
7230 if( count >= 0 )
7232 for( i = 0 ; i < count; i++ )
7234 if(is_ext(namelist[i]->d_name, ".script") || is_ext(namelist[i]->d_name, ".sh"))
7236 tpl_printf(vars, TPLAPPEND, "SCRIPTOPTIONS", "<option value=\"script.html?scriptname=%s\">%s</option>\n",namelist[i]->d_name,namelist[i]->d_name);
7238 free( namelist[i] );
7240 free(namelist);
7243 char *scriptname = getParam(params, "scriptname");
7244 char *scriptparam = getParam(params, "scriptparam");
7245 char system_str[256];
7246 struct stat s;
7247 snprintf(system_str, sizeof(system_str), "%s/%s", cfg.http_script, scriptname);
7249 if(!stat(system_str,&s))
7251 if(s.st_mode & S_IFREG)
7253 if(s.st_mode & S_IXUSR)
7255 int32_t rc;
7256 FILE *fp;
7257 char buf[256];
7259 if((scriptparam != NULL) && (sizeof(scriptparam) > 0))
7261 cs_strncat(system_str, " ", sizeof(system_str));
7262 cs_strncat(system_str, scriptparam, sizeof(system_str));
7265 fp = popen(system_str, "r");
7267 while (fgets(buf, sizeof(buf), fp) != NULL)
7269 tpl_addVar(vars, TPLAPPEND, "SCRIPTRESULTOUT", buf);
7272 rc = pclose(fp)/256;
7274 tpl_printf(vars, TPLAPPEND, "CODE", "returncode: %d", rc);
7275 tpl_printf(vars, TPLADD, "SCRIPTNAME", "scriptname: %s", scriptname);
7277 else
7279 tpl_printf(vars, TPLADD, "SCRIPTRESULTOUT", "[Error]: Script \"%s\" not executable!", scriptname);
7283 else
7285 tpl_printf(vars, TPLADD, "SCRIPTRESULTOUT", "[Error]: Script \"%s\" not found!", scriptname);
7289 return tpl_getTpl(vars, "SCRIPT");
7292 static char *send_oscam_scanusb(struct templatevars * vars)
7294 setActiveMenu(vars, MNU_READERS);
7295 #if !defined(__CYGWIN__)
7296 FILE *fp;
7297 char path[1035];
7299 fp = popen("lsusb -v | egrep '^Bus|^ *iSerial|^ *iProduct'", "r");
7300 if(!fgets(path, sizeof(path) - 1, fp) || !fp)
7302 tpl_addVar(vars, TPLADD, "USBENTRY", "<b>lsusb:</b> Failed to run or not installed!");
7303 tpl_addVar(vars, TPLADD, "USBBIT", tpl_getTpl(vars, "SCANUSBBIT"));
7305 else
7308 tpl_addVar(vars, TPLADD, "USBENTRYCLASS", "");
7309 if(strstr(path, "Bus "))
7311 tpl_addVar(vars, TPLADD, "USBENTRY", path);
7312 tpl_addVar(vars, TPLADD, "USBENTRYCLASS", "CLASS=\"scanusbsubhead\"");
7314 else
7316 tpl_printf(vars, TPLADD, "USBENTRY", "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%s", path);
7318 tpl_addVar(vars, TPLAPPEND, "USBBIT", tpl_getTpl(vars, "SCANUSBBIT"));
7320 while(fgets(path, sizeof(path) - 1, fp) != NULL);
7322 pclose(fp);
7323 #else
7324 tpl_addMsg(vars, "Function not supported in CYGWIN environment");
7325 #endif
7326 return tpl_getTpl(vars, "SCANUSB");
7329 static void webif_process_logfile(struct templatevars * vars, struct uriparams * params, char *targetfile, size_t targetfile_len)
7331 snprintf(targetfile, targetfile_len, "%s", cfg.logfile);
7332 if(strcmp(getParam(params, "clear"), "logfile") == 0)
7334 if(cs_strlen(targetfile) > 0)
7336 FILE *file = fopen(targetfile, "w");
7337 fclose(file);
7340 #ifdef WITH_DEBUG
7341 // Debuglevel Selector
7342 int32_t i, lvl;
7343 for(i = 0; i < MAX_DEBUG_LEVELS; i++)
7345 lvl = 1 << i;
7346 tpl_printf(vars, TPLADD, "TMPC", "DCLASS%d", lvl);
7347 tpl_printf(vars, TPLADD, "TMPV", "DEBUGVAL%d", lvl);
7348 if(cs_dblevel & lvl)
7350 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugls");
7351 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel - lvl);
7353 else
7355 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugl");
7356 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel + lvl);
7359 if(cs_dblevel == D_ALL_DUMP)
7360 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugls"); }
7361 else
7362 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugl"); }
7363 tpl_addVar(vars, TPLADD, "CUSTOMPARAM", "&file=logfile");
7364 tpl_printf(vars, TPLADD, "ACTDEBUG", "%d", cs_dblevel);
7365 #ifdef CS_CACHEEX_AIO
7366 tpl_addVar(vars, TPLADD, "SDEBUG", tpl_getTpl(vars, "DEBUGSELECTAIO"));
7367 #else
7368 tpl_addVar(vars, TPLADD, "SDEBUG", tpl_getTpl(vars, "DEBUGSELECT"));
7369 #endif
7370 tpl_addVar(vars, TPLADD, "NEXTPAGE", "files.html");
7371 #endif
7372 if(!cfg.disablelog)
7374 tpl_printf(vars, TPLADD, "SWITCH", "%d", 1);
7375 tpl_addVar(vars, TPLADD, "TEXT", "Stop Log");
7376 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUDISABLELOG"));
7379 else
7381 tpl_printf(vars, TPLADD, "SWITCH", "%d", 0);
7382 tpl_addVar(vars, TPLADD, "TEXT", "Start Log");
7383 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUDISABLELOG"));
7385 tpl_addVar(vars, TPLAPPEND, "LOGMENU", tpl_getTpl(vars, "CLEARLOG"));
7386 return;
7389 static void webif_process_userfile(struct templatevars * vars, struct uriparams * params, char *targetfile, size_t targetfile_len)
7391 snprintf(targetfile, targetfile_len, "%s", cfg.usrfile);
7392 if(strcmp(getParam(params, "clear"), "usrfile") == 0)
7394 if(cs_strlen(targetfile) > 0)
7396 FILE *file = fopen(targetfile, "w");
7397 fclose(file);
7400 if(!cfg.disableuserfile)
7402 tpl_printf(vars, TPLADD, "SWITCH", "%d", 1);
7403 tpl_addVar(vars, TPLADD, "TEXT", "Stop Log");
7404 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUONOFF"));
7406 else
7408 tpl_printf(vars, TPLADD, "SWITCH", "%d", 0);
7409 tpl_addVar(vars, TPLADD, "TEXT", "Start Log");
7410 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUONOFF"));
7412 tpl_addVar(vars, TPLAPPEND, "LOGMENU", tpl_getTpl(vars, "CLEARUSERLOG"));
7413 tpl_addVar(vars, TPLADD, "FFVAL", "all");
7414 tpl_addVar(vars, TPLADD, "FILTERFORMOPTIONS", tpl_getTpl(vars, "LOGMENUFILTERFORM"));
7415 struct s_auth *account;
7416 for(account = cfg.account; account; account = account->next)
7418 tpl_addVar(vars, TPLADD, "FFVAL", xml_encode(vars, account->usr));
7419 tpl_addVar(vars, TPLADD, "FFSEL", strcmp(getParam(params, "filter"), account->usr) ? "" : "selected");
7420 tpl_addVar(vars, TPLAPPEND, "FILTERFORMOPTIONS", tpl_getTpl(vars, "LOGMENUFILTERFORM"));
7422 tpl_addVar(vars, TPLADD, "FILTERFORM", tpl_getTpl(vars, "FILTERFORM"));
7425 enum file_types { FTYPE_CONFIG, FTYPE_VERSION, FTYPE_ANTICASC, FTYPE_LOGFILE, FTYPE_USERFILE , FTYPE_GBOX };
7427 struct files
7429 char *file;
7430 int menu_id;
7431 enum file_types type;
7434 static char *send_oscam_files(struct templatevars * vars, struct uriparams * params, int8_t apicall)
7436 bool writable = false;
7437 const struct files *entry;
7438 static struct files config_files[] =
7440 // id are used
7441 // new entry after last entry before first ifdef entry
7442 // ifdef must be add to end
7443 { "oscam.version", MNU_CFG_FVERSION, FTYPE_VERSION }, // id 0
7444 { "oscam.conf", MNU_CFG_FCONF, FTYPE_CONFIG }, // id 1
7445 { "oscam.user", MNU_CFG_FUSER, FTYPE_CONFIG }, // id 2
7446 { "oscam.server", MNU_CFG_FSERVER, FTYPE_CONFIG }, // id 3
7447 { "oscam.srvid", MNU_CFG_FSRVID, FTYPE_CONFIG }, // id 4
7448 { "oscam.srvid2", MNU_CFG_FSRVID2, FTYPE_CONFIG }, // id 5
7449 { "logfile", MNU_CFG_FLOGFILE, FTYPE_LOGFILE }, // id 6
7450 { "userfile", MNU_CFG_FUSERFILE, FTYPE_USERFILE }, // id 7
7451 { "css_file_name", MNU_CFG_FCSS, FTYPE_CONFIG }, // id 8
7452 { "oscam.services", MNU_CFG_FSERVICES, FTYPE_CONFIG }, // id 9
7453 { "oscam.provid", MNU_CFG_FPROVID, FTYPE_CONFIG }, // id 10
7454 { "oscam.tiers", MNU_CFG_FTIERS, FTYPE_CONFIG }, // id 11
7455 { "oscam.ratelimit", MNU_CFG_FRATELIMIT,FTYPE_CONFIG }, // id 12
7456 { "oscam.whitelist", MNU_CFG_FWHITELIST,FTYPE_CONFIG }, // id 13
7457 #ifdef HAVE_DVBAPI
7458 { "oscam.dvbapi", MNU_CFG_FDVBAPI, FTYPE_CONFIG }, // id 14
7459 #endif
7460 #ifdef CS_CACHEEX
7461 { "oscam.fakecws", MNU_CFG_FFAKECWS, FTYPE_CONFIG }, // id 15
7462 #endif
7463 #ifdef CS_ANTICASC
7464 { "anticasc", MNU_CFG_FACLOG, FTYPE_ANTICASC }, // id 16
7465 #endif
7466 #ifdef MODULE_SERIAL
7467 { "oscam.twin", MNU_CFG_FTWIN, FTYPE_CONFIG }, // id 17
7468 #endif
7469 #ifdef MODULE_CONSTCW
7470 { "constant.cw", MNU_CFG_FKEYCW, FTYPE_CONFIG }, // id 18
7471 #endif
7472 #ifdef MODULE_GBOX
7473 { "sc.info", MNU_GBX_FSCINF, FTYPE_GBOX }, // id 19
7474 { "share.info", MNU_GBX_FSHRINF, FTYPE_GBOX }, // id 20
7475 { "share.onl", MNU_GBX_FSHRONL, FTYPE_GBOX }, // id 21
7476 { "gbox.ver", MNU_GBX_FVERS, FTYPE_GBOX }, // id 22
7477 { "attack.txt", MNU_GBX_FATTACK, FTYPE_GBOX }, // id 23
7478 { "gsms.log", MNU_GBX_FSMSLOG, FTYPE_GBOX }, // id 24
7479 { "gsms.ack", MNU_GBX_FSMSACK, FTYPE_GBOX }, // id 25
7480 { "gsms.nack", MNU_GBX_FSMSNACK, FTYPE_GBOX }, // id 26
7481 { "stats.info", MNU_GBX_FSTAINF, FTYPE_GBOX }, // id 27
7482 { "expired.info", MNU_GBX_FEXPINF, FTYPE_GBOX }, // id 28
7483 { "info.log", MNU_GBX_INFOLOG, FTYPE_GBOX }, // id 29
7484 #endif
7485 #ifdef WITH_EMU
7486 { "SoftCam.Key", MNU_CFG_FSOFTCAMKEY,FTYPE_CONFIG }, // id 30
7487 #endif
7488 { NULL, 0, 0 },
7491 if(use_srvid2)
7493 config_files[4].menu_id = MNU_CFG_FSRVID2;
7494 config_files[5].menu_id = MNU_CFG_FSRVID;
7497 if(cfg.http_css)
7499 if(strchr(cfg.http_css,'/'))
7500 config_files[8].file = strrchr(cfg.http_css, '/')+1;
7501 else if(strchr(cfg.http_css,'\\'))
7502 config_files[8].file = strrchr(cfg.http_css, '\\')+1;
7503 else
7504 config_files[8].file = cfg.http_css;
7505 tpl_addVar(vars, TPLADD, "FILE_USER_CSS", xml_encode(vars, config_files[8].file));
7508 if(!apicall) { setActiveMenu(vars, MNU_FILES); }
7510 tpl_addVar(vars, TPLADD, "APIFILENAME", "null");
7511 tpl_addVar(vars, TPLADD, "APIWRITABLE", "0");
7513 if(use_srvid2)
7515 tpl_printf(vars, TPLADD, "SRVID", "%s", "oscam.srvid2");
7516 tpl_printf(vars, TPLADD, "SRVIDSUB", "%s", "oscam.srvid");
7518 else
7520 tpl_printf(vars, TPLADD, "SRVID", "%s", "oscam.srvid");
7521 tpl_printf(vars, TPLADD, "SRVIDSUB", "%s", "oscam.srvid2");
7524 char *stoplog = getParam(params, "stoplog");
7525 if(cs_strlen(stoplog) > 0)
7526 { cs_disable_log(atoi(stoplog)); }
7528 char *stopusrlog = getParam(params, "stopusrlog");
7529 if(cs_strlen(stopusrlog) > 0)
7530 { cfg.disableuserfile = atoi(stopusrlog); }
7532 char *debuglvl = getParam(params, "debug");
7533 if(cs_strlen(debuglvl) > 0)
7535 #ifndef WITH_DEBUG
7536 cs_log("*** Warning: Debug Support not compiled in ***");
7537 #else
7538 int32_t dblvl = atoi(debuglvl);
7539 if(dblvl >= 0 && dblvl <= 65535) { cs_dblevel = dblvl; }
7540 cs_log("%s debug_level=%d", "all", cs_dblevel);
7541 #endif
7543 // Process config files
7544 char *file = getParam(params, "file");
7545 char targetfile[256] = { 0 };
7546 int menu_id = 0;
7547 for(entry = config_files; entry->file; entry++)
7549 if(streq(file, entry->file))
7551 if(!apicall) { setActiveSubMenu(vars, entry->menu_id); }
7552 menu_id = entry->menu_id;
7553 tpl_addVar(vars, TPLADD, "APIWRITABLE", writable ? "1" : "0");
7554 switch(entry->type)
7556 case FTYPE_CONFIG:
7557 writable = 1;
7558 get_config_filename(targetfile, sizeof(targetfile), entry->file);
7559 break;
7560 case FTYPE_VERSION:
7561 get_tmp_dir_filename(targetfile, sizeof(targetfile), entry->file);
7562 break;
7563 case FTYPE_ANTICASC:
7564 #ifdef CS_ANTICASC
7565 if(!apicall) { snprintf(targetfile, sizeof(targetfile), "%s", ESTR(cfg.ac_logfile)); }
7566 #endif
7567 break;
7568 case FTYPE_LOGFILE:
7569 if(!apicall) { webif_process_logfile(vars, params, targetfile, sizeof(targetfile)); }
7570 break;
7571 case FTYPE_USERFILE:
7572 if(!apicall) { webif_process_userfile(vars, params, targetfile, sizeof(targetfile)); }
7573 break;
7574 case FTYPE_GBOX:
7575 #ifdef MODULE_GBOX
7576 get_gbox_filename(targetfile, sizeof(targetfile), entry->file);
7577 #endif
7578 break;
7580 tpl_addVar(vars, TPLADD, "APIFILENAME", entry->file);
7581 break;
7585 if(cfg.http_css)
7587 tpl_addVar(vars, TPLADD, "VIEW_FILEMENUCSS", tpl_getTpl(vars, "FILEMENUCSS"));
7590 if(!strstr(targetfile, "/dev/"))
7592 if(strcmp(getParam(params, "action"), "Save") == 0)
7594 if((cs_strlen(targetfile) > 0) /*&& (file_exists(targetfile) == 1)*/)
7596 FILE *fpsave;
7597 char *fcontent = getParam(params, "filecontent");
7598 if((fpsave = fopen(targetfile, "w")))
7600 int32_t i, lastpos = 0, len = cs_strlen(fcontent) + 1;
7601 //write submitted file line by line to disk and remove windows linebreaks
7602 for(i = 0; i < len; ++i)
7604 char tmp = fcontent[i];
7605 if(tmp == '\r' || tmp == '\n' || tmp == 0)
7607 fcontent[i] = 0;
7608 fprintf(fpsave, "%s%s", fcontent + lastpos, tmp == 0 ? "" : "\n");
7609 if(tmp == '\r' && fcontent[i + 1] == '\n') { ++i; }
7610 lastpos = i + 1;
7613 fclose(fpsave);
7614 tpl_addVar(vars, TPLAPPEND, "APIFILENAME", " saved!");
7615 // Reinit on save
7616 switch(menu_id)
7618 case MNU_CFG_FSRVID:
7619 case MNU_CFG_FSRVID2:
7620 init_srvid();
7621 break;
7622 case MNU_CFG_FPROVID:
7623 init_provid();
7624 break;
7625 case MNU_CFG_FUSER:
7626 cs_accounts_chk();
7627 break;
7628 case MNU_CFG_FDVBAPI:
7629 dvbapi_read_priority();
7630 break;
7631 case MNU_CFG_FWHITELIST:
7632 global_whitelist_read();
7633 break;
7634 case MNU_CFG_FFAKECWS:
7635 init_fakecws();
7636 break;
7637 default:
7638 break;
7644 if((cs_strlen(targetfile) > 0) && (file_exists(targetfile) == 1))
7646 FILE *fp;
7647 char buffer[256];
7649 if((fp = fopen(targetfile, "r")) == NULL) { return "0"; }
7650 while(fgets(buffer, sizeof(buffer), fp) != NULL)
7651 if(!strcmp(getParam(params, "filter"), "all"))
7652 { tpl_addVar(vars, TPLAPPEND, "FILECONTENT", buffer); }
7653 else if(strstr(buffer, getParam(params, "filter")))
7654 { tpl_addVar(vars, TPLAPPEND, "FILECONTENT", buffer); }
7655 fclose(fp);
7657 else
7659 tpl_addVar(vars, TPLAPPEND, "FILECONTENT", "File does not exist or no file selected!");
7662 else
7664 tpl_addVar(vars, TPLAPPEND, "FILECONTENT", "File not valid!");
7667 tpl_addVar(vars, TPLADD, "PART", file);
7669 if(!writable)
7671 tpl_addVar(vars, TPLADD, "WRITEPROTECTION", tpl_getTpl(vars, "WRITEPROTECTION"));
7672 tpl_addVar(vars, TPLADD, "BTNDISABLED", "DISABLED");
7675 if(!apicall)
7676 { return tpl_getTpl(vars, "FILE"); }
7677 else
7678 { return tpl_getTpl(vars, "APIFILE"); }
7681 static char *send_oscam_failban(struct templatevars * vars, struct uriparams * params, int8_t apicall)
7683 IN_ADDR_T ip2delete;
7684 set_null_ip(&ip2delete);
7685 LL_ITER itr = ll_iter_create(cfg.v_list);
7686 V_BAN *v_ban_entry;
7687 //int8_t apicall = 0; //remove before flight
7689 if(!apicall) { setActiveMenu(vars, MNU_FAILBAN); }
7691 if(strcmp(getParam(params, "action"), "delete") == 0)
7693 if(strcmp(getParam(params, "intip"), "all") == 0)
7695 // clear whole list
7696 while(ll_iter_next(&itr))
7698 ll_iter_remove_data(&itr);
7701 else
7703 //we have a single IP
7704 cs_inet_addr(getParam(params, "intip"), &ip2delete);
7705 while((v_ban_entry = ll_iter_next(&itr)))
7707 if(IP_EQUAL(v_ban_entry->v_ip, ip2delete))
7709 ll_iter_remove_data(&itr);
7710 break;
7715 ll_iter_reset(&itr);
7717 struct timeb now;
7718 cs_ftime(&now);
7720 while((v_ban_entry = ll_iter_next(&itr)))
7722 tpl_printf(vars, TPLADD, "IPADDRESS", "%s@%d", cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port);
7723 tpl_addVar(vars, TPLADD, "VIOLATIONUSER", v_ban_entry->info ? v_ban_entry->info : "unknown");
7724 struct tm st ;
7725 localtime_r(&v_ban_entry->v_time.time, &st); // fix me, we need walltime!
7726 if(!apicall)
7728 tpl_printf(vars, TPLADD, "VIOLATIONDATE", "%02d.%02d.%02d %02d:%02d:%02d",
7729 st.tm_mday, st.tm_mon + 1,
7730 st.tm_year % 100, st.tm_hour,
7731 st.tm_min, st.tm_sec);
7733 else
7735 char tbuffer [30];
7736 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &st);
7737 tpl_addVar(vars, TPLADD, "VIOLATIONDATE", tbuffer);
7740 tpl_printf(vars, TPLADD, "VIOLATIONCOUNT", "%d", v_ban_entry->v_count);
7742 int64_t gone = comp_timeb(&now, &v_ban_entry->v_time);
7743 if(!apicall)
7745 if(!v_ban_entry->acosc_entry)
7746 { tpl_addVar(vars, TPLADD, "LEFTTIME", sec2timeformat(vars, (cfg.failbantime * 60) - (gone / 1000))); }
7747 else
7748 { tpl_addVar(vars, TPLADD, "LEFTTIME", sec2timeformat(vars, v_ban_entry->acosc_penalty_dur - (gone / 1000))); }
7750 else
7752 if(!v_ban_entry->acosc_entry)
7753 { tpl_printf(vars, TPLADD, "LEFTTIME", "%"PRId64"", (cfg.failbantime * 60) - (gone / 1000)); }
7754 else
7755 { tpl_printf(vars, TPLADD, "LEFTTIME", "%"PRId64"", v_ban_entry->acosc_penalty_dur - (gone / 1000)); }
7758 tpl_addVar(vars, TPLADD, "INTIP", cs_inet_ntoa(v_ban_entry->v_ip));
7760 if(!apicall)
7761 { tpl_addVar(vars, TPLAPPEND, "FAILBANROW", tpl_getTpl(vars, "FAILBANBIT")); }
7762 else
7763 { tpl_addVar(vars, TPLAPPEND, "APIFAILBANROW", tpl_getTpl(vars, "APIFAILBANBIT")); }
7765 if(!apicall)
7766 { return tpl_getTpl(vars, "FAILBAN"); }
7767 else
7768 { return tpl_getTpl(vars, "APIFAILBAN"); }
7771 static bool send_EMM(struct s_reader * rdr, uint16_t caid, const struct s_cardsystem *csystem, const uint8_t *emmhex, uint32_t len)
7773 if(NULL != rdr && NULL != emmhex && 0 != len)
7775 EMM_PACKET *emm_pack = NULL;
7777 if(cs_malloc(&emm_pack, sizeof(EMM_PACKET)))
7779 struct s_client *webif_client = cur_client();
7780 webif_client->grp = 0xFF; /* to access to all readers */
7782 memset(emm_pack, '\0', sizeof(EMM_PACKET));
7783 emm_pack->client = webif_client;
7784 emm_pack->emmlen = len;
7785 memcpy(emm_pack->emm, emmhex, len);
7787 emm_pack->caid[0] = (caid >> 8) & 0xFF;
7788 emm_pack->caid[1] = caid & 0xFF;
7790 if(csystem && csystem->get_emm_type)
7792 if(!csystem->get_emm_type(emm_pack, rdr))
7794 rdr_log_dbg(rdr, D_EMM, "get_emm_type() returns error");
7798 cs_log_dbg(D_EMM, "emm is being sent to reader %s.", rdr->label);
7799 add_job(rdr->client, ACTION_READER_EMM, emm_pack, sizeof(EMM_PACKET));
7800 return true;
7804 return false;
7807 static bool process_single_emm(struct templatevars * vars, struct s_reader * rdr, uint16_t caid, const struct s_cardsystem *csystem, const char *ep)
7810 if(NULL != vars && NULL != rdr && NULL != ep)
7812 char emmdata[1025] = {'\0'}; /*1024 + '\0'*/
7813 uint8_t emmhex[513] = {'\0'};
7814 char buff[7] = {'\0'};
7815 uint16_t len = 0;
7816 cs_strncpy(emmdata, ep, sizeof(emmdata));
7817 remove_white_chars(emmdata);
7819 if('\0' != emmdata[0])
7821 len = cs_strlen(emmdata);
7822 tpl_addVar(vars, TPLADD, "EP", strtoupper(emmdata));
7823 if(key_atob_l(emmdata, emmhex, len))
7825 tpl_addMsg(vars, "Single EMM has not been sent due to wrong value!");
7827 else
7829 len /= 2;
7830 snprintf(buff, sizeof(buff), "0x%02X", len);
7831 tpl_addVar(vars, TPLADD, "EP", strtoupper(emmdata));
7832 tpl_addVar(vars, TPLADD, "SIZE", buff);
7834 if(send_EMM(rdr, caid, csystem, emmhex, len))
7836 tpl_addMsg(vars, "Single EMM has been sent.");
7837 return true;
7842 tpl_addVar(vars, TPLADD, "SIZE", "0x00");
7843 return false;
7846 static bool process_emm_file(struct templatevars * vars, struct s_reader * rdr, uint16_t caid, const struct s_cardsystem *csystem, const char *sFilePath)
7849 bool bret = false;
7850 uint32_t fsize = 0;
7851 uint32_t rlines = 0;
7852 uint32_t wemms = 0;
7853 uint32_t errsize = 0;
7854 char numerrl[256] = {'\0'};
7855 char buff[20] = {'\0'};
7857 if(NULL != rdr && NULL != sFilePath && '\0' != sFilePath[0])
7859 char sMessage[128] = {0};
7860 if(true == file_exists(sFilePath))
7862 FILE *fp;
7863 if((fp = fopen(sFilePath, "r")))
7865 char line[2048] = {'\0'};
7866 uint8_t emmhex[513] = {'\0'};
7867 uint32_t len = 0;
7869 tpl_addMsg(vars, "EMM file has been processed.");
7870 while(fgets(line, sizeof(line), fp))
7872 ++rlines;
7873 len = cs_strlen(remove_white_chars(line));
7875 // wrong emm
7876 if(len > (sizeof(emmhex) * 2) ||
7877 key_atob_l(line, emmhex, len))
7879 errsize += snprintf(numerrl + errsize, sizeof(numerrl) - errsize, "%d, ", rlines);
7880 continue;
7882 len /= 2;
7883 if(send_EMM(rdr, caid, csystem, emmhex, len))
7885 ++wemms;
7886 int32_t jcount = ll_count(rdr->client->joblist);
7887 if (jcount > 200)
7889 /* Give more time to process EMMs */
7890 cs_sleepms(1000);
7892 rdr_log_dbg(rdr, D_READER, "pending emm jobs: %i, processed emms: %i", jcount, wemms);
7895 fsize = ftell(fp);
7896 fclose(fp);
7898 else
7900 snprintf(sMessage, sizeof(sMessage), "Cannot open file '%s' (errno=%d: %s)\n", sFilePath, errno, strerror(errno));
7901 tpl_addMsg(vars, sMessage);
7904 else
7906 snprintf(sMessage, sizeof(sMessage), "FILE \"%s\" not found!", sFilePath);
7907 tpl_addMsg(vars, sMessage);
7909 bret = true;
7912 snprintf(buff, sizeof(buff), "%d bytes", fsize);
7913 tpl_addVar(vars, TPLADD, "FSIZE", buff);
7914 snprintf(buff, sizeof(buff), "%d", rlines);
7915 tpl_addVar(vars, TPLADD, "NUMRLINE", buff);
7916 snprintf(buff, sizeof(buff), "%d", wemms);
7917 tpl_addVar(vars, TPLADD, "NUMWEMM", buff);
7918 tpl_addVar(vars, TPLADD, "ERRLINE", numerrl);
7920 return bret;
7923 static char *send_oscam_EMM_running(struct templatevars * vars, struct uriparams * params)
7926 struct s_reader *rdr = NULL;
7928 setActiveMenu(vars, MNU_READERS);
7929 tpl_addVar(vars, TPLADD, "READER", getParam(params, "label"));
7930 tpl_addVar(vars, TPLADD, "FNAME", getParam(params, "emmfile"));
7932 rdr = get_reader_by_label(getParam(params, "label"));
7933 if(rdr)
7935 int32_t tcaid = dyn_word_atob(getParam(params, "emmcaid"));
7936 uint16_t caid = (-1 != tcaid) ? (uint16_t)tcaid : 0;
7937 char buff[7] = "";
7938 const struct s_cardsystem *csystem = NULL;
7939 int32_t proxy = is_cascading_reader(rdr);
7941 if((proxy || !rdr->csystem_active) && caid) // network reader (R_CAMD35 R_NEWCAMD R_CS378X R_CCCAM)
7943 if(proxy && !rdr->ph.c_send_emm)
7945 tpl_addMsg(vars, "The reader does not support EMM's!");
7946 return tpl_getTpl(vars, "EMM_RUNNING");
7949 csystem = get_cardsystem_by_caid(caid);
7950 if(!csystem)
7952 rdr_log_dbg(rdr, D_EMM, "unable to find cardsystem for caid %04X", caid);
7953 caid = 0;
7956 else if(!proxy && rdr->csystem_active) // local active reader
7958 csystem = rdr->csystem;
7960 if(rdr->typ != R_EMU)
7962 caid = rdr->caid;
7966 if(csystem)
7968 tpl_addVar(vars, TPLADD, "SYSTEM", csystem->desc);
7970 else
7972 tpl_addVar(vars, TPLADD, "SYSTEM", "unknown");
7974 if(caid)
7976 snprintf(buff, sizeof(buff), "0x%04X", caid);
7977 tpl_addVar(vars, TPLADD, "CAID", buff);
7979 else
7981 tpl_addVar(vars, TPLADD, "CAID", "unknown");
7984 process_single_emm(vars, rdr, caid, csystem, getParam(params, "ep"));
7985 process_emm_file(vars, rdr, caid, csystem, getParam(params, "emmfile"));
7987 else
7989 char sMessage[128] = {0};
7990 snprintf(sMessage, sizeof(sMessage), "READER \"%s\" not found!", getParam(params, "label"));
7991 tpl_addMsg(vars, sMessage);
7992 tpl_addVar(vars, TPLADD, "READER", "reader not found");
7995 return tpl_getTpl(vars, "EMM_RUNNING");
7998 static char *send_oscam_EMM(struct templatevars * vars, struct uriparams * params)
8001 setActiveMenu(vars, MNU_READERS);
8002 tpl_addVar(vars, TPLADD, "READER", getParam(params, "label"));
8004 struct s_reader *rdr = NULL;
8005 rdr = get_reader_by_label(getParam(params, "label"));
8006 if(rdr && rdr->caid)
8008 char buff[5] = "";
8009 snprintf(buff, sizeof(buff), "%04X", rdr->caid);
8010 tpl_addVar(vars, TPLADD, "CAID", buff);
8011 if(!is_cascading_reader(rdr))
8013 tpl_addVar(vars, TPLADD, "READONLY", "readonly=\"readonly\"");
8017 FILE *fp;
8018 struct stat sb;
8019 char buffer[1024];
8020 char emm_hex[1024];
8021 char filename[128];
8022 char targetfile[256];
8023 char tmpstr[20];
8024 char emm_txt[32];
8025 char emm_title[32];
8026 char *emm_path;
8027 char *emm_types[] = { "unique_emm", "shared_emm", "global_emm" };
8028 char *emm_names[] = { "RDREMMUNIQUE", "RDREMMSHARED", "RDREMMGLOBAL" };
8029 char *emm_cfg_names[] = { "httpemmuclean", "httpemmsclean", "httpemmgclean" };
8030 int32_t emm_max_size[] = { cfg.http_emmu_clean, cfg.http_emms_clean, cfg.http_emmg_clean };
8031 int num_emm_types = 3;
8032 int i;
8034 emm_path = cfg.emmlogdir ? cfg.emmlogdir : cs_confdir;
8036 for( i = 0 ; i < num_emm_types; i++ )
8038 snprintf(filename, sizeof(filename), "%s%s%s%s", getParam(params, "label"), "_", emm_types[i], ".log");
8039 snprintf(targetfile, sizeof(targetfile), "%s%s%s", emm_path, emm_path[cs_strlen(emm_path) - 1] == '/' ? "" : "/", filename);
8040 snprintf(emm_txt, sizeof(emm_txt), "%s_TXT", emm_names[i]);
8041 tpl_addVar(vars, TPLADD, emm_txt, filename);
8043 if((fp = fopen(targetfile, "r")) != NULL)
8045 stat(targetfile, &sb);
8046 tpl_printf(vars, TPLAPPEND, emm_txt, " (Size: %'.2f kB)", (double)sb.st_size/1024);
8048 if(emm_max_size[i]>=0)
8050 snprintf(emm_title, sizeof(emm_title), "%s_TITLE", emm_names[i]);
8051 tpl_addVar(vars, TPLADD, emm_title, "title=\"Click Line to Copy EMM in Single EMM Write Field\"");
8054 if(emm_max_size[i]>0)
8056 uint32_t emms=0, emm_d, emmrs=0;
8057 char *ptr, *saveptr1 = NULL;
8059 while(fgets(buffer, sizeof(buffer), fp) != NULL)
8061 emms++;
8062 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emms);
8063 tpl_addVar(vars, TPLADD, tmpstr, buffer);
8066 for(emm_d=emms;emm_d>0;--emm_d)
8068 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emm_d);
8069 if(sscanf(tpl_getVar(vars, tmpstr), "%*s %*s %*s %s", &emm_hex[0])==1)
8071 if(strstr(tpl_getVar(vars, "EMM_TMP"),emm_hex)==0)
8072 { tpl_addVar(vars, TPLAPPEND, "EMM_TMP", tpl_getVar(vars, tmpstr)); }
8073 tpl_addVar(vars, TPLADD, tmpstr, "");
8077 for(ptr = strtok_r(tpl_getVar(vars, "EMM_TMP"),"\n", &saveptr1); ptr; ptr = strtok_r(NULL,"\n", &saveptr1))
8079 emmrs++;
8080 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emmrs);
8081 tpl_addVar(vars, TPLADD, tmpstr, ptr);
8083 tpl_addVar(vars, TPLADD, "EMM_TMP", "");
8085 tpl_printf(vars, TPLAPPEND, emm_txt, ": %'d different EMM's from a total off %'d Entrys", emmrs,emms);
8086 for(emm_d=emmrs;emm_d>0;--emm_d)
8088 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emm_d);
8089 tpl_printf(vars, TPLAPPEND, emm_names[i], "<a class=\"tosingleemm\" href=\"#\">%s</a>\n", tpl_getVar(vars, tmpstr));
8090 if(sb.st_size>emm_max_size[i]*1024) { tpl_printf(vars, TPLAPPEND, "EMM_TMP", "%s\n", tpl_getVar(vars, tmpstr)); }
8091 tpl_addVar(vars, TPLADD, tmpstr, "");
8094 if(sb.st_size>emm_max_size[i]*1024)
8096 char orgfile[268];
8097 int f=0;
8098 do {
8099 snprintf(orgfile, sizeof(orgfile), "%s.%d", targetfile, f);
8100 f++;
8101 } while(access(orgfile, 0|F_OK) != -1);
8103 if(rename(targetfile, orgfile) == 0)
8105 FILE *fs = fopen(targetfile, "w");
8106 fprintf(fs, "%s", tpl_getVar(vars, "EMM_TMP"));
8107 fclose(fs);
8108 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);
8111 tpl_addVar(vars, TPLADD, "EMM_TMP", "");
8113 else if (emm_max_size[i]==0)
8115 while(fgets(buffer, sizeof(buffer), fp) != NULL)
8117 tpl_printf(vars, TPLAPPEND, emm_names[i], "<a class=\"tosingleemm\" href=\"#\">%s</a>", buffer);
8120 else
8122 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]);
8124 fclose(fp);
8126 if(strcmp(tpl_getVar(vars, emm_names[i]),"")==0) { tpl_addVar(vars, TPLADD, emm_names[i],"no saved EMM's"); }
8129 return tpl_getTpl(vars, "ASKEMM");
8132 #ifdef CS_CACHEEX
8133 static uint64_t get_cacheex_node(struct s_client * cl)
8135 uint64_t node = 0x00;
8136 #if defined(MODULE_CCCAM) || defined(MODULE_CAMD35) || defined(MODULE_CAMD35_TCP)
8137 struct s_module *module = (cl->reader ? &cl->reader->ph : get_module(cl));
8138 #endif
8139 #ifdef MODULE_CCCAM
8140 if(module->num == R_CCCAM && cl->cc)
8142 struct cc_data *cc = cl->cc;
8143 memcpy(&node, cc->peer_node_id, 8);
8145 else
8146 #endif
8147 #ifdef MODULE_CAMD35
8148 if(module->num == R_CAMD35)
8150 memcpy(&node, cl->ncd_skey, 8);
8152 else
8153 #endif
8154 #ifdef MODULE_CAMD35_TCP
8155 if(module->num == R_CS378X)
8157 memcpy(&node, cl->ncd_skey, 8);
8159 else
8160 #endif
8162 return node;
8166 static char *send_oscam_cacheex(struct templatevars * vars, struct uriparams * params, int8_t apicall)
8169 if(!apicall) { setActiveMenu(vars, MNU_CACHEEX); }
8171 if(strcmp(getParam(params, "x"), "x") == 0)
8173 // avoid compilerwarning unused vars
8175 char *level[] = {"NONE", "CACHE PULL", "CACHE PUSH", "REVERSE CACHE PUSH"};
8176 char *getting = "<IMG SRC=\"image?i=ICARRL\" ALT=\"Getting\">";
8177 char *pushing = "<IMG SRC=\"image?i=ICARRR\" ALT=\"Pushing\">";
8178 char *rowvariable = "";
8180 int16_t i, written = 0;
8181 struct s_client *cl;
8182 time_t now = time((time_t *)0);
8183 int delimiter=0;
8185 if(!apicall)
8187 if(strcmp(getParam(params, "action"), "resetallcacheexstats") == 0)
8189 cacheex_clear_all_stats();
8193 tpl_printf(vars, TPLADD, "OWN_CACHEEX_NODEID", "%" PRIu64 "X", cacheex_node_id(cacheex_peer_id));
8195 const char *cacheex_name_link_tpl = NULL;
8196 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
8198 for(i = 0, cl = first_client; cl ; cl = cl->next, i++)
8200 #ifdef CS_CACHEEX_AIO
8201 char classname[9];
8202 snprintf(classname, 8, "class%02d", i) < 0 ? abort() : (void)0;
8203 classname[8] = '\0';
8204 tpl_addVar(vars, TPLADD, "CLASSNAME", classname);
8205 #endif
8207 if(cl->typ == 'c' && cl->account && cl->account->cacheex.mode)
8209 cacheex_name_link_tpl = "SUSER";
8210 tpl_addVar(vars, TPLADD, "TYPE", "Client");
8211 if(!apicall)
8213 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, cl->account->usr));
8214 tpl_addVar(vars, TPLADD, "USERENC", urlencode(vars, cl->account->usr));
8216 if(cl->account->description)
8218 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->account->description));
8220 else
8222 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
8225 else
8227 tpl_addVar(vars, TPLADD, "NAME", cl->account->usr);
8229 if(cl->account->description)
8231 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", cl->account->description);
8233 else
8235 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
8239 tpl_addVar(vars, TPLADD, "IP", cs_inet_ntoa(cl->ip));
8240 tpl_printf(vars, TPLADD, "NODE", "%" PRIu64 "X", get_cacheex_node(cl));
8241 tpl_addVar(vars, TPLADD, "LEVEL", level[cl->account->cacheex.mode]);
8242 tpl_printf(vars, TPLADD, "PUSH", "%d", cl->account->cwcacheexpush);
8243 tpl_printf(vars, TPLADD, "GOT", "%d", cl->account->cwcacheexgot);
8244 tpl_printf(vars, TPLADD, "CWCINFO", "%d", cl->account->cwc_info);
8245 tpl_printf(vars, TPLADD, "HIT", "%d", cl->account->cwcacheexhit);
8246 tpl_printf(vars, TPLADD, "ERR", "%d", cl->account->cwcacheexerr);
8247 tpl_printf(vars, TPLADD, "ERRCW", "%d", cl->account->cwcacheexerrcw);
8248 #ifdef CS_CACHEEX_AIO
8249 tpl_printf(vars, TPLADD, "GOTLG", "%d", cl->account->cwcacheexgotlg);
8250 tpl_printf(vars, TPLADD, "PUSHLG", "%d", cl->account->cwcacheexpushlg);
8251 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));
8252 #endif
8253 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", (cl->account->cacheex.mode == 3) ? getting : pushing);
8254 rowvariable = "TABLECLIENTROWS";
8255 written = 1;
8257 else if((cl->typ == 'p' || cl->typ == 'r') && (cl->reader && cl->reader->cacheex.mode))
8259 cacheex_name_link_tpl = "SREADER";
8260 tpl_addVar(vars, TPLADD, "TYPE", "Reader");
8262 if(!apicall)
8264 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, cl->reader->label));
8265 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, cl->reader->label));
8267 if(cl->reader->description)
8269 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->reader->description));
8271 else
8273 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
8276 else
8278 tpl_addVar(vars, TPLADD, "NAME", cl->reader->label);
8280 if(cl->reader->description)
8282 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", cl->reader->description);
8284 else
8286 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
8290 tpl_addVar(vars, TPLADD, "IP", cs_inet_ntoa(cl->ip));
8291 tpl_printf(vars, TPLADD, "NODE", "%" PRIu64 "X", get_cacheex_node(cl));
8292 tpl_addVar(vars, TPLADD, "LEVEL", level[cl->reader->cacheex.mode]);
8293 tpl_printf(vars, TPLADD, "PUSH", "%d", cl->cwcacheexpush);
8294 tpl_printf(vars, TPLADD, "CWCINFO", "%d", cl->cwc_info);
8295 tpl_printf(vars, TPLADD, "GOT", "%d", cl->cwcacheexgot);
8296 tpl_printf(vars, TPLADD, "CWCINFO", "%d", cl->cwc_info);
8297 tpl_printf(vars, TPLADD, "HIT", "%d", cl->cwcacheexhit);
8298 tpl_printf(vars, TPLADD, "ERR", "%d", cl->cwcacheexerr);
8299 tpl_printf(vars, TPLADD, "ERRCW", "%d", cl->cwcacheexerrcw);
8300 #ifdef CS_CACHEEX_AIO
8301 tpl_printf(vars, TPLADD, "GOTLG", "%d", cl->cwcacheexgotlg);
8302 tpl_printf(vars, TPLADD, "PUSHLG", "%d", cl->cwcacheexpushlg);
8303 tpl_printf(vars, TPLADD, "REL_CACHEXHITGOT", "%.2f", (double)(cl->cwcacheexhit ? (double)cl->cwcacheexhit : 0) * 100 / (double)(cl->cwcacheexgot ? cl->cwcacheexgot : 1));
8304 #endif
8305 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", (cl->reader->cacheex.mode == 3) ? pushing : getting);
8307 rowvariable = "TABLEREADERROWS";
8308 written = 1;
8310 else if(get_module(cl)->listenertype == LIS_CSPUDP)
8312 cacheex_name_link_tpl = "SREADER";
8313 tpl_addVar(vars, TPLADD, "TYPE", "csp");
8315 if(!apicall)
8317 tpl_addVar(vars, TPLADD, "READERNAME", "csp");
8318 tpl_addVar(vars, TPLADD, "READERNAMEENC", "csp");
8320 else
8322 tpl_addVar(vars, TPLADD, "NAME", "csp");
8325 tpl_addVar(vars, TPLADD, "IP", cs_inet_ntoa(cl->ip));
8326 tpl_addVar(vars, TPLADD, "NODE", "csp");
8328 if(cl->cwcacheexping)
8330 tpl_printf(vars, TPLADD, "LEVEL", "csp (%d ms)", cl->cwcacheexping);
8332 else
8334 tpl_addVar(vars, TPLADD, "LEVEL", "csp");
8337 tpl_printf(vars, TPLADD, "PUSH", "%d", cl->cwcacheexpush);
8338 tpl_printf(vars, TPLADD, "GOT", "%d", cl->cwcacheexgot);
8339 tpl_printf(vars, TPLADD, "HIT", "%d", cl->cwcacheexhit);
8340 tpl_printf(vars, TPLADD, "ERR", "%d", cl->cwcacheexerr);
8341 tpl_printf(vars, TPLADD, "ERRCW", "%d", cl->cwcacheexerrcw);
8342 #ifdef CS_CACHEEX_AIO
8343 tpl_printf(vars, TPLADD, "GOTLG", "%d", cl->cwcacheexgotlg);
8344 tpl_printf(vars, TPLADD, "PUSHLG", "%d", cl->cwcacheexpushlg);
8345 tpl_printf(vars, TPLADD, "REL_CACHEXHITGOT", "%.2f", (double)(cl->cwcacheexhit ? (double)cl->cwcacheexhit : 0) * 100 / (double)(cl->cwcacheexgot ? cl->cwcacheexgot : 1));
8346 #endif
8347 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", getting);
8348 rowvariable = "TABLECLIENTROWS";
8349 written = 1;
8352 if(written)
8354 if(!apicall)
8356 tpl_addVar(vars, TPLADD, "NAME", tpl_getTpl(vars, cacheex_name_link_tpl));
8358 #ifdef CS_CACHEEX_AIO
8359 tpl_addVar(vars, TPLAPPEND, rowvariable, tpl_getTpl(vars, "CACHEEXAIOTABLEROW"));
8360 #else
8361 tpl_addVar(vars, TPLAPPEND, rowvariable, tpl_getTpl(vars, "CACHEEXTABLEROW"));
8362 #endif
8364 if(cl->ll_cacheex_stats)
8366 LL_ITER itr = ll_iter_create(cl->ll_cacheex_stats);
8367 S_CACHEEX_STAT_ENTRY *cacheex_stats_entry;
8369 while((cacheex_stats_entry = ll_iter_next(&itr)))
8371 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", "");
8372 if(now - cacheex_stats_entry->cache_last < 20)
8373 { tpl_addVar(vars, TPLADD, "TYPE", cacheex_stats_entry->cache_direction == 0 ? pushing : getting); }
8374 else
8375 { tpl_addVar(vars, TPLADD, "TYPE", ""); }
8376 tpl_printf(vars, TPLADD, "NAME", "%04X@%06X:%04X", cacheex_stats_entry->cache_caid,
8377 cacheex_stats_entry->cache_prid,
8378 cacheex_stats_entry->cache_srvid);
8379 if(cacheex_stats_entry->cache_direction == 0)
8381 tpl_printf(vars, TPLADD, "PUSH", "%d", cacheex_stats_entry->cache_count);
8382 #ifdef CS_CACHEEX_AIO
8383 tpl_printf(vars, TPLADD, "PUSHLG", "%d", cacheex_stats_entry->cache_count_lg);
8384 #endif
8385 tpl_addVar(vars, TPLADD, "GOT", "");
8387 else
8389 tpl_printf(vars, TPLADD, "GOT", "%d", cacheex_stats_entry->cache_count);
8390 #ifdef CS_CACHEEX_AIO
8391 tpl_printf(vars, TPLADD, "GOTLG", "%d", cacheex_stats_entry->cache_count_lg);
8392 #endif
8393 tpl_addVar(vars, TPLADD, "PUSH", "");
8395 tpl_addVar(vars, TPLADD, "HIT", "");
8396 char channame[CS_SERVICENAME_SIZE];
8397 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)));
8398 tpl_addVar(vars, TPLADD, "LEVEL", lastchan);
8399 if (apicall == 2)
8401 tpl_printf(vars, TPLADD, "JSONDELIMITER", "%s", (delimiter > 1)?",":"");
8402 #ifdef CS_CACHEEX_AIO
8403 tpl_addVar(vars, TPLAPPEND, "JSONCACHEEXBITS", tpl_getTpl(vars, "JSONCACHEEXAIOBIT"));
8404 #else
8405 tpl_addVar(vars, TPLAPPEND, "JSONCACHEEXBITS", tpl_getTpl(vars, "JSONCACHEEXBIT"));
8406 #endif
8407 delimiter++;
8409 else
8411 #ifdef CS_CACHEEX_AIO
8412 tpl_addVar(vars, TPLAPPEND, rowvariable, tpl_getTpl(vars, "CACHEEXAIOTABLEROWSTATS"));
8413 #else
8414 tpl_addVar(vars, TPLAPPEND, rowvariable, tpl_getTpl(vars, "CACHEEXTABLEROW"));
8415 #endif
8419 written = 0;
8423 float cachesum = first_client ? first_client->cwcacheexgot : 1;
8424 if(cachesum < 1)
8426 cachesum = 1;
8428 tpl_printf(vars, TPLADD, "TOTAL_CACHEXPUSH", PRINTF_LOCAL_D, first_client ? first_client->cwcacheexpush : 0);
8429 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXPUSH_IMG", pushing);
8430 tpl_printf(vars, TPLADD, "TOTAL_CACHEXGOT", PRINTF_LOCAL_D, first_client ? first_client->cwcacheexgot : 0);
8431 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXGOT_IMG", getting);
8432 tpl_printf(vars, TPLADD, "TOTAL_CACHEXHIT", PRINTF_LOCAL_D, first_client ? first_client->cwcacheexhit : 0);
8433 tpl_printf(vars, TPLADD, "TOTAL_CACHESIZE", "%d", cache_size());
8434 #ifdef CS_CACHEEX_AIO
8435 tpl_printf(vars, TPLADD, "TOTAL_CACHESIZE_LG", "%d", cache_size_lg());
8436 #endif
8438 tpl_printf(vars, TPLADD, "REL_CACHEXHIT", "%.2f", (first_client ? first_client->cwcacheexhit : 0) * 100 / cachesum);
8440 if(!apicall)
8442 #ifdef CS_CACHEEX_AIO
8443 return tpl_getTpl(vars, "CACHEEXAIOPAGE");
8444 #else
8445 return tpl_getTpl(vars, "CACHEEXPAGE");
8446 #endif
8448 else
8450 return tpl_getTpl(vars, "JSONCACHEEX");
8453 #endif
8455 static char *send_oscam_api(struct templatevars * vars, FILE * f, struct uriparams * params, int8_t *keepalive, int8_t apicall, char *extraheader)
8457 if(strcmp(getParam(params, "part"), "status") == 0)
8459 return send_oscam_status(vars, params, apicall);
8461 else if(strcmp(getParam(params, "part"), "userstats") == 0)
8463 return send_oscam_user_config(vars, params, apicall);
8465 else if(strcmp(getParam(params, "part"), "failban") == 0)
8467 return send_oscam_failban(vars, params, apicall);
8469 #ifdef CS_CACHEEX
8470 else if(strcmp(getParam(params, "part"), "cacheex") == 0)
8472 return send_oscam_cacheex(vars, params, apicall);
8474 #endif
8475 else if(strcmp(getParam(params, "part"), "files") == 0)
8477 return send_oscam_files(vars, params, apicall);
8479 else if(strcmp(getParam(params, "part"), "readerlist") == 0)
8481 return send_oscam_reader(vars, params, apicall);
8483 else if(strcmp(getParam(params, "part"), "serverconfig") == 0)
8485 //Send Errormessage
8486 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "serverconfig not yet avail");
8487 return tpl_getTpl(vars, "APIERROR");
8489 else if(strcmp(getParam(params, "part"), "userconfig") == 0)
8491 if(((strcmp(getParam(params, "action"), "Save") == 0) ||
8492 (strcmp(getParam(params, "action"), "Save As") == 0)) && cfg.http_readonly == 1)
8494 //Send Errormessage
8495 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "API is in readonly mode");
8496 return tpl_getTpl(vars, "APIERROR");
8498 else
8500 struct s_auth *account = get_account_by_name(getParam(params, "user"));
8501 if(!account && strcmp(getParam(params, "action"), "Save"))
8503 //Send Errormessage
8504 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "user not exist");
8505 return tpl_getTpl(vars, "APIERROR");
8507 else
8509 return send_oscam_user_config_edit(vars, params, apicall);
8513 else if(strcmp(getParam(params, "part"), "entitlement") == 0)
8516 if(strcmp(getParam(params, "label"), ""))
8518 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
8519 if(rdr)
8521 if(rdr->enable == 1)
8523 return send_oscam_entitlement(vars, params, apicall);
8525 else
8527 //Send Errormessage
8528 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no cccam reader or disabled");
8529 return tpl_getTpl(vars, "APIERROR");
8532 else
8534 //Send Errormessage
8535 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "reader not exist");
8536 return tpl_getTpl(vars, "APIERROR");
8539 else
8541 //Send Errormessage
8542 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no reader selected");
8543 return tpl_getTpl(vars, "APIERROR");
8546 else if(strcmp(getParam(params, "part"), "ecmhistory") == 0)
8548 int32_t i;
8549 int32_t isec;
8550 int32_t shown;
8551 time_t now = time((time_t *)0);
8552 const char *usr;
8553 struct s_client *cl;
8554 for(i = 0, cl = first_client; cl ; cl = cl->next, i++)
8556 if(cl->wihidden != 1)
8558 isec = now - cl->lastecm;
8559 usr = username(cl);
8560 shown = 0;
8561 if(strcmp(getParam(params, "label"), "") == 0)
8563 if(strcmp(getParam(params, "type"), "servers") == 0)
8565 if(cl->typ == 'p' || cl->typ == 'r')
8566 { shown = 1; }
8568 else if(strcmp(getParam(params, "type"), "users") == 0)
8570 if(cl->typ == 'c')
8571 { shown = 1; }
8573 else
8575 shown = 1;
8578 else if(strcmp(getParam(params, "label"), usr) == 0)
8580 shown = 1;
8582 if(shown == 1)
8584 tpl_printf(vars, TPLADD, "CLIENTTYPE", "%c", cl->typ);
8585 tpl_addVar(vars, TPLADD, "CLIENTUSER", xml_encode(vars, usr));
8586 if(cl->typ == 'c' || cl->typ == 'm')
8588 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", xml_encode(vars, cl->account->description ? cl->account->description : ""));
8590 else if(cl->typ == 'p' || cl->typ == 'r')
8592 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", xml_encode(vars, cl->reader->description ? cl->reader->description : ""));
8594 tpl_printf(vars, TPLADD, "CLIENTLASTRESPONSETIME", "%d", cl->cwlastresptime ? cl->cwlastresptime : -1);
8595 tpl_printf(vars, TPLADD, "CLIENTIDLESECS", "%d", isec);
8597 //load historical values from ringbuffer
8598 char *value = get_ecm_fullhistorystring(cl);
8599 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIMEHIST", value);
8600 free_mk_t(value);
8602 tpl_addVar(vars, TPLAPPEND, "APISTATUSBITS", tpl_getTpl(vars, "APISTATUSBIT"));
8606 return tpl_getTpl(vars, "APISTATUS");
8608 else if(strcmp(getParam(params, "part"), "readerstats") == 0)
8610 if(strcmp(getParam(params, "label"), ""))
8612 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
8613 if(rdr)
8615 return send_oscam_reader_stats(vars, params, apicall);
8617 else
8619 //Send Errormessage
8620 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "reader not exist");
8621 return tpl_getTpl(vars, "APIERROR");
8624 else
8626 //Send Errormessage
8627 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no reader selected");
8628 return tpl_getTpl(vars, "APIERROR");
8631 else if(strcmp(getParam(params, "part"), "sendcmd") == 0)
8633 if(strcmp(getParam(params, "label"), ""))
8635 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
8636 if(rdr)
8638 char api_msg[150];
8639 CMD_PACKET *cmd_pack = NULL;
8640 if(!cs_malloc(&cmd_pack, sizeof(CMD_PACKET)))
8642 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "cs_malloc failed!");
8643 return tpl_getTpl(vars, "APIERROR");
8645 struct s_client *webif_client = cur_client();
8646 webif_client->grp = 0xFF; // access all readers
8648 memset(cmd_pack, '0', sizeof(CMD_PACKET));
8649 cmd_pack->client = webif_client;
8650 cmd_pack->cmdlen = strlen(getParam(params, "cmd")) / 2;
8652 if(cmd_pack->cmdlen > 0 && (unsigned long)abs(cmd_pack->cmdlen) <= sizeof(cmd_pack->cmd))
8654 if(key_atob_l(getParam(params, "cmd"), cmd_pack->cmd, cmd_pack->cmdlen*2))
8656 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "'cmd' has not been sent due to wrong value!");
8657 return tpl_getTpl(vars, "APIERROR");
8660 else
8662 if(cmd_pack->cmdlen)
8664 snprintf(api_msg, sizeof(api_msg), "Command would exceed %lu bytes!", (long unsigned int)sizeof(cmd_pack->cmd));
8665 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", api_msg);
8667 else
8669 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "Missing parameter 'cmd'!");
8671 return tpl_getTpl(vars, "APIERROR");
8674 struct s_client *cl = rdr->client;
8675 if(rdr->enable == 1 && cl && cl->typ == 'r')
8677 add_job(cl, ACTION_READER_SENDCMD, cmd_pack, sizeof(CMD_PACKET));
8678 tpl_addVar(vars, TPLADD, "APICONFIRMMESSAGE", "command sent");
8679 return tpl_getTpl(vars, "APICONFIRMATION");
8681 else
8683 snprintf(api_msg, sizeof(api_msg), "Reader '%s' is not suitable!", xml_encode(vars, rdr->label));
8684 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", api_msg);
8685 return tpl_getTpl(vars, "APIERROR");
8688 else
8690 //Send Errormessage
8691 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no such reader");
8692 return tpl_getTpl(vars, "APIERROR");
8695 else
8697 //Send Errormessage
8698 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no reader selected");
8699 return tpl_getTpl(vars, "APIERROR");
8702 else if(strcmp(getParam(params, "part"), "shutdown") == 0)
8704 if((strcmp(strtolower(getParam(params, "action")), "restart") == 0) ||
8705 (strcmp(strtolower(getParam(params, "action")), "shutdown") == 0))
8707 if(!cfg.http_readonly)
8709 return send_oscam_shutdown(vars, f, params, apicall, keepalive, extraheader);
8711 else
8713 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "webif readonly mode");
8714 return tpl_getTpl(vars, "APIERROR");
8717 else
8719 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "missing parameter action");
8720 return tpl_getTpl(vars, "APIERROR");
8724 else
8726 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "part not found");
8727 return tpl_getTpl(vars, "APIERROR");
8731 static char *send_oscam_image(struct templatevars * vars, FILE * f, struct uriparams * params, char *image, time_t modifiedheader, uint32_t etagheader, char *extraheader)
8733 char *wanted;
8734 if(image == NULL) { wanted = getParam(params, "i"); }
8735 else { wanted = image; }
8736 if(cs_strlen(wanted) > 3 && wanted[0] == 'I' && wanted[1] == 'C')
8738 if(etagheader == 0)
8740 int8_t disktpl = 0;
8741 char *tpl_path;
8742 tpl_path = cfg.http_piconpath? cfg.http_piconpath : cfg.http_tpl;
8744 if(tpl_path)
8746 char path[255];
8747 if(cs_strlen(tpl_getTplPath(wanted, tpl_path, path, 255)) > 0 && file_exists(path))
8749 struct stat st;
8750 disktpl = 1;
8751 stat(path, &st);
8752 if((time_t)st.st_mtime < modifiedheader)
8754 send_header304(f, extraheader);
8755 return "1";
8759 if(disktpl == 0 && first_client->login < modifiedheader)
8761 send_header304(f, extraheader);
8762 return "1";
8765 char *header = strstr(tpl_getTpl(vars, wanted), "data:");
8766 if(header != NULL)
8768 char *ptr = header + 5;
8769 while(ptr[0] != ';' && ptr[0] != '\0') { ++ptr; }
8770 if(ptr[0] != '\0' && ptr[1] != '\0') { ptr[0] = '\0'; }
8771 else { return "0"; }
8772 ptr = strstr(ptr + 1, "base64,");
8773 if(ptr != NULL)
8775 int32_t len = b64decode((uint8_t *)ptr + 7);
8776 if(len > 0)
8778 if((uint32_t)crc32(0L, (uint8_t *)ptr + 7, len) == etagheader)
8780 send_header304(f, extraheader);
8782 else
8784 send_headers(f, 200, "OK", extraheader, header + 5, 1, len, ptr + 7, 0);
8785 webif_write_raw(ptr + 7, f, len);
8787 return "1";
8792 // Return file not found
8793 const char *not_found = "File not found.\n";
8794 send_headers(f, 404, "Not Found", extraheader, "text/plain", 0, cs_strlen(not_found), (char *)not_found, 0);
8795 webif_write_raw((char *)not_found, f, cs_strlen(not_found));
8796 return "1";
8799 static char *send_oscam_robots_txt(FILE * f)
8801 const char *content = "User-agent: *\nDisallow: /\n";
8802 send_headers(f, 200, "OK", NULL, "text/plain", 0, cs_strlen(content), (char *)content, 0);
8803 webif_write_raw((char *)content, f, cs_strlen(content));
8804 return "1";
8807 static char *send_oscam_graph(struct templatevars * vars)
8809 return tpl_getTpl(vars, "GRAPH");
8812 #ifdef MODULE_GHTTP
8813 static bool ghttp_autoconf(struct templatevars * vars, struct uriparams * params)
8815 int8_t i = 0;
8816 struct s_reader *rdr;
8817 char *name = getParam(params, "gacname");
8818 if(cs_strlen(name) < 3)
8820 tpl_addMsg(vars, "Invalid host name!");
8821 return false;
8824 LL_ITER itr = ll_iter_create(configured_readers);
8825 while((rdr = ll_iter_next(&itr)))
8826 if(rdr->ph.num == R_GHTTP) { i++; } // count existing ghttp readers
8828 while(i < 3) // if less than 3, add more
8830 char lbl[128];
8831 snprintf(lbl, sizeof(lbl), "%s%d", "ghttp", i + 1);
8832 cs_log("GHttp autoconf: adding reader %s", lbl);
8833 struct s_reader *newrdr;
8834 if(!cs_malloc(&newrdr, sizeof(struct s_reader)))
8836 tpl_addMsg(vars, "Create reader failed!");
8837 return false;
8839 newrdr->typ = R_GHTTP;
8840 cs_strncpy(newrdr->label, lbl, sizeof(newrdr->label));
8841 module_reader_set(newrdr);
8842 reader_set_defaults(newrdr);
8843 newrdr->enable = 0;
8844 newrdr->grp = 1;
8845 ll_append(configured_readers, newrdr);
8846 i++;
8849 uint16_t port = 0;
8850 char *str = strstr(name, ":");
8851 if(str)
8853 port = atoi(str + 1);
8854 str[0] = '\0';
8857 i = 0;
8858 itr = ll_iter_create(configured_readers);
8859 while((rdr = ll_iter_next(&itr)))
8861 if(rdr->ph.num == R_GHTTP)
8863 if(i > 2) // remove superflous
8865 cs_log("GHttp autoconf: removing reader %s", rdr->label);
8866 inactivate_reader(rdr);
8867 ll_iter_remove(&itr);
8868 free_reader(rdr);
8870 else // reconfigure the 3 first ghttp readers
8872 cs_log("GHttp autoconf: reconfiguring reader %s", rdr->label);
8873 snprintf(rdr->label, sizeof(rdr->label), "%s%d", "ghttp", i + 1);
8874 rdr->r_port = port;
8875 rdr->enable = 1;
8876 rdr->ghttp_use_ssl = 0;
8877 #ifdef WITH_SSL
8878 rdr->ghttp_use_ssl = 1;
8879 #endif
8880 if(rdr->grp < 1) { rdr->grp = 1; }
8881 cs_strncpy(rdr->r_usr, getParam(params, "gacuser"), sizeof(rdr->r_usr));
8882 cs_strncpy(rdr->r_pwd, getParam(params, "gacpasswd"), sizeof(rdr->r_pwd));
8883 if(i == 0) { cs_strncpy(rdr->device, name, sizeof(rdr->device)); }
8884 else
8886 if(!strstr(name, "."))
8887 { snprintf(rdr->device, sizeof(rdr->device), "%s%d", name, i); } // name, name1, name2
8888 else { cs_strncpy(rdr->device, name, sizeof(rdr->device)); }
8889 // . in the name = assume full hostname = use same for all 3 readers
8891 if(i == 2) { rdr->fallback = 1; }
8892 else { rdr->fallback = 0; }
8893 i++;
8897 cs_log("GHttp autoconf: Saving %d readers", i);
8898 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
8899 itr = ll_iter_create(configured_readers);
8900 while((rdr = ll_iter_next(&itr)))
8902 if(rdr->ph.num == R_GHTTP)
8903 { restart_cardreader(rdr, 1); }
8905 return true;
8908 static char *send_oscam_ghttp(struct templatevars * vars, struct uriparams * params, int8_t apicall)
8910 if(strcmp(strtolower(getParam(params, "action")), "autoconf") == 0)
8912 if(!apicall)
8914 bool missing = false;
8915 if(cs_strlen(getParam(params, "gacuser")) == 0)
8917 tpl_addVar(vars, TPLADD, "USERREQ", "<FONT COLOR='red'>(Required)</FONT>");
8918 missing = true;
8920 else { tpl_addVar(vars, TPLADD, "GACUSER", getParam(params, "gacuser")); }
8921 if(cs_strlen(getParam(params, "gacpasswd")) == 0)
8923 tpl_addVar(vars, TPLADD, "PWDREQ", "<FONT COLOR='red'>(Required)</FONT>");
8924 missing = true;
8926 else { tpl_addVar(vars, TPLADD, "GACPASSWD", getParam(params, "gacpasswd")); }
8927 if(cs_strlen(getParam(params, "gacname")) == 0)
8929 tpl_addVar(vars, TPLADD, "NAMEREQ", "<FONT COLOR='red'>(Required)</FONT>");
8930 missing = true;
8932 else { tpl_addVar(vars, TPLADD, "GACNAME", getParam(params, "gacname")); }
8933 if(missing) { return tpl_getTpl(vars, "PREAUTOCONF"); }
8934 cs_log("GHttp autoconf requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
8936 else
8938 tpl_addVar(vars, TPLADD, "APICONFIRMMESSAGE", "autoconf");
8939 cs_log("GHttp autoconf requested by XMLApi from %s", cs_inet_ntoa(GET_IP()));
8942 if(ghttp_autoconf(vars, params))
8944 tpl_printf(vars, TPLADD, "REFRESHTIME", "%d", 3);
8945 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
8946 tpl_printf(vars, TPLADD, "SECONDS", "%d", 3);
8947 if(apicall) { return tpl_getTpl(vars, "APICONFIRMATION"); }
8948 else { return tpl_getTpl(vars, "AUTOCONF"); }
8950 else { return tpl_getTpl(vars, "PREAUTOCONF"); } // something failed
8953 else
8955 if(cs_strlen(getParam(params, "token")) > 0) // parse autoconf token
8957 char *token = getParam(params, "token");
8958 int32_t len = b64decode((uint8_t *)token);
8959 if(len > 0)
8961 struct uriparams tokenprms;
8962 tokenprms.paramcount = 0;
8963 parseParams(&tokenprms, token);
8964 if(cs_strlen(getParam(&tokenprms, "u")) > 0)
8966 tpl_addVar(vars, TPLADD, "GACUSER", getParam(&tokenprms, "u"));
8967 tpl_addVar(vars, TPLADD, "USERRDONLY", "readonly");
8969 if(cs_strlen(getParam(&tokenprms, "p")) > 0)
8971 tpl_addVar(vars, TPLADD, "GACPASSWD", getParam(&tokenprms, "p"));
8972 tpl_addVar(vars, TPLADD, "PWDRDONLY", "readonly");
8974 if(cs_strlen(getParam(&tokenprms, "n")) > 0)
8976 tpl_addVar(vars, TPLADD, "GACNAME", getParam(&tokenprms, "n"));
8977 tpl_addVar(vars, TPLADD, "NAMERDONLY", "readonly");
8981 return tpl_getTpl(vars, "PREAUTOCONF");
8984 #endif
8986 static int8_t check_httpip(IN_ADDR_T addr)
8988 int8_t i = 0;
8989 // check all previously dyndns resolved addresses
8990 for(i = 0; i < MAX_HTTP_DYNDNS; i++)
8992 if(IP_ISSET(cfg.http_dynip[i]) && IP_EQUAL(cfg.http_dynip[i], addr))
8993 { return 1; }
8995 return 0;
8998 static int8_t check_httpdyndns(IN_ADDR_T addr)
9001 // check all previously dyndns resolved addresses
9002 if(check_httpip(addr))
9003 { return 1; }
9005 // we are not ok, so resolve all dyndns entries into IP's - maybe outdated IP's
9007 if(cfg.http_dyndns[0][0])
9009 int8_t i = 0;
9010 for(i = 0; i < MAX_HTTP_DYNDNS; i++)
9012 if(cfg.http_dyndns[i][0])
9014 cs_resolve((const char *)cfg.http_dyndns[i], &cfg.http_dynip[i], NULL, NULL);
9015 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]));
9019 else
9021 cs_log_dbg(D_TRACE, "WebIf: No dyndns addresses found");
9022 return 0;
9025 // again check all dyndns resolved addresses
9026 if(check_httpip(addr))
9027 { return 1; }
9029 return 0;
9032 static int8_t check_valid_origin(IN_ADDR_T addr)
9035 // check whether requesting IP is in allowed IP ranges
9036 if(check_ip(cfg.http_allowed, addr))
9037 { return 1; }
9039 // we havn't found the requesting IP in allowed range. So we check for allowed httpdyndns as last chance
9040 if(cfg.http_dyndns[0][0])
9042 int8_t ok;
9043 ok = check_httpdyndns(addr);
9044 return ok;
9046 return 0;
9049 static int8_t check_request(char *result, int32_t readen)
9051 if(readen < 50) { return 0; }
9052 result[readen] = '\0';
9053 int8_t method;
9054 if(strncmp(result, "POST", 4) == 0) { method = 1; }
9055 else { method = 0; }
9056 char *headerEnd = strstr(result, "\r\n\r\n");
9057 if(headerEnd == NULL) { return 0; }
9058 else if(method == 0) { return 1; }
9059 else
9061 char *ptr = strstr(result, "Content-Length: ");
9062 if(ptr != NULL)
9064 ptr += 16;
9065 if(ptr < result + readen)
9067 uint32_t length = atoi(ptr);
9068 if(cs_strlen(headerEnd + 4) >= length) { return 1; }
9072 return 0;
9075 static int32_t readRequest(FILE * f, IN_ADDR_T in, char **result, int8_t forcePlain)
9077 int32_t n, bufsize = 0, errcount = 0;
9078 char buf2[1024];
9079 struct pollfd pfd2[1];
9080 #ifdef WITH_SSL
9081 int8_t is_ssl = 0;
9082 if(ssl_active && !forcePlain)
9083 { is_ssl = 1; }
9084 #endif
9086 while(1)
9088 errno = 0;
9089 if(forcePlain)
9090 { n = read(fileno(f), buf2, sizeof(buf2)); }
9091 else
9092 { n = webif_read(buf2, sizeof(buf2), f); }
9093 if(n <= 0)
9095 if((errno == 0 || errno == EINTR))
9097 if(errcount++ < 10)
9099 cs_sleepms(5);
9100 continue;
9102 else { return -1; }
9104 #ifdef WITH_SSL
9105 if(is_ssl)
9107 if(errno != ECONNRESET)
9109 int32_t errcode = ERR_peek_error();
9110 char errstring[128];
9111 ERR_error_string_n(errcode, errstring, sizeof(errstring) - 1);
9112 cs_log_dbg(D_TRACE, "WebIf: read error ret=%d (%d%s%s)", n, SSL_get_error(cur_ssl(), n), errcode ? " " : "", errcode ? errstring : "");
9114 return -1;
9116 #else
9117 if(errno != ECONNRESET)
9118 { cs_log_dbg(D_TRACE, "WebIf: read error ret=%d (errno=%d %s)", n, errno, strerror(errno)); }
9119 #endif
9120 return -1;
9122 if(!cs_realloc(result, bufsize + n + 1))
9124 send_error500(f);
9125 NULLFREE(*result);
9126 return -1;
9129 memcpy(*result + bufsize, buf2, n);
9130 bufsize += n;
9132 #ifdef WITH_EMU
9133 if(bufsize > 204800) // max request size 200kb
9134 #else
9135 if(bufsize > 102400) // max request size 100kb
9136 #endif
9138 cs_log("error: too much data received from %s", cs_inet_ntoa(in));
9139 NULLFREE(*result);
9140 *result = NULL;
9141 return -1;
9144 #ifdef WITH_SSL
9145 if(ssl_active && !forcePlain)
9147 int32_t len = 0;
9148 len = SSL_pending((SSL *)f);
9150 if(len > 0)
9151 { continue; }
9153 pfd2[0].fd = SSL_get_fd((SSL *)f);
9156 else
9157 #endif
9158 pfd2[0].fd = fileno(f);
9160 pfd2[0].events = (POLLIN | POLLPRI);
9162 int32_t rc = poll(pfd2, 1, 100);
9163 if(rc > 0 || !check_request(*result, bufsize))
9164 { continue; }
9165 else
9166 { break; }
9168 return bufsize;
9170 static int32_t process_request(FILE * f, IN_ADDR_T in)
9172 int32_t ok = 0;
9173 int8_t *keepalive = (int8_t *)pthread_getspecific(getkeepalive);
9174 IN_ADDR_T addr = GET_IP();
9178 #ifdef WITH_SSL
9179 if(!ssl_active && *keepalive) { fflush(f); }
9180 #else
9181 if(*keepalive) { fflush(f); }
9182 #endif
9184 // at this point we do all checks related origin IP, ranges and dyndns stuff
9185 ok = check_valid_origin(addr);
9186 cs_log_dbg(D_TRACE, "WebIf: Origin checked. Result: access from %s => %s", cs_inet_ntoa(addr), (!ok) ? "forbidden" : "allowed");
9188 // based on the failed origin checks we send a 403 to calling browser
9189 if(!ok)
9191 send_error(f, 403, "Forbidden", NULL, "Access denied.", 0);
9192 cs_log("unauthorized access from %s - invalid ip or dyndns", cs_inet_ntoa(addr));
9193 return 0;
9195 int32_t authok = 0;
9196 char expectednonce[(MD5_DIGEST_LENGTH * 2) + 1], opaque[(MD5_DIGEST_LENGTH * 2) + 1];
9197 char authheadertmp[sizeof(AUTHREALM) + sizeof(expectednonce) + sizeof(opaque) + 100];
9199 char *method, *path, *protocol, *str1, *saveptr1 = NULL, *authheader = NULL, *extraheader = NULL, *filebuf = NULL;
9200 char *pch, *tmp, *buf, *nameInUrl, subdir[32];
9201 /* List of possible pages */
9202 char *pages[] =
9204 "/config.html",
9205 "/readers.html",
9206 "/entitlements.html",
9207 "/status.html",
9208 "/userconfig.html",
9209 "/readerconfig.html",
9210 "/services.html",
9211 "/user_edit.html",
9212 "/site.css",
9213 "/services_edit.html",
9214 "/savetemplates.html",
9215 "/shutdown.html",
9216 "/script.html",
9217 "/scanusb.html",
9218 "/files.html",
9219 "/readerstats.html",
9220 "/failban.html",
9221 "/oscam.js",
9222 "/oscamapi.html",
9223 "/image",
9224 "/favicon.ico",
9225 "/graph.svg",
9226 "/oscamapi.xml",
9227 "/cacheex.html",
9228 "/oscamapi.json",
9229 "/emm.html",
9230 "/emm_running.html",
9231 "/robots.txt",
9232 "/ghttp.html",
9233 "/logpoll.html",
9234 "/jquery.js",
9237 int32_t pagescnt = sizeof(pages) / sizeof(char *); // Calculate the amount of items in array
9238 int32_t i, bufsize, len, pgidx = -1;
9239 uint32_t etagheader = 0;
9240 struct uriparams params;
9241 params.paramcount = 0;
9242 time_t modifiedheader = 0;
9244 bufsize = readRequest(f, in, &filebuf, 0);
9246 if(!filebuf || bufsize < 1)
9248 if(!*keepalive) { cs_log_dbg(D_CLIENT, "WebIf: No data received from client %s. Closing connection.", cs_inet_ntoa(addr)); }
9249 return -1;
9252 buf = filebuf;
9254 if((method = strtok_r(buf, " ", &saveptr1)) != NULL)
9256 if((path = strtok_r(NULL, " ", &saveptr1)) != NULL)
9258 if((protocol = strtok_r(NULL, "\r", &saveptr1)) == NULL)
9260 NULLFREE(filebuf);
9261 return -1;
9264 else
9266 NULLFREE(filebuf);
9267 return -1;
9270 else
9272 NULLFREE(filebuf);
9273 return -1;
9275 tmp = protocol + cs_strlen(protocol) + 2;
9277 pch = path;
9278 /* advance pointer to beginning of query string */
9279 while(pch[0] != '?' && pch[0] != '\0') { ++pch; }
9280 if(pch[0] == '?')
9282 pch[0] = '\0';
9283 ++pch;
9286 nameInUrl = pch - 1;
9287 while(nameInUrl != path && nameInUrl[0] != '/') { --nameInUrl; }
9289 /* allow only alphanumeric sub-folders */
9290 int32_t subdirLen = nameInUrl - path;
9291 subdir[0] = '\0';
9292 if(subdirLen > 0 && subdirLen < 32)
9294 cs_strncpy(subdir, path + 1, subdirLen);
9296 int32_t invalidSubdir = 0;
9297 for(i = 0; i < subdirLen - 1; i++)
9299 if(!((subdir[i] >= '0' && subdir[i] <= '9')
9300 || (subdir[i] >= 'a' && subdir[i] <= 'z')
9301 || (subdir[i] >= 'A' && subdir[i] <= 'Z')))
9304 invalidSubdir = 1;
9305 subdir[0] = '\0';
9306 break;
9310 if(!invalidSubdir)
9312 subdir[subdirLen] = '\0';
9313 #ifdef WIN32
9314 subdir[subdirLen - 1] = '\\';
9315 #else
9316 subdir[subdirLen - 1] = '/';
9317 #endif
9321 /* Map page to our static page definitions */
9322 for(i = 0; i < pagescnt; i++)
9324 if(!strcmp(nameInUrl, pages[i])) { pgidx = i; }
9327 parseParams(&params, pch);
9329 if(!cfg.http_user || !cfg.http_pwd)
9330 { authok = 1; }
9332 for(str1 = strtok_r(tmp, "\n", &saveptr1); str1; str1 = strtok_r(NULL, "\n", &saveptr1))
9334 len = cs_strlen(str1);
9335 if(str1[len - 1] == '\r')
9337 str1[len - 1] = '\0';
9338 --len;
9340 if(len == 0)
9342 if(strcmp(method, "POST") == 0)
9344 parseParams(&params, str1 + 2);
9346 break;
9348 if(!authok && len > 50 && strncasecmp(str1, "Authorization:", 14) == 0 && strstr(str1, "Digest") != NULL)
9350 if(cs_dblevel & D_CLIENT)
9352 if(cs_realloc(&authheader, len + 1))
9353 { cs_strncpy(authheader, str1, len); }
9355 authok = check_auth(str1, method, path, addr, expectednonce, opaque);
9357 else if(len > 40 && strncasecmp(str1, "If-Modified-Since:", 18) == 0)
9359 modifiedheader = parse_modifiedsince(str1);
9361 else if(len > 20 && strncasecmp(str1, "If-None-Match:", 14) == 0)
9363 for(pch = str1 + 14; pch[0] != '"' && pch[0] != '\0'; ++pch) { ; }
9364 if(cs_strlen(pch) > 5) { etagheader = (uint32_t)strtoul(++pch, NULL, 10); }
9366 else if(len > 12 && strncasecmp(str1, "Connection: Keep-Alive", 22) == 0 && strcmp(method, "POST"))
9368 *keepalive = 1;
9372 if(cfg.http_user && cfg.http_pwd)
9374 if (!authok || cs_strlen(opaque) != MD5_DIGEST_LENGTH * 2)
9376 calculate_opaque(addr, opaque);
9379 if (authok != 2)
9381 if(!authok)
9383 if(authheader)
9385 cs_log_dbg(D_CLIENT, "WebIf: Received wrong auth header from %s:", cs_inet_ntoa(addr));
9386 cs_log_dbg(D_CLIENT, "%s", authheader);
9388 else
9389 { cs_log_dbg(D_CLIENT, "WebIf: Received no auth header from %s.", cs_inet_ntoa(addr)); }
9391 calculate_nonce(NULL, expectednonce, opaque);
9394 if (authok != 1)
9396 snprintf(authheadertmp, sizeof(authheadertmp), "WWW-Authenticate: Digest algorithm=\"MD5\", realm=\"%s\", qop=\"auth\", opaque=\"%s\", nonce=\"%s\"", AUTHREALM, opaque, expectednonce);
9397 if (authok == 2)
9399 if (!cs_strncat(authheadertmp, ", stale=true", sizeof(authheadertmp))) {
9400 cs_log("WARNING, bug here!");
9404 else
9406 snprintf(authheadertmp, sizeof(authheadertmp), "Authentication-Info: nextnonce=\"%s\"", expectednonce);
9409 extraheader = authheadertmp;
9411 if (authok != 1)
9413 char *msg = "Access denied.\n";
9414 send_headers(f, 401, "Unauthorized", extraheader, "text/html", 0, cs_strlen(msg), msg, 0);
9415 webif_write(msg, f);
9416 NULLFREE(authheader);
9417 NULLFREE(filebuf);
9418 if (*keepalive) {
9419 continue;
9420 } else {
9421 return 0;
9425 else
9427 NULLFREE(authheader);
9430 /*build page*/
9431 if(pgidx == 8)
9433 send_file(f, "CSS", subdir, modifiedheader, etagheader, extraheader);
9435 else if(pgidx == 17)
9437 send_file(f, "JS", subdir, modifiedheader, etagheader, extraheader);
9439 else if(pgidx == 30)
9441 send_file(f, "JQ", subdir, modifiedheader, etagheader, extraheader);
9443 else
9445 time_t t;
9446 struct templatevars *vars = tpl_create();
9447 if(vars == NULL)
9449 send_error500(f);
9450 NULLFREE(filebuf);
9451 return 0;
9454 tpl_addVar(vars, TPLADD, "SUBDIR", subdir);
9456 struct tm lt, st;
9457 time(&t);
9459 localtime_r(&t, &lt);
9461 tpl_addVar(vars, TPLADD, "CS_VERSION", CS_VERSION);
9462 tpl_addVar(vars, TPLADD, "CS_SVN_VERSION", CS_SVN_VERSION);
9463 tpl_addVar(vars, TPLADD, "CS_TARGET", CS_TARGET);
9464 tpl_addVar(vars, TPLADD, "HTTPOSCAMLABEL", xml_encode(vars,cfg.http_oscam_label));
9465 if (!boxtype_is("generic"))
9467 if (!boxname_is("generic"))
9468 tpl_printf(vars, TPLADD, "DETECTED_BOXTYPE", "%s (%s)", boxtype_get(), boxname_get());
9469 else
9470 tpl_addVar(vars, TPLADD, "DETECTED_BOXTYPE", boxtype_get());
9473 if(cfg.http_locale){
9474 float decimal_point = 0.0;
9475 setlocale(LC_ALL, cfg.http_locale);
9476 tpl_printf(vars, TPLADD, "TMP_DECPOINT", "%.1f", decimal_point);
9477 tpl_addVar(vars, TPLADD, "LOCALE_DECPOINT", strstr(tpl_getVar(vars, "TMP_DECPOINT"), ",") ? ",": ".");
9480 tpl_addVar(vars, TPLADD, "HTTP_CHARSET", cs_http_use_utf8 ? "UTF-8" : "ISO-8859-1");
9481 if(cfg.http_picon_size > 0)
9483 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);
9485 if(cfg.poll_refresh > 0)
9487 tpl_printf(vars, TPLADD, "POLLREFRESHTIME", "%d", cfg.poll_refresh);
9489 if ( cfg.http_refresh > 0 &&
9490 ((( pgidx == 1 || pgidx == 4 ) && !cfg.poll_refresh ) ||
9491 ( pgidx == 3 && ( cfg.http_status_log || !cfg.poll_refresh )) ||
9492 pgidx == 15 || pgidx == 23 || pgidx == -1 )) // wenn polling bei cachex.html eingeführt wird muss die 23 => 2 zeilen höher
9494 tpl_printf(vars, TPLADD, "REFRESHTIME", "%d", cfg.http_refresh);
9495 tpl_addVar(vars, TPLADD, "WITHQUERY", pgidx == 15 ? "1" : "0");
9496 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
9498 #ifdef WEBIF_JQUERY
9499 tpl_printf(vars, TPLADD, "SRCJQUERY", "jquery.js?v=%s", CS_SVN_VERSION);
9500 #else
9501 tpl_addVar(vars, TPLADD, "SRCJQUERY", cfg.http_extern_jquery);
9502 #endif
9504 if(picon_exists("LOGO")||cs_strlen(tpl_getTpl(vars, "IC_LOGO"))>3)
9506 tpl_addVar(vars, TPLADD, "LOGO_INS", tpl_getTpl(vars, "LOGOBITIMG"));
9508 else
9510 tpl_addVar(vars, TPLADD, "LOGO_INS", tpl_getTpl(vars, "LOGOBITSVG"));
9512 tpl_addVar(vars, TPLADD, "LOGO", tpl_getTpl(vars, "LOGOBIT"));
9513 tpl_printf(vars, TPLADD, "CURDATE", "%02d.%02d.%02d", lt.tm_mday, lt.tm_mon + 1, lt.tm_year % 100);
9514 tpl_printf(vars, TPLADD, "CURTIME", "%02d:%02d:%02d", lt.tm_hour, lt.tm_min, lt.tm_sec);
9515 localtime_r(&first_client->login, &st);
9516 tpl_printf(vars, TPLADD, "STARTDATE", "%02d.%02d.%02d", st.tm_mday, st.tm_mon + 1, st.tm_year % 100);
9517 tpl_printf(vars, TPLADD, "STARTTIME", "%02d:%02d:%02d", st.tm_hour, st.tm_min, st.tm_sec);
9518 tpl_printf(vars, TPLADD, "PROCESSID", "%d", getppid());
9519 tpl_addVar(vars, TPLADD, "RUNAS", urlencode(vars, username(first_client)));
9521 time_t now = time((time_t *)0);
9522 // XMLAPI
9523 if(pgidx == 18 || pgidx == 22 || pgidx == 24)
9525 char tbuffer [30];
9526 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &st);
9527 tpl_addVar(vars, TPLADD, "APISTARTTIME", tbuffer);
9528 tpl_printf(vars, TPLADD, "APIRUNTIME", "%ld", now - first_client->login);
9529 tpl_printf(vars, TPLADD, "APIREADONLY", "%d", cfg.http_readonly);
9530 if(strcmp(getParam(&params, "callback"), ""))
9532 tpl_printf(vars, TPLADD, "CALLBACK", "%s%s", getParam(&params, "callback"), "(");
9533 tpl_addVar(vars, TPLADD, "ENDBRACKET", ")");
9538 if (config_enabled(WITH_LB))
9539 tpl_addVar(vars, TPLADD, "LBISDEFINED", "1");
9541 // language code in helplink
9542 tpl_addVar(vars, TPLADD, "LANGUAGE", cfg.http_help_lang);
9543 tpl_addVar(vars, TPLADD, "RUNTIME", sec2timeformat(vars, (now - first_client->login)));
9544 time_t uptime = oscam_get_uptime();
9545 if(uptime > 0){
9546 tpl_printf(vars, TPLADD, "UPTIMETXT", "%s Up Time: ", strcmp(tpl_getVar(vars, "DETECTED_BOXTYPE"),"")==0 ? "System" : tpl_getVar(vars, "DETECTED_BOXTYPE"));
9547 tpl_addVar(vars, TPLADD, "UPTIME", sec2timeformat(vars, uptime));
9549 tpl_addVar(vars, TPLADD, "CURIP", cs_inet_ntoa(addr));
9550 if(cfg.http_readonly)
9551 { tpl_addVar(vars, TPLAPPEND, "BTNDISABLED", "DISABLED"); }
9553 i = ll_count(cfg.v_list);
9554 if(i > 0) { tpl_printf(vars, TPLADD, "FAILBANNOTIFIER", "<SPAN CLASS=\"span_notifier\">%d</SPAN>", i); }
9555 tpl_printf(vars, TPLADD, "FAILBANNOTIFIERPOLL", "%d", i);
9557 char *result = NULL;
9559 // WebIf allows modifying many things. Thus, all pages except images/css/static are expected to be non-threadsafe!
9560 if(pgidx != 19 && pgidx != 20 && pgidx != 21 && pgidx != 27) { cs_writelock(__func__, &http_lock); }
9561 switch(pgidx)
9563 case 0:
9564 tpl_addVar(vars, TPLADD, "CONFIG_CONTENT", send_oscam_config(vars, &params));
9565 result = tpl_getTpl(vars, "CONFIGCONTENT");
9566 break;
9567 case 1:
9568 result = send_oscam_reader(vars, &params, 0);
9569 break;
9570 case 2:
9571 result = send_oscam_entitlement(vars, &params, 0);
9572 break;
9573 case 3:
9574 result = send_oscam_status(vars, &params, 0);
9575 break;
9576 case 4:
9577 result = send_oscam_user_config(vars, &params, 0);
9578 break;
9579 case 5:
9580 result = send_oscam_reader_config(vars, &params);
9581 break;
9582 case 6:
9583 result = send_oscam_services(vars, &params);
9584 break;
9585 case 7:
9586 result = send_oscam_user_config_edit(vars, &params, 0);
9587 break;
9588 //case 8: css file
9589 case 9:
9590 result = send_oscam_services_edit(vars, &params);
9591 break;
9592 case 10:
9593 result = send_oscam_savetpls(vars);
9594 break;
9595 case 11:
9596 result = send_oscam_shutdown(vars, f, &params, 0, keepalive, extraheader);
9597 break;
9598 case 12:
9599 result = send_oscam_script(vars, &params);
9600 break;
9601 case 13:
9602 result = send_oscam_scanusb(vars);
9603 break;
9604 case 14:
9605 result = send_oscam_files(vars, &params, 0);
9606 break;
9607 case 15:
9608 result = send_oscam_reader_stats(vars, &params, 0);
9609 break;
9610 case 16:
9611 result = send_oscam_failban(vars, &params, 0);
9612 break;
9613 //case 17: js file
9614 case 18:
9615 result = send_oscam_api(vars, f, &params, keepalive, 1, extraheader);
9616 break; //oscamapi.html
9617 case 19:
9618 result = send_oscam_image(vars, f, &params, NULL, modifiedheader, etagheader, extraheader);
9619 break;
9620 case 20:
9621 result = send_oscam_image(vars, f, &params, "ICMAI", modifiedheader, etagheader, extraheader);
9622 break;
9623 case 21:
9624 result = send_oscam_graph(vars);
9625 break;
9626 case 22:
9627 result = send_oscam_api(vars, f, &params, keepalive, 1, extraheader);
9628 break; //oscamapi.xml
9629 #ifdef CS_CACHEEX
9630 case 23:
9631 result = send_oscam_cacheex(vars, &params, 0);
9632 break;
9633 #endif
9634 case 24:
9635 result = send_oscam_api(vars, f, &params, keepalive, 2, extraheader);
9636 break; //oscamapi.json
9637 case 25:
9638 result = send_oscam_EMM(vars, &params);
9639 break; //emm.html
9640 case 26:
9641 result = send_oscam_EMM_running(vars, &params);
9642 break; //emm_running.html
9643 case 27:
9644 result = send_oscam_robots_txt(f);
9645 break; //robots.txt
9646 #ifdef MODULE_GHTTP
9647 case 28:
9648 result = send_oscam_ghttp(vars, &params, 0);
9649 break;
9650 #endif
9651 #ifdef WEBIF_LIVELOG
9652 case 29:
9653 result = send_oscam_logpoll(vars, &params);
9654 break;
9655 //case 30: jquery.js
9656 #endif
9657 default:
9658 result = send_oscam_status(vars, &params, 0);
9659 break;
9661 if(pgidx != 19 && pgidx != 20 && pgidx != 21 && pgidx != 27) { cs_writeunlock(__func__, &http_lock); }
9663 if(result == NULL || !strcmp(result, "0") || cs_strlen(result) == 0) { send_error500(f); }
9664 else if(strcmp(result, "1"))
9666 //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
9667 if(pgidx == 18)
9668 { send_headers(f, 200, "OK", extraheader, "text/xml", 0, cs_strlen(result), NULL, 0); }
9669 else if(pgidx == 21)
9670 { send_headers(f, 200, "OK", extraheader, "image/svg+xml", 0, cs_strlen(result), NULL, 0); }
9671 else if(pgidx == 24)
9672 { send_headers(f, 200, "OK", extraheader, "text/javascript", 0, cs_strlen(result), NULL, 0); }
9673 else
9674 { send_headers(f, 200, "OK", extraheader, "text/html", 0, cs_strlen(result), NULL, 0); }
9675 webif_write(result, f);
9677 tpl_clear(vars);
9679 NULLFREE(filebuf);
9681 while(*keepalive == 1 && !exit_oscam);
9682 return 0;
9685 static void *serve_process(void *conn)
9687 struct s_connection *myconn = (struct s_connection *)conn;
9688 int32_t s = myconn->socket;
9689 struct s_client *cl = myconn->cl;
9690 IN_ADDR_T in;
9691 IP_ASSIGN(in, myconn->remote);
9693 set_thread_name(__func__);
9695 #ifdef WITH_SSL
9696 SSL *ssl = myconn->ssl;
9697 SAFE_SETSPECIFIC(getssl, ssl);
9698 #endif
9699 NULLFREE(myconn);
9701 SAFE_SETSPECIFIC(getip, &in);
9702 SAFE_SETSPECIFIC(getclient, cl);
9704 int8_t keepalive = 0;
9705 SAFE_SETSPECIFIC(getkeepalive, &keepalive);
9707 #ifdef WITH_SSL
9708 if(ssl_active)
9710 if(SSL_set_fd(ssl, s))
9712 int32_t ok = (SSL_accept(ssl) != -1);
9713 if(!ok)
9715 int8_t tries = 100;
9716 while(!ok && tries--)
9718 int32_t err = SSL_get_error(ssl, -1);
9719 if(err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
9720 { break; }
9721 else
9723 struct pollfd pfd;
9724 pfd.fd = s;
9725 pfd.events = POLLIN | POLLPRI;
9726 int32_t rc = poll(&pfd, 1, -1);
9727 if(rc < 0)
9729 if(errno == EINTR || errno == EAGAIN) { continue; }
9730 break;
9732 if(rc == 1)
9733 { ok = (SSL_accept(ssl) != -1); }
9737 if(ok)
9739 process_request((FILE *)ssl, in);
9741 else
9743 FILE *f;
9744 f = fdopen(s, "r+");
9745 if(f != NULL)
9747 char *ptr, *filebuf = NULL, *host = NULL;
9748 int32_t bufsize = readRequest(f, in, &filebuf, 1);
9750 if(filebuf)
9752 filebuf[bufsize] = '\0';
9753 host = strstr(filebuf, "Host: ");
9754 if(host)
9756 host += 6;
9757 ptr = strchr(host, '\r');
9758 if(ptr) { ptr[0] = '\0'; }
9761 if(host)
9763 char extra[cs_strlen(host) + 20];
9764 snprintf(extra, sizeof(extra), "Location: https://%s", host);
9765 send_error(f, 301, "Moved Permanently", extra, "This web server is running in SSL mode.", 1);
9767 else
9768 { send_error(f, 200, "Bad Request", NULL, "This web server is running in SSL mode.", 1); }
9769 fflush(f);
9770 fclose(f);
9771 NULLFREE(filebuf);
9773 else
9775 cs_log_dbg(D_TRACE, "WebIf: fdopen(%d) failed. (errno=%d %s)", s, errno, strerror(errno));
9779 else { cs_log("WebIf: Error calling SSL_set_fd()."); }
9780 SSL_shutdown(ssl);
9781 close(s);
9782 SSL_free(ssl);
9784 else
9785 #endif
9787 FILE *f;
9788 f = fdopen(s, "r+");
9789 if(f != NULL)
9791 process_request(f, in);
9792 fflush(f);
9793 fclose(f);
9795 else
9797 cs_log_dbg(D_TRACE, "WebIf: fdopen(%d) failed. (errno=%d %s)", s, errno, strerror(errno));
9799 shutdown(s, SHUT_WR);
9800 close(s);
9803 return NULL;
9806 /* Creates a random string with specified length. Note that dst must be one larger than size to hold the trailing \0*/
9807 static void create_rand_str(char *dst, int32_t size)
9809 int32_t i;
9810 for(i = 0; i < size; ++i)
9812 dst[i] = (rand() % 94) + 32;
9814 dst[i] = '\0';
9817 static void *http_server(void *UNUSED(d))
9819 struct s_client *cl = create_client(first_client->ip);
9820 if(cl == NULL) { return NULL; }
9821 SAFE_SETSPECIFIC(getclient, cl);
9822 cl->typ = 'h';
9823 int32_t s, reuse = 1;
9824 struct s_connection *conn;
9826 set_thread_name(__func__);
9828 /* Create random string for nonce value generation */
9829 create_rand_str(noncekey, 32);
9831 /* Prepare base64 decoding array */
9832 b64prepare();
9833 webif_tpls_prepare();
9835 tpl_checkDiskRevisions();
9837 cs_lock_create(__func__, &http_lock, "http_lock", 10000);
9838 init_noncelocks();
9840 memset(&p_stat_cur, 0x0, sizeof(p_stat_cur));
9842 if(pthread_key_create(&getip, NULL))
9844 cs_log("Could not create getip");
9845 return NULL;
9847 if(pthread_key_create(&getkeepalive, NULL))
9849 cs_log("Could not create getkeepalive");
9850 return NULL;
9853 struct SOCKADDR sin;
9854 socklen_t len = 0;
9855 memset(&sin, 0, sizeof(sin));
9857 bool do_ipv6 = config_enabled(IPV6SUPPORT);
9858 #ifdef IPV6SUPPORT
9859 if(do_ipv6)
9861 len = sizeof(struct sockaddr_in6);
9862 if((sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0)
9864 cs_log("HTTP Server: ERROR: Creating IPv6 socket failed! (errno=%d %s)", errno, strerror(errno));
9865 cs_log("HTTP Server: Falling back to IPv4.");
9866 do_ipv6 = false;
9868 else
9870 struct sockaddr_in6 *ia = (struct sockaddr_in6 *)&sin;
9871 ia->sin6_family = AF_INET6;
9872 ia->sin6_addr = in6addr_any;
9873 ia->sin6_port = htons(cfg.http_port);
9876 #endif
9877 if(!do_ipv6)
9879 len = sizeof(struct sockaddr_in);
9880 if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
9882 cs_log("HTTP Server: ERROR: Creating socket failed! (errno=%d %s)", errno, strerror(errno));
9883 return NULL;
9885 SIN_GET_FAMILY(sin) = AF_INET;
9886 if(IP_ISSET(cfg.http_srvip))
9887 { IP_ASSIGN(SIN_GET_ADDR(sin), cfg.http_srvip); }
9888 else if(IP_ISSET(cfg.srvip))
9889 { IP_ASSIGN(SIN_GET_ADDR(sin), cfg.srvip); }
9890 // The default is INADDR_ANY (0)
9891 SIN_GET_PORT(sin) = htons(cfg.http_port);
9894 if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
9896 cs_log("HTTP Server: Setting SO_REUSEADDR via setsockopt failed! (errno=%d %s)", errno, strerror(errno));
9899 if(bind(sock, (struct sockaddr *)&sin, len) < 0)
9901 cs_log("HTTP Server couldn't bind on port %d (errno=%d %s). Not starting HTTP!", cfg.http_port, errno, strerror(errno));
9902 close(sock);
9903 return NULL;
9906 if(listen(sock, SOMAXCONN) < 0)
9908 cs_log("HTTP Server: Call to listen() failed! (errno=%d %s)", errno, strerror(errno));
9909 close(sock);
9910 return NULL;
9913 #ifdef WITH_SSL
9914 if(pthread_key_create(&getssl, NULL))
9916 cs_log("Could not create getssl");
9919 SSL_CTX *ctx = NULL;
9920 if(cfg.http_use_ssl)
9922 ctx = SSL_Webif_Init();
9923 if(ctx == NULL)
9924 { cs_log("SSL could not be initialized. Starting WebIf in plain mode."); }
9925 else { ssl_active = 1; }
9927 else { ssl_active = 0; }
9928 cs_log("HTTP Server running. ip=%s port=%d%s", cs_inet_ntoa(SIN_GET_ADDR(sin)), cfg.http_port, ssl_active ? " (SSL)" : "");
9929 #else
9930 cs_log("HTTP Server running. ip=%s port=%d", cs_inet_ntoa(SIN_GET_ADDR(sin)), cfg.http_port);
9931 #endif
9933 struct SOCKADDR remote;
9934 memset(&remote, 0, sizeof(remote));
9936 while(!exit_oscam)
9938 if((s = accept(sock, (struct sockaddr *) &remote, &len)) < 0)
9940 if(exit_oscam)
9941 { break; }
9942 if(errno != EAGAIN && errno != EINTR)
9944 cs_log("HTTP Server: Error calling accept() (errno=%d %s)", errno, strerror(errno));
9945 cs_sleepms(100);
9947 else { cs_sleepms(5); }
9948 continue;
9950 else
9952 getpeername(s, (struct sockaddr *) &remote, &len);
9953 if(!cs_malloc(&conn, sizeof(struct s_connection)))
9955 close(s);
9956 continue;
9958 setTCPTimeouts(s);
9959 cur_client()->last = time((time_t *)0); //reset last busy time
9960 conn->cl = cur_client();
9961 #ifdef IPV6SUPPORT
9962 if(do_ipv6)
9964 struct sockaddr_in6 *ra = (struct sockaddr_in6 *)&remote;
9965 memcpy(&conn->remote, &ra->sin6_addr, sizeof(struct in6_addr));
9967 else
9969 struct sockaddr_in *fba = (struct sockaddr_in *)&remote;
9970 struct in6_addr taddr;
9971 memset(&taddr, 0, sizeof(taddr));
9972 taddr.s6_addr32[3] = fba->sin_addr.s_addr;
9973 memcpy(&conn->remote, &taddr, sizeof(struct in6_addr));
9975 #else
9976 memcpy(&conn->remote, &remote.sin_addr, sizeof(struct in_addr));
9977 #endif
9978 conn->socket = s;
9979 #ifdef WITH_SSL
9980 conn->ssl = NULL;
9981 if(ssl_active)
9983 conn->ssl = SSL_new(ctx);
9984 if(conn->ssl == NULL)
9986 close(s);
9987 cs_log("WebIf: Error calling SSL_new().");
9988 continue;
9991 #endif
9993 int32_t ret = start_thread("webif workthread", serve_process, (void *)conn, NULL, 1, 1);
9994 if(ret)
9996 NULLFREE(conn);
10000 // Wait a bit so that we don't close ressources while http threads are active
10001 cs_sleepms(300);
10002 #ifdef WITH_SSL
10003 SSL_CTX_free(ctx);
10004 CRYPTO_set_dynlock_create_callback(NULL);
10005 CRYPTO_set_dynlock_lock_callback(NULL);
10006 CRYPTO_set_dynlock_destroy_callback(NULL);
10007 CRYPTO_set_locking_callback(NULL);
10008 CRYPTO_set_id_callback(NULL);
10009 OPENSSL_free(lock_cs);
10010 lock_cs = NULL;
10011 #endif
10012 cs_log("HTTP Server stopped");
10013 free_client(cl);
10014 close(sock);
10015 return NULL;
10018 void webif_client_reset_lastresponsetime(struct s_client * cl)
10020 int32_t i;
10021 for(i = 0; i < CS_ECM_RINGBUFFER_MAX; i++)
10023 cl->cwlastresptimes[i].duration = 0;
10024 cl->cwlastresptimes[i].timestamp = time((time_t *)0);
10025 cl->cwlastresptimes[i].rc = 0;
10027 cl->cwlastresptimes_last = 0;
10030 void webif_client_add_lastresponsetime(struct s_client * cl, int32_t ltime, time_t timestamp, int32_t rc)
10032 int32_t last = cl->cwlastresptimes_last = (cl->cwlastresptimes_last + 1) & (CS_ECM_RINGBUFFER_MAX - 1);
10033 cl->cwlastresptimes[last].duration = ltime > 9999 ? 9999 : ltime;
10034 cl->cwlastresptimes[last].timestamp = timestamp;
10035 cl->cwlastresptimes[last].rc = rc;
10038 void webif_client_init_lastreader(struct s_client * client, ECM_REQUEST * er, struct s_reader * er_reader, const char *stxt[])
10040 if(er_reader)
10042 if(er->rc == E_FOUND)
10043 { cs_strncpy(client->lastreader, er_reader->label, sizeof(client->lastreader)); }
10044 else if(er->rc == E_CACHEEX)
10045 { cs_strncpy(client->lastreader, "cache3", sizeof(client->lastreader)); }
10046 else if(er->rc < E_NOTFOUND)
10047 { snprintf(client->lastreader, sizeof(client->lastreader) - 1, "%.54s (cache)", er_reader->label); }
10048 else
10049 { cs_strncpy(client->lastreader, stxt[er->rc], sizeof(client->lastreader)); }
10051 else
10053 cs_strncpy(client->lastreader, stxt[er->rc], sizeof(client->lastreader));
10057 void webif_init(void)
10059 char buf[8], fname[256];
10060 snprintf(buf, 8, "%'d", 7);
10061 if(strcmp(buf, "7"))
10063 useLocal = 0;
10066 if(cfg.http_port == 0)
10068 cs_log("http disabled");
10069 return;
10072 get_config_filename(fname, sizeof(fname), "oscam.srvid2");
10073 use_srvid2 = file_exists(fname);
10075 if(start_thread("http", http_server, NULL, &httpthread, 0, 1) == 0)
10077 httpthread_running = 1;
10081 void webif_close(void)
10083 if(!sock)
10084 { return; }
10086 shutdown(sock, 2);
10087 close(sock);
10089 if(httpthread_running)
10090 { SAFE_THREAD_JOIN(httpthread, NULL); }
10093 #endif