- Add support of ORF P4 Irdeto mode
[oscam.git] / module-webif.c
blobc8a3055029835abfe863a6f593d2588b38cd53f5
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"
34 extern const struct s_cardreader *cardreaders[];
35 extern char cs_confdir[];
36 extern uint32_t ecmcwcache_size;
37 extern uint8_t cs_http_use_utf8;
38 extern uint32_t cfg_sidtab_generation;
39 extern int32_t exit_oscam;
40 extern uint8_t cacheex_peer_id[8];
42 extern char *entitlement_type[];
43 extern char *RDR_CD_TXT[];
45 int32_t ssl_active = 0;
46 char noncekey[33];
47 pthread_key_t getkeepalive;
48 static pthread_key_t getip;
49 pthread_key_t getssl;
50 static CS_MUTEX_LOCK http_lock;
51 CS_MUTEX_LOCK *lock_cs;
53 static uint8_t useLocal = 1;
54 #define PRINTF_LOCAL_D useLocal ? "%'d" : "%d"
55 #define PRINTF_LOCAL_F useLocal ? "%'.0f" : "%.0f"
56 #define PRINTF_LOCAL_MB useLocal ? "%'.2f MB" : "%.2f MB"
58 static int8_t httpthread_running = 0;
59 static pthread_t httpthread;
60 static int32_t sock;
61 enum refreshtypes { REFR_ACCOUNTS, REFR_READERS, REFR_CLIENTS, REFR_SERVER, REFR_ANTICASC, REFR_SERVICES };
63 //initialize structs for calculating cpu-usage depending on time between refresh of status_page
64 static struct pstat p_stat_cur;
65 static struct pstat p_stat_old;
67 static bool use_srvid2 = false;
69 /* constants for menuactivating */
70 #define MNU_STATUS 0
71 #define MNU_LIVELOG 1
72 #define MNU_CONFIG 2
73 #define MNU_READERS 3
74 #define MNU_USERS 4
75 #define MNU_SERVICES 5
76 #define MNU_FILES 6
77 #define MNU_FAILBAN 7
78 #define MNU_CACHEEX 8
79 #define MNU_SCRIPT 9
80 #define MNU_SHUTDOWN 10
81 #define MNU_TOTAL_ITEMS 11 // sum of items above
83 /* constants for config.html submenuactivating */
84 #define MNU_CFG_GLOBAL 0
85 #define MNU_CFG_ANTICASC 1
86 #define MNU_CFG_CACHE 2
87 #define MNU_CFG_LOADBAL 3
88 #define MNU_CFG_CAMD33 4
89 #define MNU_CFG_CAMD35 5
90 #define MNU_CFG_CAMD35TCP 6
91 #define MNU_CFG_CCCAM 7
92 #define MNU_CFG_NEWCAMD 8
93 #define MNU_CFG_GBOX 9
94 #define MNU_CFG_RADEGAST 10
95 #define MNU_CFG_SCAM 11
96 #define MNU_CFG_SERIAL 12
97 #define MNU_CFG_DVBAPI 13
98 #define MNU_CFG_LCD 14
99 #define MNU_CFG_MONITOR 15
100 #define MNU_CFG_WEBIF 16
102 /* constants for files.html submenuactivating */
103 #define MNU_CFG_FVERSION 0
104 #define MNU_CFG_FCONF 1
105 #define MNU_CFG_FUSER 2
106 #define MNU_CFG_FSERVER 3
107 #define MNU_CFG_FSRVID 4
108 #define MNU_CFG_FDVBAPI 5
109 #define MNU_CFG_FACLOG 6
110 #define MNU_CFG_FLOGFILE 7
111 #define MNU_CFG_FUSERFILE 8
112 #define MNU_CFG_FSERVICES 9
113 #define MNU_CFG_FPROVID 10
114 #define MNU_CFG_FTIERS 11
115 #define MNU_CFG_FRATELIMIT 12
116 #define MNU_CFG_FWHITELIST 13
117 #define MNU_CFG_FSRVID2 14
118 #define MNU_CFG_FFAKECWS 15
119 #define MNU_CFG_FCSS 16
120 #define MNU_CFG_FTWIN 17
121 #define MNU_CFG_FKEYCW 18
123 #define MNU_CFG_TOTAL_ITEMS 19 // sum of items above. Use it for "All inactive" in function calls too.
125 static void set_status_info_var(struct templatevars *vars, char *varname, int no_data, char *fmt, double value) {
126 if (no_data)
127 tpl_addVar(vars, TPLADD, varname, "N/A");
128 else
129 tpl_printf(vars, TPLADD, varname, fmt, value);
133 * Creates vars Memory/CPU/OSCAM info in for status_page
134 * if check_available == 0 N/A will be displayed
135 * Bit mapping
136 * mem 0 total, 1 used & free, 2 buff, cached & free incl. buff, 3 share
137 * swap 4 total, 5 used & free,
138 * proc 6 count
139 * cpu 7 load
140 * oscam 8 vsize & rssize, 9 cpu user, 10 cpu sys, 11 cpu sum, 12 cpu refreshtime
141 * unused 13 - 15
143 static void set_status_info(struct templatevars *vars, struct pstat stats){
144 set_status_info_var(vars, "MEM_CUR_TOTAL", stats.check_available & (1 << 0), PRINTF_LOCAL_MB , (double)stats.mem_total/(1024.0*1024.0));
145 set_status_info_var(vars, "MEM_CUR_FREE", stats.check_available & (1 << 1), PRINTF_LOCAL_MB , (double)stats.mem_free/(1024.0*1024.0));
146 set_status_info_var(vars, "MEM_CUR_USED", stats.check_available & (1 << 1), PRINTF_LOCAL_MB , (double)stats.mem_used/(1024.0*1024.0));
147 set_status_info_var(vars, "MEM_CUR_BUFF", stats.check_available & (1 << 2), PRINTF_LOCAL_MB , (double)stats.mem_buff/(1024.0*1024.0));
148 set_status_info_var(vars, "MEM_CUR_CACHED", stats.check_available & (1 << 2), PRINTF_LOCAL_MB , (double)stats.mem_cached/(1024.0*1024.0));
149 set_status_info_var(vars, "MEM_CUR_FREEM", stats.check_available & (1 << 2), PRINTF_LOCAL_MB , (double)stats.mem_freem/(1024.0*1024.0));
150 set_status_info_var(vars, "MEM_CUR_SHARE", stats.check_available & (1 << 3), PRINTF_LOCAL_MB , (double)stats.mem_share/(1024.0*1024.0));
151 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));
152 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));
153 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));
155 set_status_info_var(vars, "SERVER_PROCS", stats.check_available & (1 << 6), PRINTF_LOCAL_F , stats.info_procs);
157 set_status_info_var(vars, "CPU_LOAD_0", stats.check_available & (1 << 7), "%.2f" , stats.cpu_avg[0]);
158 set_status_info_var(vars, "CPU_LOAD_1", stats.check_available & (1 << 7), "%.2f" , stats.cpu_avg[1]);
159 set_status_info_var(vars, "CPU_LOAD_2", stats.check_available & (1 << 7), "%.2f" , stats.cpu_avg[2]);
161 set_status_info_var(vars, "OSCAM_VMSIZE", stats.check_available & (1 << 8), PRINTF_LOCAL_MB , (double)stats.vsize/(1024.0*1024.0));
162 set_status_info_var(vars, "OSCAM_RSSSIZE", stats.check_available & (1 << 8), PRINTF_LOCAL_MB , (double)stats.rss/(1024.0*1024.0));
163 set_status_info_var(vars, "OSCAM_CPU_USER", stats.check_available & (1 << 9), "%.2f %%" , stats.cpu_usage_user);
164 set_status_info_var(vars, "OSCAM_CPU_SYS", stats.check_available & (1 << 10), "%.2f %%" , stats.cpu_usage_sys);
165 double sum_cpu = stats.cpu_usage_sys + stats.cpu_usage_user;
166 set_status_info_var(vars, "OSCAM_CPU_SUM", stats.check_available & (1 << 11), "%.2f %%" , sum_cpu);
168 if (stats.check_available & (1 << 12)) {
169 tpl_addVar(vars, TPLADD, "OSCAM_REFRESH" , "N/A");
170 } else {
171 tpl_printf(vars, TPLADD, "OSCAM_REFRESH" , "%02"PRId64":%02"PRId64":%02"PRId64"h",
172 stats.gone_refresh / 3600,
173 (stats.gone_refresh / 60) % 60,
174 stats.gone_refresh % 60);
178 static void clear_account_stats(struct s_auth *account)
180 account->cwfound = 0;
181 account->cwcache = 0;
182 account->cwnot = 0;
183 account->cwtun = 0;
184 account->cwignored = 0;
185 account->cwtout = 0;
186 account->emmok = 0;
187 account->emmnok = 0;
188 #ifdef CW_CYCLE_CHECK
189 account->cwcycledchecked = 0;
190 account->cwcycledok = 0;
191 account->cwcyclednok = 0;
192 account->cwcycledign = 0;
193 #endif
194 cacheex_clear_account_stats(account);
197 static void clear_all_account_stats(void)
199 struct s_auth *account = cfg.account;
200 while(account)
202 clear_account_stats(account);
203 account = account->next;
207 #ifdef CS_CACHEEX
208 static void cacheex_clear_all_stats(void)
210 struct s_auth *account = cfg.account;
211 while(account)
213 cacheex_clear_account_stats(account);
214 account = account->next;
216 struct s_client *cl;
217 for(cl = first_client->next; cl ; cl = cl->next)
219 cacheex_clear_client_stats(cl);
220 ll_clear_data(cl->ll_cacheex_stats);
222 cacheex_clear_client_stats(first_client);
224 #endif
226 static void clear_info_clients_stats(void)
228 first_client->cwfound = 0;
229 first_client->cwcache = 0;
230 first_client->cwnot = 0;
231 first_client->cwtun = 0;
232 first_client->cwignored = 0;
233 first_client->cwtout = 0;
234 first_client->emmok = 0;
235 first_client->emmnok = 0;
236 cacheex_clear_client_stats(first_client);
239 static void clear_info_readers_stats(void)
241 int8_t i;
242 cs_writelock(__func__, &readerlist_lock);
243 LL_ITER itr = ll_iter_create(configured_readers);
244 struct s_reader *rdr;
245 while((rdr = ll_iter_next(&itr)))
247 rdr->webif_ecmsok = 0;
248 rdr->webif_ecmsnok = 0;
249 rdr->webif_ecmstout = 0;
250 rdr->webif_ecmsfilteredhead = 0;
251 rdr->webif_ecmsfilteredlen = 0;
253 for(i = 0; i < 4; i++)
255 rdr->webif_emmerror[i] = 0;
256 rdr->webif_emmwritten[i] = 0;
257 rdr->webif_emmskipped[i] = 0;
258 rdr->webif_emmblocked[i] = 0;
261 cs_writeunlock(__func__, &readerlist_lock);
264 static void set_ecm_info(struct templatevars * vars)
266 //if one of the stats overloaded, reset all stats!
267 if(first_client->cwfound<0
268 || first_client->cwnot<0
269 || first_client->cwignored<0
270 || first_client->cwtout<0
271 || first_client->cwcache<0
272 || first_client->cwtun<0
273 || first_client->emmok<0
274 || first_client->emmnok<0
275 #ifdef CS_CACHEEX
276 || first_client->cwcacheexgot<0
277 || first_client->cwcacheexpush<0
278 || first_client->cwcacheexhit<0
279 #endif
281 clear_info_clients_stats();
283 //end reset stats
285 int ecm = 0, emm = 0;
286 double ecmsum = first_client->cwfound + first_client->cwcache + first_client->cwnot + first_client->cwtout; //dont count TUN its included
287 if(ecmsum < 1) {ecmsum = 1; ecm = 1;}
288 double ecmpos = first_client->cwfound + first_client->cwcache; // dont count TUN its included
289 if(ecmpos < 1) {ecmpos = 1;}
290 double ecmneg = first_client->cwnot + first_client->cwtout; //dont count IGN its not part of neagtiv
291 if(ecmneg < 1) {ecmneg = 1;}
292 double emmsum = first_client->emmok + first_client->emmnok;
293 if(emmsum < 1) {emmsum = 1; emm = 1;}
295 tpl_printf(vars, TPLADD, "TOTAL_ECM_MIN", "%d", first_client->n_request[0]);
296 tpl_printf(vars, TPLADD, "TOTAL_CW", PRINTF_LOCAL_F, !ecm ? ecmsum : 0);
297 tpl_printf(vars, TPLADD, "TOTAL_CWOK", PRINTF_LOCAL_F, (double)first_client->cwfound);
298 tpl_printf(vars, TPLADD, "TOTAL_CWNOK", PRINTF_LOCAL_F, (double)first_client->cwnot);
299 tpl_printf(vars, TPLADD, "TOTAL_CWIGN", PRINTF_LOCAL_F, (double)first_client->cwignored);
300 tpl_printf(vars, TPLADD, "TOTAL_CWTOUT", PRINTF_LOCAL_F, (double)first_client->cwtout);
301 tpl_printf(vars, TPLADD, "TOTAL_CWCACHE", PRINTF_LOCAL_F, (double)first_client->cwcache);
302 tpl_printf(vars, TPLADD, "TOTAL_CWTUN", PRINTF_LOCAL_F, (double)first_client->cwtun);
303 tpl_printf(vars, TPLADD, "TOTAL_CWPOS", PRINTF_LOCAL_F, (double)first_client->cwfound + (double)first_client->cwcache);
304 tpl_printf(vars, TPLADD, "TOTAL_CWNEG", PRINTF_LOCAL_F, (double)first_client->cwnot + (double)first_client->cwtout);
305 tpl_printf(vars, TPLADD, "TOTAL_EM", PRINTF_LOCAL_F, !emm ? emmsum : 0);
306 tpl_printf(vars, TPLADD, "TOTAL_EMOK", PRINTF_LOCAL_F, (double)first_client->emmok);
307 tpl_printf(vars, TPLADD, "TOTAL_EMNOK", PRINTF_LOCAL_F, (double)first_client->emmnok);
308 tpl_printf(vars, TPLADD, "REL_CWOK", "%.2f", (double)first_client->cwfound * 100 / ecmsum);
309 tpl_printf(vars, TPLADD, "REL_CWNOK", "%.2f", (double)first_client->cwnot * 100 / ecmsum);
310 //tpl_printf(vars, TPLADD, "REL_CWIGN", "%.2f", (double)first_client->cwignored * 100 / ecmsum);
311 tpl_printf(vars, TPLADD, "REL_CWTOUT", "%.2f", (double)first_client->cwtout * 100 / ecmsum);
312 tpl_printf(vars, TPLADD, "REL_CWCACHE", "%.2f", (double)first_client->cwcache * 100 / ecmsum);
313 tpl_printf(vars, TPLADD, "REL_CWTUN", "%.2f", (double)first_client->cwtun * 100 / ecmsum);
314 tpl_printf(vars, TPLADD, "REL_CWPOS", "%.2f", (double)(first_client->cwfound + first_client->cwcache) * 100 / ecmsum);
315 tpl_printf(vars, TPLADD, "REL_CWNEG", "%.2f", (double)(first_client->cwnot + first_client->cwtout) * 100 / ecmsum);
316 tpl_printf(vars, TPLADD, "REL_EMOK", "%.2f", (double)first_client->emmok * 100 / emmsum);
317 tpl_printf(vars, TPLADD, "REL_EMNOK", "%.2f", (double)first_client->emmnok * 100 / emmsum);
318 tpl_printf(vars, TPLADD, "REL_CWPOSOK", "%.2f", (double)first_client->cwfound * 100 / ecmpos);
319 tpl_printf(vars, TPLADD, "REL_CWPOSCACHE", "%.2f", (double)first_client->cwcache * 100 / ecmpos);
320 tpl_printf(vars, TPLADD, "REL_CWNEGNOK", "%.2f", (double)first_client->cwnot * 100 / ecmneg);
321 //tpl_printf(vars, TPLADD, "REL_CWNEGIGN", "%.2f", (double)first_client->cwignored * 100 / ecmneg);
322 tpl_printf(vars, TPLADD, "REL_CWNEGTOUT", "%.2f", (double)first_client->cwtout * 100 / ecmneg);
324 double totalrdrneg = 0, totalrdrpos = 0;
325 double totalrdrok = 0, totalrdrnok = 0, totalrdrtout = 0;
326 double flen = 0, fhead = 0;
327 double teruk = 0, terg = 0, ters = 0, teruq = 0;
328 double twruk = 0, twrg = 0, twrs = 0, twruq = 0;
329 double tskuk = 0, tskg = 0, tsks = 0, tskuq = 0;
330 double tbluk = 0, tblg = 0, tbls = 0, tbluq = 0;
332 ecmsum = 0;
333 emmsum = 0;
335 cs_readlock(__func__, &readerlist_lock);
336 LL_ITER itr = ll_iter_create(configured_readers);
337 struct s_reader *rdr;
338 while((rdr = ll_iter_next(&itr)))
340 if (rdr->webif_ecmsok) { totalrdrok += rdr->webif_ecmsok; }
341 if (rdr->webif_ecmsnok) { totalrdrnok += rdr->webif_ecmsnok; }
342 if (rdr->webif_ecmstout) { totalrdrtout += rdr->webif_ecmstout; }
344 if (rdr->webif_ecmsfilteredlen) { flen += rdr->webif_ecmsfilteredlen; }
345 if (rdr->webif_ecmsfilteredhead) { fhead += rdr->webif_ecmsfilteredhead; }
347 if (rdr->webif_emmerror[0]) { teruk += rdr->webif_emmerror[0]; }
348 if (rdr->webif_emmerror[1]) { teruq += rdr->webif_emmerror[1]; }
349 if (rdr->webif_emmerror[2]) { ters += rdr->webif_emmerror[2]; }
350 if (rdr->webif_emmerror[3]) { terg += rdr->webif_emmerror[3]; }
352 if (rdr->webif_emmwritten[0]) { twruk += rdr->webif_emmwritten[0]; }
353 if (rdr->webif_emmwritten[1]) { twruq += rdr->webif_emmwritten[1]; }
354 if (rdr->webif_emmwritten[2]) { twrs += rdr->webif_emmwritten[2]; }
355 if (rdr->webif_emmwritten[3]) { twrg += rdr->webif_emmwritten[3]; }
357 if (rdr->webif_emmskipped[0]) { tskuk += rdr->webif_emmskipped[0]; }
358 if (rdr->webif_emmskipped[1]) { tskuq += rdr->webif_emmskipped[1]; }
359 if (rdr->webif_emmskipped[2]) { tsks += rdr->webif_emmskipped[2]; }
360 if (rdr->webif_emmskipped[3]) { tskg += rdr->webif_emmskipped[3]; }
362 if (rdr->webif_emmblocked[0]) { tbluk += rdr->webif_emmblocked[0]; }
363 if (rdr->webif_emmblocked[1]) { tbluq += rdr->webif_emmblocked[1]; }
364 if (rdr->webif_emmblocked[2]) { tbls += rdr->webif_emmblocked[2]; }
365 if (rdr->webif_emmblocked[3]) { tblg += rdr->webif_emmblocked[3]; }
367 cs_readunlock(__func__, &readerlist_lock);
369 totalrdrneg = totalrdrnok + totalrdrtout;
370 totalrdrpos = totalrdrok;
371 ecmsum = totalrdrok + totalrdrnok + totalrdrtout;
373 tpl_printf(vars, TPLADD, "TOTAL_CWOK_READERS", PRINTF_LOCAL_F, totalrdrok);
374 tpl_printf(vars, TPLADD, "TOTAL_CWNOK_READERS", PRINTF_LOCAL_F, totalrdrnok);
375 tpl_printf(vars, TPLADD, "TOTAL_CWTOUT_READERS", PRINTF_LOCAL_F, totalrdrtout);
376 tpl_printf(vars, TPLADD, "REL_CWOK_READERS", "%.2f", totalrdrok * 100 / ecmsum);
377 tpl_printf(vars, TPLADD, "REL_CWNOK_READERS", "%.2f", totalrdrnok * 100 / ecmsum);
378 tpl_printf(vars, TPLADD, "REL_CWTOUT_READERS", "%.2f", totalrdrtout * 100 / ecmsum);
379 tpl_printf(vars, TPLADD, "TOTAL_CWPOS_READERS", PRINTF_LOCAL_F, totalrdrpos);
380 tpl_printf(vars, TPLADD, "TOTAL_CWNEG_READERS", PRINTF_LOCAL_F, totalrdrneg);
381 tpl_printf(vars, TPLADD, "REL_CWPOS_READERS", "%.2f", totalrdrpos * 100 / ecmsum);
382 tpl_printf(vars, TPLADD, "REL_CWNEG_READERS", "%.2f", totalrdrneg * 100 / ecmsum);
383 tpl_printf(vars, TPLADD, "TOTAL_ELENR", PRINTF_LOCAL_F, flen);
384 tpl_printf(vars, TPLADD, "TOTAL_EHEADR", PRINTF_LOCAL_F, fhead);
385 tpl_printf(vars, TPLADD, "TOTAL_SUM_ALL_READERS_ECM", PRINTF_LOCAL_F, ecmsum);
387 tpl_printf(vars, TPLADD, "TOTAL_EMMERRORUK_READERS", PRINTF_LOCAL_F, teruk);
388 tpl_printf(vars, TPLADD, "TOTAL_EMMERRORG_READERS", PRINTF_LOCAL_F, terg);
389 tpl_printf(vars, TPLADD, "TOTAL_EMMERRORS_READERS", PRINTF_LOCAL_F, ters);
390 tpl_printf(vars, TPLADD, "TOTAL_EMMERRORUQ_READERS", PRINTF_LOCAL_F, teruq);
391 tpl_printf(vars, TPLADD, "TOTAL_EMMWRITTENUK_READERS", PRINTF_LOCAL_F, twruk);
392 tpl_printf(vars, TPLADD, "TOTAL_EMMWRITTENG_READERS", PRINTF_LOCAL_F, twrg);
393 tpl_printf(vars, TPLADD, "TOTAL_EMMWRITTENS_READERS", PRINTF_LOCAL_F, twrs);
394 tpl_printf(vars, TPLADD, "TOTAL_EMMWRITTENUQ_READERS", PRINTF_LOCAL_F, twruq);
395 tpl_printf(vars, TPLADD, "TOTAL_EMMSKIPPEDUK_READERS", PRINTF_LOCAL_F, tskuk);
396 tpl_printf(vars, TPLADD, "TOTAL_EMMSKIPPEDG_READERS", PRINTF_LOCAL_F, tskg);
397 tpl_printf(vars, TPLADD, "TOTAL_EMMSKIPPEDS_READERS", PRINTF_LOCAL_F, tsks);
398 tpl_printf(vars, TPLADD, "TOTAL_EMMSKIPPEDUQ_READERS", PRINTF_LOCAL_F, tskuq);
399 tpl_printf(vars, TPLADD, "TOTAL_EMMBLOCKEDUK_READERS", PRINTF_LOCAL_F, tbluk);
400 tpl_printf(vars, TPLADD, "TOTAL_EMMBLOCKEDG_READERS", PRINTF_LOCAL_F, tblg);
401 tpl_printf(vars, TPLADD, "TOTAL_EMMBLOCKEDS_READERS", PRINTF_LOCAL_F, tbls);
402 tpl_printf(vars, TPLADD, "TOTAL_EMMBLOCKEDUQ_READERS", PRINTF_LOCAL_F, tbluq);
404 emmsum = teruk + terg + ters + teruq + twruk + twrg + twrs + twruq + tskuk + tskg + tsks + tskuq + tbluk + tblg + tbls + tbluq;
406 tpl_printf(vars, TPLADD, "TOTAL_SUM_ALL_READERS_EMM", PRINTF_LOCAL_F, emmsum);
409 static void refresh_oscam(enum refreshtypes refreshtype)
412 switch(refreshtype)
414 case REFR_ACCOUNTS:
415 cs_log("Refresh Accounts requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
416 cs_accounts_chk();
417 break;
419 case REFR_READERS:
420 cs_log("Refresh Readers requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
421 reload_readerdb();
422 break;
424 case REFR_CLIENTS:
425 cs_log("Refresh Clients requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
426 cs_reinit_clients(cfg.account);
427 break;
429 case REFR_SERVER:
430 cs_log("Refresh Server requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
431 //kill(first_client->pid, SIGHUP);
432 //todo how I can refresh the server after global settings
433 break;
435 case REFR_SERVICES:
436 cs_log("Refresh Services requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
437 //init_sidtab();
438 cs_accounts_chk();
439 break;
441 #ifdef CS_ANTICASC
442 case REFR_ANTICASC:
443 cs_log("Refresh Anticascading requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
444 ac_init_stat();
445 struct s_client *cl;
446 struct s_auth *account;
447 for(cl = first_client->next; cl ; cl = cl->next)
449 if(cl->typ == 'c' && (account = cl->account))
451 cl->ac_limit = (account->ac_users * 100 + 80) * cfg.ac_stime;
454 break;
455 #endif
456 default:
457 break;
461 * load historical values from ringbuffer and return it in the right order
462 * as string. Value should be freed with free_mk_t()
464 static char *get_ecm_historystring(struct s_client *cl)
467 if(cl)
469 int32_t k, i, pos = 0, needed = 1, v;
470 char *value, *dot = "";
471 int32_t ptr = cl->cwlastresptimes_last;
473 needed = CS_ECM_RINGBUFFER_MAX * 6; //5 digits + delimiter
474 if(!cs_malloc(&value, needed)) { return ""; }
476 k = ptr + 1;
477 for(i = 0; i < CS_ECM_RINGBUFFER_MAX; i++)
479 if(k >= CS_ECM_RINGBUFFER_MAX)
480 { k = 0; }
481 v = cl->cwlastresptimes[k].duration;
482 if(v > 0 && v < (int32_t)cfg.ctimeout * 5)
484 pos += snprintf(value + pos, needed - pos, "%s%d", dot, v);
485 dot = ",";
487 k++;
489 if(strlen(value) == 0)
491 NULLFREE(value);
492 return "";
494 else { return value; }
497 else
499 return "";
503 static char *get_ecm_fullhistorystring(struct s_client *cl)
506 if(cl)
508 int32_t k, i, pos = 0, needed = 1, v;
509 char *value, *dot = "";
510 int32_t ptr = cl->cwlastresptimes_last;
512 needed = CS_ECM_RINGBUFFER_MAX * 20; //5 digits + : + returncode(2) + : + time(10) + delimiter
513 if(!cs_malloc(&value, needed)) { return ""; }
515 k = ptr + 1;
516 for(i = 0; i < CS_ECM_RINGBUFFER_MAX; i++)
518 if(k >= CS_ECM_RINGBUFFER_MAX)
519 { k = 0; }
520 v = cl->cwlastresptimes[k].duration;
521 if(v > 0 && v < (int32_t)cfg.ctimeout * 5)
523 pos += snprintf(value + pos, needed - pos, "%s%d:%d:%ld", dot, cl->cwlastresptimes[k].duration, cl->cwlastresptimes[k].rc, cl->cwlastresptimes[k].timestamp);
524 dot = ",";
526 k++;
529 return (value);
532 else
534 return "";
539 * Set the active menu to a different CSS class
541 static void setActiveMenu(struct templatevars *vars, int8_t active)
543 int8_t i;
544 for(i = 0; i < MNU_TOTAL_ITEMS; i++)
546 tpl_printf(vars, TPLADD, "TMP", "MENUACTIVE%d", i);
547 if(i == active)
548 { tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "menu_selected"); }
549 else
550 { tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "menu"); }
552 #ifdef WEBIF_LIVELOG
553 tpl_addVar(vars, TPLADD, "LOGPAGEMENU", tpl_getTpl(vars, "LOGMENU"));
554 #endif
558 * Set the active submenu to a different CSS class
560 static void setActiveSubMenu(struct templatevars *vars, int8_t active)
562 int8_t i;
563 for(i = 0; i < MNU_CFG_TOTAL_ITEMS; i++)
565 tpl_printf(vars, TPLADD, "TMP", "CMENUACTIVE%d", i);
566 if(i == active)
567 { tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "configmenu_selected"); }
568 else
569 { tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "configmenu"); }
573 static void webif_save_config(char *section, struct templatevars *vars, struct uriparams *params)
575 if(!streq(getParam(params, "action"), "execute"))
576 { return; }
577 if(cfg.http_readonly)
579 tpl_addMsg(vars, "WebIf is in readonly mode. No changes are possible!");
580 return;
582 int i;
583 int cnt = (*params).paramcount;
584 for(i = 0; i < cnt; i++)
586 char *token = (*params).params[i];
587 char *value = (*params).values[i];
588 if(!streq(token, "part") && !streq(token, "action"))
589 { config_set(section, token, value); }
591 if(write_config() == 0)
593 tpl_addMsg(vars, "Configuration was saved.");
594 enum refreshtypes ref_type = REFR_SERVER;
595 if(streq(getParam(params, "part"), "anticasc"))
596 { ref_type = REFR_ANTICASC; }
597 refresh_oscam(ref_type);
599 else
601 tpl_addMsg(vars, "ERROR: Failed to write config file!!!");
605 static char *send_oscam_config_global(struct templatevars *vars, struct uriparams *params)
607 setActiveSubMenu(vars, MNU_CFG_GLOBAL);
609 webif_save_config("global", vars, params);
611 if(IP_ISSET(cfg.srvip))
612 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.srvip)); }
613 tpl_printf(vars, TPLADD, "NICE", "%d", cfg.nice);
614 tpl_printf(vars, TPLADD, "BINDWAIT", "%d", cfg.bindwait);
615 tpl_printf(vars, TPLADD, "NETPRIO", "%d", cfg.netprio);
616 tpl_printf(vars, TPLADD, "PIDFILE", "%s", ESTR(cfg.pidfile));
619 if(cfg.usrfile != NULL) { tpl_addVar(vars, TPLADD, "USERFILE", cfg.usrfile); }
620 if(cfg.disableuserfile == 0) { tpl_addVar(vars, TPLADD, "DISABLEUSERFILECHECKED", "checked"); }
621 if(cfg.usrfileflag == 1) { tpl_addVar(vars, TPLADD, "USERFILEFLAGCHECKED", "selected"); }
622 if(cfg.mailfile != NULL) { tpl_addVar(vars, TPLADD, "MAILFILE", cfg.mailfile); }
623 if(cfg.disablemail == 0) { tpl_addVar(vars, TPLADD, "DISABLEMAILCHECKED", "checked"); }
625 char *value = mk_t_logfile();
626 tpl_addVar(vars, TPLADD, "LOGFILE", value);
627 free_mk_t(value);
628 if(cfg.disablelog == 0) { tpl_addVar(vars, TPLADD, "DISABLELOGCHECKED", "checked"); }
629 tpl_printf(vars, TPLADD, "MAXLOGSIZE", "%d", cfg.max_log_size);
631 tpl_addVar(vars, TPLADD, "LOGDUPSCHECKED", (cfg.logduplicatelines == 1) ? "checked" : "");
632 tpl_printf(vars, TPLADD, "INITIALDEBUGLEVEL", "%u", cfg.initial_debuglevel);
634 if(cfg.cwlogdir != NULL) { tpl_addVar(vars, TPLADD, "CWLOGDIR", cfg.cwlogdir); }
635 if(cfg.emmlogdir != NULL) { tpl_addVar(vars, TPLADD, "EMMLOGDIR", cfg.emmlogdir); }
636 tpl_addVar(vars, TPLADD, "ECMFMT", cfg.ecmfmt);
637 tpl_printf(vars, TPLADD, "LOGHISTORYLINES", "%u", cfg.loghistorylines);
638 if(cfg.sysloghost != NULL) { tpl_addVar(vars, TPLADD, "SYSLOGHOST", cfg.sysloghost); }
639 tpl_printf(vars, TPLADD, "SYSLOGPORT", "%u", cfg.syslogport);
642 tpl_printf(vars, TPLADD, "CLIENTTIMEOUT", "%u", cfg.ctimeout);
643 tpl_printf(vars, TPLADD, "FALLBACKTIMEOUT", "%u", cfg.ftimeout);
644 tpl_printf(vars, TPLADD, "CLIENTMAXIDLE", "%u", cfg.cmaxidle);
647 value = mk_t_caidvaluetab(&cfg.ftimeouttab);
648 tpl_addVar(vars, TPLADD, "FALLBACKTIMEOUT_PERCAID", value);
649 free_mk_t(value);
651 tpl_printf(vars, TPLADD, "SLEEP", "%d", cfg.tosleep);
652 tpl_addVar(vars, TPLADD, "UNLOCKPARENTALCHECKED", (cfg.ulparent == 1) ? "checked" : "");
654 if(cfg.reload_useraccounts) { tpl_addVar(vars, TPLADD, "RELOADUSERACCOUNTSCHECKED", "checked"); }
655 if(cfg.reload_readers) { tpl_addVar(vars, TPLADD, "RELOADREADERSCHECKED", "checked"); }
656 if(cfg.reload_provid) { tpl_addVar(vars, TPLADD, "RELOADPROVIDCHECKED", "checked"); }
657 if(cfg.reload_services_ids) { tpl_addVar(vars, TPLADD, "RELOADSERVICESIDSCHECKED", "checked"); }
658 if(cfg.reload_tier_ids) { tpl_addVar(vars, TPLADD, "RELOADTIERUDSCHECKED", "checked"); }
659 if(cfg.reload_fakecws) { tpl_addVar(vars, TPLADD, "RELOADFAKECWSCHECKED", "checked"); }
660 if(cfg.reload_ac_stat) { tpl_addVar(vars, TPLADD, "RELOADACSTATCHECKED", "checked"); }
661 if(cfg.reload_log) { tpl_addVar(vars, TPLADD, "RELOADLOGCHECKED", "checked"); }
663 if(cfg.block_same_ip) { tpl_addVar(vars, TPLADD, "BLOCKSAMEIPCHECKED", "checked"); }
664 if(cfg.block_same_name) { tpl_addVar(vars, TPLADD, "BLOCKSAMENAMECHECKED", "checked"); }
666 if(cfg.waitforcards == 1) { tpl_addVar(vars, TPLADD, "WAITFORCARDSCHECKED", "checked"); }
667 tpl_printf(vars, TPLADD, "EXTRADELAY", "%d", cfg.waitforcards_extra_delay);
668 if(cfg.preferlocalcards == 1)
670 tpl_addVar(vars, TPLADD, "PREFERCACHEEX", "selected");
672 else if(cfg.preferlocalcards == 2)
674 tpl_addVar(vars, TPLADD, "PREFERLOCALCARDS", "selected");
677 if(cfg.c35_suppresscmd08)
678 { tpl_addVar(vars, TPLADD, "SUPPRESSCMD08", "checked"); }
680 if(cfg.getblockemmauprovid > 0)
682 tpl_addVar(vars, TPLADD, "GETBLOCKEMMAUPROVID", "checked");
685 if(cfg.reader_restart_seconds)
686 { tpl_printf(vars, TPLADD, "READERRESTARTSECONDS", "%d", cfg.reader_restart_seconds); }
688 tpl_addVar(vars, TPLADD, "DROPDUPSCHECKED", (cfg.dropdups == 1) ? "checked" : "");
690 if(cfg.resolve_gethostbyname == 1)
691 { tpl_addVar(vars, TPLADD, "RESOLVER1", "selected"); }
692 else
693 { tpl_addVar(vars, TPLADD, "RESOLVER0", "selected"); }
695 tpl_printf(vars, TPLADD, "FAILBANTIME", "%d", cfg.failbantime);
696 tpl_printf(vars, TPLADD, "FAILBANCOUNT", "%d", cfg.failbancount);
698 tpl_addVar(vars, TPLADD, "DCHECKCSELECTED", (cfg.double_check == 1) ? "checked" : "");
700 value = mk_t_caidtab(&cfg.double_check_caid);
701 tpl_addVar(vars, TPLADD, "DOUBLECHECKCAID", value);
702 free_mk_t(value);
704 #ifdef LEDSUPPORT
705 if(cfg.enableled == 1)
706 { tpl_addVar(vars, TPLADD, "ENABLELEDSELECTED1", "selected"); }
707 else if(cfg.enableled == 2)
708 { tpl_addVar(vars, TPLADD, "ENABLELEDSELECTED2", "selected"); }
709 #endif
711 return tpl_getTpl(vars, "CONFIGGLOBAL");
714 #ifdef WITH_LB
715 static char *send_oscam_config_loadbalancer(struct templatevars *vars, struct uriparams *params)
717 setActiveSubMenu(vars, MNU_CFG_LOADBAL);
719 if(strlen(getParam(params, "button")) > 0)
721 if(cfg.http_readonly)
723 tpl_addMsg(vars, "WebIf is in readonly mode. No changes are possible!");
725 else
727 if(strcmp(getParam(params, "button"), "Load Stats") == 0)
729 clear_all_stat();
730 load_stat_from_file();
731 tpl_addMsg(vars, "Stats loaded from file");
734 if(strcmp(getParam(params, "button"), "Save Stats") == 0)
736 save_stat_to_file(1);
737 tpl_addMsg(vars, "Stats saved to file");
740 if(strcmp(getParam(params, "button"), "Clear Stats") == 0)
742 clear_all_stat();
743 tpl_addMsg(vars, "Stats cleared completly");
746 if(strcmp(getParam(params, "button"), "Clear Timeouts") == 0)
748 clean_all_stats_by_rc(E_TIMEOUT, 0);
749 tpl_addMsg(vars, "Timeout cleared from Stats");
752 if(strcmp(getParam(params, "button"), "Clear Not Found") == 0)
754 clean_all_stats_by_rc(E_NOTFOUND, 0);
755 tpl_addMsg(vars, "Not Found cleared from Stats");
758 if(strcmp(getParam(params, "button"), "Clear Invalid") == 0)
760 clean_all_stats_by_rc(E_INVALID, 0);
761 tpl_addMsg(vars, "Invalid cleared from Stats");
766 webif_save_config("global", vars, params);
768 tpl_printf(vars, TPLADD, "TMP", "LBMODE%d", cfg.lb_mode);
769 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
771 tpl_printf(vars, TPLADD, "LBSAVE", "%d", cfg.lb_save);
772 if(cfg.lb_savepath) { tpl_addVar(vars, TPLADD, "LBSAVEPATH", cfg.lb_savepath); }
774 tpl_printf(vars, TPLADD, "LBNBESTREADERS", "%d", cfg.lb_nbest_readers);
775 char *value = mk_t_caidvaluetab(&cfg.lb_nbest_readers_tab);
776 tpl_addVar(vars, TPLADD, "LBNBESTPERCAID", value);
777 free_mk_t(value);
778 tpl_printf(vars, TPLADD, "LBNFBREADERS", "%d", cfg.lb_nfb_readers);
779 tpl_printf(vars, TPLADD, "LBMAXREADERS", "%d", cfg.lb_max_readers);
780 tpl_printf(vars, TPLADD, "LBMINECMCOUNT", "%d", cfg.lb_min_ecmcount);
781 tpl_printf(vars, TPLADD, "LBMAXECEMCOUNT", "%d", cfg.lb_max_ecmcount);
782 tpl_printf(vars, TPLADD, "LBRETRYLIMIT", "%d", cfg.lb_retrylimit);
784 value = mk_t_caidvaluetab(&cfg.lb_retrylimittab);
785 tpl_addVar(vars, TPLADD, "LBRETRYLIMITS", value);
786 free_mk_t(value);
788 tpl_printf(vars, TPLADD, "LBREOPENSECONDS", "%d", cfg.lb_reopen_seconds);
789 tpl_printf(vars, TPLADD, "LBCLEANUP", "%d", cfg.lb_stat_cleanup);
791 tpl_addVar(vars, TPLADD, "LBREOPENINVALID", (cfg.lb_reopen_invalid == 1) ? "checked" : "");
792 tpl_addVar(vars, TPLADD, "LBFORCEALWAYS", (cfg.lb_force_reopen_always == 1) ? "checked" : "");
794 value = mk_t_caidtab(&cfg.lb_noproviderforcaid);
795 tpl_addVar(vars, TPLADD, "LBNOPROVIDERFORCAID", value);
796 free_mk_t(value);
798 tpl_addVar(vars, TPLADD, "LBAUTOBETATUNNEL", (cfg.lb_auto_betatunnel == 1) ? "checked" : "");
800 if(cfg.lb_auto_betatunnel_mode)
802 tpl_printf(vars, TPLADD, "TMP", "LBAUTOBETATUNNELMODE%d", cfg.lb_auto_betatunnel_mode);
803 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
806 tpl_printf(vars, TPLADD, "LBPREFERBETA", "%d", cfg.lb_auto_betatunnel_prefer_beta);
808 tpl_addVar(vars, TPLADD, "LBAUTOTIMEOUT", (cfg.lb_auto_timeout == 1) ? "checked" : "");
810 tpl_printf(vars, TPLADD, "LBAUTOTIMEOUTP", "%d", cfg.lb_auto_timeout_p);
811 tpl_printf(vars, TPLADD, "LBAUTOTIMEOUTT", "%d", cfg.lb_auto_timeout_t);
813 tpl_addVar(vars, TPLADDONCE, "CONFIG_CONTROL", tpl_getTpl(vars, "CONFIGLOADBALANCERCTRL"));
815 return tpl_getTpl(vars, "CONFIGLOADBALANCER");
817 #endif
819 #ifdef MODULE_CAMD33
820 static char *send_oscam_config_camd33(struct templatevars *vars, struct uriparams *params)
822 int32_t i;
824 setActiveSubMenu(vars, MNU_CFG_CAMD33);
826 webif_save_config("camd33", vars, params);
828 if(cfg.c33_port)
830 tpl_printf(vars, TPLADD, "PORT", "%d", cfg.c33_port);
831 if(IP_ISSET(cfg.c33_srvip)) { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.c33_srvip)); }
832 tpl_addVar(vars, TPLADD, "PASSIVECHECKED", (cfg.c33_passive == 1) ? "checked" : "");
834 for(i = 0; i < (int) sizeof(cfg.c33_key); ++i) { tpl_printf(vars, TPLAPPEND, "KEY", "%02X", cfg.c33_key[i]); }
835 char *value = mk_t_iprange(cfg.c33_plain);
836 tpl_addVar(vars, TPLADD, "NOCRYPT", value);
837 free_mk_t(value);
840 return tpl_getTpl(vars, "CONFIGCAMD33");
842 #endif
844 #ifdef MODULE_CAMD35
845 static char *send_oscam_config_camd35(struct templatevars *vars, struct uriparams *params)
847 setActiveSubMenu(vars, MNU_CFG_CAMD35);
849 webif_save_config("cs357x", vars, params);
851 if(cfg.c35_port)
853 tpl_printf(vars, TPLADD, "PORT", "%d", cfg.c35_port);
854 if(IP_ISSET(cfg.c35_srvip))
855 { tpl_addVar(vars, TPLAPPEND, "SERVERIP", cs_inet_ntoa(cfg.c35_srvip)); }
857 if(cfg.c35_udp_suppresscmd08)
858 { tpl_addVar(vars, TPLADD, "SUPPRESSCMD08UDP", "checked"); }
861 return tpl_getTpl(vars, "CONFIGCAMD35");
863 #endif
865 #ifdef MODULE_CAMD35_TCP
866 static char *send_oscam_config_camd35tcp(struct templatevars *vars, struct uriparams *params)
868 setActiveSubMenu(vars, MNU_CFG_CAMD35TCP);
870 webif_save_config("cs378x", vars, params);
872 if((cfg.c35_tcp_ptab.nports > 0) && (cfg.c35_tcp_ptab.ports[0].s_port > 0))
875 char *value = mk_t_camd35tcp_port();
876 tpl_addVar(vars, TPLADD, "PORT", value);
877 free_mk_t(value);
879 if(IP_ISSET(cfg.c35_tcp_srvip))
880 { tpl_addVar(vars, TPLAPPEND, "SERVERIP", cs_inet_ntoa(cfg.c35_tcp_srvip)); }
882 if(cfg.c35_tcp_suppresscmd08)
883 { tpl_addVar(vars, TPLADD, "SUPPRESSCMD08TCP", "checked"); }
885 return tpl_getTpl(vars, "CONFIGCAMD35TCP");
887 #endif
889 static char *send_oscam_config_cache(struct templatevars *vars, struct uriparams *params)
891 setActiveSubMenu(vars, MNU_CFG_CACHE);
893 webif_save_config("cache", vars, params);
895 tpl_printf(vars, TPLADD, "CACHEDELAY", "%u", cfg.delay);
897 tpl_printf(vars, TPLADD, "MAXCACHETIME", "%d", cfg.max_cache_time);
899 #ifdef CS_CACHEEX
900 char *value = NULL;
901 value = mk_t_cacheex_valuetab(&cfg.cacheex_wait_timetab);
902 tpl_addVar(vars, TPLADD, "WAIT_TIME", value);
903 free_mk_t(value);
905 value = mk_t_caidvaluetab(&cfg.cacheex_mode1_delay_tab);
906 tpl_addVar(vars, TPLADD, "CACHEEXMODE1DELAY", value);
907 free_mk_t(value);
909 tpl_printf(vars, TPLADD, "MAX_HIT_TIME", "%d", cfg.max_hitcache_time);
911 tpl_addVar(vars, TPLADD, "CACHEEXSTATSSELECTED", (cfg.cacheex_enable_stats == 1) ? "checked" : "");
913 tpl_addVar(vars, TPLADD, "WTTCHECKED", (cfg.wait_until_ctimeout == 1) ? "checked" : "");
915 if(cfg.csp_port)
916 { tpl_printf(vars, TPLADD, "PORT", "%d", cfg.csp_port); }
918 if(IP_ISSET(cfg.csp_srvip))
919 { tpl_addVar(vars, TPLAPPEND, "SERVERIP", cs_inet_ntoa(cfg.csp_srvip)); }
921 value = mk_t_cacheex_hitvaluetab(&cfg.csp.filter_caidtab);
922 tpl_addVar(vars, TPLADD, "CSP_ECM_FILTER", value);
923 free_mk_t(value);
925 value = mk_t_cacheex_cwcheck_valuetab(&cfg.cacheex_cwcheck_tab);
926 tpl_addVar(vars, TPLADD, "CACHEEXCWCHECK", value);
927 free_mk_t(value);
929 tpl_addVar(vars, TPLADD, "ARCHECKED", (cfg.csp.allow_request == 1) ? "checked" : "");
930 tpl_addVar(vars, TPLADD, "ARFCHECKED", (cfg.csp.allow_reforward == 1) ? "checked" : "");
931 tpl_addVar(vars, TPLADD, "BLOCKFAKECWSCHECKED", (cfg.csp.block_fakecws == 1) ? "checked" : "");
932 #endif
934 #ifdef CW_CYCLE_CHECK
935 #ifndef CS_CACHEEX
936 char *value = NULL;
937 #endif
939 tpl_addVar(vars, TPLADD, "CWCYCLECHECK", (cfg.cwcycle_check_enable == 1) ? "checked" : "");
941 value = mk_t_caidtab(&cfg.cwcycle_check_caidtab);
942 tpl_addVar(vars, TPLADD, "CWCYCLECHECKCAID", value);
943 free_mk_t(value);
945 tpl_printf(vars, TPLADD, "MAXCYCLELIST", "%d", cfg.maxcyclelist);
946 tpl_printf(vars, TPLADD, "KEEPCYCLETIME", "%d", cfg.keepcycletime);
948 if(cfg.onbadcycle)
950 tpl_printf(vars, TPLADD, "TMP", "ONBADCYCLE%d", cfg.onbadcycle);
951 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
954 tpl_addVar(vars, TPLADD, "DROPOLD", (cfg.cwcycle_dropold == 1) ? "checked" : "");
956 if(cfg.cwcycle_sensitive)
958 tpl_printf(vars, TPLADD, "TMP", "CWCSEN%d", cfg.cwcycle_sensitive);
959 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
962 tpl_addVar(vars, TPLADD, "ALLOWBADFROMFFB", (cfg.cwcycle_allowbadfromffb == 1) ? "checked" : "");
964 tpl_addVar(vars, TPLADD, "USECWCFROMCE", (cfg.cwcycle_usecwcfromce == 1) ? "checked" : "");
967 #endif
969 return tpl_getTpl(vars, "CONFIGCACHE");
972 #ifdef MODULE_NEWCAMD
973 static char *send_oscam_config_newcamd(struct templatevars *vars, struct uriparams *params)
975 int32_t i;
977 setActiveSubMenu(vars, MNU_CFG_NEWCAMD);
979 webif_save_config("newcamd", vars, params);
981 if((cfg.ncd_ptab.nports > 0) && (cfg.ncd_ptab.ports[0].s_port > 0))
984 char *value = mk_t_newcamd_port();
985 tpl_addVar(vars, TPLADD, "PORT", value);
986 free_mk_t(value);
988 if(IP_ISSET(cfg.ncd_srvip))
989 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.ncd_srvip)); }
991 for(i = 0; i < (int32_t)sizeof(cfg.ncd_key); i++)
992 { tpl_printf(vars, TPLAPPEND, "KEY", "%02X", cfg.ncd_key[i]); }
994 value = mk_t_iprange(cfg.ncd_allowed);
995 tpl_addVar(vars, TPLADD, "ALLOWED", value);
996 free_mk_t(value);
998 if(cfg.ncd_keepalive)
999 { tpl_addVar(vars, TPLADD, "KEEPALIVE", "checked"); }
1000 if(cfg.ncd_mgclient)
1001 { tpl_addVar(vars, TPLADD, "MGCLIENTCHK", "checked"); }
1003 return tpl_getTpl(vars, "CONFIGNEWCAMD");
1005 #endif
1007 #ifdef MODULE_GBOX
1008 static char *send_oscam_config_gbox(struct templatevars *vars, struct uriparams *params)
1010 setActiveSubMenu(vars, MNU_CFG_GBOX);
1011 webif_save_config("gbox", vars, params);
1013 tpl_addVar(vars, TPLADD, "HOSTNAME", xml_encode(vars, cfg.gbox_hostname));
1014 char *value = mk_t_gbox_port();
1015 tpl_addVar(vars, TPLAPPEND, "PORT", value);
1016 free_mk_t(value);
1017 tpl_addVar(vars, TPLADD, "MYPASSWORD", xml_encode(vars, cfg.gbox_my_password));
1019 return tpl_getTpl(vars, "CONFIGGBOX");
1021 #endif
1023 #ifdef MODULE_RADEGAST
1024 static char *send_oscam_config_radegast(struct templatevars *vars, struct uriparams *params)
1026 setActiveSubMenu(vars, MNU_CFG_RADEGAST);
1028 webif_save_config("radegast", vars, params);
1030 tpl_printf(vars, TPLADD, "PORT", "%d", cfg.rad_port);
1031 if(IP_ISSET(cfg.rad_srvip))
1032 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.rad_srvip)); }
1033 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, cfg.rad_usr));
1035 char *value = mk_t_iprange(cfg.rad_allowed);
1036 tpl_addVar(vars, TPLADD, "ALLOWED", value);
1037 free_mk_t(value);
1039 return tpl_getTpl(vars, "CONFIGRADEGAST");
1041 #endif
1043 #ifdef MODULE_SCAM
1044 static char *send_oscam_config_scam(struct templatevars *vars, struct uriparams *params)
1046 setActiveSubMenu(vars, MNU_CFG_SCAM);
1048 webif_save_config("scam", vars, params);
1050 tpl_printf(vars, TPLADD, "PORT", "%d", cfg.scam_port);
1051 if(IP_ISSET(cfg.scam_srvip))
1052 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.scam_srvip)); }
1054 char *value = mk_t_iprange(cfg.scam_allowed);
1055 tpl_addVar(vars, TPLADD, "ALLOWED", value);
1056 free_mk_t(value);
1058 return tpl_getTpl(vars, "CONFIGSCAM");
1060 #endif
1062 #ifdef MODULE_CCCAM
1063 static char *send_oscam_config_cccam(struct templatevars *vars, struct uriparams *params)
1066 setActiveSubMenu(vars, MNU_CFG_CCCAM);
1068 if(strcmp(getParam(params, "button"), "Refresh list") == 0)
1070 cs_log_dbg(D_TRACE, "Entitlements: Refresh Shares start");
1071 #ifdef MODULE_CCCSHARE
1072 refresh_shares();
1073 #endif
1074 cs_log_dbg(D_TRACE, "Entitlements: Refresh Shares finished");
1075 tpl_addMsg(vars, "Refresh Shares started");
1078 webif_save_config("cccam", vars, params);
1080 if(streq(getParam(params, "action"), "execute") && !cfg.http_readonly)
1081 { cc_update_nodeid(); }
1083 char *value = mk_t_cccam_port();
1084 tpl_addVar(vars, TPLAPPEND, "PORT", value);
1085 free_mk_t(value);
1087 if(IP_ISSET(cfg.cc_srvip))
1088 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.cc_srvip)); }
1090 tpl_printf(vars, TPLADD, "RESHARE", "%d", cfg.cc_reshare);
1092 if(!strcmp((char *)cfg.cc_version, "2.0.11"))
1094 tpl_addVar(vars, TPLADD, "VERSIONSELECTED0", "selected");
1096 else if(!strcmp((char *)cfg.cc_version, "2.1.1"))
1098 tpl_addVar(vars, TPLADD, "VERSIONSELECTED1", "selected");
1100 else if(!strcmp((char *)cfg.cc_version, "2.1.2"))
1102 tpl_addVar(vars, TPLADD, "VERSIONSELECTED2", "selected");
1104 else if(!strcmp((char *)cfg.cc_version, "2.1.3"))
1106 tpl_addVar(vars, TPLADD, "VERSIONSELECTED3", "selected");
1108 else if(!strcmp((char *)cfg.cc_version, "2.1.4"))
1110 tpl_addVar(vars, TPLADD, "VERSIONSELECTED4", "selected");
1112 else if(!strcmp((char *)cfg.cc_version, "2.2.0"))
1114 tpl_addVar(vars, TPLADD, "VERSIONSELECTED5", "selected");
1116 else if(!strcmp((char *)cfg.cc_version, "2.2.1"))
1118 tpl_addVar(vars, TPLADD, "VERSIONSELECTED6", "selected");
1120 else if(!strcmp((char *)cfg.cc_version, "2.3.0"))
1122 tpl_addVar(vars, TPLADD, "VERSIONSELECTED7", "selected");
1125 tpl_printf(vars, TPLADD, "UPDATEINTERVAL", "%d", cfg.cc_update_interval);
1126 tpl_printf(vars, TPLADD, "RECV_TIMEOUT", "%u", cfg.cc_recv_timeout);
1128 tpl_addVar(vars, TPLADD, "STEALTH", (cfg.cc_stealth == 1) ? "checked" : "");
1130 tpl_printf(vars, TPLADD, "NODEID", "%02X%02X%02X%02X%02X%02X%02X%02X",
1131 cfg.cc_fixed_nodeid[0], cfg.cc_fixed_nodeid[1], cfg.cc_fixed_nodeid[2], cfg.cc_fixed_nodeid[3],
1132 cfg.cc_fixed_nodeid[4], cfg.cc_fixed_nodeid[5], cfg.cc_fixed_nodeid[6], cfg.cc_fixed_nodeid[7]);
1134 tpl_printf(vars, TPLADD, "TMP", "MINIMIZECARDSELECTED%d", cfg.cc_minimize_cards);
1135 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1137 tpl_printf(vars, TPLADD, "TMP", "RESHAREMODE%d", cfg.cc_reshare_services);
1138 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1140 tpl_printf(vars, TPLADD, "TMP", "IGNRSHRSELECTED%d", cfg.cc_ignore_reshare);
1141 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1143 tpl_addVar(vars, TPLADD, "FORWARDORIGINCARD", (cfg.cc_forward_origin_card == 1) ? "checked" : "");
1145 tpl_addVar(vars, TPLADD, "KEEPCONNECTED", (cfg.cc_keep_connected == 1) ? "checked" : "");
1147 tpl_addVar(vars, TPLADDONCE, "CONFIG_CONTROL", tpl_getTpl(vars, "CONFIGCCCAMCTRL"));
1149 return tpl_getTpl(vars, "CONFIGCCCAM");
1151 #endif
1153 static bool is_ext(const char *path, const char *ext)
1155 size_t lenpath = strlen(path);
1156 size_t lenext = strlen(ext);
1157 if(lenext > lenpath)
1158 { return 0; }
1159 return memcmp(path + lenpath - lenext, ext, lenext) == 0;
1162 static char *send_oscam_config_webif(struct templatevars *vars, struct uriparams *params)
1164 int32_t i;
1166 setActiveSubMenu(vars, MNU_CFG_WEBIF);
1168 webif_save_config("webif", vars, params);
1170 tpl_printf(vars, TPLADD, "HTTPPORT", "%s%d", cfg.http_use_ssl ? "+" : "", cfg.http_port);
1171 if(IP_ISSET(cfg.http_srvip))
1172 { tpl_addVar(vars, TPLAPPEND, "SERVERIP", cs_inet_ntoa(cfg.http_srvip)); }
1174 tpl_addVar(vars, TPLADD, "HTTPUSER", cfg.http_user);
1175 tpl_addVar(vars, TPLADD, "HTTPPASSWORD", cfg.http_pwd);
1176 tpl_addVar(vars, TPLADD, "HTTPOSCAMLABEL", cfg.http_oscam_label);
1178 // css style selector
1179 tpl_printf(vars, TPLADD, "CSSOPTIONS", "\t\t\t\t\t\t<option value=\"\"%s>embedded</option>\n",
1180 !cfg.http_css ? " selected" : "");
1182 if(cfg.http_tpl)
1184 char path[255];
1185 tpl_getFilePathInSubdir(cfg.http_tpl, "", "style", ".css", path, 255);
1186 if(file_exists(path))
1187 tpl_printf(vars, TPLAPPEND, "CSSOPTIONS", "\t\t\t\t\t\t<option value=\"%s\"%s>%s (template)</option>\n",
1188 path,
1189 cfg.http_css && strstr(cfg.http_css, path) ? " selected" : "",
1190 path);
1193 struct dirent **namelist;
1194 int count;
1195 count = scandir(cs_confdir, &namelist, 0, alphasort );
1197 if( count >= 0 )
1199 for( i = 0 ; i < count; i++ )
1201 if(is_ext(namelist[i]->d_name, ".css"))
1203 tpl_printf(vars, TPLAPPEND, "CSSOPTIONS", "\t\t\t\t\t\t<option value=\"%s%s\"%s>%s%s</option>\n",
1204 cs_confdir,
1205 namelist[i]->d_name,
1206 cfg.http_css && strstr(cfg.http_css, namelist[i]->d_name) ? " selected" : "",
1207 cs_confdir, namelist[i]->d_name);
1209 free( namelist[i] );
1211 free(namelist);
1214 if(cfg.http_prepend_embedded_css)
1215 { tpl_addVar(vars, TPLADD, "HTTPPREPENDEMBEDDEDCSS", "checked"); }
1217 tpl_addVar(vars, TPLADD, "HTTPHELPLANG", cfg.http_help_lang);
1218 tpl_addVar(vars, TPLADD, "HTTPLOCALE", cfg.http_locale);
1219 tpl_printf(vars, TPLADD, "HTTPEMMUCLEAN", "%d", cfg.http_emmu_clean);
1220 tpl_printf(vars, TPLADD, "HTTPEMMSCLEAN", "%d", cfg.http_emms_clean);
1221 tpl_printf(vars, TPLADD, "HTTPEMMGCLEAN", "%d", cfg.http_emmg_clean);
1222 tpl_printf(vars, TPLADD, "HTTPREFRESH", "%d", cfg.http_refresh);
1223 tpl_printf(vars, TPLADD, "HTTPPOLLREFRESH", "%d", cfg.poll_refresh);
1224 tpl_addVar(vars, TPLADD, "HTTPTPL", cfg.http_tpl);
1225 tpl_addVar(vars, TPLADD, "HTTPPICONPATH", cfg.http_piconpath);
1226 tpl_addVar(vars, TPLADD, "HTTPSCRIPT", cfg.http_script);
1227 tpl_addVar(vars, TPLADD, "HTTPJSCRIPT", cfg.http_jscript);
1228 #ifndef WEBIF_JQUERY
1229 tpl_addVar(vars, TPLADD, "HTTPEXTERNJQUERY", cfg.http_extern_jquery);
1230 #endif
1231 tpl_printf(vars, TPLADD, "HTTPPICONSIZE", "%d", cfg.http_picon_size);
1233 if(cfg.http_hide_idle_clients > 0) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
1234 tpl_addVar(vars, TPLADD, "HTTPHIDETYPE", cfg.http_hide_type);
1235 if(cfg.http_status_log > 0) { tpl_addVar(vars, TPLADD, "SHOWLOGCHECKED", "checked"); }
1236 if(cfg.http_showpicons > 0) { tpl_addVar(vars, TPLADD, "SHOWPICONSCHECKED", "checked"); }
1237 if(cfg.http_showmeminfo > 0) { tpl_addVar(vars, TPLADD, "SHOWMEMINFOCHECKED", "checked"); }
1238 if(cfg.http_showuserinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWUSERINFOCHECKED", "checked"); }
1239 if(cfg.http_showreaderinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWREADERINFOCHECKED", "checked"); }
1240 if(cfg.http_showcacheexinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWCACHEEXINFOCHECKED", "checked"); }
1241 if(cfg.http_showloadinfo > 0) { tpl_addVar(vars, TPLADD, "SHOWLOADINFOCHECKED", "checked"); }
1242 if(cfg.http_showecminfo > 0) { tpl_addVar(vars, TPLADD, "SHOWECMINFOCHECKED", "checked"); }
1244 char *value = mk_t_iprange(cfg.http_allowed);
1245 tpl_addVar(vars, TPLADD, "HTTPALLOW", value);
1246 free_mk_t(value);
1248 for(i = 0; i < MAX_HTTP_DYNDNS; i++)
1250 if(cfg.http_dyndns[i][0])
1252 tpl_addVar(vars, TPLAPPEND, "HTTPDYNDNS", i > 0 ? "," : "");
1253 tpl_addVar(vars, TPLAPPEND, "HTTPDYNDNS", (char *)cfg.http_dyndns[i]);
1257 tpl_addVar(vars, TPLADD, "HTTPSAVEFULLSELECT", (cfg.http_full_cfg == 1) ? "checked" : "");
1258 tpl_addVar(vars, TPLADD, "HTTPOVERWRITEBAKFILE", (cfg.http_overwrite_bak_file == 1) ? "checked" : "");
1261 #ifdef WITH_SSL
1262 if(cfg.http_cert != NULL) { tpl_addVar(vars, TPLADD, "HTTPCERT", cfg.http_cert); }
1263 tpl_addVar(vars, TPLADD, "HTTPFORCESECUREMODESELECT", (cfg.https_force_secure_mode == 1) ? "checked" : "");
1264 #endif
1266 #ifndef WEBIF_JQUERY
1267 tpl_addVar(vars, TPLADDONCE, "CONFIGWEBIFJQUERY", tpl_getTpl(vars, "CONFIGWEBIFJQUERYBIT"));
1268 #endif
1270 tpl_printf(vars, TPLADD, "AULOW", "%d", cfg.aulow);
1271 tpl_printf(vars, TPLADD, "HIDECLIENTTO", "%d", cfg.hideclient_to);
1273 return tpl_getTpl(vars, "CONFIGWEBIF");
1276 #ifdef LCDSUPPORT
1277 static char *send_oscam_config_lcd(struct templatevars *vars, struct uriparams *params)
1279 setActiveSubMenu(vars, MNU_CFG_LCD);
1281 webif_save_config("lcd", vars, params);
1283 tpl_addVar(vars, TPLADD, "ENABLELCDSELECTED", (cfg.enablelcd == 1) ? "checked" : "");
1285 if(cfg.lcd_output_path != NULL)
1286 { tpl_addVar(vars, TPLADD, "LCDOUTPUTPATH", cfg.lcd_output_path); }
1288 tpl_addVar(vars, TPLADD, "LCDHIDEIDLE", (cfg.lcd_hide_idle == 1) ? "checked" : "");
1290 tpl_printf(vars, TPLADD, "LCDREFRESHINTERVAL", "%d", cfg.lcd_write_intervall);
1292 return tpl_getTpl(vars, "CONFIGLCD");
1294 #endif
1296 #ifdef MODULE_MONITOR
1297 static char *send_oscam_config_monitor(struct templatevars *vars, struct uriparams *params)
1299 setActiveSubMenu(vars, MNU_CFG_MONITOR);
1301 webif_save_config("monitor", vars, params);
1303 tpl_printf(vars, TPLADD, "MONPORT", "%d", cfg.mon_port);
1304 if(IP_ISSET(cfg.mon_srvip))
1305 { tpl_addVar(vars, TPLADD, "SERVERIP", cs_inet_ntoa(cfg.mon_srvip)); }
1307 tpl_printf(vars, TPLADD, "AULOW", "%d", cfg.aulow);
1308 tpl_printf(vars, TPLADD, "HIDECLIENTTO", "%d", cfg.hideclient_to);
1310 char *value = mk_t_iprange(cfg.mon_allowed);
1311 tpl_addVar(vars, TPLADD, "NOCRYPT", value);
1312 free_mk_t(value);
1314 //Monlevel selector
1315 tpl_printf(vars, TPLADD, "TMP", "MONSELECTED%d", cfg.mon_level);
1316 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1318 return tpl_getTpl(vars, "CONFIGMONITOR");
1320 #endif
1322 #ifdef MODULE_SERIAL
1323 static char *send_oscam_config_serial(struct templatevars *vars, struct uriparams *params)
1325 setActiveSubMenu(vars, MNU_CFG_SERIAL);
1327 webif_save_config("serial", vars, params);
1329 if(cfg.ser_device)
1331 char sdevice[strlen(cfg.ser_device)];
1332 cs_strncpy(sdevice, cfg.ser_device, sizeof(sdevice));
1333 char *ptr, *saveptr1 = NULL;
1334 char delimiter[2];
1335 delimiter[0] = 1;
1336 delimiter[1] = '\0';
1337 for(ptr = strtok_r(sdevice, delimiter, &saveptr1); ptr; ptr = strtok_r(NULL, delimiter, &saveptr1))
1339 tpl_addVar(vars, TPLADD, "SERIALDEVICE", xml_encode(vars, ptr));
1340 tpl_addVar(vars, TPLAPPEND, "DEVICES", tpl_getTpl(vars, "CONFIGSERIALDEVICEBIT"));
1344 tpl_addVar(vars, TPLADD, "SERIALDEVICE", "");
1345 tpl_addVar(vars, TPLAPPEND, "DEVICES", tpl_getTpl(vars, "CONFIGSERIALDEVICEBIT"));
1347 return tpl_getTpl(vars, "CONFIGSERIAL");
1349 #endif
1351 #ifdef HAVE_DVBAPI
1352 extern const char *boxdesc[];
1354 static char *send_oscam_config_dvbapi(struct templatevars *vars, struct uriparams *params)
1356 int32_t i;
1358 setActiveSubMenu(vars, MNU_CFG_DVBAPI);
1360 webif_save_config("dvbapi", vars, params);
1362 if(cfg.dvbapi_enabled > 0)
1363 { tpl_addVar(vars, TPLADD, "ENABLEDCHECKED", "checked"); }
1365 if(cfg.dvbapi_au > 0)
1366 { tpl_addVar(vars, TPLADD, "AUCHECKED", "checked"); }
1368 if(cfg.dvbapi_delayer > 0)
1369 { tpl_printf(vars, TPLADD, "DELAYER", "%d", cfg.dvbapi_delayer); }
1371 tpl_printf(vars, TPLADD, "BOXTYPE", "<option value=\"\"%s>None</option>\n", cfg.dvbapi_boxtype == 0 ? " selected" : "");
1372 for(i = 1; i <= BOXTYPES; i++)
1374 tpl_printf(vars, TPLAPPEND, "BOXTYPE", "<option%s>%s</option>\n", cfg.dvbapi_boxtype == i ? " selected" : "", boxdesc[i]);
1377 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, cfg.dvbapi_usr));
1379 //PMT Mode
1380 tpl_printf(vars, TPLADD, "TMP", "PMTMODESELECTED%d", cfg.dvbapi_pmtmode);
1381 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1383 //Request Mode
1384 tpl_printf(vars, TPLADD, "TMP", "REQMODESELECTED%d", cfg.dvbapi_requestmode);
1385 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1387 //ecminfo_type
1388 tpl_printf(vars, TPLADD, "TMP", "ECMINFOTYPESELECTED%d", cfg.dvbapi_ecminfo_type);
1389 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1391 //read_sdt
1392 tpl_printf(vars, TPLADD, "TMP", "READSDTSELECTED%d", cfg.dvbapi_read_sdt);
1393 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1395 //extended_cw_api
1396 tpl_printf(vars, TPLADD, "TMP", "EXTENDEDCWAPISELECTED%d", cfg.dvbapi_extended_cw_api);
1397 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1399 //write_sdt_prov
1400 if(cfg.dvbapi_write_sdt_prov > 0)
1401 { tpl_addVar(vars, TPLADD, "WRITESDTPROVCHECKED", "checked"); }
1403 //TCP listen port
1404 if(cfg.dvbapi_listenport > 0)
1405 { tpl_printf(vars, TPLADD, "LISTENPORT", "%d", cfg.dvbapi_listenport); }
1407 return tpl_getTpl(vars, "CONFIGDVBAPI");
1409 #endif
1411 #ifdef CS_ANTICASC
1412 static char *send_oscam_config_anticasc(struct templatevars *vars, struct uriparams *params)
1414 setActiveSubMenu(vars, MNU_CFG_ANTICASC);
1416 webif_save_config("anticasc", vars, params);
1418 if(cfg.ac_enabled > 0) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
1419 tpl_printf(vars, TPLADD, "NUMUSERS", "%d", cfg.ac_users);
1420 tpl_printf(vars, TPLADD, "SAMPLETIME", "%d", cfg.ac_stime);
1421 tpl_printf(vars, TPLADD, "SAMPLES", "%d", cfg.ac_samples);
1423 tpl_printf(vars, TPLADD, "TMP", "PENALTY%d", cfg.ac_penalty);
1424 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1426 if(cfg.ac_logfile)
1427 { tpl_addVar(vars, TPLADD, "ACLOGFILE", cfg.ac_logfile); }
1428 tpl_printf(vars, TPLADD, "FAKEDELAY", "%d", cfg.ac_fakedelay);
1429 tpl_printf(vars, TPLADD, "DENYSAMPLES", "%d", cfg.ac_denysamples);
1431 if(cfg.acosc_enabled == 1)
1432 { tpl_addVar(vars, TPLADD, "ACOSC_CHECKED", "checked"); }
1433 tpl_printf(vars, TPLADD, "ACOSC_MAX_ACTIVE_SIDS", "%d", cfg.acosc_max_active_sids);
1434 tpl_printf(vars, TPLADD, "ACOSC_ZAP_LIMIT", "%d", cfg.acosc_zap_limit);
1435 tpl_printf(vars, TPLADD, "TMP", "ACOSC_PENALTY%d", cfg.acosc_penalty);
1436 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
1437 tpl_printf(vars, TPLADD, "ACOSC_PENALTY_DURATION", "%d", cfg.acosc_penalty_duration);
1438 tpl_printf(vars, TPLADD, "ACOSC_DELAY", "%d", cfg.acosc_delay);
1440 return tpl_getTpl(vars, "CONFIGANTICASC");
1442 #endif
1444 static char *send_oscam_config(struct templatevars *vars, struct uriparams *params)
1447 setActiveMenu(vars, MNU_CONFIG);
1449 char *part = getParam(params, "part");
1450 if(!strcmp(part, "webif")) { return send_oscam_config_webif(vars, params); }
1451 #ifdef MODULE_MONITOR
1452 else if(!strcmp(part, "monitor")) { return send_oscam_config_monitor(vars, params); }
1453 #endif
1454 #ifdef LCDSUPPORT
1455 else if(!strcmp(part, "lcd")) { return send_oscam_config_lcd(vars, params); }
1456 #endif
1457 #ifdef MODULE_CAMD33
1458 else if(!strcmp(part, "camd33")) { return send_oscam_config_camd33(vars, params); }
1459 #endif
1460 #ifdef MODULE_CAMD35
1461 else if(!strcmp(part, "camd35")) { return send_oscam_config_camd35(vars, params); }
1462 #endif
1463 #ifdef MODULE_CAMD35_TCP
1464 else if(!strcmp(part, "camd35tcp")) { return send_oscam_config_camd35tcp(vars, params); }
1465 #endif
1466 else if(!strcmp(part, "cache")) { return send_oscam_config_cache(vars, params); }
1467 #ifdef MODULE_NEWCAMD
1468 else if(!strcmp(part, "newcamd")) { return send_oscam_config_newcamd(vars, params); }
1469 #endif
1470 #ifdef MODULE_RADEGAST
1471 else if(!strcmp(part, "radegast")) { return send_oscam_config_radegast(vars, params); }
1472 #endif
1473 #ifdef MODULE_SCAM
1474 else if(!strcmp(part, "scam")) { return send_oscam_config_scam(vars, params); }
1475 #endif
1476 #ifdef MODULE_CCCAM
1477 else if(!strcmp(part, "cccam")) { return send_oscam_config_cccam(vars, params); }
1478 #endif
1479 #ifdef MODULE_GBOX
1480 else if(!strcmp(part, "gbox")) { return send_oscam_config_gbox(vars, params); }
1481 #endif
1482 #ifdef HAVE_DVBAPI
1483 else if(!strcmp(part, "dvbapi")) { return send_oscam_config_dvbapi(vars, params); }
1484 #endif
1485 #ifdef CS_ANTICASC
1486 else if(!strcmp(part, "anticasc")) { return send_oscam_config_anticasc(vars, params); }
1487 #endif
1488 #ifdef MODULE_SERIAL
1489 else if(!strcmp(part, "serial")) { return send_oscam_config_serial(vars, params); }
1490 #endif
1491 #ifdef WITH_LB
1492 else if(!strcmp(part, "loadbalancer")) { return send_oscam_config_loadbalancer(vars, params); }
1493 #endif
1494 else { return send_oscam_config_global(vars, params); }
1497 static void inactivate_reader(struct s_reader *rdr)
1499 struct s_client *cl = rdr->client;
1500 if(cl)
1501 { kill_thread(cl); }
1504 static bool picon_exists(char *name)
1506 char picon_name[64], path[255];
1507 char *tpl_path;
1508 tpl_path = cfg.http_piconpath ? cfg.http_piconpath : cfg.http_tpl;
1509 if(!tpl_path)
1510 { return false; }
1511 snprintf(picon_name, sizeof(picon_name) - 1, "IC_%s", name);
1512 return strlen(tpl_getTplPath(picon_name, tpl_path, path, sizeof(path) - 1)) && file_exists(path);
1515 static void clear_rdr_stats(struct s_reader *rdr)
1517 int i;
1518 for(i = 0; i < 4; i++)
1520 rdr->emmerror[i] = 0;
1521 rdr->emmwritten[i] = 0;
1522 rdr->emmskipped[i] = 0;
1523 rdr->emmblocked[i] = 0;
1525 rdr->ecmsok = 0;
1526 rdr->ecmsnok = 0;
1527 rdr->ecmstout = 0;
1528 rdr->ecmshealthok = 0;
1529 rdr->ecmshealthnok = 0;
1530 rdr->ecmshealthtout = 0;
1531 rdr->ecmsfilteredhead = 0;
1532 rdr->ecmsfilteredlen = 0;
1535 static void clear_all_rdr_stats(void)
1537 struct s_reader *rdr;
1538 LL_ITER itr = ll_iter_create(configured_readers);
1539 while((rdr = ll_iter_next(&itr)))
1541 clear_rdr_stats(rdr);
1545 static char *send_oscam_reader(struct templatevars *vars, struct uriparams *params, int32_t apicall)
1547 struct s_reader *rdr;
1548 int32_t i;
1549 unsigned char md5tmp[MD5_DIGEST_LENGTH];
1551 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
1552 if(!apicall)
1554 if(strcmp(getParam(params, "action"), "resetallrdrstats") == 0)
1556 clear_all_rdr_stats();
1560 tpl_addVar(vars, TPLADD, "READERACTIONCOLS", config_enabled(WITH_LB) ? "6" : "5");
1562 if(strcmp(getParam(params, "action"), "resetuserstats") == 0)
1564 clear_info_clients_stats();
1566 if(strcmp(getParam(params, "action"), "resetreaderstats") == 0)
1568 clear_info_readers_stats();
1570 if(strcmp(getParam(params, "action"), "reloadreaders") == 0)
1572 if(!cfg.http_readonly)
1573 { refresh_oscam(REFR_READERS); }
1575 if((strcmp(getParam(params, "action"), "disable") == 0) || (strcmp(getParam(params, "action"), "enable") == 0))
1577 if(cfg.http_readonly)
1579 tpl_addMsg(vars, "WebIf is in readonly mode. Enabling or disabling readers is not possible!");
1581 else
1583 rdr = get_reader_by_label(getParam(params, "label"));
1584 if(rdr)
1586 if(strcmp(getParam(params, "action"), "enable") == 0)
1588 if(!rdr->enable)
1590 rdr->enable = 1;
1593 else
1595 if(rdr->enable)
1597 rdr->enable = 0;
1600 restart_cardreader(rdr, 1);
1601 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
1606 if(strcmp(getParam(params, "action"), "delete") == 0)
1608 if(cfg.http_readonly)
1610 tpl_addMsg(vars, "WebIf is in readonly mode. No deletion will be made!");
1612 else
1614 rdr = get_reader_by_label(getParam(params, "label"));
1615 if(rdr)
1617 inactivate_reader(rdr);
1618 ll_remove(configured_readers, rdr);
1620 free_reader(rdr);
1622 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
1627 if(strcmp(getParam(params, "action"), "reread") == 0)
1629 rdr = get_reader_by_label(getParam(params, "label"));
1630 if(rdr)
1632 struct s_client *cl = rdr->client;
1633 //reset the counters
1634 for(i = 0; i < 4; i++)
1636 rdr->emmerror[i] = 0;
1637 rdr->emmwritten[i] = 0;
1638 rdr->emmskipped[i] = 0;
1639 rdr->emmblocked[i] = 0;
1642 if(rdr->enable == 1 && cl && cl->typ == 'r')
1644 add_job(cl, ACTION_READER_CARDINFO, NULL, 0);
1649 LL_ITER itr = ll_iter_create(configured_readers);
1651 if(!apicall)
1653 for(i = 0, rdr = ll_iter_next(&itr); rdr && rdr->label[0]; rdr = ll_iter_next(&itr), i++) { ; }
1654 tpl_printf(vars, TPLADD, "NEXTREADER", "Reader-%d", i); //Next Readername
1657 int jsondelimiter = 0;
1658 int existing_insert = 0;
1660 int32_t total_readers = 0;
1661 int32_t disabled_readers = 0;
1662 int32_t active_readers = 0;
1663 int32_t connected_readers = 0;
1665 ll_iter_reset(&itr); //going to iterate all configured readers
1666 while((rdr = ll_iter_next(&itr)))
1668 struct s_client *cl = rdr->client;
1669 if(rdr->label[0] && rdr->typ)
1671 total_readers += 1;
1673 // used for API and WebIf
1674 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
1676 MD5((unsigned char *)rdr->label, strlen(rdr->label), md5tmp);
1677 int z;
1678 tpl_addVar(vars, TPLADD, "LABELMD5","id_");
1679 for (z = 0; z < MD5_DIGEST_LENGTH; z++){
1680 tpl_printf(vars, TPLAPPEND, "LABELMD5", "%02x", md5tmp[z]);
1682 #ifdef MODULE_GBOX
1683 if(apicall){
1684 tpl_addVar(vars, TPLADD, "LASTGSMS", "");
1685 tpl_addVar(vars, TPLADD, "LASTGSMS", rdr->last_gsms);
1687 #endif
1688 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, rdr->label));
1689 if(!existing_insert){
1690 tpl_printf(vars, TPLADD, "EXISTING_INS", "'%s'", urlencode(vars, rdr->label));
1691 existing_insert++;
1692 }else{
1693 tpl_printf(vars, TPLAPPEND, "EXISTING_INS", ",'%s'", urlencode(vars, rdr->label));
1695 tpl_addVar(vars, TPLADD, "CTYP", reader_get_type_desc(rdr, 0));
1696 tpl_addVar(vars, TPLADD, "CTYPSORT", reader_get_type_desc(rdr, 0));
1698 tpl_addVar(vars, TPLADD, "READERCLASS", rdr->enable ? "enabledreader" : "disabledreader");
1700 if(rdr->enable) { active_readers += 1; }
1701 else { disabled_readers += 1; }
1703 if(rdr->tcp_connected) { connected_readers += 1; }
1705 if(rdr->description)
1706 tpl_printf(vars, TPLADD, "DESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, rdr->description));
1707 else
1708 tpl_addVar(vars, TPLADD, "DESCRIPTION", "");
1710 if(cfg.http_showpicons && !apicall)
1712 tpl_addVar(vars, TPLADD, "READERBIT", tpl_getTpl(vars, picon_exists(xml_encode(vars, rdr->label)) ? "READERNAMEBIT" : "READERNOICON"));
1713 tpl_addVar(vars, TPLADD, "CTYP", picon_exists(xml_encode(vars, reader_get_type_desc(rdr, 0))) ? tpl_getTpl(vars, "READERCTYPBIT") : tpl_getTpl(vars, "READERCTYPNOICON"));
1715 else
1716 tpl_addVar(vars, TPLADD, "READERBIT", tpl_getTpl(vars, "READERLABEL"));
1718 char *value = mk_t_group(rdr->grp);
1719 tpl_addVar(vars, TPLADD, "GROUPS", value);
1720 free_mk_t(value);
1721 tpl_printf(vars, TPLADD, "EMMERRORUK", PRINTF_LOCAL_D, rdr->emmerror[UNKNOWN]);
1722 tpl_printf(vars, TPLADD, "EMMERRORG", PRINTF_LOCAL_D, rdr->emmerror[GLOBAL]);
1723 tpl_printf(vars, TPLADD, "EMMERRORS", PRINTF_LOCAL_D, rdr->emmerror[SHARED]);
1724 tpl_printf(vars, TPLADD, "EMMERRORUQ", PRINTF_LOCAL_D, rdr->emmerror[UNIQUE]);
1726 tpl_printf(vars, TPLADD, "EMMWRITTENUK", PRINTF_LOCAL_D, rdr->emmwritten[UNKNOWN]);
1727 tpl_printf(vars, TPLADD, "EMMWRITTENG", PRINTF_LOCAL_D, rdr->emmwritten[GLOBAL]);
1728 tpl_printf(vars, TPLADD, "EMMWRITTENS", PRINTF_LOCAL_D, rdr->emmwritten[SHARED]);
1729 tpl_printf(vars, TPLADD, "EMMWRITTENUQ", PRINTF_LOCAL_D, rdr->emmwritten[UNIQUE]);
1731 tpl_printf(vars, TPLADD, "EMMSKIPPEDUK", PRINTF_LOCAL_D, rdr->emmskipped[UNKNOWN]);
1732 tpl_printf(vars, TPLADD, "EMMSKIPPEDG", PRINTF_LOCAL_D, rdr->emmskipped[GLOBAL]);
1733 tpl_printf(vars, TPLADD, "EMMSKIPPEDS", PRINTF_LOCAL_D, rdr->emmskipped[SHARED]);
1734 tpl_printf(vars, TPLADD, "EMMSKIPPEDUQ", PRINTF_LOCAL_D, rdr->emmskipped[UNIQUE]);
1736 tpl_printf(vars, TPLADD, "EMMBLOCKEDUK", PRINTF_LOCAL_D, rdr->emmblocked[UNKNOWN]);
1737 tpl_printf(vars, TPLADD, "EMMBLOCKEDG", PRINTF_LOCAL_D, rdr->emmblocked[GLOBAL]);
1738 tpl_printf(vars, TPLADD, "EMMBLOCKEDS", PRINTF_LOCAL_D, rdr->emmblocked[SHARED]);
1739 tpl_printf(vars, TPLADD, "EMMBLOCKEDUQ", PRINTF_LOCAL_D, rdr->emmblocked[UNIQUE]);
1741 tpl_printf(vars, TPLADD, "ECMSOK", PRINTF_LOCAL_D, rdr->ecmsok);
1742 tpl_printf(vars, TPLADD, "ECMSOKREL", " (%.2f %%)", rdr->ecmshealthok);
1743 tpl_printf(vars, TPLADD, "ECMSNOK", PRINTF_LOCAL_D, rdr->ecmsnok);
1744 tpl_printf(vars, TPLADD, "ECMSNOKREL", " (%.2f %%)",rdr->ecmshealthnok);
1745 tpl_printf(vars, TPLADD, "ECMSTOUT", PRINTF_LOCAL_D, rdr->ecmstout);
1746 tpl_printf(vars, TPLADD, "ECMSTOUTREL", " (%.2f %%)",rdr->ecmshealthtout);
1747 tpl_printf(vars, TPLADD, "ECMSFILTEREDHEAD", PRINTF_LOCAL_D, rdr->ecmsfilteredhead);
1748 tpl_printf(vars, TPLADD, "ECMSFILTEREDLEN", PRINTF_LOCAL_D, rdr->ecmsfilteredlen);
1749 #ifdef WITH_LB
1750 tpl_printf(vars, TPLADD, "LBWEIGHT", "%d", rdr->lb_weight);
1751 #endif
1752 if(!is_network_reader(rdr)) //reader is physical
1754 tpl_addVar(vars, TPLADD, "REFRICO", "image?i=ICREF");
1755 tpl_addVar(vars, TPLADD, "READERREFRESH", tpl_getTpl(vars, "READERREFRESHBIT"));
1756 tpl_addVar(vars, TPLADD, "ENTICO", "image?i=ICENT");
1757 tpl_addVar(vars, TPLADD, "ENTITLEMENT", tpl_getTpl(vars, "READERENTITLEBIT"));
1759 else
1761 tpl_addVar(vars, TPLADD, "READERREFRESH", "");
1762 if(rdr->typ == R_CCCAM)
1764 tpl_addVar(vars, TPLADD, "ENTICO", "image?i=ICENT");
1765 tpl_addVar(vars, TPLADD, "ENTITLEMENT", tpl_getTpl(vars, "READERENTITLEBIT"));
1767 else
1769 tpl_addVar(vars, TPLADD, "ENTITLEMENT", "");
1773 if(rdr->enable == 0)
1775 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICENA");
1776 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Enable");
1777 tpl_addVar(vars, TPLADD, "SWITCH", "enable");
1778 tpl_addVar(vars, TPLADD, "WRITEEMM", "");
1780 else
1782 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICDIS");
1783 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Disable");
1784 tpl_addVar(vars, TPLADD, "SWITCH", "disable");
1786 tpl_addVar(vars, TPLADD, "EMMICO", "image?i=ICEMM");
1787 tpl_addVar(vars, TPLADD, "WRITEEMM", tpl_getTpl(vars, "READERWRITEEMMBIT"));
1790 if(!apicall)
1792 // Add to WebIf Template
1793 tpl_addVar(vars, TPLAPPEND, "READERLIST", tpl_getTpl(vars, "READERSBIT"));
1795 else
1798 // used only for API
1799 tpl_addVar(vars, TPLADD, "APIREADERENABLED", !rdr->enable ? "0" : "1");
1800 if(cl)
1802 tpl_printf(vars, TPLADD, "APIREADERTYPE", "%c", cl->typ ? cl->typ : 'x');
1805 if(apicall==1)
1807 // Add to API Template
1808 tpl_addVar(vars, TPLAPPEND, "APIREADERLIST", tpl_getTpl(vars, "APIREADERSBIT"));
1810 if(apicall==2)
1812 tpl_printf(vars, TPLAPPEND, "APIREADERLIST","%s%s",jsondelimiter?",":"", tpl_getTpl(vars, "JSONREADERBIT"));
1813 jsondelimiter++;
1820 tpl_printf(vars, TPLADD, "TOTAL_READERS", "%d", total_readers);
1821 tpl_printf(vars, TPLADD, "TOTAL_DISABLED_READERS", "%d", disabled_readers);
1822 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE_READERS", "%d", active_readers);
1823 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED_READERS", "%d", connected_readers);
1825 //CM info
1826 tpl_addVar(vars, TPLADD, "DISPLAYUSERINFO", "hidden"); // no userinfo in readers
1827 set_ecm_info(vars);
1829 if(!apicall)
1831 #ifdef MODULE_CAMD33
1832 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>camd33</option>\n");
1833 #endif
1834 #ifdef MODULE_CAMD35
1835 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>cs357x</option>\n");
1836 #endif
1837 #ifdef MODULE_CAMD35_TCP
1838 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>cs378x</option>\n");
1839 #endif
1840 #ifdef MODULE_NEWCAMD
1841 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>newcamd</option>\n");
1842 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>newcamd524</option>\n");
1843 #endif
1844 #ifdef MODULE_CCCAM
1845 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>cccam</option>\n");
1846 #endif
1847 #ifdef MODULE_GBOX
1848 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>gbox</option>\n");
1849 #endif
1850 #ifdef MODULE_RADEGAST
1851 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>radegast</option>\n");
1852 #endif
1853 #ifdef MODULE_SERIAL
1854 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>serial</option>\n");
1855 #endif
1856 #ifdef MODULE_CONSTCW
1857 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>constcw</option>\n");
1858 #endif
1859 #ifdef MODULE_SCAM
1860 tpl_addVar(vars, TPLAPPEND, "ADDPROTOCOL", "<option>scam</option>\n");
1861 #endif
1863 for(i = 0; cardreaders[i]; i++)
1865 tpl_printf(vars, TPLAPPEND, "ADDPROTOCOL", "<option>%s</option>\n", xml_encode(vars, cardreaders[i]->desc));
1867 return tpl_getTpl(vars, "READERS");
1869 else
1871 if(apicall == 1)
1873 return tpl_getTpl(vars, "APIREADERS");
1875 else
1877 return tpl_getTpl(vars, "JSONREADER");
1882 static char *send_oscam_reader_config(struct templatevars *vars, struct uriparams *params)
1884 int32_t i;
1885 int32_t apicall = 0;
1886 char *reader_ = getParam(params, "label");
1887 char *value;
1889 struct s_reader *rdr;
1891 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
1893 if(strcmp(getParam(params, "action"), "Add") == 0)
1895 // Add new reader
1896 struct s_reader *newrdr;
1897 if(!cs_malloc(&newrdr, sizeof(struct s_reader))) { return "0"; }
1898 for(i = 0; i < (*params).paramcount; ++i)
1900 if(strcmp((*params).params[i], "action"))
1901 { chk_reader((*params).params[i], (*params).values[i], newrdr); }
1903 module_reader_set(newrdr);
1904 reader_ = newrdr->label;
1905 reader_set_defaults(newrdr);
1906 newrdr->enable = 0; // do not start the reader because must configured before
1907 ll_append(configured_readers, newrdr);
1908 tpl_addMsg(vars, "New Reader has been added with default settings");
1910 else if(strcmp(getParam(params, "action"), "Save") == 0)
1913 rdr = get_reader_by_label(getParam(params, "label"));
1914 if(!rdr)
1915 { return NULL; }
1916 //if (is_network_reader(rdr))
1917 // inactivate_reader(rdr); //Stop reader before reinitialization
1918 char servicelabels[1024] = "";
1919 char servicelabelslb[1024] = "";
1921 for(i = 0; i < (*params).paramcount; ++i)
1923 if((strcmp((*params).params[i], "reader")) && (strcmp((*params).params[i], "action")))
1925 if(!strcmp((*params).params[i], "services"))
1926 { snprintf(servicelabels + strlen(servicelabels), sizeof(servicelabels) - strlen(servicelabels), "%s,", (*params).values[i]); }
1927 else if(!strcmp((*params).params[i], "lb_whitelist_services"))
1928 { snprintf(servicelabelslb + strlen(servicelabelslb), sizeof(servicelabelslb) - strlen(servicelabelslb), "%s,", (*params).values[i]); }
1929 else
1930 /*if(strlen((*params).values[i]) > 0)*/
1931 { chk_reader((*params).params[i], (*params).values[i], rdr); }
1933 //printf("param %s value %s\n",(*params).params[i], (*params).values[i]);
1935 chk_reader("services", servicelabels, rdr);
1936 chk_reader("lb_whitelist_services", servicelabelslb, rdr);
1938 if(is_network_reader(rdr)) //physical readers make trouble if re-started
1940 restart_cardreader(rdr, 1);
1943 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); } else { tpl_addMsg(vars, "Reader config updated and saved"); }
1947 rdr = get_reader_by_label(reader_);
1948 if(!rdr)
1949 { return NULL; }
1951 // Label, Description
1952 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
1953 tpl_addVar(vars, TPLADD, "DESCRIPTION", xml_encode(vars, rdr->description));
1955 // enabled
1956 if(!apicall)
1958 tpl_addVar(vars, TPLADD, "ENABLED", (rdr->enable == 1) ? "checked" : "");
1960 else
1962 tpl_addVar(vars, TPLADD, "ENABLEDVALUE", (rdr->enable == 1) ? "1" : "0");
1965 tpl_addVar(vars, TPLADD, "PASSWORD", xml_encode(vars, rdr->r_pwd));
1966 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, rdr->r_usr));
1967 tpl_addVar(vars, TPLADD, "PASS", xml_encode(vars, rdr->r_pwd));
1969 // Key Newcamd
1970 for(i = 0; i < (int32_t)sizeof(rdr->ncd_key); i++)
1971 { tpl_printf(vars, TPLAPPEND, "NCD_KEY", "%02X", rdr->ncd_key[i]); }
1973 // Pincode
1974 tpl_addVar(vars, TPLADD, "PINCODE", rdr->pincode);
1976 // Emmfile Path
1977 if(rdr->emmfile) { tpl_addVar(vars, TPLADD, "EMMFILE", (char *)rdr->emmfile); }
1979 // Inactivity timeout
1980 tpl_printf(vars, TPLADD, "INACTIVITYTIMEOUT", "%d", rdr->tcp_ito);
1982 // Receive timeout
1983 tpl_printf(vars, TPLADD, "RECEIVETIMEOUT", "%d", rdr->tcp_rto);
1985 // keepalive
1986 tpl_addVar(vars, TPLADD, "RDRKEEPALIVE", (rdr->keepalive == 1) ? "checked" : "");
1988 // Connect on init (newcamd)
1989 if(!apicall)
1991 tpl_addVar(vars, TPLADD, "CONNECTONINITCHECKED", (rdr->ncd_connect_on_init == 1) ? "checked" : "");
1993 else
1995 tpl_addVar(vars, TPLADD, "CONNECTONINITCHECKED", (rdr->ncd_connect_on_init == 1) ? "1" : "0");
1998 // Reset Cycle
1999 tpl_printf(vars, TPLADD, "RESETCYCLE", "%d", rdr->resetcycle);
2001 // Disable Serverfilter
2002 if(!apicall)
2004 tpl_addVar(vars, TPLADD, "DISABLESERVERFILTERCHECKED", (rdr->ncd_disable_server_filt == 1) ? "checked" : "");
2006 else
2008 tpl_addVar(vars, TPLADD, "DISABLESERVERFILTERVALUE", (rdr->ncd_disable_server_filt == 1) ? "1" : "0");
2011 #ifdef MODULE_GHTTP
2012 // Use SSL
2013 if(!apicall)
2015 tpl_addVar(vars, TPLADD, "USESSLCHECKED", (rdr->ghttp_use_ssl == 1) ? "checked" : "");
2017 else
2019 tpl_addVar(vars, TPLADD, "USESSLVALUE", (rdr->ghttp_use_ssl == 1) ? "1" : "0");
2021 #endif
2023 // Fallback
2024 if(!apicall)
2026 tpl_addVar(vars, TPLADD, "FALLBACKCHECKED", (rdr->fallback == 1) ? "checked" : "");
2028 else
2030 tpl_addVar(vars, TPLADD, "FALLBACKVALUE", (rdr->fallback == 1) ? "1" : "0");
2033 // Fallback per caid
2034 value = mk_t_ftab(&rdr->fallback_percaid);
2035 tpl_addVar(vars, TPLADD, "FALLBACK_PERCAID", value);
2036 free_mk_t(value);
2038 #ifdef WITH_LB
2039 tpl_addVar(vars, TPLADD, "LBFORCEFALLBACK", (rdr->lb_force_fallback == 1) ? "checked" : "");
2040 #endif
2042 #ifdef CS_CACHEEX
2043 // Cacheex
2044 if(!apicall)
2046 tpl_printf(vars, TPLADD, "TMP", "CACHEEXSELECTED%d", rdr->cacheex.mode);
2047 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
2049 else
2051 tpl_printf(vars, TPLADD, "CACHEEX", "%d", rdr->cacheex.mode);
2053 tpl_printf(vars, TPLADD, "CACHEEX_MAXHOP", "%d", rdr->cacheex.maxhop);
2054 value = mk_t_cacheex_hitvaluetab(&rdr->cacheex.filter_caidtab);
2055 //if (strlen(value) > 0)
2056 tpl_printf(vars, TPLADD, "CACHEEX_ECM_FILTER", "%s", value);
2057 free_mk_t(value);
2059 tpl_addVar(vars, TPLADD, "DCCHECKED", (rdr->cacheex.drop_csp == 1) ? "checked" : "");
2060 tpl_addVar(vars, TPLADD, "ARCHECKED", (rdr->cacheex.allow_request == 1) ? "checked" : "");
2061 tpl_addVar(vars, TPLADD, "AFCHECKED", (rdr->cacheex.allow_filter == 1) ? "checked" : "");
2062 tpl_addVar(vars, TPLADD, "BLOCKFAKECWSCHECKED", (rdr->cacheex.block_fakecws == 1) ? "checked" : "");
2063 #endif
2065 // BoxID
2066 if(rdr->boxid)
2067 { tpl_printf(vars, TPLADD, "BOXID", "%08X", rdr->boxid); }
2069 // Filt 07
2070 if(!apicall)
2072 tpl_addVar(vars, TPLADD, "FIX07CHECKED", (rdr->fix_07 == 1) ? "checked" : "");
2074 else
2076 tpl_addVar(vars, TPLADD, "FIX07VALUE", (rdr->fix_07 == 1) ? "1" : "0");
2080 // Fix 9993
2081 if(!apicall)
2083 tpl_addVar(vars, TPLADD, "FIX9993CHECKED", (rdr->fix_9993 == 1) ? "checked" : "");
2085 else
2087 tpl_addVar(vars, TPLADD, "FIX9993VALUE", (rdr->fix_9993 == 1) ? "1" : "0");
2090 // Drop CWs with wrong checksum:
2091 if(!apicall)
2093 tpl_addVar(vars, TPLADD, "DROPBADCWSCHECKED", (rdr->dropbadcws == 1) ? "checked" : "");
2095 else
2097 tpl_addVar(vars, TPLADD, "DROPBADCWSVALUE", (rdr->dropbadcws == 1) ? "1" : "0");
2100 // Disable CWs checksum test:
2101 if(!apicall)
2103 tpl_addVar(vars, TPLADD, "DISABLECRCCWSCHECKED", (rdr->disablecrccws == 1) ? "checked" : "");
2105 else
2107 tpl_addVar(vars, TPLADD, "DISABLECRCCWSVALUE", (rdr->disablecrccws == 1) ? "1" : "0");
2110 // Set reader to use GPIO
2111 if(!apicall)
2113 tpl_addVar(vars, TPLADD, "USE_GPIOCHECKED", rdr->use_gpio ? "checked" : "");
2115 else
2117 tpl_addVar(vars, TPLADD, "USE_GPIOVALUE", rdr->use_gpio ? "1" : "0");
2120 // AUdisabled
2121 if(!apicall)
2123 tpl_addVar(vars, TPLADD, "AUDISABLED", (rdr->audisabled == 1) ? "checked" : "");
2125 else
2127 tpl_addVar(vars, TPLADD, "AUDISABLEDVALUE", (rdr->audisabled == 1) ? "1" : "0");
2130 // AUprovid
2131 if(rdr->auprovid)
2132 { tpl_printf(vars, TPLADD, "AUPROVID", "%06X", rdr->auprovid); }
2134 if(rdr->ecmnotfoundlimit)
2135 { tpl_printf(vars, TPLADD, "ECMNOTFOUNDLIMIT", "%u", rdr->ecmnotfoundlimit); }
2137 // Force Irdeto
2138 if(!apicall)
2140 tpl_addVar(vars, TPLADD, "FORCEIRDETOCHECKED", (rdr->force_irdeto == 1) ? "checked" : "");
2142 else
2144 tpl_addVar(vars, TPLADD, "FORCEIRDETOVALUE", (rdr->force_irdeto == 1) ? "1" : "0");
2147 // needsemmfirst
2149 if(!apicall)
2151 tpl_addVar(vars, TPLADD, "NEEDSEMMFIRST", (rdr->needsemmfirst == 1) ? "checked" : "");
2153 else
2155 tpl_addVar(vars, TPLADD, "NEEDSEMMFIRST", (rdr->needsemmfirst == 1) ? "1" : "0");
2158 // RSA Key
2159 int32_t len = rdr->rsa_mod_length;
2160 if(len > 0)
2162 for(i = 0; i < len; i++) { tpl_printf(vars, TPLAPPEND, "RSAKEY", "%02X", rdr->rsa_mod[i]); }
2165 // 3DES Key
2166 len = rdr->des_key_length;
2167 if(len > 0)
2169 for(i = 0; i < len; i++) { tpl_printf(vars, TPLAPPEND, "DESKEY", "%02X", rdr->des_key[i]); }
2172 // BoxKey
2173 len = rdr->boxkey_length;
2174 if(len > 0)
2176 for(i = 0; i < len ; i++)
2177 { tpl_printf(vars, TPLAPPEND, "BOXKEY", "%02X", rdr->boxkey[i]); }
2180 // ins7E
2181 if(rdr->ins7E[0x1A])
2183 for(i = 0; i < 26 ; i++) { tpl_printf(vars, TPLAPPEND, "INS7E", "%02X", rdr->ins7E[i]); }
2186 // ins7E11
2187 if(rdr->ins7E11[0x01])
2189 tpl_printf(vars, TPLAPPEND, "INS7E11", "%02X", rdr->ins7E11[0]);
2192 // ins2e06
2193 if(rdr->ins2e06[0x04])
2195 for(i = 0; i < 4 ; i++) { tpl_printf(vars, TPLAPPEND, "INS2E06", "%02X", rdr->ins2e06[i]); }
2198 // ATR
2199 if(rdr->atr[0])
2200 for(i = 0; i < rdr->atrlen / 2; i++)
2201 { tpl_printf(vars, TPLAPPEND, "ATR", "%02X", rdr->atr[i]); }
2203 // ECM Whitelist
2204 value = mk_t_ecm_whitelist(&rdr->ecm_whitelist);
2205 tpl_addVar(vars, TPLADD, "ECMWHITELIST", value);
2206 free_mk_t(value);
2208 // ECM Header Whitelist
2209 value = mk_t_ecm_hdr_whitelist(&rdr->ecm_hdr_whitelist);
2210 tpl_addVar(vars, TPLADD, "ECMHEADERWHITELIST", value);
2211 free_mk_t(value);
2213 // Deprecated
2214 if(!apicall)
2216 tpl_addVar(vars, TPLADD, "DEPRECATEDCHECKED", (rdr->deprecated == 1) ? "checked" : "");
2218 else
2220 tpl_addVar(vars, TPLADD, "DEPRECATEDVALUE", (rdr->deprecated == 1) ? "1" : "0");
2223 // Smargopatch
2224 if(!apicall)
2226 tpl_addVar(vars, TPLADD, "SMARGOPATCHCHECKED", (rdr->smargopatch == 1) ? "checked" : "");
2228 else
2230 tpl_addVar(vars, TPLADD, "SMARGOPATCHVALUE", (rdr->smargopatch == 1) ? "1" : "0");
2233 // Autospeed
2234 if(!apicall)
2236 tpl_addVar(vars, TPLADD, "AUTOSPEEDCHECKED", (rdr->autospeed == 1) ? "checked" : "");
2238 else
2240 tpl_addVar(vars, TPLADD, "AUTOSPEEDVALUE", (rdr->autospeed == 1) ? "1" : "0");
2242 // sc8in1 dtrrts patch
2243 if(!apicall)
2245 tpl_addVar(vars, TPLADD, "SC8IN1DTRRTSPATCHCHECKED", (rdr->sc8in1_dtrrts_patch == 1) ? "checked" : "");
2247 else
2249 tpl_addVar(vars, TPLADD, "SC8IN1DTRRTSPATCHVALUE", (rdr->sc8in1_dtrrts_patch == 1) ? "1" : "0");
2252 if(!apicall)
2254 tpl_addVar(vars, TPLADD, "READOLDCLASSES", (rdr->read_old_classes == 1) ? "checked" : "");
2256 else
2258 tpl_addVar(vars, TPLADD, "READOLDCLASSES", (rdr->read_old_classes == 1) ? "1" : "0");
2261 // Detect
2262 if(rdr->detect & 0x80)
2263 { tpl_printf(vars, TPLADD, "DETECT", "!%s", RDR_CD_TXT[rdr->detect & 0x7f]); }
2264 else
2265 { tpl_addVar(vars, TPLADD, "DETECT", RDR_CD_TXT[rdr->detect & 0x7f]); }
2267 // Ratelimit
2268 if(rdr->ratelimitecm)
2270 tpl_printf(vars, TPLADD, "RATELIMITECM", "%d", rdr->ratelimitecm);
2271 tpl_printf(vars, TPLADD, "RATELIMITTIME", "%d", rdr->ratelimittime);
2272 tpl_printf(vars, TPLADD, "SRVIDHOLDTIME", "%d", rdr->srvidholdtime);
2273 // ECMUNIQUE
2274 if(!apicall)
2276 tpl_addVar(vars, TPLADD, "ECMUNIQUECHECKED", (rdr->ecmunique == 1) ? "checked" : "");
2278 else
2280 tpl_addVar(vars, TPLADD, "ECMUNIQUE", (rdr->ecmunique == 1) ? "1" : "0");
2283 // Cooldown
2284 if(rdr->cooldown[0] && rdr->cooldown[1])
2286 tpl_printf(vars, TPLADD, "COOLDOWNDELAY", "%d", rdr->cooldown[0]);
2287 tpl_printf(vars, TPLADD, "COOLDOWNTIME", "%d", rdr->cooldown[1]);
2289 // Frequencies
2290 tpl_printf(vars, TPLADD, "MHZ", "%d", rdr->mhz);
2291 tpl_printf(vars, TPLADD, "CARDMHZ", "%d", rdr->cardmhz);
2293 // Device
2294 if(!apicall)
2296 tpl_addVar(vars, TPLADD, "DEVICE", xml_encode(vars, rdr->device));
2298 else
2300 tpl_addVar(vars, TPLADD, "DEVICE", rdr->device);
2303 if(rdr->r_port)
2304 { tpl_printf(vars, TPLAPPEND, "DEVICE", ",%d", rdr->r_port); }
2305 if(rdr->l_port)
2307 if(rdr->r_port)
2308 { tpl_printf(vars, TPLAPPEND, "DEVICE", ",%d", rdr->l_port); }
2309 else
2310 { tpl_printf(vars, TPLAPPEND, "DEVICE", ",,%d", rdr->l_port); }
2313 // Group
2314 value = mk_t_group(rdr->grp);
2315 tpl_addVar(vars, TPLADD, "GRP", value);
2316 free_mk_t(value);
2318 #ifdef WITH_LB
2319 if(rdr->lb_weight)
2320 { tpl_printf(vars, TPLADD, "LBWEIGHT", "%d", rdr->lb_weight); }
2321 #endif
2323 //services
2324 if(!apicall)
2326 struct s_sidtab *sidtab = cfg.sidtab;
2327 //build matrix
2328 i = 0;
2329 while(sidtab != NULL)
2331 tpl_addVar(vars, TPLADD, "SIDLABEL", xml_encode(vars, sidtab->label));
2332 if(rdr->sidtabs.ok & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
2333 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
2334 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "READERCONFIGSIDOKBIT"));
2335 if(rdr->sidtabs.no & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
2336 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
2337 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "READERCONFIGSIDNOBIT"));
2338 if(rdr->lb_sidtabs.ok & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
2339 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
2340 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "READERCONFIGSIDLBOKBIT"));
2341 sidtab = sidtab->next;
2342 i++;
2344 if(i){
2345 tpl_addVar(vars, TPLADD, "READERCONFIGSIDINS", tpl_getTpl(vars, "READERCONFIGSID"));
2348 else
2350 value = mk_t_service(&rdr->sidtabs);
2351 if(strlen(value) > 0)
2352 { tpl_addVar(vars, TPLADD, "SERVICES", value); }
2353 free_mk_t(value);
2356 // CAID
2357 value = mk_t_caidtab(&rdr->ctab);
2358 tpl_addVar(vars, TPLADD, "CAIDS", value);
2359 free_mk_t(value);
2361 // AESkeys
2362 value = mk_t_aeskeys(rdr);
2363 tpl_addVar(vars, TPLADD, "AESKEYS", value);
2364 free_mk_t(value);
2366 //ident
2367 value = mk_t_ftab(&rdr->ftab);
2368 tpl_addVar(vars, TPLADD, "IDENTS", value);
2369 free_mk_t(value);
2371 //CHID
2372 value = mk_t_ftab(&rdr->fchid);
2373 tpl_addVar(vars, TPLADD, "CHIDS", value);
2374 free_mk_t(value);
2376 //Local cards
2377 value = mk_t_ftab(&rdr->localcards);
2378 tpl_addVar(vars, TPLADD, "LOCALCARDS", value);
2379 free_mk_t(value);
2381 //class
2382 value = mk_t_cltab(&rdr->cltab);
2383 tpl_addVar(vars, TPLADD, "CLASS", value);
2384 free_mk_t(value);
2386 if(rdr->cachemm || rdr->logemm)
2387 { tpl_printf(vars, TPLADD, "EMMCACHE", "%d,%d,%d,%d", rdr->cachemm, rdr->rewritemm, rdr->logemm, rdr->deviceemm); }
2389 //savenano
2390 value = mk_t_nano(rdr->s_nano);
2391 tpl_addVar(vars, TPLADD, "SAVENANO", value);
2392 free_mk_t(value);
2394 //blocknano
2395 value = mk_t_nano(rdr->b_nano);
2396 tpl_addVar(vars, TPLADD, "BLOCKNANO", value);
2397 free_mk_t(value);
2399 // Blocke EMM
2400 if(!apicall)
2402 tpl_addVar(vars, TPLADD, "BLOCKEMMUNKNOWNCHK", (rdr->blockemm & EMM_UNKNOWN) ? "checked" : "");
2403 tpl_addVar(vars, TPLADD, "BLOCKEMMUNIQCHK", (rdr->blockemm & EMM_UNIQUE) ? "checked" : "");
2404 tpl_addVar(vars, TPLADD, "BLOCKEMMSHAREDCHK", (rdr->blockemm & EMM_SHARED) ? "checked" : "");
2405 tpl_addVar(vars, TPLADD, "BLOCKEMMGLOBALCHK", (rdr->blockemm & EMM_GLOBAL) ? "checked" : "");
2407 else
2409 tpl_addVar(vars, TPLADD, "BLOCKEMMUNKNOWNVALUE", (rdr->blockemm & EMM_UNKNOWN) ? "1" : "0");
2410 tpl_addVar(vars, TPLADD, "BLOCKEMMUNIQVALUE", (rdr->blockemm & EMM_UNIQUE) ? "1" : "0");
2411 tpl_addVar(vars, TPLADD, "BLOCKEMMSHAREDVALUE", (rdr->blockemm & EMM_SHARED) ? "1" : "0");
2412 tpl_addVar(vars, TPLADD, "BLOCKEMMGLOBALVALUE", (rdr->blockemm & EMM_GLOBAL) ? "1" : "0");
2415 // Save EMM
2416 if(!apicall)
2418 tpl_addVar(vars, TPLADD, "SAVEEMMUNKNOWNCHK", (rdr->saveemm & EMM_UNKNOWN) ? "checked" : "");
2419 tpl_addVar(vars, TPLADD, "SAVEEMMUNIQCHK", (rdr->saveemm & EMM_UNIQUE) ? "checked" : "");
2420 tpl_addVar(vars, TPLADD, "SAVEEMMSHAREDCHK", (rdr->saveemm & EMM_SHARED) ? "checked" : "");
2421 tpl_addVar(vars, TPLADD, "SAVEEMMGLOBALCHK", (rdr->saveemm & EMM_GLOBAL) ? "checked" : "");
2423 else
2425 tpl_addVar(vars, TPLADD, "SAVEEMMUNKNOWNVALUE", (rdr->saveemm & EMM_UNKNOWN) ? "1" : "0");
2426 tpl_addVar(vars, TPLADD, "SAVEEMMUNIQVALUE", (rdr->saveemm & EMM_UNIQUE) ? "1" : "0");
2427 tpl_addVar(vars, TPLADD, "SAVEEMMSHAREDVALUE", (rdr->saveemm & EMM_SHARED) ? "1" : "0");
2428 tpl_addVar(vars, TPLADD, "SAVEEMMGLOBALVALUE", (rdr->saveemm & EMM_GLOBAL) ? "1" : "0");
2431 value = mk_t_emmbylen(rdr);
2432 if(strlen(value) > 0)
2433 { tpl_addVar(vars, TPLADD, "BLOCKEMMBYLEN", value); }
2434 free_mk_t(value);
2436 #ifdef MODULE_CCCAM
2437 if(!strcmp(rdr->cc_version, "2.0.11"))
2439 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED0", "selected");
2441 else if(!strcmp(rdr->cc_version, "2.1.1"))
2443 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED1", "selected");
2445 else if(!strcmp(rdr->cc_version, "2.1.2"))
2447 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED2", "selected");
2449 else if(!strcmp(rdr->cc_version, "2.1.3"))
2451 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED3", "selected");
2453 else if(!strcmp(rdr->cc_version, "2.1.4"))
2455 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED4", "selected");
2457 else if(!strcmp(rdr->cc_version, "2.2.0"))
2459 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED5", "selected");
2461 else if(!strcmp(rdr->cc_version, "2.2.1"))
2463 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED6", "selected");
2465 else if(!strcmp(rdr->cc_version, "2.3.0"))
2467 tpl_addVar(vars, TPLADD, "CCCVERSIONSELECTED7", "selected");
2469 #endif
2471 tpl_printf(vars, TPLADD, "TMP", "NDSVERSION%d", rdr->ndsversion);
2472 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
2474 tpl_printf(vars, TPLADD, "TMP", "NDSREADTIERS%d", rdr->readtiers);
2475 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
2477 tpl_printf(vars, TPLADD, "TMP", "NAGRAREAD%d", rdr->nagra_read);
2478 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
2480 if(rdr->detect_seca_nagra_tunneled_card)
2481 { tpl_addVar(vars, TPLADD, "NAGRADETECTSECACARDCHECKED", "checked"); }
2483 #ifdef MODULE_CCCAM
2484 tpl_printf(vars, TPLADD, "CCCMAXHOPS", "%d", rdr->cc_maxhops);
2485 tpl_printf(vars, TPLADD, "CCCMINDOWN", "%d", rdr->cc_mindown);
2486 tpl_printf(vars, TPLADD, "CCCRESHARE", "%d", rdr->cc_reshare);
2487 tpl_printf(vars, TPLADD, "RESHARE", "%d", cfg.cc_reshare);
2488 tpl_printf(vars, TPLADD, "CCCRECONNECT", "%d", rdr->cc_reconnect);
2490 if(rdr->cc_want_emu)
2491 { tpl_addVar(vars, TPLADD, "CCCWANTEMUCHECKED", "checked"); }
2492 if(rdr->cc_keepalive)
2493 { tpl_addVar(vars, TPLADD, "KEEPALIVECHECKED", "checked"); }
2494 #endif
2496 #ifdef MODULE_GBOX
2497 tpl_printf(vars, TPLADD, "GBOXMAXDISTANCE", "%d", rdr->gbox_maxdist);
2498 tpl_printf(vars, TPLADD, "GBOXMAXECMSEND", "%d", rdr->gbox_maxecmsend);
2499 tpl_printf(vars, TPLADD, "GBOXRESHARE", "%d", rdr->gbox_reshare);
2500 #endif
2502 #ifdef READER_DRECAS
2503 tpl_addVar(vars, TPLADD, "STMKEYS", rdr->stmkeys);
2504 #endif
2506 #if defined(READER_DRE) || defined(READER_DRECAS)
2507 tpl_addVar(vars, TPLADD, "USERSCRIPT", rdr->userscript);
2508 #endif
2510 tpl_addVar(vars, TPLADD, "PROTOCOL", reader_get_type_desc(rdr, 0));
2512 // Show only parameters which needed for the reader
2513 switch(rdr->typ)
2515 case R_CONSTCW:
2516 case R_DB2COM1:
2517 case R_DB2COM2:
2518 case R_MOUSE :
2519 case R_DRECAS :
2520 case R_MP35:
2521 case R_SC8in1 :
2522 case R_SMART :
2523 case R_INTERNAL:
2524 case R_SERIAL :
2525 case R_PCSC :
2526 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGSTDHWREADERBIT"));
2527 break;
2528 case R_CAMD35 :
2529 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGCAMD35BIT"));
2530 break;
2531 case R_CS378X :
2532 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGCS378XBIT"));
2533 break;
2534 case R_RADEGAST:
2535 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGRADEGASTBIT"));
2536 break;
2537 case R_SCAM:
2538 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGSCAMBIT"));
2539 break;
2540 case R_GHTTP:
2541 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGGHTTPBIT"));
2542 break;
2543 case R_GBOX:
2544 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGGBOXBIT"));
2545 break;
2546 case R_NEWCAMD:
2547 if(rdr->ncd_proto == NCD_525)
2549 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGNCD525BIT"));
2551 else if(rdr->ncd_proto == NCD_524)
2553 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGNCD524BIT"));
2555 break;
2556 #ifdef MODULE_CCCAM
2557 case R_CCCAM :
2558 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGCCCAMBIT"));
2559 break;
2560 #endif
2561 default :
2562 tpl_addMsg(vars, "Error: protocol not resolvable");
2563 break;
2567 #ifdef MODULE_CCCAM
2568 if(rdr->typ != R_CCCAM)
2570 tpl_printf(vars, TPLADD, "CCCHOP", "%d", rdr->cc_hop);
2571 tpl_addVar(vars, TPLAPPEND, "READERDEPENDINGCONFIG", tpl_getTpl(vars, "READERCONFIGHOPBIT"));
2573 #endif
2575 return tpl_getTpl(vars, "READERCONFIG");
2578 static char *send_oscam_reader_stats(struct templatevars *vars, struct uriparams *params, int32_t apicall)
2581 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
2583 int8_t error;
2584 struct s_client *cl = NULL;
2585 struct s_reader *rdr;
2587 rdr = get_reader_by_label(getParam(params, "label"));
2588 error = (rdr ? 0 : 1);
2590 if(!error && rdr)
2592 cl = rdr->client;
2593 error = (cl ? 0 : 1);
2596 if(error)
2598 tpl_addVar(vars, TPLAPPEND, "READERSTATSROW", tpl_getTpl(vars, "READERSTATSROWBIT"));
2599 if(!apicall)
2600 { return tpl_getTpl(vars, "READERSTATS"); }
2601 else
2602 { return tpl_getTpl(vars, "APIREADERSTATS"); }
2605 #ifdef WITH_LB
2606 char *stxt[] = {"found", "cache1", "cache2", "cache3",
2607 "not found", "timeout", "sleeping",
2608 "fake", "invalid", "corrupt", "no card", "expdate",
2609 "disabled", "stopped"
2612 if(strcmp(getParam(params, "action"), "resetstat") == 0)
2614 char *rcs = getParam(params, "rc");
2615 int32_t retval = 0;
2616 if(strlen(rcs) > 0)
2618 int8_t rc;
2619 rc = atoi(rcs);
2620 retval = clean_stat_by_rc(rdr, rc, 0);
2621 cs_log("Reader %s stats %d %s entr%s deleted by WebIF from %s",
2622 rdr->label, retval, stxt[rc],
2623 retval == 1 ? "y" : "ies",
2624 cs_inet_ntoa(GET_IP()));
2626 else
2628 clear_reader_stat(rdr);
2629 cs_log("Reader %s stats resetted by WebIF from %s", rdr->label, cs_inet_ntoa(GET_IP()));
2634 if(strcmp(getParam(params, "action"), "deleterecord") == 0)
2636 char *record = getParam(params, "record");
2637 if(strlen(record) > 0)
2639 int32_t retval = 0;
2640 uint32_t caid, provid, sid, cid, len;
2641 sscanf(record, "%4x@%6x:%4x:%4x:%4x", &caid, &provid, &sid, &cid, &len);
2642 retval = clean_stat_by_id(rdr, caid, provid, sid, cid, len);
2643 cs_log("Reader %s stats %d entr%s deleted by WebIF from %s",
2644 rdr->label, retval,
2645 retval == 1 ? "y" : "ies",
2646 cs_inet_ntoa(GET_IP()));
2650 if(strcmp(getParam(params, "action"), "updateecmlen") == 0)
2652 update_ecmlen_from_stat(rdr);
2653 write_server();
2656 #endif
2658 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
2659 tpl_addVar(vars, TPLADD, "LABEL", xml_encode(vars, rdr->label));
2660 tpl_addVar(vars, TPLADD, "ENCODEDLABEL", urlencode(vars, rdr->label));
2662 if(apicall)
2664 int32_t i, emmcount = 0;
2665 char *ttxt[] = {"unknown", "unique", "shared", "global"};
2667 for(i = 0; i < 4; i++)
2669 tpl_addVar(vars, TPLADD, "EMMRESULT", "error");
2670 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
2671 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmerror[i]);
2672 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
2673 emmcount += rdr->emmerror[i];
2674 tpl_printf(vars, TPLADD, "TOTALERROR", "%d", emmcount);
2676 emmcount = 0;
2677 for(i = 0; i < 4; i++)
2679 tpl_addVar(vars, TPLADD, "EMMRESULT", "written");
2680 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
2681 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmwritten[i]);
2682 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
2683 emmcount += rdr->emmwritten[i];
2684 tpl_printf(vars, TPLADD, "TOTALWRITTEN", "%d", emmcount);
2686 emmcount = 0;
2687 for(i = 0; i < 4; i++)
2689 tpl_addVar(vars, TPLADD, "EMMRESULT", "skipped");
2690 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
2691 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmskipped[i]);
2692 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
2693 emmcount += rdr->emmskipped[i];
2694 tpl_printf(vars, TPLADD, "TOTALSKIPPED", "%d", emmcount);
2696 emmcount = 0;
2697 for(i = 0; i < 4; i++)
2699 tpl_addVar(vars, TPLADD, "EMMRESULT", "blocked");
2700 tpl_addVar(vars, TPLADD, "EMMTYPE", ttxt[i]);
2701 tpl_printf(vars, TPLADD, "EMMCOUNT", "%d", rdr->emmblocked[i]);
2702 tpl_addVar(vars, TPLAPPEND, "EMMSTATS", tpl_getTpl(vars, "APIREADERSTATSEMMBIT"));
2703 emmcount += rdr->emmblocked[i];
2704 tpl_printf(vars, TPLADD, "TOTALBLOCKED", "%d", emmcount);
2708 if(apicall)
2710 char *txt = "UNDEF";
2711 switch(rdr->card_status)
2713 case NO_CARD:
2714 txt = "OFF";
2715 break;
2716 case UNKNOWN:
2717 txt = "UNKNOWN";
2718 break;
2719 case READER_DEVICE_ERROR:
2720 txt = "READER DEVICE ERROR";
2721 break;
2722 case CARD_NEED_INIT:
2723 txt = "NEEDINIT";
2724 break;
2725 case CARD_INSERTED:
2726 if(cl->typ == 'p')
2727 { txt = "CONNECTED"; }
2728 else
2729 { txt = "CARDOK"; }
2730 break;
2731 case CARD_FAILURE:
2732 txt = "ERROR";
2733 break;
2734 default:
2735 txt = "UNDEF";
2737 tpl_addVar(vars, TPLADD, "READERSTATUS", txt);
2738 tpl_printf(vars, TPLADD, "READERCAID", "%04X", rdr->caid);
2741 int32_t rowcount = 0;
2742 uint64_t ecmcount = 0;
2743 time_t lastaccess = 0;
2745 #ifdef WITH_LB
2746 int32_t rc2hide = (-1);
2747 if(strlen(getParam(params, "hide")) > 0)
2748 { rc2hide = atoi(getParam(params, "hide")); }
2750 int32_t rc2show = (-1);
2751 if(strlen(getParam(params, "show")) > 0)
2752 { rc2show = atoi(getParam(params, "show")); }
2754 if(rdr->lb_stat)
2756 int32_t statsize;
2757 // @todo alno: sort by click, 0=ascending, 1=descending (maybe two buttons or reverse on second click)
2758 READER_STAT **statarray = get_sorted_stat_copy(rdr, 0, &statsize);
2759 char channame[CS_SERVICENAME_SIZE];
2760 for(; rowcount < statsize; ++rowcount)
2762 READER_STAT *s = statarray[rowcount];
2763 if(!(s->rc == rc2hide) && ((rc2show == -1) || (s->rc == rc2show)))
2765 struct tm lt;
2766 localtime_r(&s->last_received.time, &lt); // fixme we need walltime!
2767 ecmcount += s->ecm_count;
2768 if(!apicall)
2770 tpl_printf(vars, TPLADD, "CHANNEL", "%04X@%06X:%04X:%04X", s->caid, s->prid, s->srvid, s->chid);
2771 tpl_addVar(vars, TPLADD, "CHANNELNAME", xml_encode(vars, get_servicename(cur_client(), s->srvid, s->prid, s->caid, channame, sizeof(channame))));
2772 tpl_printf(vars, TPLADD, "ECMLEN", "%04hX", s->ecmlen);
2773 tpl_addVar(vars, TPLADD, "RC", stxt[s->rc]);
2774 tpl_printf(vars, TPLADD, "TIME", PRINTF_LOCAL_D " ms", s->time_avg);
2775 if(s->time_stat[s->time_idx])
2776 { tpl_printf(vars, TPLADD, "TIMELAST", PRINTF_LOCAL_D " ms", s->time_stat[s->time_idx]); }
2777 else
2778 { tpl_addVar(vars, TPLADD, "TIMELAST", ""); }
2779 tpl_printf(vars, TPLADD, "COUNT", PRINTF_LOCAL_D, s->ecm_count);
2781 if(s->last_received.time)
2783 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);
2786 else
2788 tpl_addVar(vars, TPLADD, "LAST", "never");
2791 else
2793 tpl_printf(vars, TPLADD, "ECMCAID", "%04X", s->caid);
2794 tpl_printf(vars, TPLADD, "ECMPROVID", "%06X", s->prid);
2795 tpl_printf(vars, TPLADD, "ECMSRVID", "%04X", s->srvid);
2796 tpl_printf(vars, TPLADD, "ECMLEN", "%04hX", s->ecmlen);
2797 tpl_addVar(vars, TPLADD, "ECMCHANNELNAME", xml_encode(vars, get_servicename(cur_client(), s->srvid, s->prid, s->caid, channame, sizeof(channame))));
2798 tpl_printf(vars, TPLADD, "ECMTIME", PRINTF_LOCAL_D, s->time_avg);
2799 tpl_printf(vars, TPLADD, "ECMTIMELAST", PRINTF_LOCAL_D, s->time_stat[s->time_idx]);
2800 tpl_printf(vars, TPLADD, "ECMRC", "%d", s->rc);
2801 tpl_addVar(vars, TPLADD, "ECMRCS", stxt[s->rc]);
2802 if(s->last_received.time)
2804 char tbuffer [30];
2805 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &lt);
2806 tpl_addVar(vars, TPLADD, "ECMLAST", tbuffer);
2808 else
2810 tpl_addVar(vars, TPLADD, "ECMLAST", "");
2812 tpl_printf(vars, TPLADD, "ECMCOUNT", PRINTF_LOCAL_D, s->ecm_count);
2814 if(s->last_received.time > lastaccess)
2815 { lastaccess = s->last_received.time; }
2818 if(!apicall)
2820 if(s->rc == E_NOTFOUND)
2822 tpl_addVar(vars, TPLAPPEND, "READERSTATSROWNOTFOUND", tpl_getTpl(vars, "READERSTATSBIT"));
2823 tpl_addVar(vars, TPLADD, "RESETA", urlencode(vars, rdr->label));
2824 tpl_addVar(vars, TPLADD, "READERSTATSNFHEADLINE", tpl_getTpl(vars, "READERSTATSROWNOTFOUNDBIT"));
2826 else if(s->rc == E_TIMEOUT)
2828 tpl_addVar(vars, TPLAPPEND, "READERSTATSROWTIMEOUT", tpl_getTpl(vars, "READERSTATSBIT"));
2829 tpl_addVar(vars, TPLADD, "RESETB", urlencode(vars, rdr->label));
2830 tpl_addVar(vars, TPLADD, "READERSTATSTOHEADLINE", tpl_getTpl(vars, "READERSTATSROWTIMEOUTBIT"));
2832 else if(s->rc == E_INVALID)
2834 tpl_addVar(vars, TPLAPPEND, "READERSTATSROWINVALID", tpl_getTpl(vars, "READERSTATSBIT"));
2835 tpl_addVar(vars, TPLADD, "RESETC", urlencode(vars, rdr->label));
2836 tpl_addVar(vars, TPLADD, "READERSTATSIVHEADLINE", tpl_getTpl(vars, "READERSTATSROWINVALIDBIT"));
2838 else
2839 { tpl_addVar(vars, TPLAPPEND, "READERSTATSROWFOUND", tpl_getTpl(vars, "READERSTATSBIT")); }
2841 else
2844 tpl_addVar(vars, TPLAPPEND, "ECMSTATS", tpl_getTpl(vars, "APIREADERSTATSECMBIT"));
2848 NULLFREE(statarray);
2850 else
2851 #endif
2852 tpl_addVar(vars, TPLAPPEND, "READERSTATSROW", tpl_getTpl(vars, "READERSTATSNOSTATS"));
2854 tpl_printf(vars, TPLADD, "ROWCOUNT", "%d", rowcount);
2856 if(lastaccess > 0)
2858 char tbuffer [30];
2859 struct tm lt;
2860 localtime_r(&lastaccess, &lt);
2861 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &lt);
2862 tpl_addVar(vars, TPLADD, "LASTACCESS", tbuffer);
2864 else
2866 tpl_addVar(vars, TPLADD, "LASTACCESS", "");
2869 if(apicall)
2871 if(cl)
2873 char *value = get_ecm_historystring(cl);
2874 tpl_addVar(vars, TPLADD, "ECMHISTORY", value);
2875 free_mk_t(value);
2879 tpl_printf(vars, TPLADD, "TOTALECM", "%'" PRIu64, ecmcount);
2881 if(!apicall)
2882 { return tpl_getTpl(vars, "READERSTATS"); }
2883 else
2884 { return tpl_getTpl(vars, "APIREADERSTATS"); }
2887 static char *send_oscam_user_config_edit(struct templatevars *vars, struct uriparams *params, int32_t apicall)
2889 struct s_auth *account, *ptr, *chk;
2890 char user[sizeof(first_client->account->usr)];
2892 int32_t i;
2893 int existing_insert = 0;
2895 if(!apicall) { setActiveMenu(vars, MNU_USERS); }
2897 if(strcmp(getParam(params, "action"), "Save As") == 0) { cs_strncpy(user, getParam(params, "newuser"), sizeof(user) / sizeof(char)); }
2898 else { cs_strncpy(user, getParam(params, "user"), sizeof(user) / sizeof(char)); }
2900 account = NULL;
2901 for(chk = cfg.account; chk != NULL; chk = chk->next) {
2902 if(strcmp(user, chk->usr) == 0)
2903 { account = chk; }
2904 if(!existing_insert){
2905 tpl_printf(vars, TPLADD, "EXISTING_INS", "'%s'", urlencode(vars, chk->usr));
2906 existing_insert++;
2907 }else{
2908 tpl_printf(vars, TPLAPPEND, "EXISTING_INS", ",'%s'", urlencode(vars, chk->usr));
2912 // Create a new user if it doesn't yet
2913 if(account == NULL)
2915 i = 1;
2916 while(strlen(user) < 1)
2918 snprintf(user, sizeof(user) / sizeof(char) - 1, "NEWUSER%d", i);
2919 for(account = cfg.account; account != NULL && strcmp(user, account->usr) != 0; account = account->next) { ; }
2920 if(account != NULL) { user[0] = '\0'; }
2921 ++i;
2923 if(!cs_malloc(&account, sizeof(struct s_auth))) { return "0"; }
2924 if(cfg.account == NULL) { cfg.account = account; }
2925 else
2927 for(ptr = cfg.account; ptr != NULL && ptr->next != NULL; ptr = ptr->next) { ; }
2928 ptr->next = account;
2930 account_set_defaults(account);
2931 account->disabled = 1;
2932 cs_strncpy((char *)account->usr, user, sizeof(account->usr));
2933 if(!account->grp)
2934 { account->grp = 1; }
2935 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
2936 else if(strcmp(getParam(params, "action"), "Save As") == 0) { tpl_addMsg(vars, "New user has been added with cloned settings"); }
2937 else { tpl_addMsg(vars, "New user has been added with default settings"); }
2938 // no need to refresh anything here as the account is disabled by default and there's no client with this new account anyway!
2941 if((strcmp(getParam(params, "action"), "Save") == 0) || (strcmp(getParam(params, "action"), "Save As") == 0))
2943 char servicelabels[1024] = "";
2945 for(i = 0; i < (*params).paramcount; i++)
2947 if((strcmp((*params).params[i], "action")) &&
2948 (strcmp((*params).params[i], "user")) &&
2949 (strcmp((*params).params[i], "newuser")) &&
2950 (strcmp((*params).params[i], "part")))
2953 if(!strcmp((*params).params[i], "services"))
2954 { snprintf(servicelabels + strlen(servicelabels), sizeof(servicelabels) - strlen(servicelabels), "%s,", (*params).values[i]); }
2955 else
2956 { chk_account((*params).params[i], (*params).values[i], account); }
2959 chk_account("services", servicelabels, account);
2961 refresh_oscam(REFR_CLIENTS);
2963 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
2964 else if(strcmp(getParam(params, "action"), "Save As") != 0) { tpl_addMsg(vars, "User Account updated and saved"); }
2967 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, account->usr));
2968 tpl_addVar(vars, TPLADD, "PASSWORD", xml_encode(vars, account->pwd));
2969 tpl_addVar(vars, TPLADD, "DESCRIPTION", xml_encode(vars, account->description));
2971 //Disabled
2972 if(!apicall)
2974 if(account->disabled)
2975 { tpl_addVar(vars, TPLADD, "DISABLEDCHECKED", "checked"); }
2977 else
2979 tpl_printf(vars, TPLADD, "DISABLEDVALUE", "%d", account->disabled);
2982 //Expirationdate
2983 struct tm timeinfo;
2984 cs_gmtime_r(&account->expirationdate, &timeinfo);
2985 char buf [80];
2986 strftime(buf, 80, "%Y-%m-%d", &timeinfo);
2987 if(strcmp(buf, "1970-01-01")) { tpl_addVar(vars, TPLADD, "EXPDATE", buf); }
2989 //Allowed TimeFrame
2990 if(account->allowedtimeframe[0] && account->allowedtimeframe[1])
2992 tpl_printf(vars, TPLADD, "ALLOWEDTIMEFRAME", "%02d:%02d-%02d:%02d",
2993 account->allowedtimeframe[0] / 60,
2994 account->allowedtimeframe[0] % 60,
2995 account->allowedtimeframe[1] / 60,
2996 account->allowedtimeframe[1] % 60);
2999 //Group
3000 char *value = mk_t_group(account->grp);
3001 tpl_addVar(vars, TPLADD, "GROUPS", value);
3002 free_mk_t(value);
3004 // allowed protocols
3005 value = mk_t_allowedprotocols(account);
3006 tpl_addVar(vars, TPLADD, "ALLOWEDPROTOCOLS", value);
3007 free_mk_t(value);
3009 //Hostname
3010 tpl_addVar(vars, TPLADD, "DYNDNS", xml_encode(vars, account->dyndns));
3012 //Uniq
3013 if(!apicall)
3015 tpl_printf(vars, TPLADD, "TMP", "UNIQSELECTED%d", account->uniq);
3016 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3018 else
3020 tpl_printf(vars, TPLADD, "UNIQVALUE", "%d", account->uniq);
3023 //Sleep
3024 if(!account->tosleep) { tpl_addVar(vars, TPLADD, "SLEEP", "0"); }
3025 else { tpl_printf(vars, TPLADD, "SLEEP", "%d", account->tosleep); }
3027 //Monlevel selector
3028 if(!apicall)
3030 tpl_printf(vars, TPLADD, "TMP", "MONSELECTED%d", account->monlvl);
3031 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3033 else
3035 tpl_printf(vars, TPLADD, "MONVALUE", "%d", account->monlvl);
3038 //Au
3039 if(account->autoau == 1)
3040 { tpl_addVar(vars, TPLADD, "AUREADER", "1"); }
3041 else if(account->aureader_list)
3043 value = mk_t_aureader(account);
3044 tpl_addVar(vars, TPLADD, "AUREADER", value);
3045 free_mk_t(value);
3048 if(!apicall)
3050 /* SERVICES */
3051 struct s_sidtab *sidtab = cfg.sidtab;
3052 //build matrix
3053 i = 0;
3054 while(sidtab != NULL)
3056 tpl_addVar(vars, TPLADD, "SIDLABEL", xml_encode(vars, sidtab->label));
3057 if(account->sidtabs.ok & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
3058 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
3059 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "USEREDITSIDOKBIT"));
3060 if(account->sidtabs.no & ((SIDTABBITS)1 << i)) { tpl_addVar(vars, TPLADD, "CHECKED", "checked"); }
3061 else { tpl_addVar(vars, TPLADD, "CHECKED", ""); }
3062 tpl_addVar(vars, TPLAPPEND, "SIDS", tpl_getTpl(vars, "USEREDITSIDNOBIT"));
3063 sidtab = sidtab->next;
3064 i++;
3066 if(i){
3067 tpl_addVar(vars, TPLADD, "USEREDITSIDINS", tpl_getTpl(vars, "USEREDITSID"));
3070 else
3072 value = mk_t_service(&account->sidtabs);
3073 if(strlen(value) > 0)
3074 { tpl_addVar(vars, TPLADD, "SERVICES", value); }
3075 free_mk_t(value);
3078 // CAID
3079 value = mk_t_caidtab(&account->ctab);
3080 tpl_addVar(vars, TPLADD, "CAIDS", value);
3081 free_mk_t(value);
3083 //ident
3084 value = mk_t_ftab(&account->ftab);
3085 tpl_addVar(vars, TPLADD, "IDENTS", value);
3086 free_mk_t(value);
3088 //CHID
3089 value = mk_t_ftab(&account->fchid);
3090 tpl_addVar(vars, TPLADD, "CHIDS", value);
3091 free_mk_t(value);
3093 //class
3094 value = mk_t_cltab(&account->cltab);
3095 tpl_addVar(vars, TPLADD, "CLASS", value);
3096 free_mk_t(value);
3098 //Betatunnel
3099 value = mk_t_tuntab(&account->ttab);
3100 tpl_addVar(vars, TPLADD, "BETATUNNELS", value);
3101 free_mk_t(value);
3103 //SUPPRESSCMD08
3104 if(!apicall)
3106 if(account->c35_suppresscmd08)
3107 { tpl_addVar(vars, TPLADD, "SUPPRESSCMD08", "selected"); }
3109 else
3111 tpl_printf(vars, TPLADD, "SUPPRESSCMD08VALUE", "%d", account->c35_suppresscmd08);
3114 //Sleepsend
3115 if(account->c35_sleepsend)
3117 tpl_printf(vars, TPLADD, "SLEEPSEND", "selected");
3120 //max_connections
3121 tpl_printf(vars, TPLADD, "MAXCONNECTIONS", "%d", account->max_connections);
3123 //User Max Idle
3124 tpl_printf(vars, TPLADD, "UMAXIDLE", "%d", account->umaxidle);
3126 //EMM Reassembly selector
3127 if(!apicall)
3129 tpl_printf(vars, TPLADD, "TMP", "EMMRSELECTED%d", account->emm_reassembly);
3130 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3132 else
3134 tpl_printf(vars, TPLADD, "EMMRVALUE", "%d", account->emm_reassembly);
3137 //Prefer local cards
3138 if(!apicall)
3140 tpl_printf(vars, TPLADD, "TMP", "PREFERLOCALCARDS%d", account->preferlocalcards);
3141 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3142 char *tmp = NULL;
3143 switch(cfg.preferlocalcards)
3145 case -1:
3146 tmp = "-1 - Use Global prefer local cards";
3147 break;
3148 case 0:
3149 tmp = "0 - local cards like proxied";
3150 break;
3151 case 1:
3152 tmp = "1 - prefer cache-ex then local cards";
3153 break;
3154 case 2:
3155 tmp = "2 - prefer local cards above cache-ex";
3156 break;
3158 tpl_addVar(vars, TPLADD, "CFGPREFERLOCALCARDS", tmp);
3160 else
3162 tpl_printf(vars, TPLADD, "PREFERLOCALCARDSVALUE", "%d", account->preferlocalcards);
3165 #ifdef CS_CACHEEX
3166 // Cacheex
3167 if(!apicall)
3169 tpl_printf(vars, TPLADD, "TMP", "CACHEEXSELECTED%d", account->cacheex.mode);
3170 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3173 else
3175 tpl_printf(vars, TPLADD, "CACHEEX", "%d", account->cacheex.mode);
3177 tpl_printf(vars, TPLADD, "CACHEEX_MAXHOP", "%d", account->cacheex.maxhop);
3179 value = mk_t_cacheex_hitvaluetab(&account->cacheex.filter_caidtab);
3180 //if (strlen(value) > 0)
3181 tpl_printf(vars, TPLADD, "CACHEEX_ECM_FILTER", "%s", value);
3182 free_mk_t(value);
3184 tpl_addVar(vars, TPLADD, "DCCHECKED", (account->cacheex.drop_csp == 1) ? "checked" : "");
3185 tpl_addVar(vars, TPLADD, "ARCHECKED", (account->cacheex.allow_request == 1) ? "checked" : "");
3186 tpl_addVar(vars, TPLADD, "AFCHECKED", (account->cacheex.allow_filter == 1) ? "checked" : "");
3187 tpl_addVar(vars, TPLADD, "BLOCKFAKECWSCHECKED", (account->cacheex.block_fakecws == 1) ? "checked" : "");
3188 tpl_addVar(vars, TPLADD, "NWTCHECKED", (account->no_wait_time == 1) ? "checked" : "");
3190 #endif
3192 #ifdef CW_CYCLE_CHECK
3193 tpl_addVar(vars, TPLADD, "USERCWCYCLEDISABLE", (account->cwc_disable == 1) ? "checked" : "");
3194 #endif
3196 //Keepalive
3197 if(!apicall)
3199 if(account->ncd_keepalive)
3200 { tpl_addVar(vars, TPLADD, "KEEPALIVE", "checked"); }
3202 else
3204 tpl_printf(vars, TPLADD, "KEEPALIVEVALUE", "%d", account->ncd_keepalive);
3207 #ifdef CS_ANTICASC
3208 tpl_printf(vars, TPLADD, "AC_USERS", "%d", account->ac_users);
3209 tpl_printf(vars, TPLADD, "CFGNUMUSERS", "%d", cfg.ac_users);
3210 if(!apicall)
3212 tpl_printf(vars, TPLADD, "TMP", "PENALTY%d", account->ac_penalty);
3213 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3214 char *tmp = NULL;
3215 switch(cfg.ac_penalty)
3217 case 0:
3218 tmp = "(0) Only write to log";
3219 break;
3220 case 1:
3221 tmp = "(1) NULL CW";
3222 break;
3223 case 2:
3224 tmp = "(2) Ban";
3225 break;
3226 case 3:
3227 tmp = "(3) Real CW delayed";
3228 break;
3230 tpl_addVar(vars, TPLADD, "CFGPENALTY", tmp);
3232 else
3234 tpl_printf(vars, TPLADD, "PENALTYVALUE", "%d", account->ac_penalty);
3236 tpl_printf(vars, TPLADD, "ACOSC_MAX_ACTIVE_SIDS", "%d", account->acosc_max_active_sids);
3237 tpl_printf(vars, TPLADD, "CFG_ACOSC_MAX_ACTIVE_SIDS", "%d", cfg.acosc_max_active_sids);
3238 tpl_printf(vars, TPLADD, "ACOSC_ZAP_LIMIT", "%d", account->acosc_zap_limit);
3239 tpl_printf(vars, TPLADD, "CFG_ACOSC_ZAP_LIMIT", "%d", cfg.acosc_zap_limit);
3240 if(!apicall)
3242 tpl_printf(vars, TPLADD, "TMP", "ACOSC_PENALTY%d", account->acosc_penalty);
3243 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3244 char *tmp = NULL;
3245 switch(cfg.acosc_penalty)
3247 case -1:
3248 tmp = "(-1) Use Global Value";
3249 break;
3250 case 0:
3251 tmp = "(0) Only write to log";
3252 break;
3253 case 1:
3254 tmp = "(1) NULL CW";
3255 break;
3256 case 2:
3257 tmp = "(2) Ban";
3258 break;
3259 case 3:
3260 tmp = "(3) CW delayed";
3261 break;
3263 tpl_addVar(vars, TPLADD, "CFG_ACOSC_PENALTY", tmp);
3264 } else
3266 tpl_printf(vars, TPLADD, "ACOSC_PENALTYVALUE", "%d", account->acosc_penalty);
3269 tpl_printf(vars, TPLADD, "ACOSC_PENALTY_DURATION", "%d", account->acosc_penalty_duration);
3270 tpl_printf(vars, TPLADD, "CFG_ACOSC_PENALTY_DURATION", "%d", cfg.acosc_penalty_duration);
3271 tpl_printf(vars, TPLADD, "ACOSC_DELAY", "%d", account->acosc_delay);
3272 tpl_printf(vars, TPLADD, "CFG_ACOSC_DELAY", "%d", cfg.acosc_delay);
3273 #endif
3275 #ifdef MODULE_CCCAM
3276 tpl_printf(vars, TPLADD, "CCCMAXHOPS", "%d", account->cccmaxhops);
3277 tpl_printf(vars, TPLADD, "CCCRESHARE", "%d", account->cccreshare);
3278 tpl_printf(vars, TPLADD, "RESHARE", "%d", cfg.cc_reshare);
3280 //CCcam Ignore Reshare
3281 tpl_printf(vars, TPLADD, "TMP", "CCCIGNRSHRSELECTED%d", account->cccignorereshare);
3282 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3283 tpl_addVar(vars, TPLADD, "CFGIGNORERESHARE",
3284 cfg.cc_ignore_reshare == 0 ?
3285 "0 - use reshare level of Server" : "1 - use reshare level of Reader or User");
3287 //CCcam Stealth Mode
3288 tpl_printf(vars, TPLADD, "TMP", "CCCSTEALTHSELECTED%d", account->cccstealth);
3289 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMP"), "selected");
3291 tpl_addVar(vars, TPLADD, "STEALTH", cfg.cc_stealth ? "enable" : "disable");
3292 #endif
3294 //Failban
3295 tpl_printf(vars, TPLADD, "FAILBAN", "%d", account->failban);
3297 if(!apicall)
3298 { return tpl_getTpl(vars, "USEREDIT"); }
3299 else
3300 { return tpl_getTpl(vars, "APIUSEREDIT"); }
3304 static void webif_add_client_proto(struct templatevars *vars, struct s_client *cl, const char *proto, int8_t apicall)
3306 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTO", "");
3307 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOSORT", "");
3308 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOTITLE", "");
3309 tpl_addVar(vars, TPLADDONCE, "PROTOICON", "");
3310 if(!cl) { return; }
3311 #ifdef MODULE_NEWCAMD
3312 if(streq(proto, "newcamd") && cl->typ == 'c')
3314 tpl_printf(vars, TPLADD, "CLIENTPROTO", "%s (%s)", proto, newcamd_get_client_name(cl->ncd_client_id));
3315 tpl_printf(vars, TPLADD, "CLIENTPROTOSORT", "%s (%s)", proto, newcamd_get_client_name(cl->ncd_client_id));
3316 if(cfg.http_showpicons )
3318 char picon_name[32];
3319 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s_%s", (char *)proto, newcamd_get_client_name(cl->ncd_client_id));
3320 if(picon_exists(picon_name))
3322 if (!apicall) {
3323 tpl_addVar(vars, TPLADD, "NCMDA", (char *)proto);
3324 tpl_addVar(vars, TPLADD, "NCMDB", (char *)newcamd_get_client_name(cl->ncd_client_id));
3325 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTONEWCAMDPIC"));
3326 } else {
3327 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s_%s",(char *)proto, (char *)newcamd_get_client_name(cl->ncd_client_id));
3330 else
3332 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s_%s.tpl", proto, newcamd_get_client_name(cl->ncd_client_id));
3335 return;
3337 #endif
3338 #ifdef MODULE_CCCAM
3339 if(strncmp(proto, "cccam", 5) == 0)
3341 struct cc_data *cc = cl->cc;
3342 if(cc && cc->remote_version && cc->remote_build)
3344 tpl_printf(vars, TPLADD, "CLIENTPROTO", "%s (%s-%s)", proto, cc->remote_version, cc->remote_build);
3345 tpl_printf(vars, TPLADD, "CLIENTPROTOSORT", "%s (%s-%s)", proto, cc->remote_version, cc->remote_build);
3346 if(cccam_client_multics_mode(cl))
3348 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "Multics, revision r%d", cc->multics_version[0] | (cc->multics_version[1] << 8));
3350 else
3352 tpl_addVar(vars, TPLADD, "CLIENTPROTOTITLE", cc->extended_mode ? cc->remote_oscam : "");
3355 if(cfg.http_showpicons)
3357 char picon_name[32];
3359 int8_t is_other_proto = 0;
3360 if(cccam_client_multics_mode(cl)) { is_other_proto = 1; }
3362 switch(is_other_proto)
3364 case 1:
3365 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s_r_%d", proto, cc->multics_version[0] | (cc->multics_version[1] << 8));
3366 if(picon_exists(picon_name))
3368 if (!apicall) {
3369 tpl_addVar(vars, TPLADD, "CCA", (char *)proto);
3370 tpl_addVar(vars, TPLADD, "CCB", "r");
3371 tpl_printf(vars, TPLADD, "CCC", "%d", cc->multics_version[0] | (cc->multics_version[1] << 8));
3372 tpl_addVar(vars, TPLADD, "CCD", "");
3373 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTOCCCAMPIC"));
3374 } else {
3375 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s_r_%d",(char *)proto, cc->multics_version[0] | (cc->multics_version[1] << 8));
3378 else
3380 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "Multics, revision r%d missing icon: IC_%s_r_%d.tpl",
3381 cc->multics_version[0] | (cc->multics_version[1] << 8), proto, cc->multics_version[0] | (cc->multics_version[1] << 8));
3383 break;
3385 default:
3386 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s_%s_%s", proto, cc->remote_version, cc->remote_build);
3387 if(picon_exists(picon_name))
3389 if (!apicall) {
3390 tpl_addVar(vars, TPLADD, "CCA", (char *)proto);
3391 tpl_addVar(vars, TPLADD, "CCB", cc->remote_version);
3392 tpl_addVar(vars, TPLADD, "CCC", cc->remote_build);
3393 tpl_addVar(vars, TPLADD, "CCD", cc->extended_mode ? cc->remote_oscam : "");
3394 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTOCCCAMPIC"));
3395 } else {
3396 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s_%s_%s",(char *)proto, cc->remote_version, cc->remote_build);
3399 else
3401 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "%s missing icon: IC_%s_%s_%s.tpl",
3402 cc->extended_mode ? cc->remote_oscam : "", proto, cc->remote_version, cc->remote_build);
3404 break;
3408 return;
3410 #endif
3411 #ifdef HAVE_DVBAPI
3412 if(streq(proto, "dvbapi") && cl->typ == 'c' && strcmp(dvbapi_get_client_name(), ""))
3414 if (!apicall)
3415 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());
3416 else
3417 tpl_printf(vars, TPLADD, "CLIENTPROTO", "%s (client: %s, protocol version: %d)", proto, dvbapi_get_client_name(), dvbapi_get_client_proto_version());
3418 tpl_printf(vars, TPLADD, "CLIENTPROTOSORT", "%s", proto);
3419 return;
3421 #endif
3422 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTO", (char *)proto);
3423 tpl_addVar(vars, TPLADDONCE, "CLIENTPROTOSORT", (char *)proto);
3424 if(cfg.http_showpicons)
3426 char picon_name[32];
3427 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", proto);
3428 if(picon_exists(picon_name))
3430 if (!apicall) {
3431 tpl_addVar(vars, TPLADD, "OTHER", (char *)proto);
3432 tpl_addVar(vars, TPLADD, "CLIENTPROTO", tpl_getTpl(vars, "PROTOOTHERPIC"));
3433 } else {
3434 tpl_printf(vars, TPLADDONCE, "PROTOICON", "%s",(char *)proto);
3437 else
3439 tpl_printf(vars, TPLADD, "CLIENTPROTOTITLE", "missing icon: IC_%s.tpl", proto);
3444 static void kill_account_thread(struct s_auth *account)
3446 struct s_client *cl;
3447 for(cl = first_client->next; cl ; cl = cl->next)
3449 if(cl->account == account)
3451 if(get_module(cl)->type & MOD_CONN_NET)
3453 kill_thread(cl);
3455 else
3457 cl->account = first_client->account;
3463 static char *send_oscam_user_config(struct templatevars *vars, struct uriparams *params, int32_t apicall)
3465 struct s_auth *account;
3466 struct s_client *cl;
3467 char *user = getParam(params, "user");
3468 int32_t found = 0;
3469 unsigned char md5tmp[MD5_DIGEST_LENGTH];
3471 if(!apicall)
3473 setActiveMenu(vars, MNU_USERS);
3475 if(strcmp(getParam(params, "action"), "reinit") == 0)
3477 if(!cfg.http_readonly)
3478 { refresh_oscam(REFR_ACCOUNTS); }
3480 if(strcmp(getParam(params, "action"), "delete") == 0)
3482 if(cfg.http_readonly)
3484 tpl_addMsg(vars, "WebIf is in readonly mode. No deletion will be made!");
3486 else
3488 struct s_auth *account_prev = NULL;
3490 for(account = cfg.account; (account); account = account->next)
3492 if(strcmp(account->usr, user) == 0)
3494 if(account_prev == NULL)
3495 { cfg.account = account->next; }
3496 else
3497 { account_prev->next = account->next; }
3498 ll_clear(account->aureader_list);
3499 kill_account_thread(account);
3500 add_garbage(account);
3501 found = 1;
3502 break;
3504 account_prev = account;
3506 if(found > 0)
3508 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
3510 else { tpl_addMsg(vars, "Sorry but the specified user doesn't exist. No deletion will be made!"); }
3514 if((strcmp(getParam(params, "action"), "disable") == 0) || (strcmp(getParam(params, "action"), "enable") == 0))
3516 account = get_account_by_name(getParam(params, "user"));
3517 if(account)
3519 if(strcmp(getParam(params, "action"), "disable") == 0)
3521 account->disabled = 1;
3522 kill_account_thread(account);
3524 else
3525 { account->disabled = 0; }
3526 if(write_userdb() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
3528 else
3530 tpl_addMsg(vars, "Sorry but the specified user doesn't exist. No deletion will be made!");
3534 if(strcmp(getParam(params, "action"), "resetstats") == 0)
3536 account = get_account_by_name(getParam(params, "user"));
3537 if(account) { clear_account_stats(account); }
3540 if(strcmp(getParam(params, "action"), "resetuserstats") == 0)
3542 clear_info_clients_stats();
3545 if(strcmp(getParam(params, "action"), "resetreaderstats") == 0)
3547 clear_info_readers_stats();
3550 if(strcmp(getParam(params, "action"), "resetalluserstats") == 0)
3552 clear_all_account_stats();
3555 if((strcmp(getParam(params, "part"), "adduser") == 0) && (!cfg.http_readonly))
3557 tpl_addVar(vars, TPLAPPEND, "NEWUSERFORM", tpl_getTpl(vars, "ADDNEWUSER"));
3560 /* List accounts*/
3561 char *status, *expired, *classname, *lastchan;
3562 time_t now = time((time_t *)0);
3563 int32_t isec = 0, chsec = 0;
3565 char *filter = NULL;
3566 int32_t clientcount = 0;
3567 if(apicall)
3569 filter = getParam(params, "label");
3571 int8_t grp_set = 0;
3572 int8_t expdate_set = 0;
3573 int32_t total_users = 0;
3574 int32_t disabled_users = 0;
3575 int32_t expired_users = 0;
3576 int32_t expired_or_disabled_users = 0;
3577 int32_t connected_users = 0;
3578 int32_t online_users = 0;
3579 int8_t isactive;
3580 int32_t casc_users = 0;
3581 int32_t casc_users2 = 0;
3582 int32_t n_request = 0;
3583 int existing_insert = 0;
3585 for(account = cfg.account; (account); account = account->next)
3587 if(account->expirationdate){
3588 expdate_set = 1;
3591 if(account->next){
3592 if(account->grp != account->next->grp){
3593 grp_set = 1;
3596 if(expdate_set && grp_set)
3597 break;
3600 for(account = cfg.account; (account); account = account->next)
3602 //clear for next client
3603 total_users++;
3604 isactive = 1;
3606 status = "offline";
3607 expired = "";
3608 classname = "offline";
3609 isec = 0;
3610 chsec = 0;
3612 //reset caid/srevid template variables
3613 tpl_addVar(vars, TPLADD, "CLIENTCAID", "");
3614 tpl_addVar(vars, TPLADD, "CLIENTPROVID", "");
3615 tpl_addVar(vars, TPLADD, "CLIENTSRVID", "");
3616 tpl_addVar(vars, TPLADD, "LASTCHANNEL", "");
3617 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", "");
3618 tpl_addVar(vars, TPLADD, "USERMD5", "");
3619 tpl_addVar(vars, TPLADD, "CWLASTRESPONSET", "");
3620 tpl_addVar(vars, TPLADD, "CWLASTRESPONSETMS", "");
3621 tpl_addVar(vars, TPLADD, "CLIENTIP", "");
3622 tpl_addVar(vars, TPLADD, "LASTCHANNELTITLE", "");
3623 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", "");
3624 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNELAPI", "");
3625 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", "");
3626 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEP", "");
3627 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEPAPI", "");
3628 tpl_addVar(vars, TPLADD, "IDLESECS", "");
3629 tpl_addVar(vars, TPLADD, "UNOTIFY", "");
3631 if(account->expirationdate && account->expirationdate < now)
3633 expired = " (expired)";
3634 classname = "expired";
3635 expired_users++;
3636 isactive = 0;
3638 else
3640 expired = "";
3643 if(account->disabled != 0)
3645 expired = " (disabled)";
3646 classname = "disabled";
3647 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICENA");
3648 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Enable");
3649 tpl_addVar(vars, TPLADD, "SWITCH", "enable");
3650 disabled_users++;
3651 isactive = 0;
3653 else
3655 tpl_addVar(vars, TPLADD, "SWITCHICO", "image?i=ICDIS");
3656 tpl_addVar(vars, TPLADD, "SWITCHTITLE", "Disable");
3657 tpl_addVar(vars, TPLADD, "SWITCH", "disable");
3659 if((account->expirationdate && account->expirationdate < now)||account->disabled != 0)
3661 expired_or_disabled_users++;
3664 int32_t lastresponsetm = 0, latestactivity = 0;
3665 const char *proto = "";
3666 double cwrate = 0.0, cwrate2 = 0.0;
3668 //search account in active clients
3669 isactive = 0;
3670 int16_t nrclients = 0;
3671 struct s_client *latestclient = NULL;
3672 for(cl = first_client->next; cl ; cl = cl->next)
3674 if(cl->account && !strcmp(cl->account->usr, account->usr))
3676 if(cl->lastecm > latestactivity || cl->login > latestactivity)
3678 if(cl->lastecm > cl->login) { latestactivity = cl->lastecm; }
3679 else { latestactivity = cl->login; }
3680 latestclient = cl;
3682 nrclients++;
3685 if(account->cwfound + account->cwnot + account->cwcache > 0)
3687 cwrate = now - account->firstlogin;
3688 cwrate /= (account->cwfound + account->cwnot + account->cwcache);
3691 casc_users = 0;
3692 casc_users2 = 0;
3693 int8_t conn = 0;
3694 if(latestclient != NULL)
3696 char channame[CS_SERVICENAME_SIZE];
3697 status = (!apicall) ? "<B>connected</B>" : "connected";
3698 if(account->expirationdate && account->expirationdate < now) { classname = "expired"; }
3699 else { classname = "connected";conn = 1; }
3701 proto = client_get_proto(latestclient);
3702 int clientcaid = latestclient->last_caid;
3703 int clientsrvid = latestclient->last_srvid;
3704 int clientprovid = latestclient->last_provid;
3705 tpl_printf(vars, TPLADD, "CLIENTCAID", "%04X", clientcaid);
3706 tpl_printf(vars, TPLADD, "CLIENTPROVID", "%06X", clientprovid);
3707 tpl_printf(vars, TPLADD, "CLIENTSRVID", "%04X", clientsrvid);
3709 if(clientsrvid != NO_SRVID_VALUE || clientcaid != NO_CAID_VALUE)
3711 lastchan = xml_encode(vars, get_servicename(latestclient, clientsrvid, clientprovid, clientcaid, channame, sizeof(channame)));
3712 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", lastchan);
3714 else
3716 lastchan = "";
3717 tpl_addVar(vars, TPLADD, "LASTCHANNELSORT", "~~~~~");
3720 tpl_addVar(vars, TPLADDONCE, "LASTCHANNEL", lastchan);
3721 tpl_addVar(vars, TPLADD, "LASTCHANNELTITLE", lastchan);
3723 if(cfg.http_showpicons )
3725 char picon_name[128];
3726 char picon_channame[128];
3727 int8_t picon_ok = 0;
3729 get_picon_servicename_or_null(latestclient, clientsrvid, clientprovid, clientcaid, picon_channame, sizeof(picon_channame));
3730 if(picon_channame[0])
3732 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", picon_channame);
3733 picon_ok = picon_exists(picon_name);
3735 if(!picon_ok && picon_servicename_remve_hd(picon_channame, sizeof(picon_channame)))
3737 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", picon_channame);
3738 picon_ok = picon_exists(picon_name);
3741 if(!picon_ok)
3743 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%04X_%06X_%04X", clientcaid, clientprovid, clientsrvid);
3744 picon_ok = picon_exists(picon_name);
3746 if(!picon_ok)
3748 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%04X_%04X", clientcaid, clientsrvid);
3749 picon_ok = picon_exists(picon_name);
3751 if(!picon_ok)
3753 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "0000_%04X", clientsrvid);
3754 picon_ok = picon_exists(picon_name);
3756 if(picon_ok)
3758 tpl_addVar(vars, TPLADDONCE, "LCA", picon_name);
3759 tpl_addVar(vars, TPLADDONCE, "LCB", lastchan);
3760 if(!apicall)
3762 tpl_addVar(vars, TPLADDONCE, "LASTCHANNEL", tpl_getTpl(vars, "USERCONFIGLASTCHANEL"));
3765 else
3767 tpl_printf(vars, TPLADD, "LASTCHANNELTITLE", "missing icon: IC_%s.tpl", picon_name);
3771 lastresponsetm = latestclient->cwlastresptime;
3772 tpl_addVar(vars, TPLADD, "CLIENTIP", cs_inet_ntoa(latestclient->ip));
3773 connected_users++;
3774 casc_users = ll_count(latestclient->cascadeusers);
3775 LL_ITER it = ll_iter_create(latestclient->cascadeusers);
3776 struct s_cascadeuser *cu;
3777 while((cu = ll_iter_next(&it)))
3779 if(cu->cwrate > 0)
3780 { casc_users2++; }
3782 if(latestactivity > 0)
3784 isec = now - latestactivity;
3785 chsec = latestclient->lastswitch ? now - latestclient->lastswitch : 0;
3786 if(isec < cfg.hideclient_to)
3788 isactive = 1;
3789 status = (!apicall) ? "<B>online</B>" : "online";
3790 if(account->expirationdate && account->expirationdate < now) { classname = "expired"; }
3791 else { classname = "online"; }
3792 if(latestclient->cwfound + latestclient->cwnot + latestclient->cwcache > 0)
3794 cwrate2 = now - latestclient->login;
3795 cwrate2 /= (latestclient->cwfound + latestclient->cwnot + latestclient->cwcache);
3796 tpl_printf(vars, TPLADDONCE, "CWRATE2", " (%.2f)", cwrate2);
3797 online_users++;
3803 n_request = 0;
3804 if(latestclient != NULL){
3805 n_request = latestclient->n_request[0];
3808 tpl_addVar(vars, TPLADD, "EXPIREVIEW", expdate_set ? "" : "exp");
3809 tpl_addVar(vars, TPLADD, "GRPVIEW", grp_set ? "" : "grp");
3810 #ifdef CS_ANTICASC
3811 tpl_addVar(vars, TPLADD, "ANTICASCVIEW", cfg.ac_enabled ? "" : "acas");
3812 #endif
3813 tpl_printf(vars, TPLADD, "CWOK", PRINTF_LOCAL_D, account->cwfound);
3814 tpl_printf(vars, TPLADD, "CWNOK", PRINTF_LOCAL_D, account->cwnot);
3815 tpl_printf(vars, TPLADD, "CWIGN", PRINTF_LOCAL_D, account->cwignored);
3816 tpl_printf(vars, TPLADD, "CWTOUT", PRINTF_LOCAL_D, account->cwtout);
3817 #ifdef CW_CYCLE_CHECK
3818 tpl_addVar(vars, TPLADD, "CWCCYCVIEW", cfg.cwcycle_check_enable ? "" : "cwc");
3819 tpl_printf(vars, TPLADD, "CWCYCLECHECKED", "%d", account->cwcycledchecked);
3820 tpl_printf(vars, TPLADD, "CWCYCLEOK", "%d", account->cwcycledok);
3821 tpl_printf(vars, TPLADD, "CWCYCLENOK", "%d", account->cwcyclednok);
3822 tpl_printf(vars, TPLADD, "CWCYCLEIGN", "%d", account->cwcycledign);
3823 #endif
3824 tpl_printf(vars, TPLADD, "CWCACHE", PRINTF_LOCAL_D, account->cwcache);
3825 tpl_printf(vars, TPLADD, "CWTUN", PRINTF_LOCAL_D, account->cwtun);
3826 tpl_printf(vars, TPLADD, "EMMOK", PRINTF_LOCAL_D, account->emmok);
3827 tpl_printf(vars, TPLADD, "EMMNOK", PRINTF_LOCAL_D, account->emmnok);
3828 tpl_printf(vars, TPLADD, "CWRATE", "%.2f", cwrate);
3829 tpl_printf(vars, TPLADD, "CASCUSERS", "%d", casc_users);
3830 tpl_printf(vars, TPLADD, "CASCUSERS2", "%d", casc_users2);
3831 tpl_printf(vars, TPLADD, "CASCUSERSCOMB", "%d/%d", casc_users, casc_users2);
3832 tpl_printf(vars, TPLADD, "N_REQUEST_MIN", "%d", n_request);
3834 if(isactive > 0 || conn > 0)
3836 if(casc_users+casc_users2>0)
3838 tpl_printf(vars, TPLADD, "CWLASTRESPONSET", "%d", lastresponsetm);
3839 tpl_printf(vars, TPLADD, "CWLASTRESPONSETMS", PRINTF_LOCAL_D " ms", lastresponsetm);
3841 tpl_addVar(vars, TPLADD, "IDLESECS", sec2timeformat(vars, isec));
3844 if(isactive > 0)
3846 tpl_printf(vars, TPLADD, "CLIENTTIMEONCHANNELAPI", "%d", chsec);
3847 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", sec2timeformat(vars, chsec));
3849 if(account->tosleep)
3851 if(account->tosleep >0){
3852 tpl_printf(vars, TPLADD, "CLIENTTIMETOSLEEP", "Sleeping in %d minutes", account->tosleep - (chsec / 60));
3853 } else {
3854 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEP", "Sleeping");
3856 tpl_printf(vars, TPLADD, "CLIENTTIMETOSLEEPAPI", "%d", account->tosleep - (chsec / 60));
3857 } else {
3858 tpl_addVar(vars, TPLADD, "CLIENTTIMETOSLEEPAPI", "undefined");
3862 webif_add_client_proto(vars, latestclient, proto, apicall);
3864 tpl_addVar(vars, TPLADD, "CLASSNAME", classname);
3865 MD5((unsigned char *)account->usr, strlen(account->usr), md5tmp);
3866 int z;
3867 tpl_addVar(vars, TPLADD, "USERMD5","id_");
3868 for (z = 0; z < MD5_DIGEST_LENGTH; z++){
3869 tpl_printf(vars, TPLAPPEND, "USERMD5", "%02x", md5tmp[z]);
3871 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, account->usr));
3872 tpl_addVar(vars, TPLADD, "USERNAMEENC", urlencode(vars, account->usr));
3873 if(!existing_insert){
3874 tpl_printf(vars, TPLADD, "EXISTING_INS", "'%s'", urlencode(vars, account->usr));
3875 existing_insert++;
3876 }else{
3877 tpl_printf(vars, TPLAPPEND, "EXISTING_INS", ",'%s'", urlencode(vars, account->usr));
3880 if(account->description)
3881 tpl_printf(vars, TPLADD, "DESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, account->description));
3882 else
3883 tpl_addVar(vars, TPLADD, "DESCRIPTION", "");
3885 if(cfg.http_showpicons && !apicall)
3886 tpl_addVar(vars, TPLADD, "USERBIT", tpl_getTpl(vars, picon_exists(xml_encode(vars, account->usr)) ? "USERICON" : "USERNOICON"));
3887 else
3888 tpl_addVar(vars, TPLADD, "USERBIT", tpl_getTpl(vars, "USERLABEL"));
3890 char *value = mk_t_group(account->grp);
3891 tpl_addVar(vars, TPLADD, "GROUPS", value);
3892 free_mk_t(value);
3893 tpl_addVar(vars, TPLADD, "STATUS", status);
3894 tpl_addVar(vars, TPLAPPEND, "STATUS", expired);
3896 if(nrclients > 1)
3898 tpl_printf(vars, TPLADD, "UNOTIFY", "%d", nrclients);
3899 tpl_addVar(vars, TPLADDONCE, "CLIENTCOUNTNOTIFIER", tpl_getTpl(vars, "CLIENTCOUNTNOTIFIERBIT"));
3902 //Expirationdate
3903 struct tm timeinfo;
3904 cs_gmtime_r(&account->expirationdate, &timeinfo);
3905 char buf [80];
3906 strftime(buf, 80, "%Y-%m-%d", &timeinfo);
3907 if(strcmp(buf, "1970-01-01")) { tpl_addVar(vars, TPLADD, "EXPDATE", buf); }
3908 else { tpl_addVar(vars, TPLADD, "EXPDATE", ""); }
3910 // append row to table template
3911 if(!apicall)
3912 { tpl_addVar(vars, TPLAPPEND, "USERCONFIGS", tpl_getTpl(vars, "USERCONFIGLISTBIT")); }
3913 else if(!filter || strcmp(filter, account->usr) == 0 || strcmp(filter, "all") == 0 || strlen(filter) == 0)
3915 if(apicall == 1){
3916 tpl_addVar(vars, TPLAPPEND, "APIUSERCONFIGS", tpl_getTpl(vars, "APIUSERCONFIGLISTBIT"));
3917 } else if (apicall == 2){
3918 tpl_printf(vars, TPLADD, "JSONDELIMITER", "%s", (total_users > 1)?",":"");
3919 tpl_addVar(vars, TPLAPPEND, "APIUSERCONFIGS", tpl_getTpl(vars, "JSONUSERBIT"));
3921 ++clientcount;
3925 tpl_printf(vars, TPLADD, "TOTAL_USERS", "%d", total_users);
3926 tpl_printf(vars, TPLADD, "TOTAL_DISABLED", "%d", disabled_users);
3927 tpl_printf(vars, TPLADD, "TOTAL_EXPIRED", "%d", expired_users);
3928 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE", "%d", total_users - expired_or_disabled_users);
3929 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED", "%d", connected_users);
3930 tpl_printf(vars, TPLADD, "TOTAL_ONLINE", "%d", online_users);
3932 //CM info
3933 tpl_addVar(vars, TPLADD, "DISPLAYREADERINFO", "hidden"); // no readerinfo in users
3934 set_ecm_info(vars);
3936 if(!apicall)
3937 { return tpl_getTpl(vars, "USERCONFIGLIST"); }
3938 else
3940 if(!filter || clientcount > 0)
3942 return tpl_getTpl(vars, (apicall==1)?"APIUSERCONFIGLIST":"JSONUSER");
3944 else
3946 tpl_printf(vars, TPLADD, "APIERRORMESSAGE", "Invalid client %s", xml_encode(vars, filter));
3947 return tpl_getTpl(vars, "APIERROR");
3953 #define ENTITLEMENT_PAGE_SIZE 500
3955 #ifdef MODULE_CCCSHARE
3956 static void print_cards(struct templatevars *vars, struct uriparams *params, struct cc_card **cardarray, int32_t cardsize,
3957 int8_t show_global_list, struct s_reader *rdr, int32_t offset, int32_t apicall)
3959 if(cardarray)
3961 uint8_t serbuf[8];
3962 int32_t i, count = 0;
3963 char provname[83];
3964 struct cc_card *card;
3965 int32_t cardcount = 0;
3966 int32_t providercount = 0;
3967 int32_t nodecount = 0;
3969 char *provider = "";
3971 // @todo alno: sort by click, 0=ascending, 1=descending (maybe two buttons or reverse on second click)
3972 for(i = offset; i < cardsize; ++i)
3974 card = cardarray[i];
3975 if(count == ENTITLEMENT_PAGE_SIZE)
3976 { break; }
3977 count++;
3979 if(!apicall)
3981 if(show_global_list)
3982 { rdr = card->origin_reader; }
3983 if(rdr)
3984 { tpl_printf(vars, TPLADD, "HOST", "%s:%d", xml_encode(vars, rdr->device), rdr->r_port); }
3985 tpl_printf(vars, TPLADD, "CAID", "%04X", card->caid);
3986 tpl_printf(vars, TPLADD, "CARDTYPE", "%02X", card->card_type);
3988 else
3990 tpl_printf(vars, TPLADD, "APICARDNUMBER", "%d", cardcount);
3991 tpl_printf(vars, TPLADD, "APICAID", "%04X", card->caid);
3992 tpl_printf(vars, TPLADD, "APICARDTYPE", "%02X", card->card_type);
3995 if(cc_UA_valid(card->hexserial)) //Add UA:
3997 cc_UA_cccam2oscam(card->hexserial, serbuf, card->caid);
3998 char tmp[20];
3999 tpl_printf(vars, TPLAPPEND, "HOST", "<BR>\nUA_OSCam:%s", cs_hexdump(0, serbuf, 8, tmp, 20));
4000 tpl_printf(vars, TPLAPPEND, "HOST", "<BR>\nUA_CCcam:%s", cs_hexdump(0, card->hexserial, 8, tmp, 20));
4002 if(!apicall)
4004 int32_t n;
4005 char channame[CS_SERVICENAME_SIZE];
4006 int8_t sidname = 0;
4007 LL_ITER its = ll_iter_create(card->goodsids);
4008 struct cc_srvid *srv;
4009 n = 0;
4010 if(strcmp(getParam(params, "button"), "Show detail list") == 0)
4011 { sidname = 1; }
4013 tpl_addVar(vars, TPLADD, "SERVICESGOOD", "");
4014 while((srv = ll_iter_next(&its)))
4016 if(sidname)
4018 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))));
4019 } else {
4020 tpl_printf(vars, TPLAPPEND, "SERVICESGOOD", "%04X%s", srv->sid, ++n % 10 == 0 ? "<BR>\n" : " ");
4024 its = ll_iter_create(card->badsids);
4025 n = 0;
4026 tpl_addVar(vars, TPLADD, "SERVICESBAD", "");
4027 while((srv = ll_iter_next(&its)))
4029 if(sidname)
4031 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))));
4032 } else {
4033 tpl_printf(vars, TPLAPPEND, "SERVICESBAD", "%04X%s", srv->sid, ++n % 10 == 0 ? "<BR>\n" : " ");
4038 tpl_addVar(vars, TPLADD, "SYSTEM", get_cardsystem_desc_by_caid(card->caid));
4040 tpl_printf(vars, TPLADD, "SHAREID", "%08X", card->id);
4041 tpl_printf(vars, TPLADD, "REMOTEID", "%08X", card->remote_id);
4042 tpl_printf(vars, TPLADD, "UPHOPS", "%d", card->hop);
4043 tpl_printf(vars, TPLADD, "MAXDOWN", "%d", card->reshare);
4045 LL_ITER pit = ll_iter_create(card->providers);
4046 struct cc_provider *prov;
4048 providercount = 0;
4050 if(!apicall)
4051 { tpl_addVar(vars, TPLADD, "PROVIDERS", ""); }
4052 else
4053 { tpl_addVar(vars, TPLADD, "PROVIDERLIST", ""); }
4055 while((prov = ll_iter_next(&pit)))
4057 provider = xml_encode(vars, get_provider(prov->prov, card->caid, provname, sizeof(provname)));
4059 if(!apicall)
4061 if(prov->sa[0] || prov->sa[1] || prov->sa[2] || prov->sa[3])
4063 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]);
4065 else
4067 tpl_printf(vars, TPLAPPEND, "PROVIDERS", "%s<BR>\n", provider);
4070 else
4072 if(prov->sa[0] || prov->sa[1] || prov->sa[2] || prov->sa[3])
4073 { tpl_printf(vars, TPLADD, "APIPROVIDERSA", "%02X%02X%02X%02X", prov->sa[0], prov->sa[1], prov->sa[2], prov->sa[3]); }
4074 else
4075 { tpl_addVar(vars, TPLADD, "APIPROVIDERSA", ""); }
4076 tpl_printf(vars, TPLADD, "APIPROVIDERCAID", "%04X", card->caid);
4077 tpl_printf(vars, TPLADD, "APIPROVIDERPROVID", "%06X", prov->prov);
4078 tpl_printf(vars, TPLADD, "APIPROVIDERNUMBER", "%d", providercount);
4079 tpl_addVar(vars, TPLADD, "APIPROVIDERNAME", xml_encode(vars, provider));
4080 tpl_addVar(vars, TPLAPPEND, "PROVIDERLIST", tpl_getTpl(vars, "APICCCAMCARDPROVIDERBIT"));
4083 providercount++;
4084 tpl_printf(vars, TPLADD, "APITOTALPROVIDERS", "%d", providercount);
4087 LL_ITER nit = ll_iter_create(card->remote_nodes);
4088 uint8_t *node;
4090 nodecount = 0;
4091 if(!apicall) { tpl_addVar(vars, TPLADD, "NODES", ""); }
4092 else { tpl_addVar(vars, TPLADD, "NODELIST", ""); }
4094 while((node = ll_iter_next(&nit)))
4097 if(!apicall)
4099 tpl_printf(vars, TPLAPPEND, "NODES", "%02X%02X%02X%02X%02X%02X%02X%02X<BR>\n",
4100 node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7]);
4102 else
4104 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]);
4105 tpl_printf(vars, TPLADD, "APINODENUMBER", "%d", nodecount);
4106 tpl_addVar(vars, TPLAPPEND, "NODELIST", tpl_getTpl(vars, "APICCCAMCARDNODEBIT"));
4108 nodecount++;
4109 tpl_printf(vars, TPLADD, "APITOTALNODES", "%d", nodecount);
4112 if(!apicall)
4113 { tpl_addVar(vars, TPLAPPEND, "CCCAMSTATSENTRY", tpl_getTpl(vars, "ENTITLEMENTCCCAMENTRYBIT")); }
4114 else
4115 { tpl_addVar(vars, TPLAPPEND, "CARDLIST", tpl_getTpl(vars, "APICCCAMCARDBIT")); }
4117 cardcount++;
4119 // set previous Link if needed
4120 if(offset >= ENTITLEMENT_PAGE_SIZE)
4122 tpl_printf(vars, TPLAPPEND, "CONTROLS", "<A HREF=\"entitlements.html?offset=%d&globallist=%s&amp;label=%s\"> << PREVIOUS < </A>",
4123 offset - ENTITLEMENT_PAGE_SIZE,
4124 getParam(params, "globallist"),
4125 urlencode(vars, getParam(params, "label")));
4128 // set next link if needed
4129 if(cardsize > count && offset < cardsize)
4131 tpl_printf(vars, TPLAPPEND, "CONTROLS", "<A HREF=\"entitlements.html?offset=%d&globallist=%s&amp;label=%s\"> > NEXT >> </A>",
4132 offset + ENTITLEMENT_PAGE_SIZE,
4133 getParam(params, "globallist"),
4134 urlencode(vars, getParam(params, "label")));
4137 if(!apicall)
4139 tpl_printf(vars, TPLADD, "TOTALS", "card count=%d", cardsize);
4140 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTCCCAMBIT"));
4142 else
4144 tpl_printf(vars, TPLADD, "APITOTALCARDS", "%d", cardsize);
4148 else
4150 if(!apicall)
4152 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTGENERICBIT"));
4153 tpl_addVar(vars, TPLADD, "LOGHISTORY", "no cards found<BR>\n");
4155 else
4157 tpl_printf(vars, TPLADD, "APITOTALCARDS", "%d", 0);
4162 #endif
4164 static char *send_oscam_entitlement(struct templatevars *vars, struct uriparams *params, int32_t apicall)
4166 if(!apicall) { setActiveMenu(vars, MNU_READERS); }
4167 char *reader_ = getParam(params, "label");
4168 #ifdef MODULE_CCCAM
4169 char *sharelist_ = getParam(params, "globallist");
4170 int32_t show_global_list = sharelist_ && sharelist_[0] == '1';
4172 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
4173 if(show_global_list || strlen(reader_) || (rdr && rdr->typ == R_CCCAM))
4176 if(show_global_list || (rdr && rdr->typ == R_CCCAM && rdr->enable))
4179 if(show_global_list)
4181 tpl_addVar(vars, TPLADD, "READERNAME", "GLOBAL");
4182 tpl_addVar(vars, TPLADD, "APIHOST", "GLOBAL");
4183 tpl_addVar(vars, TPLADD, "APIHOSTPORT", "GLOBAL");
4185 else
4187 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
4188 tpl_addVar(vars, TPLADD, "APIHOST", xml_encode(vars, rdr->device));
4189 tpl_printf(vars, TPLADD, "APIHOSTPORT", "%d", rdr->r_port);
4192 #ifdef MODULE_CCCSHARE
4193 int32_t offset = atoi(getParam(params, "offset")); //should be 0 if parameter is missed on very first call
4194 int32_t cardsize;
4195 if(show_global_list)
4197 int32_t i;
4198 LLIST **sharelist = get_and_lock_sharelist();
4199 LLIST *sharelist2 = ll_create("web-sharelist");
4200 for(i = 0; i < CAID_KEY; i++)
4202 if(sharelist[i])
4203 { ll_putall(sharelist2, sharelist[i]); }
4205 unlock_sharelist();
4206 struct cc_card **cardarray = get_sorted_card_copy(sharelist2, 0, &cardsize);
4207 ll_destroy(&sharelist2);
4208 print_cards(vars, params, cardarray, cardsize, 1, NULL, offset, apicall);
4209 NULLFREE(cardarray);
4211 else
4213 struct s_client *rc = rdr->client;
4214 struct cc_data *rcc = (rc) ? rc->cc : NULL;
4215 if(rcc && rcc->cards)
4217 struct cc_card **cardarray = get_sorted_card_copy(rcc->cards, 0, &cardsize);
4218 print_cards(vars, params, cardarray, cardsize, 0, rdr, offset, apicall);
4219 NULLFREE(cardarray);
4222 #endif
4225 else
4227 #else
4228 if(strlen(reader_))
4231 struct s_reader *rdr;
4232 #endif
4233 tpl_addVar(vars, TPLADD, "LOGHISTORY", "->");
4234 // normal non-cccam reader
4236 rdr = get_reader_by_label(reader_);
4238 if(rdr)
4240 struct s_client *cl = rdr->client;
4241 if(rdr->ll_entitlements)
4244 time_t now = time((time_t *)0);
4246 struct tm start_t, end_t;
4247 LL_ITER itr = ll_iter_create(rdr->ll_entitlements);
4248 S_ENTITLEMENT *item;
4250 tpl_addVar(vars, TPLAPPEND, "LOGHISTORY", "<BR><BR>New Structure:<BR>");
4251 char tbuffer[83];
4252 int jsondelimiter = 0;
4253 while((item = ll_iter_next(&itr)))
4255 localtime_r(&item->start, &start_t);
4256 localtime_r(&item->end, &end_t);
4258 if(!apicall)
4259 { strftime(tbuffer, 30, "%Y-%m-%d", &start_t); }
4260 else
4261 { strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &start_t); }
4262 tpl_addVar(vars, TPLADD, "ENTSTARTDATE", tbuffer);
4264 if(!apicall)
4265 { strftime(tbuffer, 30, "%Y-%m-%d", &end_t); }
4266 else
4267 { strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &end_t); }
4268 tpl_addVar(vars, TPLADD, "ENTENDDATE", tbuffer);
4270 tpl_addVar(vars, TPLADD, "ENTEXPIERED", item->end > now ? "e_valid" : "e_expired");
4271 tpl_printf(vars, TPLADD, "ENTCAID", "%04X", item->caid);
4272 tpl_printf(vars, TPLADD, "ENTPROVID", "%06X", item->provid);
4273 tpl_printf(vars, TPLADD, "ENTID", "%08X%08X", (uint32_t)(item->id >> 32), (uint32_t)item->id);
4274 tpl_printf(vars, TPLADD, "ENTCLASS", "%08X", item->class);
4275 tpl_addVar(vars, TPLADD, "ENTTYPE", entitlement_type[item->type]);
4277 char *entresname;
4278 entresname = xml_encode(vars, get_tiername((uint16_t)(item->id & 0xFFFF), item->caid, tbuffer));
4279 if(!tbuffer[0])
4280 { entresname = xml_encode(vars, get_provider(item->provid, item->caid, tbuffer, sizeof(tbuffer))); }
4281 tpl_addVar(vars, TPLADD, "ENTRESNAME", entresname);
4283 if((strcmp(getParam(params, "hideexpired"), "1") != 0) || (item->end > now))
4284 { tpl_addVar(vars, TPLAPPEND, "READERENTENTRY", tpl_getTpl(vars, "ENTITLEMENTITEMBIT")); }
4286 if(apicall==2)
4288 tpl_printf(vars, TPLAPPEND, "APIENTITLEMENTLIST","%s%s",jsondelimiter?",":"", tpl_getTpl(vars, "JSONENTITLEMENTBIT"));
4289 jsondelimiter++;
4294 if(cl && cl->typ)
4295 { tpl_printf(vars, TPLADD, "READERTYPE", "%c", cl->typ); }
4296 else
4297 { tpl_addVar(vars, TPLADD, "READERTYPE", "null"); }
4298 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, rdr->label));
4300 int8_t i, j;
4301 for(i = 0; i < 15; i++) { tpl_printf(vars, TPLAPPEND, "READERROM", "%c", rdr->rom[i]); }
4302 if(rdr->hexserial[0] || rdr->hexserial[1]) { i = 0; }
4303 else { i = 2; }
4304 if(rdr->hexserial[6] || rdr->hexserial[7]) { j = 8; }
4305 else { j = 6; }
4306 for(; i < j; i++) { tpl_printf(vars, TPLAPPEND, "READERSERIAL", "%02X%s", rdr->hexserial[i], i < j - 1 ? " " : ""); }
4307 for(i = 0; i < rdr->nprov; i++)
4309 for(j = 0; j < 4; j++) { tpl_printf(vars, TPLAPPEND, "READERPROVIDS", "%02X ", rdr->prid[i][j]); }
4310 tpl_addVar(vars, TPLAPPEND, "READERPROVIDS", i == 0 ? "(sysid)<BR>\n" : "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>\n");
4313 //CountryCode Vg card
4314 char add_nds_line = 0;
4315 if(rdr->VgCountryC[0])
4317 for(i = 0; i < 3; i++) { tpl_printf(vars, TPLAPPEND, "READERCOUNTRYC", "%c", rdr->VgCountryC[i]); }
4318 add_nds_line = 1;
4320 else
4322 tpl_addVar(vars, TPLADD, "READERCOUNTRYC", "n/a");
4325 //regional code for Vg card
4326 if(rdr->VgRegionC[0])
4328 for(i = 0; i < 8; i++) { tpl_printf(vars, TPLAPPEND, "READER_RCODE", "%c", rdr->VgRegionC[i]); }
4329 add_nds_line = 1;
4331 else
4333 tpl_addVar(vars, TPLADD, "READER_RCODE", "n/a");
4336 //Pin Vg card
4337 if(rdr->VgPin)
4339 tpl_printf(vars, TPLAPPEND, "READERPIN", "%04i", rdr->VgPin);
4340 add_nds_line = 1;
4342 else
4344 tpl_addVar(vars, TPLADD, "READERPIN", "n/a");
4347 //Fuse Vg card
4348 if(rdr->VgFuse)
4350 tpl_printf(vars, TPLAPPEND, "READERFUSE", "%02X", rdr->VgFuse);
4351 add_nds_line = 1;
4354 if(caid_is_videoguard(rdr->caid))
4356 tpl_printf(vars, TPLAPPEND, "READERPAYLOAD", "%02X %02X %02X %02X %02X %02X", rdr->VgLastPayload[0],
4357 rdr->VgLastPayload[1], rdr->VgLastPayload[2], rdr->VgLastPayload[3], rdr->VgLastPayload[4], rdr->VgLastPayload[5]);
4358 add_nds_line = 1;
4361 //credit on Vg card
4362 if(rdr->VgCredit)
4364 tpl_printf(vars, TPLAPPEND, "READERCREDIT", "%i", rdr->VgCredit);
4365 add_nds_line = 1;
4367 else
4369 tpl_addVar(vars, TPLADD, "READERCREDIT", "n/a");
4372 if(rdr->card_valid_to)
4374 struct tm vto_t;
4375 char vtobuffer[30];
4376 localtime_r(&rdr->card_valid_to, &vto_t);
4377 strftime(vtobuffer, 30, "%Y-%m-%d", &vto_t);
4378 tpl_addVar(vars, TPLADD, "READERCARDVALIDTO", vtobuffer);
4380 else
4382 tpl_addVar(vars, TPLADD, "READERCARDVALIDTO", "n/a");
4385 if(rdr->irdId[0])
4387 for(i = 0; i < 4; i++) { tpl_printf(vars, TPLAPPEND, "READERIRDID", "%02X ", rdr->irdId[i]); }
4389 else
4391 tpl_addVar(vars, TPLADD, "READERIRDID", "n/a");
4394 if(rdr->card_atr_length)
4395 for(i = 0; i < rdr->card_atr_length; i++) { tpl_printf(vars, TPLAPPEND, "READERATR", "%02X ", rdr->card_atr[i]); }
4397 if(caid_is_seca(rdr->caid) || caid_is_viaccess(rdr->caid))
4399 if(rdr->maturity==0xF)
4401 tpl_printf(vars, TPLAPPEND, "READERMATURITY", "%s ", "no limit");
4403 else
4405 tpl_printf(vars, TPLAPPEND, "READERMATURITY", "%d+", rdr->maturity);
4408 else
4410 tpl_printf(vars, TPLAPPEND, "READERMATURITY", "%s ", "n/a");
4413 if (rdr->csystem)
4414 tpl_addVar(vars, TPLADD, "READERCSYSTEM", rdr->csystem->desc);
4416 if(add_nds_line)
4418 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENTNDS", tpl_getTpl(vars, "ENTITLEMENTBITNDS"));
4420 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTBIT"));
4422 else
4424 tpl_addMsg(vars, "Reader does not exist or is not started!");
4429 else
4431 tpl_addVar(vars, TPLADD, "ENTITLEMENTCONTENT", tpl_getTpl(vars, "ENTITLEMENTGENERICBIT"));
4434 if(!apicall)
4435 { return tpl_getTpl(vars, "ENTITLEMENTS"); }
4436 else
4438 if(apicall==1)
4439 { return tpl_getTpl(vars, "APICCCAMCARDLIST"); }
4440 else
4441 { return tpl_getTpl(vars, "JSONENTITLEMENTS"); }
4445 #ifdef WEBIF_LIVELOG
4446 static char *send_oscam_logpoll(struct templatevars * vars, struct uriparams * params)
4449 uint64_t lastid = 0;
4451 #ifdef WITH_DEBUG
4452 tpl_addVar(vars, TPLADD, "LOG_DEBUGMENU", tpl_getTpl(vars, "LOGDEBUGMENU"));
4453 #endif
4454 tpl_addVar(vars, TPLADD, "LOG_SIZEMENU", tpl_getTpl(vars, "LOGSIZEMENU"));
4455 tpl_addVar(vars, TPLADD, "TITLEADD1", "Move mouse over log-window to stop scroll");
4457 if(strcmp(getParam(params, "lastid"), "start") == 0){
4458 setActiveMenu(vars, MNU_LIVELOG);
4459 return tpl_getTpl(vars, "LOGPAGE");
4461 else
4463 lastid = strtoull(getParam(params, "lastid"), NULL, 10);
4466 char *dot = ""; //Delimiter
4468 #ifdef WITH_DEBUG
4469 char *debuglvl = getParam(params, "debug");
4470 if(strlen(debuglvl) > 0) {
4471 int32_t dblvl = atoi(debuglvl);
4472 if(cs_dblevel != dblvl) {
4473 if(dblvl >= 0 && dblvl <= 65535) { cs_dblevel = dblvl; }
4474 cs_log("%s debug_level=%d", "all", cs_dblevel);
4477 tpl_printf(vars, TPLAPPEND, "DATA","%s\"debug\":\"%d\"", dot, cs_dblevel);
4478 dot = ",";
4479 tpl_printf(vars, TPLAPPEND, "DATA","%s\"maxdebug\":\"%d\"",dot, MAX_DEBUG_LEVELS);
4480 #endif
4482 if(cfg.loghistorylines == 0){
4483 tpl_printf(vars, TPLAPPEND, "DATA","%s\"logdisabled\":\"1\"",dot);
4484 return tpl_getTpl(vars, "POLL");
4487 if(log_history)
4489 LL_ITER it = ll_iter_create(log_history);
4490 struct s_log_history *hist;
4492 tpl_printf(vars, TPLAPPEND, "DATA", "%s\"lines\":[", dot);
4494 dot = "";
4496 while((hist = (struct s_log_history*)ll_iter_next(&it)))
4498 char p_usr[32];
4499 size_t pos1 = strcspn(hist->txt, "\t") + 1;
4500 cs_strncpy(p_usr, hist->txt , pos1 > sizeof(p_usr) ? sizeof(p_usr) : pos1);
4502 char *p_txt = hist->txt + pos1;
4504 pos1 = strcspn(p_txt, "\n") + 1;
4505 char str_out[pos1];
4506 cs_strncpy(str_out, p_txt, pos1);
4507 uint64_t id = hist->counter;
4509 size_t b64_str_in = strlen(xml_encode(vars, str_out));
4510 size_t b64_str_out = 32 + BASE64_LENGTH(b64_str_in);
4511 char *b64_str_out_buf;
4512 if(!cs_malloc(&b64_str_out_buf, b64_str_out))
4513 { continue; }
4514 base64_encode(xml_encode(vars, str_out), b64_str_in, b64_str_out_buf, b64_str_out);
4516 if(id > lastid){
4517 tpl_printf(vars, TPLAPPEND, "DATA","%s{\"id\":\"%" PRIu64 "\",\"usr\":\"%s\",\"line\":\"%s\"}",
4518 dot,
4520 urlencode(vars, xml_encode(vars, p_usr)),
4521 b64_str_out_buf);
4522 dot = ","; // next in Array with leading delimiter
4524 NULLFREE(b64_str_out_buf);
4528 tpl_addVar(vars, TPLAPPEND, "DATA", "]");
4529 return tpl_getTpl(vars, "POLL");
4531 #endif
4533 static char *send_oscam_status(struct templatevars * vars, struct uriparams * params, int32_t apicall)
4535 int32_t i;
4536 const char *usr;
4537 int32_t lsec, isec, chsec, con, cau = 0;
4538 time_t now = time((time_t *)0);
4539 struct tm lt;
4540 int delimiter=0;
4542 if(!apicall)
4544 setActiveMenu(vars, MNU_STATUS);
4545 if (config_enabled(WITH_LB))
4546 tpl_addVar(vars, TPLADD, "STATUSCOL14HEAD","LB Value/");
4548 if(strcmp(getParam(params, "action"), "kill") == 0)
4550 char *cptr = getParam(params, "threadid");
4551 struct s_client *cl = NULL;
4552 if(strlen(cptr) > 1)
4553 { sscanf(cptr, "%p", (void **)(void *)&cl); }
4555 if(cl && is_valid_client(cl))
4557 if(is_dvbapi_usr(cl->account->usr))
4559 cs_log("WebIF from %s requests to kill dvbapi client %s -> ignoring!", cs_inet_ntoa(GET_IP()), cl->account->usr);
4561 else
4563 kill_thread(cl);
4564 cs_log("Client %s killed by WebIF from %s", cl->account->usr, cs_inet_ntoa(GET_IP()));
4569 if(strcmp(getParam(params, "action"), "resetuserstats") == 0)
4571 clear_info_clients_stats();
4573 if(strcmp(getParam(params, "action"), "resetreaderstats") == 0)
4575 clear_info_readers_stats();
4577 if(strcmp(getParam(params, "action"), "restart") == 0)
4579 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
4580 if(rdr)
4582 add_job(rdr->client, ACTION_READER_RESTART, NULL, 0);
4583 cs_log("Reader %s restarted by WebIF from %s", rdr->label, cs_inet_ntoa(GET_IP()));
4587 char *debuglvl = getParam(params, "debug");
4588 if(strlen(debuglvl) > 0)
4590 #ifndef WITH_DEBUG
4591 cs_log("*** Warning: Debug Support not compiled in ***");
4592 #else
4593 int32_t dblvl = atoi(debuglvl);
4594 if(dblvl >= 0 && dblvl <= 65535) { cs_dblevel = dblvl; }
4595 cs_log("%s debug_level=%d", "all", cs_dblevel);
4596 #endif
4599 char *hide = getParam(params, "hide");
4600 if(strlen(hide) > 0)
4602 struct s_client *hideidx = NULL;
4603 sscanf(hide, "%p", (void **)(void *)&hideidx);
4605 if(hideidx && is_valid_client(hideidx))
4606 { hideidx->wihidden = 1; }
4609 char *hideidle = getParam(params, "hideidle");
4610 if(strlen(hideidle) > 0)
4612 if(atoi(hideidle) == 2)
4614 struct s_client *cl;
4615 for(cl = first_client; cl ; cl = cl->next)
4617 if(cl->typ == 's' || cl->typ == 'h' || cl->typ == 'm'){
4618 cl->wihidden = 0;
4622 else if(atoi(hideidle) == 3)
4624 struct s_client *cl;
4625 for(cl = first_client; cl ; cl = cl->next)
4627 if(cl->typ == 'r'){
4628 cl->wihidden = 0;
4632 else if(atoi(hideidle) == 4)
4634 struct s_client *cl;
4635 for(cl = first_client; cl ; cl = cl->next)
4637 if(cl->typ == 'p'){
4638 cl->wihidden = 0;
4642 else if(atoi(hideidle) == 5)
4644 struct s_client *cl;
4645 for(cl = first_client; cl ; cl = cl->next)
4647 if(cl->typ == 'c'){
4648 cl->wihidden = 0;
4652 else
4654 int32_t oldval = cfg.http_hide_idle_clients;
4655 config_set("webif", "httphideidleclients", hideidle);
4656 if(oldval != cfg.http_hide_idle_clients)
4658 refresh_oscam(REFR_SERVER);
4663 if(cfg.http_hide_idle_clients > 0) { tpl_addVar(vars, TPLADD, "HIDEIDLECLIENTSSELECTED1", "selected"); }
4664 else { tpl_addVar(vars, TPLADD, "HIDEIDLECLIENTSSELECTED0", "selected"); }
4666 tpl_addVar(vars, TPLADD, "SRVIDFILE", use_srvid2 ? "oscam.srvid2" : "oscam.srvid");
4668 int32_t user_count_all = 0, user_count_shown = 0, user_count_active = 0;
4669 int32_t reader_count_all = 0, reader_count_conn = 0, reader_count_off = 0;
4670 int32_t proxy_count_all = 0, proxy_count_conn = 0, proxy_count_off = 0;
4671 int32_t server_count_all = 0, server_count_shown = 0, server_count_hidden = 0;
4672 int32_t monitor_count_all = 0, monitor_count_shown = 0;
4673 int32_t shown;
4675 int32_t total_readers = 0;
4676 int32_t active_readers = 0;
4677 int32_t disabled_readers = 0;
4678 int32_t connected_readers = 0;
4680 struct s_client *cl;
4681 int8_t filtered;
4683 cs_readlock(__func__, &readerlist_lock);
4684 cs_readlock(__func__, &clientlist_lock);
4685 for(i = 0, cl = first_client; cl ; cl = cl->next, i++)
4687 if(cl->kill) { continue; }
4688 #ifdef CS_CACHEEX
4689 if(get_module(cl)->listenertype != LIS_CSPUDP)
4691 #endif
4693 // Reset template variables
4694 tpl_addVar(vars, TPLADD, "LBLRPSTRVALUE", "");
4695 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", "");
4696 tpl_addVar(vars, TPLADD, "LASTREADER", "");
4697 tpl_addVar(vars, TPLADD, "CLIENTPROTO", "");
4698 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
4699 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIME", "");
4700 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIMEHIST", "");
4701 tpl_addVar(vars, TPLADD, "UPICMISSING" , "");
4702 tpl_addVar(vars, TPLADD, "ENTITLEMENTS", "");
4704 if(cl->typ == 'c')
4705 { user_count_all++; }
4706 else if(cl->typ == 'p')
4707 { proxy_count_all++; if(cl->reader->card_status != CARD_INSERTED) { proxy_count_off++; } }
4708 else if(cl->typ == 'r')
4709 { reader_count_all++; if(cl->reader->card_status != CARD_INSERTED) { reader_count_off++; } }
4710 else if(cl->typ == 's' || cl->typ == 'h')
4711 { server_count_all++; if(cl->wihidden) {server_count_hidden++;} }
4712 else if(cl->typ == 'm')
4713 { monitor_count_all++; }
4715 shown = 0;
4716 if(cl->wihidden != 1)
4718 filtered = !(cfg.http_hide_idle_clients != 1 || cl->typ != 'c' || (now - cl->lastecm) <= cfg.hideclient_to);
4719 if(!filtered && cfg.http_hide_type)
4721 char *p = cfg.http_hide_type;
4722 while(*p && !filtered)
4724 char type = *p++;
4725 #ifdef CS_CACHEEX
4726 filtered = (type == cl->typ) || (type == 'x' && (cl->typ == 'p' || cl->typ == 'r') && (cl->reader && cl->reader->cacheex.mode));
4727 #else
4728 filtered = (type == cl->typ);
4729 #endif
4733 if(!filtered)
4735 if(cl->typ == 'c')
4737 user_count_shown++;
4738 if(cfg.http_hide_idle_clients != 1 && cfg.hideclient_to > 0 && (now - cl->lastecm) <= cfg.hideclient_to)
4740 user_count_active++;
4743 else if(cl->typ == 's' || cl->typ == 'h')
4745 server_count_shown++;
4747 else if(cl->typ == 'm')
4749 monitor_count_shown++;
4751 else if(cl->typ == 'r')
4753 reader_count_conn++;
4755 else if(cl->typ == 'p')
4757 proxy_count_conn++;
4760 if(cl->typ == 'c' || cl->typ == 'r' || cl->typ == 'p')
4762 if(cl->lastecm >= cl->login && cl->lastecm >= cl->logout) { isec = now - cl->lastecm; }
4763 else if(cl->logout >= cl->login) { isec = now - cl->logout; }
4764 else { isec = now - cl->login; }
4766 else { isec = now - cl->last; }
4768 shown = 1;
4769 lsec = now - cl->login;
4770 chsec = now - cl->lastswitch;
4771 usr = username(cl);
4773 if((cl->typ == 'r') || (cl->typ == 'p')) { usr = cl->reader->label; }
4775 if(cl->dup) { con = 2; }
4776 else if((cl->tosleep) && (now - cl->lastswitch > cl->tosleep)) { con = 1; }
4777 else { con = 0; }
4779 // no AU reader == 0 / AU ok == 1 / Last EMM > aulow == -1
4780 if(cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r')
4782 if((cl->typ == 'c' && ll_count(cl->aureader_list) == 0) || ((cl->typ == 'p' || cl->typ == 'r') && cl->reader->audisabled)) { cau = 0; }
4783 else if((now - cl->lastemm) / 60 > cfg.aulow) { cau = -1; }
4784 else { cau = 1; }
4786 if(cau == 0)
4788 tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", "OFF");
4790 else
4792 if(cau == -1)
4793 { tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", !apicall?"<A HREF=\"#\" CLASS=\"tooltip\">ON":""); }
4794 else
4795 { tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", !apicall?"<A HREF=\"#\" CLASS=\"tooltip\">ACTIVE":""); }
4796 tpl_addVar(vars, TPLAPPEND, "CLIENTCAUHTTP", !apicall?"<SPAN>":"");
4797 if(cl->typ == 'c')
4799 struct s_reader *rdr;
4800 LL_ITER itr = ll_iter_create(cl->aureader_list);
4801 while((rdr = ll_iter_next(&itr)))
4803 if(rdr->audisabled)
4804 { tpl_printf(vars, TPLAPPEND, "CLIENTCAUHTTP", "(%s)<BR>", xml_encode(vars, rdr->label)); }
4805 else
4806 { tpl_printf(vars, TPLAPPEND, "CLIENTCAUHTTP", "%s<BR>", xml_encode(vars, rdr->label)); }
4809 else { tpl_addVar(vars, TPLAPPEND, "CLIENTCAUHTTP", xml_encode(vars, cl->reader->label)); }
4810 tpl_addVar(vars, TPLAPPEND, "CLIENTCAUHTTP", !apicall?"</SPAN></A>":"");
4813 else
4815 cau = 0;
4816 tpl_addVar(vars, TPLADD, "CLIENTCAUHTTP", "");
4818 localtime_r(&cl->login, &lt);
4820 if(cl->typ == 'c' || cl->typ == 'm')
4822 if(cl->account && cl->account->description)
4823 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->account->description));
4824 else
4825 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
4827 else if(cl->typ == 'p' || cl->typ == 'r')
4829 if(cl->reader && cl->reader->description)
4830 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->reader->description));
4831 else
4832 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
4834 if(!apicall)
4836 tpl_addVar(vars, TPLADD, "LBL", xml_encode(vars, usr));
4837 tpl_printf(vars, TPLADD, "CID", "%p", cl);
4838 if(cl->typ == 'c' || cl->typ == 'm')
4840 tpl_addVar(vars, TPLADD, "TARGET", "User");
4841 tpl_addVar(vars, TPLADD, "CSIDX", tpl_getTpl(vars, "STATUSKBUTTON"));
4843 else if(cl->typ == 'p')
4845 tpl_addVar(vars, TPLADD, "TARGET", "Proxy");
4846 tpl_addVar(vars, TPLADD, "LBLENC", urlencode(vars, usr));
4847 tpl_addVar(vars, TPLADD, "CSIDX", tpl_getTpl(vars, "STATUSRBUTTON"));
4849 else if(cl->typ == 'r')
4851 tpl_addVar(vars, TPLADD, "TARGET", "Reader");
4852 tpl_addVar(vars, TPLADD, "LBLENC", urlencode(vars, usr));
4853 tpl_addVar(vars, TPLADD, "CSIDX", tpl_getTpl(vars, "STATUSRBUTTON"));
4855 else if (cl->typ == 'h' || cl->typ == 's')
4857 tpl_addVar(vars, TPLADD, "TARGET", "Server");
4858 tpl_addVar(vars, TPLADD, "CSIDX", "");
4860 tpl_addVar(vars, TPLADD, "HIDEIDX", tpl_getTpl(vars, "STATUSHBUTTON"));
4861 tpl_printf(vars, TPLADD, "CSIDXPLAIN", "id_%p", cl);
4863 else
4865 tpl_printf(vars, TPLADD, "HIDEIDX", "%p", cl);
4866 tpl_printf(vars, TPLADD, "CSIDX", "id_%p", cl);
4868 tpl_printf(vars, TPLADD, "CLIENTTYPE", "%c", cl->typ);
4869 tpl_printf(vars, TPLADD, "CLIENTCNR", "%d", get_threadnum(cl));
4870 tpl_addVar(vars, TPLADD, "CLIENTUSER", xml_encode(vars, usr));
4872 tpl_addVar(vars, TPLADD, "STATUSUSERICON", xml_encode(vars, usr));
4873 if (cl->typ == 'c' || cl->typ == 'm') {
4874 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, usr));
4875 tpl_addVar(vars, TPLADD, "USERENC", urlencode(vars, usr));
4876 } else if (cl->typ == 'p' || cl->typ == 'r') {
4877 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, usr));
4878 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, usr));
4881 bool picon_shown = false;
4882 const char *status_user_icon_tpl = NULL;
4884 char picon_name[32];
4885 if(cfg.http_showpicons)
4887 if(picon_exists(xml_encode(vars, usr)))
4889 switch (cl->typ) {
4890 case 'm': // Fall through
4891 case 'c': status_user_icon_tpl = "SUSERICON"; picon_shown = true; break;
4892 case 'p': // Fall through
4893 case 'r': status_user_icon_tpl = "SREADERICON"; picon_shown = true; break;
4896 else
4897 tpl_printf(vars, TPLADD, "UPICMISSING", "%smissing icon: IC_%s.tpl",!apicall?"&#13;":"",xml_encode(vars, usr));
4900 if (!picon_shown) {
4901 switch (cl->typ) {
4902 case 'm': // Fall through
4903 case 'c': status_user_icon_tpl = "SUSER"; break;
4904 case 'p': // Fall through
4905 case 'r': status_user_icon_tpl = "SREADER"; break;
4909 if (status_user_icon_tpl)
4910 tpl_addVar(vars, TPLADD, "STATUSUSERICON", tpl_getTpl(vars, status_user_icon_tpl));
4912 tpl_printf(vars, TPLADD, "CLIENTCAU", "%d", cau);
4913 if(!apicall)
4915 if(cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r')
4917 if(cl->crypted) { tpl_addVar(vars, TPLADD, "CLIENTCRYPTED", "ON"); }
4918 else { tpl_addVar(vars, TPLADD, "CLIENTCRYPTED", "OFF"); }
4920 else { tpl_addVar(vars, TPLADD, "CLIENTCRYPTED", ""); }
4922 else { tpl_printf(vars, TPLADD, "CLIENTCRYPTED", "%d", cl->crypted); }
4923 tpl_addVar(vars, TPLADD, "CLIENTIP", cs_inet_ntoa(cl->ip));
4924 tpl_printf(vars, TPLADD, "CLIENTPORT", "%d", cl->port);
4925 const char *proto = client_get_proto(cl);
4926 webif_add_client_proto(vars, cl, proto, apicall);
4928 if(!apicall)
4930 if((cl->typ != 'p' && cl->typ != 'r') || cl->reader->card_status == CARD_INSERTED)
4932 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);
4933 tpl_addVar(vars, TPLADD, "CLIENTLOGINSECS", sec2timeformat(vars, lsec));
4935 else
4937 tpl_addVar(vars, TPLADD, "CLIENTLOGINDATE", "");
4938 tpl_addVar(vars, TPLADD, "CLIENTLOGINSECS", "");
4941 else
4943 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);
4944 char tbuffer [30];
4945 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &lt);
4946 tpl_addVar(vars, TPLADD, "CLIENTLOGINDATE", tbuffer);
4947 tpl_printf(vars, TPLADD, "CLIENTLOGINSECS", "%d", lsec);
4950 //load historical values from ringbuffer
4951 char *value = get_ecm_historystring(cl);
4952 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIMEHIST", value);
4953 free_mk_t(value);
4955 if((isec < cfg.hideclient_to || cfg.hideclient_to == 0 || is_dvbapi_usr(cl->account->usr)) && (cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r'))
4957 if(((cl->typ == 'c')) && (cl->lastreader[0]))
4959 tpl_printf(vars, TPLADD, "MSVALUE", PRINTF_LOCAL_D, cl->cwlastresptime);
4960 if(apicall)
4962 tpl_addVar(vars, TPLADD, "LASTREADER", (cl->last_caid == NO_CAID_VALUE || isec > cfg.hideclient_to ) ? "" : cl->lastreader);
4963 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, cl->lastreader));
4965 else
4967 #ifdef WITH_LB
4968 tpl_addVar(vars, TPLADD, "LBLVALUE", xml_encode(vars, cl->lastreader));
4969 if(strstr(cl->lastreader, " (cache)"))
4971 char lastreader_tmp[strlen(cl->lastreader)-8];
4972 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", tpl_getVar(vars, "LBLRPSTRVALUE"));
4973 strncpy(lastreader_tmp, cl->lastreader, strlen(cl->lastreader)-8);
4974 tpl_addVar(vars, TPLADD, "LBLVALUEENC", urlencode(vars, lastreader_tmp));
4975 tpl_addVar(vars, TPLADD, "LBLVALUETITLE", xml_encode(vars, lastreader_tmp));
4977 else
4979 tpl_addVar(vars, TPLADD, "LBLVALUEENC", urlencode(vars, cl->lastreader));
4980 tpl_addVar(vars, TPLADD, "LBLVALUETITLE", xml_encode(vars, cl->lastreader));
4982 tpl_addVar(vars, TPLAPPEND, "CLIENTLBVALUE", tpl_getTpl(vars, "CLIENTLBLVALUEBIT"));
4983 #else
4984 tpl_printf(vars, TPLAPPEND, "CLIENTLBVALUE", "%s (%'d ms)", xml_encode(vars, cl->lastreader), cl->cwlastresptime);
4985 #endif
4987 if(cl->last_caid == NO_CAID_VALUE || isec > cfg.hideclient_to) tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", "");
4989 if(cl->last_caid != NO_CAID_VALUE || cl->last_srvid != NO_SRVID_VALUE)
4991 char channame[CS_SERVICENAME_SIZE];
4992 const char *lastprovidername;
4994 get_servicename_or_null(cl, cl->last_srvid, cl->last_provid, cl->last_caid, channame, sizeof(channame));
4995 if(channame[0] == '\0')
4997 cs_strncpy(channame, "unknown", sizeof(channame));
5000 lastprovidername = get_cl_lastprovidername(cl);
5002 tpl_printf(vars, TPLADD, "CLIENTCAID", "%04X", cl->last_caid);
5003 tpl_printf(vars, TPLADD, "CLIENTPROVID", "%06X", cl->last_provid);
5004 tpl_printf(vars, TPLADD, "CLIENTSRVID", "%04X", cl->last_srvid);
5005 tpl_printf(vars, TPLADD, "CLIENTSRVPROVIDER", "%s%s%s", (lastprovidername[0] != '\0' && strcmp(lastprovidername, " ")) ? " [" : "", xml_encode(vars, lastprovidername), (lastprovidername[0] != '\0' && strcmp(lastprovidername, " ")) ? "]" : "");
5006 tpl_addVar(vars, TPLADD, "CLIENTSRVNAME", xml_encode(vars, channame));
5007 tpl_printf(vars, TPLADD, "CLIENTLASTRESPONSETIME", "%d", cl->cwlastresptime ? cl->cwlastresptime : 1);
5008 tpl_addVar(vars, TPLADD, "CLIENTSRVTYPE", cl->last_srvidptr && cl->last_srvidptr->type ? xml_encode(vars, cl->last_srvidptr->type) : "");
5009 tpl_addVar(vars, TPLADD, "CLIENTSRVDESCRIPTION", cl->last_srvidptr && cl->last_srvidptr->desc ? xml_encode(vars, cl->last_srvidptr->desc) : "");
5010 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", sec2timeformat(vars, chsec));
5011 if(cfg.http_showpicons && cl->last_srvid)
5013 char picon_channame[128];
5014 int8_t picon_ok = 0;
5016 get_picon_servicename_or_null(cl, cl->last_srvid, cl->last_provid, cl->last_caid, picon_channame, sizeof(picon_channame));
5017 if(picon_channame[0])
5019 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", picon_channame);
5020 picon_ok = picon_exists(picon_name);
5021 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
5023 if(!picon_ok && picon_servicename_remve_hd(picon_channame, sizeof(picon_channame)))
5025 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%s", picon_channame);
5026 picon_ok = picon_exists(picon_name);
5027 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
5030 if(!picon_ok)
5032 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%04X_%06X_%04X", cl->last_caid, cl->last_provid, cl->last_srvid);
5033 tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
5034 picon_ok = picon_exists(picon_name);
5036 if(!picon_ok)
5038 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "%04X_%04X", cl->last_caid, cl->last_srvid);
5039 picon_ok = picon_exists(picon_name);
5040 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
5042 if(!picon_ok)
5044 snprintf(picon_name, sizeof(picon_name) / sizeof(char) - 1, "0000_%04X", cl->last_srvid);
5045 picon_ok = picon_exists(picon_name);
5046 if(picon_ok) tpl_addVar(vars, TPLADD, "PICONNAME", picon_name);
5048 if(picon_ok)
5050 tpl_addVar(vars, TPLADDONCE, "CURRENTPICON", tpl_getTpl(vars, "CLIENTCURRENTCHANNELPIC"));
5052 else
5054 tpl_addVar(vars, TPLADDONCE, "CURRENTPICON", tpl_getTpl(vars, "CLIENTCURRENTCHANNEL"));
5055 tpl_addVar(vars, TPLADD, "PICONNAME", "");
5058 else
5060 tpl_addVar(vars, TPLADDONCE, "CURRENTPICON", tpl_getTpl(vars, "CLIENTCURRENTCHANNELBIT"));
5061 tpl_addVar(vars, TPLADD, "PICONNAME", "0000_0000");
5064 else
5066 tpl_addVar(vars, TPLADD, "CLIENTCAID", "0000");
5067 tpl_addVar(vars, TPLADD, "CLIENTPROVID", "000000");
5068 tpl_printf(vars, TPLADD, "CLIENTSRVID", "0000");
5071 else
5073 tpl_addVar(vars, TPLADD, "CLIENTCAID", "0000");
5074 tpl_addVar(vars, TPLADD, "CLIENTPROVID", "000000");
5075 tpl_addVar(vars, TPLADD, "CLIENTSRVID", "0000");
5076 tpl_addVar(vars, TPLADD, "CURRENTPICON", "");
5077 tpl_addVar(vars, TPLADD, "CLIENTSRVPROVIDER", "");
5078 tpl_addVar(vars, TPLADD, "CLIENTSRVNAME", "");
5079 tpl_addVar(vars, TPLADD, "CLIENTSRVTYPE", "");
5080 tpl_addVar(vars, TPLADD, "CLIENTSRVDESCRIPTION", "");
5081 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", "");
5082 tpl_addVar(vars, TPLADD, "CLIENTTIMEONCHANNEL", "");
5085 if(!apicall)
5087 tpl_addVar(vars, TPLADD, "CLIENTIDLESECS", sec2timeformat(vars, isec));
5089 if((cl->typ != 'p' && cl->typ != 'r') || cl->reader->card_status == CARD_INSERTED)
5090 { tpl_addVar(vars, TPLADD, "CLIENTIDLESECSCLASS", "idlesec_normal"); }
5091 else
5092 { tpl_addVar(vars, TPLADD, "CLIENTIDLESECSCLASS", "idlesec_alert"); }
5094 else
5096 tpl_printf(vars, TPLADD, "CLIENTIDLESECS", "%d", isec);
5099 if(con == 2) { tpl_addVar(vars, TPLADD, "CLIENTCON", "Duplicate"); }
5100 else if(con == 1) { tpl_addVar(vars, TPLADD, "CLIENTCON", "Sleep"); }
5101 else
5103 struct s_reader *rdr = cl->reader;
5104 char *txt = "OK";
5105 if(!rdr && (cl->typ == 'r' || cl->typ == 'p')) { txt = "UNKNOWN"; }
5106 else if(cl->typ == 'r' || cl->typ == 'p') //reader or proxy
5108 #ifdef WITH_LB
5109 if(rdr->lbvalue)
5111 tpl_printf(vars, TPLADD, "LBLRPSTRVALUE", "%d", rdr->lbvalue);
5113 else
5115 tpl_addVar(vars, TPLADD, "LBLRPSTRVALUE", "no data");
5117 tpl_addVar(vars, TPLADD, "LBLRPVALUE", rdr->label);
5118 tpl_addVar(vars, TPLADD, "LBLRPVALUEENC", urlencode(vars, rdr->label));
5119 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", tpl_getTpl(vars, "CLIENTLBLVALUERP"));
5120 #else
5121 tpl_addVar(vars, TPLADD, "CLIENTLBVALUE", tpl_getVar(vars, "LBLRPSTRVALUE"));
5122 #endif
5123 switch(rdr->card_status)
5125 case NO_CARD:
5126 txt = "OFF";
5127 break;
5128 case UNKNOWN:
5129 txt = "UNKNOWN";
5130 break;
5131 case READER_DEVICE_ERROR:
5132 txt = "READER DEVICE ERROR";
5133 break;
5134 case CARD_NEED_INIT:
5135 #ifdef CS_CACHEEX
5136 if (cl->reader->cacheex.mode > 0)
5138 txt = "CCcam CacheEX";
5140 else
5142 #endif
5143 txt = "NEEDINIT";
5144 #ifdef CS_CACHEEX
5146 #endif
5147 break;
5148 case CARD_INSERTED:
5149 if(cl->typ == 'p')
5150 { txt = "CONNECTED"; }
5151 else
5152 { txt = "CARDOK"; }
5153 break;
5154 case CARD_FAILURE:
5155 txt = "ERROR";
5156 break;
5157 default:
5158 txt = "UNDEF";
5161 tpl_addVar(vars, TPLADD, "CLIENTCON", txt);
5163 if(rdr && (cl->typ == 'r')) //reader
5165 if(rdr->ll_entitlements)
5167 LL_ITER itr = ll_iter_create(rdr->ll_entitlements);
5168 S_ENTITLEMENT *ent;
5169 uint16_t total_ent = 0;
5170 uint16_t active_ent = 0;
5171 struct tm end_t;
5172 tpl_addVar(vars, TPLADD, "TMPSPAN", "<SPAN>");
5173 while((ent = ll_iter_next(&itr)))
5175 total_ent++;
5176 if((ent->end > now) && (ent->type != 7))
5178 if(active_ent) {tpl_addVar(vars, TPLAPPEND, "TMPSPAN", "<BR><BR>");}
5179 active_ent++;
5180 localtime_r(&ent->end, &end_t);
5181 tpl_printf(vars, TPLAPPEND, "TMPSPAN", "%04X@%06X<BR>exp:%04d/%02d/%02d",
5182 ent->caid, ent->provid,
5183 end_t.tm_year + 1900, end_t.tm_mon + 1, end_t.tm_mday);
5184 tpl_printf(vars, TPLAPPEND, "ENTITLEMENTS", "%s{\"caid\":\"%04X\",\"provid\":\"%06X\",\"exp\":\"%04d/%02d/%02d\"}",
5185 active_ent > 1 ? ",": "",
5186 ent->caid, ent->provid,
5187 end_t.tm_year + 1900, end_t.tm_mon + 1, end_t.tm_mday);
5190 tpl_printf(vars, TPLADD, "TOTENTITLEMENTS", "%d", total_ent);
5191 if(((total_ent) && (active_ent == 0)) || (total_ent == 0))
5193 tpl_addVar(vars, TPLAPPEND, "TMPSPAN", "No active entitlements found");
5195 tpl_addVar(vars, TPLAPPEND, "TMPSPAN", "</SPAN>");
5196 if(active_ent)
5198 tpl_printf(vars, TPLADD, "TMP", "(%d entitlement%s)", active_ent, (active_ent != 1) ? "s" : "");
5200 else
5202 tpl_addVar(vars, TPLADD, "TMP", "(no entitlements)");
5204 tpl_addVar(vars, TPLADD, "ENTLABEL", urlencode(vars, cl->reader->label));
5205 tpl_addVar(vars, TPLADD, "ENTVALUE", active_ent > 0 ? "" : "1");
5206 if (!apicall) tpl_addVar(vars, TPLAPPEND, "CLIENTCON", tpl_getTpl(vars, "FOUNDENTITLEMENTS"));
5208 else
5210 tpl_addVar(vars, TPLADD, "ENTLABEL", urlencode(vars, cl->reader->label));
5211 if (!apicall) tpl_addVar(vars, TPLAPPEND, "CLIENTCON", tpl_getTpl(vars, "NOENTITLEMENTS"));
5214 #ifdef MODULE_CCCAM
5215 if(!apicall || apicall == 2)
5217 if(rdr && (cl->typ == 'r' || cl->typ == 'p') && strncmp(proto, "cccam", 5) == 0 && rdr->tcp_connected && rdr->card_status != CARD_FAILURE)
5219 struct cc_data *rcc = cl->cc;
5220 if(rcc)
5222 LLIST *cards = rcc->cards;
5223 if(cards)
5225 int32_t cnt = ll_count(cards);
5226 int32_t locals = rcc->num_hop1;
5227 if(!apicall)
5229 tpl_printf(vars, TPLADD, "TMP", "(%d of %d card%s)", locals, cnt, (cnt > 1) ? "s" : "");
5230 tpl_printf(vars, TPLADD, "CCCOUNT", "%d", cnt);
5231 tpl_printf(vars, TPLADD, "CCCHOP1", "%d", rcc->num_hop1);
5232 tpl_printf(vars, TPLADD, "CCCHOP2", "%d", rcc->num_hop2);
5233 tpl_printf(vars, TPLADD, "CCCHOPX", "%d", rcc->num_hopx);
5234 tpl_printf(vars, TPLADD, "CCCCURR", "%d", cl->reader->currenthops);
5235 tpl_printf(vars, TPLADD, "CCCRES0", "%d", rcc->num_reshare0);
5236 tpl_printf(vars, TPLADD, "CCCRES1", "%d", rcc->num_reshare1);
5237 tpl_printf(vars, TPLADD, "CCCRES2", "%d", rcc->num_reshare2);
5238 tpl_printf(vars, TPLADD, "CCCRESX", "%d", rcc->num_resharex);
5239 tpl_addVar(vars, TPLADD, "TMPSPAN", tpl_getTpl(vars, "CCENTITLEMENTS"));
5240 tpl_addVar(vars, TPLADD, "CCCLABEL", urlencode(vars, cl->reader->label));
5241 tpl_addVar(vars, TPLADD, "CCCRESHARE", rcc->num_reshare0 > 0 ? "1" : "");
5242 tpl_addVar(vars, TPLADD, "CCCTMP", tpl_getVar(vars, "TMP"));
5243 tpl_addVar(vars, TPLADD, "CCCTMPSPAN", tpl_getVar(vars, "TMPSPAN"));
5244 tpl_addVar(vars, TPLAPPEND, "CLIENTCON", tpl_getTpl(vars, "CCENTITLETOOLTIP"));
5246 if (apicall == 2)
5248 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, cl->reader->label));
5249 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\"}",
5250 locals, cnt, rcc->num_hop1, rcc->num_hop2, rcc->num_hopx, cl->reader->currenthops,
5251 rcc->num_reshare0, rcc->num_reshare1, rcc->num_reshare2, rcc->num_resharex,
5252 rcc->num_reshare0 > 0 ? "1" : "");
5258 #endif
5262 if(!apicall)
5264 // select right suborder
5265 if(cl->typ == 'c')
5267 if(shown) { tpl_addVar(vars, TPLAPPEND, "CLIENTSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT")); }
5268 if(cfg.http_hide_idle_clients != 1 && cfg.hideclient_to > 0)
5270 tpl_printf(vars, TPLADD, "UCAC", "%d", user_count_active);
5271 tpl_printf(vars, TPLADD, "CFGH", "%d", cfg.hideclient_to);
5272 tpl_addVar(vars, TPLADD, "CHEADADD", tpl_getTpl(vars, "CLIENTHEADLINEADD"));
5274 tpl_printf(vars, TPLADD, "UCS", "%d", user_count_shown);
5275 tpl_printf(vars, TPLADD, "UCA", "%d", user_count_all);
5276 tpl_addVar(vars, TPLADD, "HIDEIDLE", "5");
5277 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "User");
5278 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTHEADLINE"));
5279 tpl_addVar(vars, TPLADD, "CLIENTOPTIONADD", tpl_getTpl(vars, "CLIENTHEADLINEBIT"));
5280 tpl_addVar(vars, TPLADD, "CLIENTHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
5281 tpl_addVar(vars, TPLADD, "CLIENTOPTIONADD", "");
5283 else if(cl->typ == 'r')
5285 if(shown) { tpl_addVar(vars, TPLAPPEND, "READERSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT")); }
5286 tpl_printf(vars, TPLADD, "RCC", "%d", reader_count_conn);
5287 tpl_printf(vars, TPLADD, "RCA", "%d", reader_count_all);
5288 if(reader_count_off) {
5289 tpl_printf(vars, TPLADD, "RCO", "%d", reader_count_all-reader_count_off);
5290 tpl_addVar(vars, TPLADD, "RHEADADD", tpl_getTpl(vars, "CLIENTRHEADLINEADD"));
5292 tpl_addVar(vars, TPLADD, "HIDEIDLE", "3");
5293 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "Reader");
5294 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTRHEADLINE"));
5295 tpl_addVar(vars, TPLADD, "READERHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
5297 else if(cl->typ == 'p')
5299 if(shown) { tpl_addVar(vars, TPLAPPEND, "PROXYSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT")); }
5300 tpl_printf(vars, TPLADD, "PCC", "%d", proxy_count_conn);
5301 tpl_printf(vars, TPLADD, "PCA", "%d", proxy_count_all);
5302 if(proxy_count_off) {
5303 tpl_printf(vars, TPLADD, "PCO", "%d", proxy_count_all-proxy_count_off);
5304 tpl_addVar(vars, TPLADD, "PHEADADD", tpl_getTpl(vars, "CLIENTPHEADLINEADD"));
5306 tpl_addVar(vars, TPLADD, "HIDEIDLE", "4");
5307 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "Proxy");
5308 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTPHEADLINE"));
5309 tpl_addVar(vars, TPLADD, "PROXYHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
5311 else if(cl->typ == 'm' || cl->typ == 's' || cl->typ == 'h')
5313 if(shown) { tpl_addVar(vars, TPLAPPEND, "SERVERSTATUS", tpl_getTpl(vars, "CLIENTSTATUSBIT")); }
5314 tpl_addVar(vars, TPLADD, "HIDEIDLE", "2");
5315 tpl_addVar(vars, TPLADD, "SHOWHIDDEN", "Server");
5316 if(cl->typ == 's' || cl->typ == 'h')
5318 tpl_printf(vars, TPLADD, "SCS", "%d", server_count_shown);
5319 tpl_printf(vars, TPLADD, "SCA", "%d", server_count_all);
5320 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTSHEADLINE"));
5321 if(shown || cl->wihidden)
5323 tpl_addVar(vars, TPLADD, "SERVERHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
5324 usr = username(cl);
5327 else
5329 tpl_addVar(vars, TPLADD, "SHOWHIDDENADD", " & Monitors");
5330 tpl_printf(vars, TPLADD, "MCS", "%d", monitor_count_shown);
5331 tpl_printf(vars, TPLADD, "MCA", "%d", monitor_count_all);
5332 tpl_addVar(vars, TPLADD, "MHEADADD", tpl_getTpl(vars, "CLIENTMHEADLINE"));
5333 tpl_addVar(vars, TPLADD, "XHEAD", tpl_getTpl(vars, "CLIENTSHEADLINE"));
5334 tpl_addVar(vars, TPLADD, "SERVERHEADLINE", tpl_getTpl(vars, "STATUSHEADLINE"));
5335 tpl_addVar(vars, TPLADD, "SHOWHIDDENADD", "");
5339 else
5341 if(shown)
5343 if(apicall == 1)
5344 { tpl_addVar(vars, TPLAPPEND, "APISTATUSBITS", tpl_getTpl(vars, "APISTATUSBIT")); }
5345 if(apicall == 2)
5347 tpl_addVar(vars, TPLADD, "JSONARRAYDELIMITER", delimiter?",":"");
5348 tpl_addVar(vars, TPLAPPEND, "JSONSTATUSBITS", tpl_getTpl(vars, "JSONSTATUSBIT"));
5349 delimiter++;
5354 #ifdef CS_CACHEEX
5356 #endif
5360 LL_ITER itr = ll_iter_create(configured_readers);
5361 struct s_reader *rdrr;
5362 while((rdrr = ll_iter_next(&itr)))
5364 if(rdrr->label[0] && rdrr->typ)
5366 total_readers += 1;
5368 if(rdrr->enable) { active_readers += 1; }
5369 else { disabled_readers += 1; }
5371 if(rdrr->tcp_connected) { connected_readers += 1; }
5375 cs_readunlock(__func__, &clientlist_lock);
5376 cs_readunlock(__func__, &readerlist_lock);
5378 uint8_t is_touch = 0;
5379 if(config_enabled(TOUCH) && streq(tpl_getVar(vars, "SUBDIR"), TOUCH_SUBDIR))
5380 {is_touch=1;}
5382 if(cfg.http_status_log || (apicall == 1 && strcmp(getParam(params, "appendlog"), "1") == 0) || is_touch)
5384 if(cfg.loghistorylines && log_history)
5386 LL_ITER it = ll_iter_create(log_history);
5387 struct s_log_history *hist;
5389 while((hist = (struct s_log_history*)ll_iter_next(&it)))
5391 char p_usr[32];
5392 size_t pos1 = strcspn(hist->txt, "\t") + 1;
5393 cs_strncpy(p_usr, hist->txt , pos1 > sizeof(p_usr) ? sizeof(p_usr) : pos1);
5395 char *p_txt = hist->txt + pos1;
5397 if(!apicall)
5399 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));
5401 else
5403 tpl_addVar(vars, TPLAPPEND, "LOGHISTORY", p_txt);
5407 else
5409 tpl_addVar(vars, TPLADD, "LOGHISTORY", "loghistorylines is set to 0 in your configuration");
5413 #ifdef CS_CACHEEX
5414 char *getting = "<IMG SRC=\"image?i=ICARRL\" ALT=\"Getting\">";
5415 char *pushing = "<IMG SRC=\"image?i=ICARRR\" ALT=\"Pushing\">";
5417 float cachesum = first_client ? first_client->cwcacheexgot : 1;
5418 if(cachesum < 1)
5420 cachesum = 1;
5422 tpl_printf(vars, TPLADD, "TOTAL_CACHEXPUSH", "%d", first_client ? first_client->cwcacheexpush : 0);
5423 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXPUSH_IMG", pushing);
5424 tpl_printf(vars, TPLADD, "TOTAL_CACHEXGOT", "%d", first_client ? first_client->cwcacheexgot : 0);
5425 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXGOT_IMG", getting);
5426 tpl_printf(vars, TPLADD, "TOTAL_CACHEXHIT", "%d", first_client ? first_client->cwcacheexhit : 0);
5427 tpl_printf(vars, TPLADD, "TOTAL_CACHESIZE", "%d", cache_size());
5428 tpl_printf(vars, TPLADD, "REL_CACHEXHIT", "%.2f", (first_client ? first_client->cwcacheexhit : 0) * 100 / cachesum);
5429 tpl_addVar(vars, TPLADD, "CACHEEXSTATS", tpl_getTpl(vars, "STATUSCACHEX"));
5430 #endif
5431 //User info
5432 struct s_auth *account;
5433 int32_t total_users = 0;
5434 int32_t disabled_users = 0;
5435 int32_t expired_users = 0;
5436 int32_t expired_or_disabled_users = 0;
5437 int32_t connected_users = 0;
5438 int32_t online_users = 0;
5440 for(account = cfg.account; (account); account = account->next)
5442 total_users++;
5443 if(account->expirationdate && account->expirationdate < now)
5445 expired_users++;
5447 if(account->disabled != 0)
5449 disabled_users++;
5451 if((account->expirationdate && account->expirationdate < now)||account->disabled != 0)
5453 expired_or_disabled_users++;
5455 int32_t latestactivity = 0;
5456 struct s_client *latestclient = NULL;
5457 for(cl = first_client->next; cl ; cl = cl->next)
5459 if(cl->account && !strcmp(cl->account->usr, account->usr))
5461 if(cl->lastecm > latestactivity || cl->login > latestactivity)
5463 if(cl->lastecm > cl->login) { latestactivity = cl->lastecm; }
5464 else { latestactivity = cl->login; }
5465 latestclient = cl;
5470 if(latestclient != NULL)
5472 connected_users++;
5474 if(latestactivity > 0)
5476 if((now - latestactivity) < cfg.hideclient_to)
5478 if(latestclient->cwfound + latestclient->cwnot + latestclient->cwcache > 0)
5480 online_users++;
5486 tpl_printf(vars, TPLADD, "TOTAL_USERS", "%d", total_users);
5487 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE", "%d", total_users - expired_or_disabled_users);
5488 tpl_printf(vars, TPLADD, "TOTAL_EXPIRED", "%d", expired_users);
5489 tpl_printf(vars, TPLADD, "TOTAL_DISABLED", "%d", disabled_users);
5490 tpl_printf(vars, TPLADD, "TOTAL_ONLINE", "%d", online_users);
5491 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED", "%d", connected_users);
5493 tpl_printf(vars, TPLADD, "TOTAL_READERS", "%d", total_readers);
5494 tpl_printf(vars, TPLADD, "TOTAL_DISABLED_READERS", "%d", disabled_readers);
5495 tpl_printf(vars, TPLADD, "TOTAL_ACTIVE_READERS", "%d", active_readers);
5496 tpl_printf(vars, TPLADD, "TOTAL_CONNECTED_READERS", "%d", connected_readers);
5498 //CM info
5499 set_ecm_info(vars);
5501 //copy struct to p_stat_old for cpu_usage calculation
5502 p_stat_old = p_stat_cur;
5505 * check_available Bit mapping
5506 * mem 0 total, 1 used & free, 2 buff, cached & free incl. buff, 3 share
5507 * swap 4 total, 5 used & free,
5508 * proc 6 count
5509 * cpu 7 load
5510 * oscam 8 vsize & rssize, 9 cpu user, 10 cpu sys, 11 cpu sum, 12 cpu refreshtime
5511 * unused 13 - 15
5513 //Memory-CPU Info for linux based systems
5514 #if defined(__linux__)
5515 //get actual stats
5516 if(!get_stats_linux(getpid(),&p_stat_cur)){
5517 if(p_stat_old.cpu_total_time != 0){
5518 calc_cpu_usage_pct(&p_stat_cur, &p_stat_old);
5521 else{
5522 //something went wrong, so fill with "N/A"
5523 p_stat_cur.check_available = 65535;
5525 #else // if not linux, fill with "N/A" but probably in future gets filled also for other platforms
5526 p_stat_cur.check_available = 65535;
5527 #endif
5528 set_status_info(vars, p_stat_cur);
5530 if(cfg.http_showmeminfo || cfg.http_showuserinfo || cfg.http_showreaderinfo || cfg.http_showloadinfo || cfg.http_showecminfo || (cfg.http_showcacheexinfo && config_enabled(CS_CACHEEX))){
5531 tpl_addVar(vars, TPLADD, "DISPLAYINFO", "visible");
5533 else{
5534 tpl_addVar(vars, TPLADD, "DISPLAYINFO", "hidden");
5537 tpl_addVar(vars, TPLADD, "DISPLAYSYSINFO", cfg.http_showmeminfo ? "visible" : "hidden");
5538 tpl_addVar(vars, TPLADD, "DISPLAYUSERINFO", cfg.http_showuserinfo ? "visible" : "hidden");
5539 tpl_addVar(vars, TPLADD, "DISPLAYREADERINFO", cfg.http_showreaderinfo ? "visible" : "hidden");
5540 tpl_addVar(vars, TPLADD, "DISPLAYLOADINFO", cfg.http_showloadinfo ?"visible" : "hidden");
5541 tpl_addVar(vars, TPLADD, "DISPLAYECMINFO", cfg.http_showecminfo ? "visible" : "hidden");
5542 tpl_addVar(vars, TPLADD, "DISPLAYECMINFO_READERS", cfg.http_showecminfo ? "visible" : "hidden");
5544 if(cfg.http_showcacheexinfo == 1 && config_enabled(CS_CACHEEX)){
5545 tpl_addVar(vars, TPLADD, "DISPLAYCACHEEXINFO", "visible");
5547 else{
5548 tpl_addVar(vars, TPLADD, "DISPLAYCACHEEXINFO", "hidden");
5551 #ifdef WITH_DEBUG
5552 if(cfg.http_status_log || is_touch)
5554 // Debuglevel Selector
5555 int32_t lvl;
5556 for(i = 0; i < MAX_DEBUG_LEVELS; i++)
5558 lvl = 1 << i;
5559 tpl_printf(vars, TPLADD, "TMPC", "DCLASS%d", lvl);
5560 tpl_printf(vars, TPLADD, "TMPV", "DEBUGVAL%d", lvl);
5561 if(cs_dblevel & lvl)
5563 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugls");
5564 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel - lvl);
5566 else
5568 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugl");
5569 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel + lvl);
5573 if(cs_dblevel == D_ALL_DUMP)
5574 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugls"); }
5575 else
5576 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugl"); }
5578 tpl_addVar(vars, TPLADD, "NEXTPAGE", "status.html");
5579 tpl_addVar(vars, TPLADD, "DCLASS", "debugl"); //default
5580 tpl_printf(vars, TPLADD, "ACTDEBUG", "%d", cs_dblevel);
5581 tpl_addVar(vars, TPLADD, "SDEBUG", tpl_getTpl(vars, "DEBUGSELECT"));
5583 #endif
5585 if(cfg.http_status_log || is_touch)
5586 tpl_addVar(vars, TPLADDONCE, "LOG_HISTORY", tpl_getTpl(vars, "LOGHISTORYBIT"));
5588 if(apicall)
5590 if(apicall == 1)
5591 { return tpl_getTpl(vars, "APISTATUS"); }
5592 if(apicall == 2)
5594 tpl_printf(vars, TPLADD, "UCS", "%d", user_count_shown);
5595 tpl_printf(vars, TPLADD, "UCA", "%d", user_count_all);
5596 if(cfg.http_hide_idle_clients != 1 && cfg.hideclient_to > 0){
5597 tpl_printf(vars, TPLADD, "UCAC", "%d", user_count_active);
5599 tpl_printf(vars, TPLADD, "CFGH", "%d", cfg.hideclient_to);
5600 tpl_printf(vars, TPLADD, "MCS", "%d", monitor_count_shown);
5601 tpl_printf(vars, TPLADD, "MCA", "%d", monitor_count_all);
5602 tpl_printf(vars, TPLADD, "SCS", "%d", server_count_shown);
5603 tpl_printf(vars, TPLADD, "SCH", "%d", server_count_hidden);
5604 tpl_printf(vars, TPLADD, "SCA", "%d", server_count_all);
5605 tpl_printf(vars, TPLADD, "RCC", "%d", reader_count_conn);
5606 tpl_printf(vars, TPLADD, "RCO", "%d", reader_count_off);
5607 tpl_printf(vars, TPLADD, "RCA", "%d", reader_count_all);
5608 tpl_printf(vars, TPLADD, "PCC", "%d", proxy_count_conn);
5609 tpl_printf(vars, TPLADD, "PCO", "%d", proxy_count_off);
5610 tpl_printf(vars, TPLADD, "PCA", "%d", proxy_count_all);
5611 tpl_printf(vars, TPLADD, "PICONENABLED", "%d", cfg.http_showpicons?1:0);
5612 tpl_printf(vars, TPLADD, "SRVIDFILE", "%s", use_srvid2 ? "oscam.srvid2" : "oscam.srvid");
5613 return tpl_getTpl(vars, "JSONSTATUS");
5617 if(is_touch)
5618 { return tpl_getTpl(vars, "TOUCH_STATUS"); }
5619 else
5620 { return tpl_getTpl(vars, "STATUS"); }
5623 static char *send_oscam_services_edit(struct templatevars * vars, struct uriparams * params)
5625 struct s_sidtab *sidtab, *ptr;
5626 char label[sizeof(cfg.sidtab->label)];
5627 int32_t i;
5629 setActiveMenu(vars, MNU_SERVICES);
5631 cs_strncpy(label, strtolower(getParam(params, "service")), sizeof(label));
5632 ++cfg_sidtab_generation;
5633 for(sidtab = cfg.sidtab; sidtab != NULL && strcmp(label, sidtab->label) != 0; sidtab = sidtab->next) { ; }
5635 if(sidtab == NULL)
5637 i = 1;
5638 while(strlen(label) < 1)
5640 snprintf(label, sizeof(label) / sizeof(char) - 1, "newservice%d", i);
5641 for(sidtab = cfg.sidtab; sidtab != NULL && strcmp(label, sidtab->label) != 0; sidtab = sidtab->next) { ; }
5642 if(sidtab != NULL) { label[0] = '\0'; }
5643 ++i;
5645 if(!cs_malloc(&sidtab, sizeof(struct s_sidtab))) { return "0"; }
5647 if(cfg.sidtab == NULL) { cfg.sidtab = sidtab; }
5648 else
5650 for(ptr = cfg.sidtab; ptr != NULL && ptr->next != NULL; ptr = ptr->next) { ; }
5651 ptr->next = sidtab;
5653 cs_strncpy((char *)sidtab->label, label, sizeof(sidtab->label));
5654 ++cfg_sidtab_generation;
5655 tpl_addMsg(vars, "New service has been added");
5656 // Adding is uncritical as the new service is appended to sidtabs.ok/sidtabs.no and accounts/clients/readers have zeros there
5657 if(write_services() != 0) { tpl_addMsg(vars, "Writing services to disk failed!"); }
5660 if(strcmp(getParam(params, "action"), "Save") == 0)
5662 for(i = 0; i < (*params).paramcount; i++)
5664 if((strcmp((*params).params[i], "action")) && (strcmp((*params).params[i], "service")))
5666 chk_sidtab((*params).params[i], (*params).values[i], sidtab);
5669 ++cfg_sidtab_generation;
5670 tpl_addMsg(vars, "Services updated");
5671 // We don't need any refresh here as accounts/clients/readers sidtabs.ok/sidtabs.no are unaffected!
5672 if(write_services() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
5674 for(sidtab = cfg.sidtab; sidtab != NULL && strcmp(label, sidtab->label) != 0; sidtab = sidtab->next) { ; }
5677 tpl_addVar(vars, TPLADD, "LABEL", xml_encode(vars, sidtab->label));
5678 tpl_addVar(vars, TPLADD, "LABELENC", urlencode(vars, sidtab->label));
5680 if(sidtab)
5682 for(i = 0; i < sidtab->num_caid; i++)
5684 if(i == 0) { tpl_printf(vars, TPLADD, "CAIDS", "%04X", sidtab->caid[i]); }
5685 else { tpl_printf(vars, TPLAPPEND, "CAIDS", ",%04X", sidtab->caid[i]); }
5687 for(i = 0; i < sidtab->num_provid; i++)
5689 if(i == 0) { tpl_printf(vars, TPLADD, "PROVIDS", "%06X", sidtab->provid[i]); }
5690 else { tpl_printf(vars, TPLAPPEND, "PROVIDS", ",%06X", sidtab->provid[i]); }
5692 for(i = 0; i < sidtab->num_srvid; i++)
5694 if(i == 0) { tpl_printf(vars, TPLADD, "SRVIDS", "%04X", sidtab->srvid[i]); }
5695 else { tpl_printf(vars, TPLAPPEND, "SRVIDS", ",%04X", sidtab->srvid[i]); }
5698 return tpl_getTpl(vars, "SERVICEEDIT");
5701 static void delete_from_SIDTABBITS(SIDTABBITS * orgsidtab, int32_t position, int32_t sidtablength)
5703 if(*orgsidtab)
5705 int32_t i;
5706 SIDTABBITS newsidtab = 0;
5707 for(i = 0; i < position; ++i)
5709 if(*orgsidtab & ((SIDTABBITS)1 << i))
5710 { newsidtab |= ((SIDTABBITS)1 << i); }
5712 for(; i < sidtablength; ++i)
5714 if(*orgsidtab & ((SIDTABBITS)1 << (i + 1)))
5715 { newsidtab |= ((SIDTABBITS)1 << i); }
5717 *orgsidtab = newsidtab;
5721 static char *send_oscam_services(struct templatevars * vars, struct uriparams * params)
5723 struct s_sidtab *sidtab;
5724 char *service = getParam(params, "service");
5725 char channame[CS_SERVICENAME_SIZE];
5726 int32_t i, counter = 0;
5728 setActiveMenu(vars, MNU_SERVICES);
5730 if(strcmp(getParam(params, "action"), "delete") == 0)
5732 if(cfg.http_readonly)
5734 tpl_addMsg(vars, "Sorry, Webif is in readonly mode. No deletion will be made!");
5736 else
5738 struct s_sidtab *sidtab_prev = NULL;
5739 int32_t sidtablength = -1;
5740 int32_t position = 0;
5742 // Calculate sidtablength before deletion so that updating sidtabs is faster
5743 for(sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next)
5744 { ++sidtablength; }
5746 for(sidtab = cfg.sidtab; sidtab; sidtab = sidtab->next)
5748 if(strcmp(sidtab->label, service) == 0)
5750 struct s_auth *account;
5751 struct s_client *cl;
5752 struct s_reader *rdr;
5754 if(!sidtab_prev)
5755 { cfg.sidtab = sidtab->next; }
5756 else
5757 { sidtab_prev->next = sidtab->next; }
5759 for(account = cfg.account; (account); account = account->next)
5761 delete_from_SIDTABBITS(&account->sidtabs.ok, position, sidtablength);
5762 delete_from_SIDTABBITS(&account->sidtabs.no, position, sidtablength);
5764 for(cl = first_client->next; cl ; cl = cl->next)
5766 if(account == cl->account)
5768 cl->sidtabs.ok = account->sidtabs.ok;
5769 cl->sidtabs.no = account->sidtabs.no;
5774 LL_ITER itr = ll_iter_create(configured_readers);
5775 while((rdr = ll_iter_next(&itr)))
5777 delete_from_SIDTABBITS(&rdr->sidtabs.ok, position, sidtablength);
5778 delete_from_SIDTABBITS(&rdr->sidtabs.no, position, sidtablength);
5779 delete_from_SIDTABBITS(&rdr->lb_sidtabs.ok, position, sidtablength);
5781 free_sidtab(sidtab);
5782 ++counter;
5783 break;
5785 sidtab_prev = sidtab;
5786 position++;
5788 if(counter > 0)
5790 ++cfg_sidtab_generation;
5791 tpl_addMsg(vars, "Service has been deleted!");
5792 if(write_services() != 0) { tpl_addMsg(vars, "Writing services to disk failed!"); }
5794 else { tpl_addMsg(vars, "Sorry but the specified service doesn't exist. No deletion will be made!"); }
5798 sidtab = cfg.sidtab;
5799 // Show List
5800 counter = 0;
5801 while(sidtab != NULL)
5803 tpl_addVar(vars, TPLADD, "SID", "");
5804 if((strcmp(getParam(params, "service"), sidtab->label) == 0) && (strcmp(getParam(params, "action"), "list") == 0))
5806 tpl_addVar(vars, TPLADD, "SIDCLASS", "sidlist");
5807 tpl_addVar(vars, TPLAPPEND, "SID", "<DIV CLASS=\"sidlistclose\"><A HREF=\"services.html\">X</A></DIV>");
5808 for(i = 0; i < sidtab->num_srvid; i++)
5810 tpl_printf(vars, TPLAPPEND, "SID", "%04X : %s<BR>", sidtab->srvid[i],
5811 xml_encode(vars, get_servicename(cur_client(), sidtab->srvid[i], sidtab->num_provid ? sidtab->provid[0] : 0,
5812 sidtab->num_caid ? sidtab->caid[0] : 0, channame, sizeof(channame))));
5815 else
5817 tpl_addVar(vars, TPLADD, "SIDCLASS", "");
5818 tpl_printf(vars, TPLADD, "SID", "<A HREF=\"services.html?service=%s&amp;action=list\">Show Services</A>", urlencode(vars, sidtab->label));
5820 tpl_addVar(vars, TPLADD, "LABELENC", urlencode(vars, sidtab->label));
5821 tpl_addVar(vars, TPLADD, "LABEL", xml_encode(vars, sidtab->label));
5822 tpl_addVar(vars, TPLADD, "SIDLIST", tpl_getTpl(vars, "SERVICECONFIGSIDBIT"));
5824 tpl_addVar(vars, TPLAPPEND, "SERVICETABS", tpl_getTpl(vars, "SERVICECONFIGLISTBIT"));
5825 sidtab = sidtab->next;
5826 counter++;
5828 if(counter >= MAX_SIDBITS)
5830 tpl_addVar(vars, TPLADD, "BTNDISABLED", "DISABLED");
5831 tpl_addMsg(vars, "Maximum Number of Services is reached");
5833 return tpl_getTpl(vars, "SERVICECONFIGLIST");
5836 static char *send_oscam_savetpls(struct templatevars * vars)
5838 if(cfg.http_tpl)
5840 tpl_printf(vars, TPLADD, "CNT", "%d", tpl_saveIncludedTpls(cfg.http_tpl));
5841 tpl_addVar(vars, TPLADD, "PATH", cfg.http_tpl);
5843 else { tpl_addVar(vars, TPLADD, "CNT", "0"); }
5844 return tpl_getTpl(vars, "SAVETEMPLATES");
5847 static char *send_oscam_shutdown(struct templatevars * vars, FILE * f, struct uriparams * params, int8_t apicall, int8_t *keepalive, char *extraheader)
5849 if(!apicall) { setActiveMenu(vars, MNU_SHUTDOWN); }
5850 if(strcmp(strtolower(getParam(params, "action")), "shutdown") == 0)
5852 *keepalive = 0;
5853 if(!apicall)
5855 char *CSS = tpl_getUnparsedTpl("CSS", 1, "");
5856 tpl_addVar(vars, TPLADD, "STYLESHEET", CSS);
5857 NULLFREE(CSS);
5858 tpl_printf(vars, TPLADD, "REFRESHTIME", "%d", SHUTDOWNREFRESH);
5859 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
5860 tpl_printf(vars, TPLADD, "SECONDS", "%d", SHUTDOWNREFRESH);
5861 char *result = tpl_getTpl(vars, "SHUTDOWN");
5862 send_headers(f, 200, "OK", extraheader, "text/html", 0, strlen(result), NULL, 0);
5863 webif_write(result, f);
5864 cs_log("Shutdown requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
5866 else
5868 tpl_addVar(vars, TPLADD, "APICONFIRMMESSAGE", "shutdown");
5869 cs_log("Shutdown requested by XMLApi from %s", cs_inet_ntoa(GET_IP()));
5871 cs_exit_oscam();
5873 if(!apicall)
5874 { return "1"; }
5875 else
5876 { return tpl_getTpl(vars, "APICONFIRMATION"); }
5879 else if(strcmp(strtolower(getParam(params, "action")), "restart") == 0)
5881 *keepalive = 0;
5882 if(!apicall)
5884 char *CSS = tpl_getUnparsedTpl("CSS", 1, "");
5885 tpl_addVar(vars, TPLADD, "STYLESHEET", CSS);
5886 NULLFREE(CSS);
5887 tpl_addVar(vars, TPLADD, "REFRESHTIME", "5");
5888 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
5889 tpl_addVar(vars, TPLADD, "SECONDS", "5");
5890 char *result = tpl_getTpl(vars, "SHUTDOWN");
5891 send_headers(f, 200, "OK", extraheader, "text/html", 0, strlen(result), NULL, 0);
5892 webif_write(result, f);
5893 cs_log("Restart requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
5895 else
5897 tpl_addVar(vars, TPLADD, "APICONFIRMMESSAGE", "restart");
5898 cs_log("Restart requested by XMLApi from %s", cs_inet_ntoa(GET_IP()));
5900 cs_restart_oscam();
5902 if(!apicall)
5903 { return "1"; }
5904 else
5905 { return tpl_getTpl(vars, "APICONFIRMATION"); }
5908 else
5910 return tpl_getTpl(vars, "PRESHUTDOWN");
5914 static char *send_oscam_script(struct templatevars * vars, struct uriparams * params)
5916 setActiveMenu(vars, MNU_SCRIPT);
5917 tpl_printf(vars, TPLADD, "SCRIPTOPTIONS", "<option value=\"\">----select script----</option>\n");
5919 if(!cfg.http_readonly && cfg.http_script)
5921 struct dirent **namelist;
5922 int count, i;
5923 count = scandir(cfg.http_script, &namelist, 0, alphasort );
5924 if( count >= 0 )
5926 for( i = 0 ; i < count; i++ )
5928 if(is_ext(namelist[i]->d_name, ".script") || is_ext(namelist[i]->d_name, ".sh"))
5930 tpl_printf(vars, TPLAPPEND, "SCRIPTOPTIONS", "<option value=\"script.html?scriptname=%s\">%s</option>\n",namelist[i]->d_name,namelist[i]->d_name);
5932 free( namelist[i] );
5934 free(namelist);
5937 char *scriptname = getParam(params, "scriptname");
5938 char *scriptparam = getParam(params, "scriptparam");
5939 char system_str[256];
5940 struct stat s;
5941 snprintf(system_str, sizeof(system_str), "%s/%s", cfg.http_script, scriptname);
5943 if(!stat(system_str,&s))
5945 if(s.st_mode & S_IFREG)
5947 if(s.st_mode & S_IXUSR)
5949 int32_t rc;
5950 FILE *fp;
5951 char buf[256];
5953 if((scriptparam != NULL) && (sizeof(scriptparam) > 0))
5955 strcat(system_str, " ");
5956 strcat(system_str, scriptparam);
5959 fp = popen(system_str,"r");
5961 while (fgets(buf, sizeof(buf), fp) != NULL) {
5962 tpl_addVar(vars, TPLAPPEND, "SCRIPTRESULTOUT", buf);
5965 rc = pclose(fp)/256;
5967 tpl_printf(vars, TPLAPPEND, "CODE", "returncode: %d", rc);
5968 tpl_printf(vars, TPLADD, "SCRIPTNAME", "scriptname: %s", scriptname);
5970 else
5972 tpl_printf(vars, TPLADD, "SCRIPTRESULTOUT", "[Error]: Script \"%s\" not executable!", scriptname);
5976 else
5978 tpl_printf(vars, TPLADD, "SCRIPTRESULTOUT", "[Error]: Script \"%s\" not found!", scriptname);
5982 return tpl_getTpl(vars, "SCRIPT");
5985 static char *send_oscam_scanusb(struct templatevars * vars)
5987 setActiveMenu(vars, MNU_READERS);
5988 #if !defined(__CYGWIN__)
5989 FILE *fp;
5990 char path[1035];
5992 fp = popen("lsusb -v | egrep '^Bus|^ *iSerial|^ *iProduct'", "r");
5993 if(!fgets(path, sizeof(path) - 1, fp) || !fp)
5995 tpl_addVar(vars, TPLADD, "USBENTRY", "<b>lsusb:</b> Failed to run or not installed!");
5996 tpl_addVar(vars, TPLADD, "USBBIT", tpl_getTpl(vars, "SCANUSBBIT"));
5998 else
6001 tpl_addVar(vars, TPLADD, "USBENTRYCLASS", "");
6002 if(strstr(path, "Bus "))
6004 tpl_addVar(vars, TPLADD, "USBENTRY", path);
6005 tpl_addVar(vars, TPLADD, "USBENTRYCLASS", "CLASS=\"scanusbsubhead\"");
6007 else
6009 tpl_printf(vars, TPLADD, "USBENTRY", "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%s", path);
6011 tpl_addVar(vars, TPLAPPEND, "USBBIT", tpl_getTpl(vars, "SCANUSBBIT"));
6013 while(fgets(path, sizeof(path) - 1, fp) != NULL);
6015 pclose(fp);
6016 #else
6017 tpl_addMsg(vars, "Function not supported in CYGWIN environment");
6018 #endif
6019 return tpl_getTpl(vars, "SCANUSB");
6022 static void webif_process_logfile(struct templatevars * vars, struct uriparams * params, char *targetfile, size_t targetfile_len)
6024 snprintf(targetfile, targetfile_len, "%s", cfg.logfile);
6025 if(strcmp(getParam(params, "clear"), "logfile") == 0)
6027 if(strlen(targetfile) > 0)
6029 FILE *file = fopen(targetfile, "w");
6030 fclose(file);
6033 #ifdef WITH_DEBUG
6034 // Debuglevel Selector
6035 int32_t i, lvl;
6036 for(i = 0; i < MAX_DEBUG_LEVELS; i++)
6038 lvl = 1 << i;
6039 tpl_printf(vars, TPLADD, "TMPC", "DCLASS%d", lvl);
6040 tpl_printf(vars, TPLADD, "TMPV", "DEBUGVAL%d", lvl);
6041 if(cs_dblevel & lvl)
6043 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugls");
6044 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel - lvl);
6046 else
6048 tpl_addVar(vars, TPLADD, tpl_getVar(vars, "TMPC"), "debugl");
6049 tpl_printf(vars, TPLADD, tpl_getVar(vars, "TMPV"), "%d", cs_dblevel + lvl);
6052 if(cs_dblevel == D_ALL_DUMP)
6053 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugls"); }
6054 else
6055 { tpl_addVar(vars, TPLADD, "DCLASS65535", "debugl"); }
6056 tpl_addVar(vars, TPLADD, "CUSTOMPARAM", "&file=logfile");
6057 tpl_printf(vars, TPLADD, "ACTDEBUG", "%d", cs_dblevel);
6058 tpl_addVar(vars, TPLADD, "SDEBUG", tpl_getTpl(vars, "DEBUGSELECT"));
6059 tpl_addVar(vars, TPLADD, "NEXTPAGE", "files.html");
6060 #endif
6061 if(!cfg.disablelog)
6063 tpl_printf(vars, TPLADD, "SWITCH", "%d", 1);
6064 tpl_addVar(vars, TPLADD, "TEXT", "Stop Log");
6065 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUDISABLELOG"));
6068 else
6070 tpl_printf(vars, TPLADD, "SWITCH", "%d", 0);
6071 tpl_addVar(vars, TPLADD, "TEXT", "Start Log");
6072 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUDISABLELOG"));
6074 tpl_addVar(vars, TPLAPPEND, "LOGMENU", tpl_getTpl(vars, "CLEARLOG"));
6075 return;
6078 static void webif_process_userfile(struct templatevars * vars, struct uriparams * params, char *targetfile, size_t targetfile_len)
6080 snprintf(targetfile, targetfile_len, "%s", cfg.usrfile);
6081 if(strcmp(getParam(params, "clear"), "usrfile") == 0)
6083 if(strlen(targetfile) > 0)
6085 FILE *file = fopen(targetfile, "w");
6086 fclose(file);
6089 if(!cfg.disableuserfile)
6091 tpl_printf(vars, TPLADD, "SWITCH", "%d", 1);
6092 tpl_addVar(vars, TPLADD, "TEXT", "Stop Log");
6093 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUONOFF"));
6095 else
6097 tpl_printf(vars, TPLADD, "SWITCH", "%d", 0);
6098 tpl_addVar(vars, TPLADD, "TEXT", "Start Log");
6099 tpl_addVar(vars, TPLADD, "LOGMENU", tpl_getTpl(vars, "LOGMENUONOFF"));
6101 tpl_addVar(vars, TPLAPPEND, "LOGMENU", tpl_getTpl(vars, "CLEARUSERLOG"));
6102 tpl_addVar(vars, TPLADD, "FFVAL", "all");
6103 tpl_addVar(vars, TPLADD, "FILTERFORMOPTIONS", tpl_getTpl(vars, "LOGMENUFILTERFORM"));
6104 struct s_auth *account;
6105 for(account = cfg.account; account; account = account->next)
6107 tpl_addVar(vars, TPLADD, "FFVAL", xml_encode(vars, account->usr));
6108 tpl_addVar(vars, TPLADD, "FFSEL", strcmp(getParam(params, "filter"), account->usr) ? "" : "selected");
6109 tpl_addVar(vars, TPLAPPEND, "FILTERFORMOPTIONS", tpl_getTpl(vars, "LOGMENUFILTERFORM"));
6111 tpl_addVar(vars, TPLADD, "FILTERFORM", tpl_getTpl(vars, "FILTERFORM"));
6114 enum file_types { FTYPE_CONFIG, FTYPE_VERSION, FTYPE_ANTICASC, FTYPE_LOGFILE, FTYPE_USERFILE };
6116 struct files
6118 char *file;
6119 int menu_id;
6120 enum file_types type;
6123 static char *send_oscam_files(struct templatevars * vars, struct uriparams * params, int8_t apicall)
6125 bool writable = false;
6126 const struct files *entry;
6127 static struct files config_files[] =
6129 // id are used
6130 // new entry after last entry before first ifdef entry
6131 // ifdef must be add to end
6132 { "oscam.version", MNU_CFG_FVERSION, FTYPE_VERSION }, // id 0
6133 { "oscam.conf", MNU_CFG_FCONF, FTYPE_CONFIG }, // id 1
6134 { "oscam.user", MNU_CFG_FUSER, FTYPE_CONFIG }, // id 2
6135 { "oscam.server", MNU_CFG_FSERVER, FTYPE_CONFIG }, // id 3
6136 { "oscam.srvid", MNU_CFG_FSRVID, FTYPE_CONFIG }, // id 4
6137 { "oscam.srvid2", MNU_CFG_FSRVID2, FTYPE_CONFIG }, // id 5
6138 { "logfile", MNU_CFG_FLOGFILE, FTYPE_LOGFILE }, // id 6
6139 { "userfile", MNU_CFG_FUSERFILE, FTYPE_USERFILE }, // id 7
6140 { "css_file_name", MNU_CFG_FCSS, FTYPE_CONFIG }, // id 8
6141 { "oscam.services", MNU_CFG_FSERVICES, FTYPE_CONFIG }, // id 9
6142 { "oscam.provid", MNU_CFG_FPROVID, FTYPE_CONFIG }, // id 10
6143 { "oscam.tiers", MNU_CFG_FTIERS, FTYPE_CONFIG }, // id 11
6144 { "oscam.ratelimit", MNU_CFG_FRATELIMIT,FTYPE_CONFIG }, // id 12
6145 { "oscam.whitelist", MNU_CFG_FWHITELIST,FTYPE_CONFIG }, // id 13
6146 #ifdef HAVE_DVBAPI
6147 { "oscam.dvbapi", MNU_CFG_FDVBAPI, FTYPE_CONFIG }, // id 14
6148 #endif
6149 #ifdef CS_CACHEEX
6150 { "oscam.fakecws", MNU_CFG_FFAKECWS, FTYPE_CONFIG }, // id 15
6151 #endif
6152 #ifdef CS_ANTICASC
6153 { "anticasc", MNU_CFG_FACLOG, FTYPE_ANTICASC }, // id 16
6154 #endif
6155 #ifdef MODULE_SERIAL
6156 { "oscam.twin", MNU_CFG_FTWIN, FTYPE_CONFIG }, // id 17
6157 #endif
6158 #ifdef MODULE_CONSTCW
6159 { "constant.cw", MNU_CFG_FKEYCW, FTYPE_CONFIG }, // id 18
6160 #endif
6161 { NULL, 0, 0 },
6164 if(use_srvid2)
6166 config_files[4].menu_id = MNU_CFG_FSRVID2;
6167 config_files[5].menu_id = MNU_CFG_FSRVID;
6170 if(cfg.http_css)
6172 if(strchr(cfg.http_css,'/'))
6173 config_files[8].file = strrchr(cfg.http_css, '/')+1;
6174 else if(strchr(cfg.http_css,'\\'))
6175 config_files[8].file = strrchr(cfg.http_css, '\\')+1;
6176 else
6177 config_files[8].file = cfg.http_css;
6178 tpl_addVar(vars, TPLADD, "FILE_USER_CSS", xml_encode(vars, config_files[8].file));
6181 if(!apicall) { setActiveMenu(vars, MNU_FILES); }
6183 tpl_addVar(vars, TPLADD, "APIFILENAME", "null");
6184 tpl_addVar(vars, TPLADD, "APIWRITABLE", "0");
6186 if(use_srvid2)
6188 tpl_printf(vars, TPLADD, "SRVID", "%s", "oscam.srvid2");
6189 tpl_printf(vars, TPLADD, "SRVIDSUB", "%s", "oscam.srvid");
6191 else
6193 tpl_printf(vars, TPLADD, "SRVID", "%s", "oscam.srvid");
6194 tpl_printf(vars, TPLADD, "SRVIDSUB", "%s", "oscam.srvid2");
6197 char *stoplog = getParam(params, "stoplog");
6198 if(strlen(stoplog) > 0)
6199 { cs_disable_log(atoi(stoplog)); }
6201 char *stopusrlog = getParam(params, "stopusrlog");
6202 if(strlen(stopusrlog) > 0)
6203 { cfg.disableuserfile = atoi(stopusrlog); }
6205 char *debuglvl = getParam(params, "debug");
6206 if(strlen(debuglvl) > 0)
6208 #ifndef WITH_DEBUG
6209 cs_log("*** Warning: Debug Support not compiled in ***");
6210 #else
6211 int32_t dblvl = atoi(debuglvl);
6212 if(dblvl >= 0 && dblvl <= 65535) { cs_dblevel = dblvl; }
6213 cs_log("%s debug_level=%d", "all", cs_dblevel);
6214 #endif
6216 // Process config files
6217 char *file = getParam(params, "file");
6218 char targetfile[256] = { 0 };
6219 int menu_id = 0;
6220 for(entry = config_files; entry->file; entry++)
6222 if(streq(file, entry->file))
6224 if(!apicall) { setActiveSubMenu(vars, entry->menu_id); }
6225 menu_id = entry->menu_id;
6226 tpl_addVar(vars, TPLADD, "APIWRITABLE", writable ? "1" : "0");
6227 switch(entry->type)
6229 case FTYPE_CONFIG:
6230 writable = 1;
6231 get_config_filename(targetfile, sizeof(targetfile), entry->file);
6232 break;
6233 case FTYPE_VERSION:
6234 get_tmp_dir_filename(targetfile, sizeof(targetfile), entry->file);
6235 break;
6236 case FTYPE_ANTICASC:
6237 #ifdef CS_ANTICASC
6238 if(!apicall) { snprintf(targetfile, sizeof(targetfile), "%s", ESTR(cfg.ac_logfile)); }
6239 #endif
6240 break;
6241 case FTYPE_LOGFILE:
6242 if(!apicall) { webif_process_logfile(vars, params, targetfile, sizeof(targetfile)); }
6243 break;
6244 case FTYPE_USERFILE:
6245 if(!apicall) { webif_process_userfile(vars, params, targetfile, sizeof(targetfile)); }
6246 break;
6248 tpl_addVar(vars, TPLADD, "APIFILENAME", entry->file);
6249 break;
6253 if(cfg.http_css)
6255 tpl_addVar(vars, TPLADD, "VIEW_FILEMENUCSS", tpl_getTpl(vars, "FILEMENUCSS"));
6258 if(!strstr(targetfile, "/dev/"))
6260 if(strcmp(getParam(params, "action"), "Save") == 0)
6262 if((strlen(targetfile) > 0) /*&& (file_exists(targetfile) == 1)*/)
6264 FILE *fpsave;
6265 char *fcontent = getParam(params, "filecontent");
6266 if((fpsave = fopen(targetfile, "w")))
6268 int32_t i, lastpos = 0, len = strlen(fcontent) + 1;
6269 //write submitted file line by line to disk and remove windows linebreaks
6270 for(i = 0; i < len; ++i)
6272 char tmp = fcontent[i];
6273 if(tmp == '\r' || tmp == '\n' || tmp == 0)
6275 fcontent[i] = 0;
6276 fprintf(fpsave, "%s%s", fcontent + lastpos, tmp == 0 ? "" : "\n");
6277 if(tmp == '\r' && fcontent[i + 1] == '\n') { ++i; }
6278 lastpos = i + 1;
6281 fclose(fpsave);
6282 tpl_addVar(vars, TPLAPPEND, "APIFILENAME", " saved!");
6283 // Reinit on save
6284 switch(menu_id)
6286 case MNU_CFG_FSRVID:
6287 case MNU_CFG_FSRVID2:
6288 init_srvid();
6289 break;
6290 case MNU_CFG_FPROVID:
6291 init_provid();
6292 break;
6293 case MNU_CFG_FUSER:
6294 cs_accounts_chk();
6295 break;
6296 case MNU_CFG_FDVBAPI:
6297 dvbapi_read_priority();
6298 break;
6299 case MNU_CFG_FWHITELIST:
6300 global_whitelist_read();
6301 break;
6302 case MNU_CFG_FFAKECWS:
6303 init_fakecws();
6304 break;
6305 default:
6306 break;
6312 if((strlen(targetfile) > 0) && (file_exists(targetfile) == 1))
6314 FILE *fp;
6315 char buffer[256];
6317 if((fp = fopen(targetfile, "r")) == NULL) { return "0"; }
6318 while(fgets(buffer, sizeof(buffer), fp) != NULL)
6319 if(!strcmp(getParam(params, "filter"), "all"))
6320 { tpl_addVar(vars, TPLAPPEND, "FILECONTENT", buffer); }
6321 else if(strstr(buffer, getParam(params, "filter")))
6322 { tpl_addVar(vars, TPLAPPEND, "FILECONTENT", buffer); }
6323 fclose(fp);
6325 else
6327 tpl_addVar(vars, TPLAPPEND, "FILECONTENT", "File does not exist or no file selected!");
6330 else
6332 tpl_addVar(vars, TPLAPPEND, "FILECONTENT", "File not valid!");
6335 tpl_addVar(vars, TPLADD, "PART", file);
6337 if(!writable)
6339 tpl_addVar(vars, TPLADD, "WRITEPROTECTION", tpl_getTpl(vars, "WRITEPROTECTION"));
6340 tpl_addVar(vars, TPLADD, "BTNDISABLED", "DISABLED");
6343 if(!apicall)
6344 { return tpl_getTpl(vars, "FILE"); }
6345 else
6346 { return tpl_getTpl(vars, "APIFILE"); }
6349 static char *send_oscam_failban(struct templatevars * vars, struct uriparams * params, int8_t apicall)
6351 IN_ADDR_T ip2delete;
6352 set_null_ip(&ip2delete);
6353 LL_ITER itr = ll_iter_create(cfg.v_list);
6354 V_BAN *v_ban_entry;
6355 //int8_t apicall = 0; //remove before flight
6357 if(!apicall) { setActiveMenu(vars, MNU_FAILBAN); }
6359 if(strcmp(getParam(params, "action"), "delete") == 0)
6362 if(strcmp(getParam(params, "intip"), "all") == 0)
6364 // clear whole list
6365 while((v_ban_entry = ll_iter_next(&itr)))
6367 ll_iter_remove_data(&itr);
6371 else
6373 //we have a single IP
6374 cs_inet_addr(getParam(params, "intip"), &ip2delete);
6375 while((v_ban_entry = ll_iter_next(&itr)))
6377 if(IP_EQUAL(v_ban_entry->v_ip, ip2delete))
6379 ll_iter_remove_data(&itr);
6380 break;
6385 ll_iter_reset(&itr);
6387 struct timeb now;
6388 cs_ftime(&now);
6390 while((v_ban_entry = ll_iter_next(&itr)))
6393 tpl_printf(vars, TPLADD, "IPADDRESS", "%s@%d", cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port);
6394 tpl_addVar(vars, TPLADD, "VIOLATIONUSER", v_ban_entry->info ? v_ban_entry->info : "unknown");
6395 struct tm st ;
6396 localtime_r(&v_ban_entry->v_time.time, &st); // fix me, we need walltime!
6397 if(!apicall)
6399 tpl_printf(vars, TPLADD, "VIOLATIONDATE", "%02d.%02d.%02d %02d:%02d:%02d",
6400 st.tm_mday, st.tm_mon + 1,
6401 st.tm_year % 100, st.tm_hour,
6402 st.tm_min, st.tm_sec);
6404 else
6406 char tbuffer [30];
6407 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &st);
6408 tpl_addVar(vars, TPLADD, "VIOLATIONDATE", tbuffer);
6411 tpl_printf(vars, TPLADD, "VIOLATIONCOUNT", "%d", v_ban_entry->v_count);
6413 int64_t gone = comp_timeb(&now, &v_ban_entry->v_time);
6414 if(!apicall)
6416 if(!v_ban_entry->acosc_entry)
6417 { tpl_addVar(vars, TPLADD, "LEFTTIME", sec2timeformat(vars, (cfg.failbantime * 60) - (gone / 1000))); }
6418 else
6419 { tpl_addVar(vars, TPLADD, "LEFTTIME", sec2timeformat(vars, v_ban_entry->acosc_penalty_dur - (gone / 1000))); }
6421 else
6423 if(!v_ban_entry->acosc_entry)
6424 { tpl_printf(vars, TPLADD, "LEFTTIME", "%"PRId64"", (cfg.failbantime * 60) - (gone / 1000)); }
6425 else
6426 { tpl_printf(vars, TPLADD, "LEFTTIME", "%"PRId64"", v_ban_entry->acosc_penalty_dur - (gone / 1000)); }
6429 tpl_addVar(vars, TPLADD, "INTIP", cs_inet_ntoa(v_ban_entry->v_ip));
6431 if(!apicall)
6432 { tpl_addVar(vars, TPLAPPEND, "FAILBANROW", tpl_getTpl(vars, "FAILBANBIT")); }
6433 else
6434 { tpl_addVar(vars, TPLAPPEND, "APIFAILBANROW", tpl_getTpl(vars, "APIFAILBANBIT")); }
6436 if(!apicall)
6437 { return tpl_getTpl(vars, "FAILBAN"); }
6438 else
6439 { return tpl_getTpl(vars, "APIFAILBAN"); }
6442 static bool send_EMM(struct s_reader * rdr, uint16_t caid, const struct s_cardsystem *csystem, const unsigned char *emmhex, uint32_t len)
6445 if(NULL != rdr && NULL != emmhex && 0 != len)
6447 EMM_PACKET *emm_pack = NULL;
6449 if(cs_malloc(&emm_pack, sizeof(EMM_PACKET)))
6451 struct s_client *webif_client = cur_client();
6452 webif_client->grp = 0xFF; /* to access to all readers */
6454 memset(emm_pack, '\0', sizeof(EMM_PACKET));
6455 emm_pack->client = webif_client;
6456 emm_pack->emmlen = len;
6457 memcpy(emm_pack->emm, emmhex, len);
6459 emm_pack->caid[0] = (caid >> 8) & 0xFF;
6460 emm_pack->caid[1] = caid & 0xFF;
6462 if(csystem && csystem->get_emm_type)
6464 if(!csystem->get_emm_type(emm_pack, rdr))
6466 rdr_log_dbg(rdr, D_EMM, "get_emm_type() returns error");
6470 cs_log_dbg(D_EMM, "emm is being sent to reader %s.", rdr->label);
6471 add_job(rdr->client, ACTION_READER_EMM, emm_pack, sizeof(EMM_PACKET));
6472 return true;
6476 return false;
6479 static bool process_single_emm(struct templatevars * vars, struct s_reader * rdr, uint16_t caid, const struct s_cardsystem *csystem, const char *ep)
6482 if(NULL != vars && NULL != rdr && NULL != ep)
6484 char emmdata[1025] = {'\0'}; /*1024 + '\0'*/
6485 unsigned char emmhex[513] = {'\0'};
6486 char buff[5] = {'\0'};
6487 uint32_t len = 0;
6488 cs_strncpy(emmdata, ep, sizeof(emmdata));
6489 remove_white_chars(emmdata);
6491 if('\0' != emmdata[0])
6493 len = strlen(emmdata);
6494 tpl_addVar(vars, TPLADD, "EP", strtoupper(emmdata));
6495 if(key_atob_l(emmdata, emmhex, len))
6497 tpl_addMsg(vars, "Single EMM has not been sent due to wrong value!");
6499 else
6501 len /= 2;
6502 snprintf(buff, sizeof(buff), "0x%02X", len);
6503 tpl_addVar(vars, TPLADD, "EP", strtoupper(emmdata));
6504 tpl_addVar(vars, TPLADD, "SIZE", buff);
6506 if(send_EMM(rdr, caid, csystem, emmhex, len))
6508 tpl_addMsg(vars, "Single EMM has been sent.");
6509 return true;
6514 tpl_addVar(vars, TPLADD, "SIZE", "0x00");
6515 return false;
6518 static bool process_emm_file(struct templatevars * vars, struct s_reader * rdr, uint16_t caid, const struct s_cardsystem *csystem, const char *sFilePath)
6521 bool bret = false;
6522 uint32_t fsize = 0;
6523 uint32_t rlines = 0;
6524 uint32_t wemms = 0;
6525 uint32_t errsize = 0;
6526 char numerrl[256] = {'\0'};
6527 char buff[20] = {'\0'};
6529 if(NULL != rdr && NULL != sFilePath && '\0' != sFilePath[0])
6531 char sMessage[128] = {0};
6532 if(true == file_exists(sFilePath))
6534 FILE *fp;
6535 if((fp = fopen(sFilePath, "r")))
6537 char line[2048] = {'\0'};
6538 unsigned char emmhex[513] = {'\0'};
6539 uint32_t len = 0;
6541 tpl_addMsg(vars, "EMM file has been processed.");
6542 while(fgets(line, sizeof(line), fp))
6544 ++rlines;
6545 len = strlen(remove_white_chars(line));
6547 // wrong emm
6548 if(len > (sizeof(emmhex) * 2) ||
6549 key_atob_l(line, emmhex, len))
6551 errsize += snprintf(numerrl + errsize, sizeof(numerrl) - errsize, "%d, ", rlines);
6552 continue;
6554 len /= 2;
6555 if(send_EMM(rdr, caid, csystem, emmhex, len))
6557 ++wemms;
6558 /* Give time to process EMM, otherwise, too many jobs can be added*/
6559 cs_sleepms(1000); //TODO: use oscam signal to catch reader answer
6562 fsize = ftell(fp);
6563 fclose(fp);
6565 else
6567 snprintf(sMessage, sizeof(sMessage), "Cannot open file '%s' (errno=%d: %s)\n", sFilePath, errno, strerror(errno));
6568 tpl_addMsg(vars, sMessage);
6571 else
6573 snprintf(sMessage, sizeof(sMessage), "FILE \"%s\" not found!", sFilePath);
6574 tpl_addMsg(vars, sMessage);
6576 bret = true;
6579 snprintf(buff, sizeof(buff), "%d bytes", fsize);
6580 tpl_addVar(vars, TPLADD, "FSIZE", buff);
6581 snprintf(buff, sizeof(buff), "%d", rlines);
6582 tpl_addVar(vars, TPLADD, "NUMRLINE", buff);
6583 snprintf(buff, sizeof(buff), "%d", wemms);
6584 tpl_addVar(vars, TPLADD, "NUMWEMM", buff);
6585 tpl_addVar(vars, TPLADD, "ERRLINE", numerrl);
6587 return bret;
6590 static char *send_oscam_EMM_running(struct templatevars * vars, struct uriparams * params)
6593 struct s_reader *rdr = NULL;
6595 setActiveMenu(vars, MNU_READERS);
6596 tpl_addVar(vars, TPLADD, "READER", getParam(params, "label"));
6597 tpl_addVar(vars, TPLADD, "FNAME", getParam(params, "emmfile"));
6599 rdr = get_reader_by_label(getParam(params, "label"));
6600 if(rdr)
6602 int32_t tcaid = dyn_word_atob(getParam(params, "emmcaid"));
6603 uint16_t caid = (-1 != tcaid) ? (uint16_t)tcaid : 0;
6604 char buff[7] = "";
6605 const struct s_cardsystem *csystem = NULL;
6606 int32_t proxy = is_cascading_reader(rdr);
6608 if((proxy || !rdr->csystem_active) && caid) // network reader (R_CAMD35 R_NEWCAMD R_CS378X R_CCCAM)
6610 if(proxy && !rdr->ph.c_send_emm)
6612 tpl_addMsg(vars, "The reader does not support EMM's!");
6613 return tpl_getTpl(vars, "EMM_RUNNING");
6616 csystem = get_cardsystem_by_caid(caid);
6617 if(!csystem)
6619 rdr_log_dbg(rdr, D_EMM, "unable to find cardsystem for caid %04X", caid);
6620 caid = 0;
6623 else if(!proxy && rdr->csystem_active) // local active reader
6625 csystem = rdr->csystem;
6626 caid = rdr->caid;
6629 if(csystem)
6631 tpl_addVar(vars, TPLADD, "SYSTEM", csystem->desc);
6633 else
6635 tpl_addVar(vars, TPLADD, "SYSTEM", "unknown");
6637 if(caid)
6639 snprintf(buff, sizeof(buff), "0x%04X", caid);
6640 tpl_addVar(vars, TPLADD, "CAID", buff);
6642 else
6644 tpl_addVar(vars, TPLADD, "CAID", "unknown");
6647 process_single_emm(vars, rdr, caid, csystem, getParam(params, "ep"));
6648 process_emm_file(vars, rdr, caid, csystem, getParam(params, "emmfile"));
6650 else
6652 char sMessage[128] = {0};
6653 snprintf(sMessage, sizeof(sMessage), "READER \"%s\" not found!", getParam(params, "label"));
6654 tpl_addMsg(vars, sMessage);
6655 tpl_addVar(vars, TPLADD, "READER", "reader not found");
6658 return tpl_getTpl(vars, "EMM_RUNNING");
6661 static char *send_oscam_EMM(struct templatevars * vars, struct uriparams * params)
6664 setActiveMenu(vars, MNU_READERS);
6665 tpl_addVar(vars, TPLADD, "READER", getParam(params, "label"));
6667 struct s_reader *rdr = NULL;
6668 rdr = get_reader_by_label(getParam(params, "label"));
6669 if(rdr && rdr->caid)
6671 char buff[5] = "";
6672 snprintf(buff, sizeof(buff), "%04X", rdr->caid);
6673 tpl_addVar(vars, TPLADD, "CAID", buff);
6674 if(!is_cascading_reader(rdr))
6676 tpl_addVar(vars, TPLADD, "READONLY", "readonly=\"readonly\"");
6680 FILE *fp;
6681 struct stat sb;
6682 char buffer[1024];
6683 char emm_hex[1024];
6684 char filename[128];
6685 char targetfile[256];
6686 char tmpstr[20];
6687 char emm_txt[32];
6688 char emm_title[32];
6689 char *emm_path;
6690 char *emm_types[] = { "unique_emm", "shared_emm", "global_emm" };
6691 char *emm_names[] = { "RDREMMUNIQUE", "RDREMMSHARED", "RDREMMGLOBAL" };
6692 char *emm_cfg_names[] = { "httpemmuclean", "httpemmsclean", "httpemmgclean" };
6693 int32_t emm_max_size[] = { cfg.http_emmu_clean, cfg.http_emms_clean, cfg.http_emmg_clean };
6694 int num_emm_types = 3;
6695 int i;
6697 emm_path = cfg.emmlogdir ? cfg.emmlogdir : cs_confdir;
6699 for( i = 0 ; i < num_emm_types; i++ )
6701 snprintf(filename, sizeof(filename), "%s%s%s%s", getParam(params, "label"), "_", emm_types[i], ".log");
6702 snprintf(targetfile, sizeof(targetfile), "%s%s%s", emm_path, emm_path[strlen(emm_path) - 1] == '/' ? "" : "/", filename);
6703 snprintf(emm_txt, sizeof(emm_txt), "%s_TXT", emm_names[i]);
6704 tpl_addVar(vars, TPLADD, emm_txt, filename);
6706 if((fp = fopen(targetfile, "r")) != NULL)
6708 stat(targetfile, &sb);
6709 tpl_printf(vars, TPLAPPEND, emm_txt, " (Size: %'.2f kB)", (double)sb.st_size/1024);
6711 if(emm_max_size[i]>=0)
6713 snprintf(emm_title, sizeof(emm_title), "%s_TITLE", emm_names[i]);
6714 tpl_addVar(vars, TPLADD, emm_title, "title=\"Click Line to Copy EMM in Single EMM Write Field\"");
6717 if(emm_max_size[i]>0)
6719 uint32_t emms=0, emm_d, emmrs=0;
6720 char *ptr, *saveptr1 = NULL;
6722 while(fgets(buffer, sizeof(buffer), fp) != NULL)
6724 emms++;
6725 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emms);
6726 tpl_addVar(vars, TPLADD, tmpstr, buffer);
6729 for(emm_d=emms;emm_d>0;--emm_d)
6731 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emm_d);
6732 if(sscanf(tpl_getVar(vars, tmpstr), "%*s %*s %*s %s", &emm_hex[0])==1)
6734 if(strstr(tpl_getVar(vars, "EMM_TMP"),emm_hex)==0)
6735 { tpl_addVar(vars, TPLAPPEND, "EMM_TMP", tpl_getVar(vars, tmpstr)); }
6736 tpl_addVar(vars, TPLADD, tmpstr, "");
6740 for(ptr = strtok_r(tpl_getVar(vars, "EMM_TMP"),"\n", &saveptr1); ptr; ptr = strtok_r(NULL,"\n", &saveptr1))
6742 emmrs++;
6743 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emmrs);
6744 tpl_addVar(vars, TPLADD, tmpstr, ptr);
6746 tpl_addVar(vars, TPLADD, "EMM_TMP", "");
6748 tpl_printf(vars, TPLAPPEND, emm_txt, ": %'d different EMM's from a total off %'d Entrys", emmrs,emms);
6749 for(emm_d=emmrs;emm_d>0;--emm_d)
6751 snprintf(tmpstr, sizeof(tmpstr), "LINE_%d", emm_d);
6752 tpl_printf(vars, TPLAPPEND, emm_names[i], "<a class=\"tosingleemm\" href=\"#\">%s</a>\n", tpl_getVar(vars, tmpstr));
6753 if(sb.st_size>emm_max_size[i]*1024) { tpl_printf(vars, TPLAPPEND, "EMM_TMP", "%s\n", tpl_getVar(vars, tmpstr)); }
6754 tpl_addVar(vars, TPLADD, tmpstr, "");
6757 if(sb.st_size>emm_max_size[i]*1024)
6759 char orgfile[256];
6760 int f=0;
6761 do {
6762 snprintf(orgfile, sizeof(orgfile), "%s.%d", targetfile, f);
6763 f++;
6764 } while(access(orgfile, 0|F_OK) != -1);
6766 if(rename(targetfile, orgfile) == 0)
6768 FILE *fs = fopen(targetfile, "w");
6769 fprintf(fs, "%s", tpl_getVar(vars, "EMM_TMP"));
6770 fclose(fs);
6771 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);
6774 tpl_addVar(vars, TPLADD, "EMM_TMP", "");
6776 else if (emm_max_size[i]==0)
6778 while(fgets(buffer, sizeof(buffer), fp) != NULL)
6780 tpl_printf(vars, TPLAPPEND, emm_names[i], "<a class=\"tosingleemm\" href=\"#\">%s</a>", buffer);
6783 else
6785 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]);
6787 fclose(fp);
6789 if(strcmp(tpl_getVar(vars, emm_names[i]),"")==0) { tpl_addVar(vars, TPLADD, emm_names[i],"no saved EMM's"); }
6792 return tpl_getTpl(vars, "ASKEMM");
6795 #ifdef CS_CACHEEX
6796 static uint64_t get_cacheex_node(struct s_client * cl)
6798 uint64_t node = 0x00;
6799 struct s_module *module = (cl->reader ? &cl->reader->ph : get_module(cl));
6800 #ifdef MODULE_CCCAM
6801 if(module->num == R_CCCAM && cl->cc)
6803 struct cc_data *cc = cl->cc;
6804 memcpy(&node, cc->peer_node_id, 8);
6806 else
6807 #endif
6808 #ifdef MODULE_CAMD35
6809 if(module->num == R_CAMD35)
6811 memcpy(&node, cl->ncd_skey, 8);
6813 else
6814 #endif
6815 #ifdef MODULE_CAMD35_TCP
6816 if(module->num == R_CS378X)
6818 memcpy(&node, cl->ncd_skey, 8);
6820 else
6821 #endif
6823 return node;
6827 static char *send_oscam_cacheex(struct templatevars * vars, struct uriparams * params, int8_t apicall)
6830 if(!apicall) { setActiveMenu(vars, MNU_CACHEEX); }
6832 if(strcmp(getParam(params, "x"), "x") == 0)
6834 // avoid compilerwarning unused vars
6836 char *level[] = {"NONE", "CACHE PULL", "CACHE PUSH", "REVERSE CACHE PUSH"};
6837 char *getting = "<IMG SRC=\"image?i=ICARRL\" ALT=\"Getting\">";
6838 char *pushing = "<IMG SRC=\"image?i=ICARRR\" ALT=\"Pushing\">";
6839 char *rowvariable = "";
6841 int16_t i, written = 0;
6842 struct s_client *cl;
6843 time_t now = time((time_t *)0);
6844 int delimiter=0;
6846 if(!apicall)
6848 if(strcmp(getParam(params, "action"), "resetallcacheexstats") == 0)
6850 cacheex_clear_all_stats();
6854 tpl_printf(vars, TPLADD, "OWN_CACHEEX_NODEID", "%" PRIu64 "X", cacheex_node_id(cacheex_peer_id));
6856 const char *cacheex_name_link_tpl = NULL;
6857 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", "");
6859 for(i = 0, cl = first_client; cl ; cl = cl->next, i++)
6861 if(cl->typ == 'c' && cl->account && cl->account->cacheex.mode)
6863 cacheex_name_link_tpl = "SUSER";
6864 tpl_addVar(vars, TPLADD, "TYPE", "Client");
6865 if(!apicall) {
6866 tpl_addVar(vars, TPLADD, "USERNAME", xml_encode(vars, cl->account->usr));
6867 tpl_addVar(vars, TPLADD, "USERENC", urlencode(vars, cl->account->usr));
6868 if(cl->account->description) {
6869 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->account->description));
6871 } else {
6872 tpl_addVar(vars, TPLADD, "NAME", cl->account->usr);
6873 if(cl->account->description) {
6874 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", cl->account->description);
6877 tpl_addVar(vars, TPLADD, "IP", cs_inet_ntoa(cl->ip));
6878 tpl_printf(vars, TPLADD, "NODE", "%" PRIu64 "X", get_cacheex_node(cl));
6879 tpl_addVar(vars, TPLADD, "LEVEL", level[cl->account->cacheex.mode]);
6880 tpl_printf(vars, TPLADD, "PUSH", "%d", cl->account->cwcacheexpush);
6881 tpl_printf(vars, TPLADD, "GOT", "%d", cl->account->cwcacheexgot);
6882 tpl_printf(vars, TPLADD, "CWCINFO", "%d", cl->account->cwc_info);
6883 tpl_printf(vars, TPLADD, "HIT", "%d", cl->account->cwcacheexhit);
6884 tpl_printf(vars, TPLADD, "ERR", "%d", cl->account->cwcacheexerr);
6885 tpl_printf(vars, TPLADD, "ERRCW", "%d", cl->account->cwcacheexerrcw);
6886 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", (cl->account->cacheex.mode == 3) ? getting : pushing);
6887 rowvariable = "TABLECLIENTROWS";
6888 written = 1;
6890 else if((cl->typ == 'p' || cl->typ == 'r') && (cl->reader && cl->reader->cacheex.mode))
6892 cacheex_name_link_tpl = "SREADER";
6893 tpl_addVar(vars, TPLADD, "TYPE", "Reader");
6894 if(!apicall) {
6895 tpl_addVar(vars, TPLADD, "READERNAME", xml_encode(vars, cl->reader->label));
6896 tpl_addVar(vars, TPLADD, "READERNAMEENC", urlencode(vars, cl->reader->label));
6897 if(cl->reader->description) {
6898 tpl_printf(vars, TPLADD, "CLIENTDESCRIPTION","%s(%s)",!apicall?"&#13;":"",xml_encode(vars, cl->reader->description));
6900 } else {
6901 tpl_addVar(vars, TPLADD, "NAME", cl->reader->label);
6902 if(cl->reader->description) {
6903 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", cl->reader->description);
6906 tpl_addVar(vars, TPLADD, "IP", cs_inet_ntoa(cl->ip));
6907 tpl_printf(vars, TPLADD, "NODE", "%" PRIu64 "X", get_cacheex_node(cl));
6908 tpl_addVar(vars, TPLADD, "LEVEL", level[cl->reader->cacheex.mode]);
6909 tpl_printf(vars, TPLADD, "PUSH", "%d", cl->cwcacheexpush);
6910 tpl_printf(vars, TPLADD, "CWCINFO", "%d", cl->cwc_info);
6911 tpl_printf(vars, TPLADD, "GOT", "%d", cl->cwcacheexgot);
6912 tpl_printf(vars, TPLADD, "CWCINFO", "%d", cl->cwc_info);
6913 tpl_printf(vars, TPLADD, "HIT", "%d", cl->cwcacheexhit);
6914 tpl_printf(vars, TPLADD, "ERR", "%d", cl->cwcacheexerr);
6915 tpl_printf(vars, TPLADD, "ERRCW", "%d", cl->cwcacheexerrcw);
6916 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", (cl->reader->cacheex.mode == 3) ? pushing : getting);
6917 rowvariable = "TABLEREADERROWS";
6918 written = 1;
6920 else if(get_module(cl)->listenertype == LIS_CSPUDP)
6922 cacheex_name_link_tpl = "SREADER";
6923 tpl_addVar(vars, TPLADD, "TYPE", "csp");
6924 if(!apicall) {
6925 tpl_addVar(vars, TPLADD, "READERNAME", "csp");
6926 tpl_addVar(vars, TPLADD, "READERNAMEENC", "csp");
6927 } else {
6928 tpl_addVar(vars, TPLADD, "NAME", "csp");
6930 tpl_addVar(vars, TPLADD, "IP", cs_inet_ntoa(cl->ip));
6931 tpl_addVar(vars, TPLADD, "NODE", "csp");
6932 if(cl->cwcacheexping)
6934 tpl_printf(vars, TPLADD, "LEVEL", "csp (%d ms)", cl->cwcacheexping);
6936 else
6938 tpl_addVar(vars, TPLADD, "LEVEL", "csp");
6940 tpl_printf(vars, TPLADD, "PUSH", "%d", cl->cwcacheexpush);
6941 tpl_printf(vars, TPLADD, "GOT", "%d", cl->cwcacheexgot);
6942 tpl_printf(vars, TPLADD, "HIT", "%d", cl->cwcacheexhit);
6943 tpl_printf(vars, TPLADD, "ERR", "%d", cl->cwcacheexerr);
6944 tpl_printf(vars, TPLADD, "ERRCW", "%d", cl->cwcacheexerrcw);
6945 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", getting);
6946 rowvariable = "TABLECLIENTROWS";
6947 written = 1;
6950 if(written)
6952 if(!apicall) {
6953 tpl_addVar(vars, TPLADD, "NAME", tpl_getTpl(vars, cacheex_name_link_tpl));
6955 tpl_addVar(vars, TPLAPPEND, rowvariable, tpl_getTpl(vars, "CACHEEXTABLEROW"));
6957 if(cl->ll_cacheex_stats)
6959 LL_ITER itr = ll_iter_create(cl->ll_cacheex_stats);
6960 S_CACHEEX_STAT_ENTRY *cacheex_stats_entry;
6962 while((cacheex_stats_entry = ll_iter_next(&itr)))
6965 tpl_addVar(vars, TPLADD, "DIRECTIONIMG", "");
6966 if(now - cacheex_stats_entry->cache_last < 20)
6967 { tpl_addVar(vars, TPLADD, "TYPE", cacheex_stats_entry->cache_direction == 0 ? pushing : getting); }
6968 else
6969 { tpl_addVar(vars, TPLADD, "TYPE", ""); }
6970 tpl_printf(vars, TPLADD, "NAME", "%04X@%06X:%04X", cacheex_stats_entry->cache_caid,
6971 cacheex_stats_entry->cache_prid,
6972 cacheex_stats_entry->cache_srvid);
6973 if(cacheex_stats_entry->cache_direction == 0)
6975 tpl_printf(vars, TPLADD, "PUSH", "%d", cacheex_stats_entry->cache_count);
6976 tpl_addVar(vars, TPLADD, "GOT", "");
6978 else
6980 tpl_printf(vars, TPLADD, "GOT", "%d", cacheex_stats_entry->cache_count);
6981 tpl_addVar(vars, TPLADD, "PUSH", "");
6983 tpl_addVar(vars, TPLADD, "HIT", "");
6984 char channame[CS_SERVICENAME_SIZE];
6985 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)));
6986 tpl_addVar(vars, TPLADD, "LEVEL", lastchan);
6987 if (apicall == 2){
6988 tpl_printf(vars, TPLADD, "JSONDELIMITER", "%s", (delimiter > 1)?",":"");
6989 tpl_addVar(vars, TPLAPPEND, "JSONCACHEEXBITS", tpl_getTpl(vars, "JSONCACHEEXBIT"));
6990 delimiter++;
6992 else{
6993 tpl_addVar(vars, TPLAPPEND, rowvariable, tpl_getTpl(vars, "CACHEEXTABLEROW"));
6998 written = 0;
7002 float cachesum = first_client ? first_client->cwcacheexgot : 1;
7003 if(cachesum < 1)
7005 cachesum = 1;
7007 tpl_printf(vars, TPLADD, "TOTAL_CACHEXPUSH", PRINTF_LOCAL_D, first_client ? first_client->cwcacheexpush : 0);
7008 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXPUSH_IMG", pushing);
7009 tpl_printf(vars, TPLADD, "TOTAL_CACHEXGOT", PRINTF_LOCAL_D, first_client ? first_client->cwcacheexgot : 0);
7010 tpl_addVar(vars, TPLADD, "TOTAL_CACHEXGOT_IMG", getting);
7011 tpl_printf(vars, TPLADD, "TOTAL_CACHEXHIT", PRINTF_LOCAL_D, first_client ? first_client->cwcacheexhit : 0);
7012 tpl_printf(vars, TPLADD, "TOTAL_CACHESIZE", "%d", cache_size());
7014 tpl_printf(vars, TPLADD, "REL_CACHEXHIT", "%.2f", (first_client ? first_client->cwcacheexhit : 0) * 100 / cachesum);
7016 if(!apicall)
7017 { return tpl_getTpl(vars, "CACHEEXPAGE"); }
7018 else
7020 return tpl_getTpl(vars, "JSONCACHEEX");
7023 #endif
7025 static char *send_oscam_api(struct templatevars * vars, FILE * f, struct uriparams * params, int8_t *keepalive, int8_t apicall, char *extraheader)
7027 if(strcmp(getParam(params, "part"), "status") == 0)
7029 return send_oscam_status(vars, params, apicall);
7031 else if(strcmp(getParam(params, "part"), "userstats") == 0)
7033 return send_oscam_user_config(vars, params, apicall);
7035 else if(strcmp(getParam(params, "part"), "failban") == 0)
7037 return send_oscam_failban(vars, params, apicall);
7039 #ifdef CS_CACHEEX
7040 else if(strcmp(getParam(params, "part"), "cacheex") == 0)
7042 return send_oscam_cacheex(vars, params, apicall);
7044 #endif
7045 else if(strcmp(getParam(params, "part"), "files") == 0)
7047 return send_oscam_files(vars, params, apicall);
7049 else if(strcmp(getParam(params, "part"), "readerlist") == 0)
7051 return send_oscam_reader(vars, params, apicall);
7053 else if(strcmp(getParam(params, "part"), "serverconfig") == 0)
7055 //Send Errormessage
7056 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "serverconfig not yet avail");
7057 return tpl_getTpl(vars, "APIERROR");
7059 else if(strcmp(getParam(params, "part"), "userconfig") == 0)
7061 if(((strcmp(getParam(params, "action"), "Save") == 0) ||
7062 (strcmp(getParam(params, "action"), "Save As") == 0)) && cfg.http_readonly == 1)
7064 //Send Errormessage
7065 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "API is in readonly mode");
7066 return tpl_getTpl(vars, "APIERROR");
7068 else
7070 struct s_auth *account = get_account_by_name(getParam(params, "user"));
7071 if(!account && strcmp(getParam(params, "action"), "Save"))
7073 //Send Errormessage
7074 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "user not exist");
7075 return tpl_getTpl(vars, "APIERROR");
7077 else
7079 return send_oscam_user_config_edit(vars, params, apicall);
7083 else if(strcmp(getParam(params, "part"), "entitlement") == 0)
7086 if(strcmp(getParam(params, "label"), ""))
7088 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
7089 if(rdr)
7091 if(rdr->enable == 1)
7093 return send_oscam_entitlement(vars, params, apicall);
7095 else
7097 //Send Errormessage
7098 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no cccam reader or disabled");
7099 return tpl_getTpl(vars, "APIERROR");
7102 else
7104 //Send Errormessage
7105 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "reader not exist");
7106 return tpl_getTpl(vars, "APIERROR");
7109 else
7111 //Send Errormessage
7112 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no reader selected");
7113 return tpl_getTpl(vars, "APIERROR");
7116 else if(strcmp(getParam(params, "part"), "ecmhistory") == 0)
7118 int32_t i;
7119 int32_t isec;
7120 int32_t shown;
7121 time_t now = time((time_t *)0);
7122 const char *usr;
7123 struct s_client *cl;
7124 for(i = 0, cl = first_client; cl ; cl = cl->next, i++)
7126 if(cl->wihidden != 1)
7128 isec = now - cl->lastecm;
7129 usr = username(cl);
7130 shown = 0;
7131 if(strcmp(getParam(params, "label"), "") == 0)
7133 if(strcmp(getParam(params, "type"), "servers") == 0)
7135 if(cl->typ == 'p' || cl->typ == 'r')
7136 { shown = 1; }
7138 else if(strcmp(getParam(params, "type"), "users") == 0)
7140 if(cl->typ == 'c')
7141 { shown = 1; }
7143 else
7145 shown = 1;
7148 else if(strcmp(getParam(params, "label"), usr) == 0)
7150 shown = 1;
7152 if(shown == 1)
7154 tpl_printf(vars, TPLADD, "CLIENTTYPE", "%c", cl->typ);
7155 tpl_addVar(vars, TPLADD, "CLIENTUSER", xml_encode(vars, usr));
7156 if(cl->typ == 'c' || cl->typ == 'm')
7158 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", xml_encode(vars, cl->account->description ? cl->account->description : ""));
7160 else if(cl->typ == 'p' || cl->typ == 'r')
7162 tpl_addVar(vars, TPLADD, "CLIENTDESCRIPTION", xml_encode(vars, cl->reader->description ? cl->reader->description : ""));
7164 tpl_printf(vars, TPLADD, "CLIENTLASTRESPONSETIME", "%d", cl->cwlastresptime ? cl->cwlastresptime : -1);
7165 tpl_printf(vars, TPLADD, "CLIENTIDLESECS", "%d", isec);
7167 //load historical values from ringbuffer
7168 char *value = get_ecm_fullhistorystring(cl);
7169 tpl_addVar(vars, TPLADD, "CLIENTLASTRESPONSETIMEHIST", value);
7170 free_mk_t(value);
7172 tpl_addVar(vars, TPLAPPEND, "APISTATUSBITS", tpl_getTpl(vars, "APISTATUSBIT"));
7176 return tpl_getTpl(vars, "APISTATUS");
7178 else if(strcmp(getParam(params, "part"), "readerstats") == 0)
7180 if(strcmp(getParam(params, "label"), ""))
7182 struct s_reader *rdr = get_reader_by_label(getParam(params, "label"));
7183 if(rdr)
7185 return send_oscam_reader_stats(vars, params, apicall);
7187 else
7189 //Send Errormessage
7190 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "reader not exist");
7191 return tpl_getTpl(vars, "APIERROR");
7194 else
7196 //Send Errormessage
7197 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "no reader selected");
7198 return tpl_getTpl(vars, "APIERROR");
7201 else if(strcmp(getParam(params, "part"), "shutdown") == 0)
7203 if((strcmp(strtolower(getParam(params, "action")), "restart") == 0) ||
7204 (strcmp(strtolower(getParam(params, "action")), "shutdown") == 0))
7206 if(!cfg.http_readonly)
7208 return send_oscam_shutdown(vars, f, params, apicall, keepalive, extraheader);
7210 else
7212 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "webif readonly mode");
7213 return tpl_getTpl(vars, "APIERROR");
7216 else
7218 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "missing parameter action");
7219 return tpl_getTpl(vars, "APIERROR");
7223 else
7225 tpl_addVar(vars, TPLADD, "APIERRORMESSAGE", "part not found");
7226 return tpl_getTpl(vars, "APIERROR");
7230 static char *send_oscam_image(struct templatevars * vars, FILE * f, struct uriparams * params, char *image, time_t modifiedheader, uint32_t etagheader, char *extraheader)
7232 char *wanted;
7233 if(image == NULL) { wanted = getParam(params, "i"); }
7234 else { wanted = image; }
7235 if(strlen(wanted) > 3 && wanted[0] == 'I' && wanted[1] == 'C')
7237 if(etagheader == 0)
7239 int8_t disktpl = 0;
7240 char *tpl_path;
7241 tpl_path = cfg.http_piconpath? cfg.http_piconpath : cfg.http_tpl;
7243 if(tpl_path)
7245 char path[255];
7246 if(strlen(tpl_getTplPath(wanted, tpl_path, path, 255)) > 0 && file_exists(path))
7248 struct stat st;
7249 disktpl = 1;
7250 stat(path, &st);
7251 if((time_t)st.st_mtime < modifiedheader)
7253 send_header304(f, extraheader);
7254 return "1";
7258 if(disktpl == 0 && first_client->login < modifiedheader)
7260 send_header304(f, extraheader);
7261 return "1";
7264 char *header = strstr(tpl_getTpl(vars, wanted), "data:");
7265 if(header != NULL)
7267 char *ptr = header + 5;
7268 while(ptr[0] != ';' && ptr[0] != '\0') { ++ptr; }
7269 if(ptr[0] != '\0' && ptr[1] != '\0') { ptr[0] = '\0'; }
7270 else { return "0"; }
7271 ptr = strstr(ptr + 1, "base64,");
7272 if(ptr != NULL)
7274 int32_t len = b64decode((uchar *)ptr + 7);
7275 if(len > 0)
7277 if((uint32_t)crc32(0L, (uchar *)ptr + 7, len) == etagheader)
7279 send_header304(f, extraheader);
7281 else
7283 send_headers(f, 200, "OK", extraheader, header + 5, 1, len, ptr + 7, 0);
7284 webif_write_raw(ptr + 7, f, len);
7286 return "1";
7291 // Return file not found
7292 const char *not_found = "File not found.\n";
7293 send_headers(f, 404, "Not Found", extraheader, "text/plain", 0, strlen(not_found), (char *)not_found, 0);
7294 webif_write_raw((char *)not_found, f, strlen(not_found));
7295 return "1";
7298 static char *send_oscam_robots_txt(FILE * f)
7300 const char *content = "User-agent: *\nDisallow: /\n";
7301 send_headers(f, 200, "OK", NULL, "text/plain", 0, strlen(content), (char *)content, 0);
7302 webif_write_raw((char *)content, f, strlen(content));
7303 return "1";
7306 static char *send_oscam_graph(struct templatevars * vars)
7308 return tpl_getTpl(vars, "GRAPH");
7311 #ifdef MODULE_GHTTP
7312 static bool ghttp_autoconf(struct templatevars * vars, struct uriparams * params)
7314 int8_t i = 0;
7315 struct s_reader *rdr;
7316 char *name = getParam(params, "gacname");
7317 if(strlen(name) < 3)
7319 tpl_addMsg(vars, "Invalid host name!");
7320 return false;
7323 LL_ITER itr = ll_iter_create(configured_readers);
7324 while((rdr = ll_iter_next(&itr)))
7325 if(rdr->ph.num == R_GHTTP) { i++; } // count existing ghttp readers
7327 while(i < 3) // if less than 3, add more
7329 char lbl[128];
7330 snprintf(lbl, sizeof(lbl), "%s%d", "ghttp", i + 1);
7331 cs_log("GHttp autoconf: adding reader %s", lbl);
7332 struct s_reader *newrdr;
7333 if(!cs_malloc(&newrdr, sizeof(struct s_reader)))
7335 tpl_addMsg(vars, "Create reader failed!");
7336 return false;
7338 newrdr->typ = R_GHTTP;
7339 cs_strncpy(newrdr->label, lbl, sizeof(newrdr->label));
7340 module_reader_set(newrdr);
7341 reader_set_defaults(newrdr);
7342 newrdr->enable = 0;
7343 newrdr->grp = 1;
7344 ll_append(configured_readers, newrdr);
7345 i++;
7348 uint16_t port = 0;
7349 char *str = strstr(name, ":");
7350 if(str)
7352 port = atoi(str + 1);
7353 str[0] = '\0';
7356 i = 0;
7357 itr = ll_iter_create(configured_readers);
7358 while((rdr = ll_iter_next(&itr)))
7360 if(rdr->ph.num == R_GHTTP)
7362 if(i > 2) // remove superflous
7364 cs_log("GHttp autoconf: removing reader %s", rdr->label);
7365 inactivate_reader(rdr);
7366 ll_iter_remove(&itr);
7367 free_reader(rdr);
7369 else // reconfigure the 3 first ghttp readers
7371 cs_log("GHttp autoconf: reconfiguring reader %s", rdr->label);
7372 snprintf(rdr->label, sizeof(rdr->label), "%s%d", "ghttp", i + 1);
7373 rdr->r_port = port;
7374 rdr->enable = 1;
7375 rdr->ghttp_use_ssl = 0;
7376 #ifdef WITH_SSL
7377 rdr->ghttp_use_ssl = 1;
7378 #endif
7379 if(rdr->grp < 1) { rdr->grp = 1; }
7380 cs_strncpy(rdr->r_usr, getParam(params, "gacuser"), sizeof(rdr->r_usr));
7381 cs_strncpy(rdr->r_pwd, getParam(params, "gacpasswd"), sizeof(rdr->r_pwd));
7382 if(i == 0) { cs_strncpy(rdr->device, name, sizeof(rdr->device)); }
7383 else
7385 if(!strstr(name, "."))
7386 { snprintf(rdr->device, sizeof(rdr->device), "%s%d", name, i); } // name, name1, name2
7387 else { cs_strncpy(rdr->device, name, sizeof(rdr->device)); }
7388 // . in the name = assume full hostname = use same for all 3 readers
7390 if(i == 2) { rdr->fallback = 1; }
7391 else { rdr->fallback = 0; }
7392 i++;
7396 cs_log("GHttp autoconf: Saving %d readers", i);
7397 if(write_server() != 0) { tpl_addMsg(vars, "Write Config failed!"); }
7398 itr = ll_iter_create(configured_readers);
7399 while((rdr = ll_iter_next(&itr)))
7401 if(rdr->ph.num == R_GHTTP)
7402 { restart_cardreader(rdr, 1); }
7404 return true;
7407 static char *send_oscam_ghttp(struct templatevars * vars, struct uriparams * params, int8_t apicall)
7409 if(strcmp(strtolower(getParam(params, "action")), "autoconf") == 0)
7411 if(!apicall)
7413 bool missing = false;
7414 if(strlen(getParam(params, "gacuser")) == 0)
7416 tpl_addVar(vars, TPLADD, "USERREQ", "<FONT COLOR='red'>(Required)</FONT>");
7417 missing = true;
7419 else { tpl_addVar(vars, TPLADD, "GACUSER", getParam(params, "gacuser")); }
7420 if(strlen(getParam(params, "gacpasswd")) == 0)
7422 tpl_addVar(vars, TPLADD, "PWDREQ", "<FONT COLOR='red'>(Required)</FONT>");
7423 missing = true;
7425 else { tpl_addVar(vars, TPLADD, "GACPASSWD", getParam(params, "gacpasswd")); }
7426 if(strlen(getParam(params, "gacname")) == 0)
7428 tpl_addVar(vars, TPLADD, "NAMEREQ", "<FONT COLOR='red'>(Required)</FONT>");
7429 missing = true;
7431 else { tpl_addVar(vars, TPLADD, "GACNAME", getParam(params, "gacname")); }
7432 if(missing) { return tpl_getTpl(vars, "PREAUTOCONF"); }
7433 cs_log("GHttp autoconf requested by WebIF from %s", cs_inet_ntoa(GET_IP()));
7435 else
7437 tpl_addVar(vars, TPLADD, "APICONFIRMMESSAGE", "autoconf");
7438 cs_log("GHttp autoconf requested by XMLApi from %s", cs_inet_ntoa(GET_IP()));
7441 if(ghttp_autoconf(vars, params))
7443 tpl_printf(vars, TPLADD, "REFRESHTIME", "%d", 3);
7444 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
7445 tpl_printf(vars, TPLADD, "SECONDS", "%d", 3);
7446 if(apicall) { return tpl_getTpl(vars, "APICONFIRMATION"); }
7447 else { return tpl_getTpl(vars, "AUTOCONF"); }
7449 else { return tpl_getTpl(vars, "PREAUTOCONF"); } // something failed
7452 else
7454 if(strlen(getParam(params, "token")) > 0) // parse autoconf token
7456 char *token = getParam(params, "token");
7457 int32_t len = b64decode((uchar *)token);
7458 if(len > 0)
7460 struct uriparams tokenprms;
7461 tokenprms.paramcount = 0;
7462 parseParams(&tokenprms, token);
7463 if(strlen(getParam(&tokenprms, "u")) > 0)
7465 tpl_addVar(vars, TPLADD, "GACUSER", getParam(&tokenprms, "u"));
7466 tpl_addVar(vars, TPLADD, "USERRDONLY", "readonly");
7468 if(strlen(getParam(&tokenprms, "p")) > 0)
7470 tpl_addVar(vars, TPLADD, "GACPASSWD", getParam(&tokenprms, "p"));
7471 tpl_addVar(vars, TPLADD, "PWDRDONLY", "readonly");
7473 if(strlen(getParam(&tokenprms, "n")) > 0)
7475 tpl_addVar(vars, TPLADD, "GACNAME", getParam(&tokenprms, "n"));
7476 tpl_addVar(vars, TPLADD, "NAMERDONLY", "readonly");
7480 return tpl_getTpl(vars, "PREAUTOCONF");
7483 #endif
7485 static int8_t check_httpip(IN_ADDR_T addr)
7487 int8_t i = 0;
7488 // check all previously dyndns resolved addresses
7489 for(i = 0; i < MAX_HTTP_DYNDNS; i++)
7491 if(IP_ISSET(cfg.http_dynip[i]) && IP_EQUAL(cfg.http_dynip[i], addr))
7492 { return 1; }
7494 return 0;
7497 static int8_t check_httpdyndns(IN_ADDR_T addr)
7500 // check all previously dyndns resolved addresses
7501 if(check_httpip(addr))
7502 { return 1; }
7504 // we are not ok, so resolve all dyndns entries into IP's - maybe outdated IP's
7506 if(cfg.http_dyndns[0][0])
7508 int8_t i = 0;
7509 for(i = 0; i < MAX_HTTP_DYNDNS; i++)
7511 if(cfg.http_dyndns[i][0])
7513 cs_resolve((const char *)cfg.http_dyndns[i], &cfg.http_dynip[i], NULL, NULL);
7514 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]));
7518 else
7520 cs_log_dbg(D_TRACE, "WebIf: No dyndns addresses found");
7521 return 0;
7524 // again check all dyndns resolved addresses
7525 if(check_httpip(addr))
7526 { return 1; }
7528 return 0;
7531 static int8_t check_valid_origin(IN_ADDR_T addr)
7534 // check whether requesting IP is in allowed IP ranges
7535 if(check_ip(cfg.http_allowed, addr))
7536 { return 1; }
7538 // we havn't found the requesting IP in allowed range. So we check for allowed httpdyndns as last chance
7539 if(cfg.http_dyndns[0][0])
7541 int8_t ok;
7542 ok = check_httpdyndns(addr);
7543 return ok;
7545 return 0;
7548 static int8_t check_request(char *result, int32_t readen)
7550 if(readen < 50) { return 0; }
7551 result[readen] = '\0';
7552 int8_t method;
7553 if(strncmp(result, "POST", 4) == 0) { method = 1; }
7554 else { method = 0; }
7555 char *headerEnd = strstr(result, "\r\n\r\n");
7556 if(headerEnd == NULL) { return 0; }
7557 else if(method == 0) { return 1; }
7558 else
7560 char *ptr = strstr(result, "Content-Length: ");
7561 if(ptr != NULL)
7563 ptr += 16;
7564 if(ptr < result + readen)
7566 uint32_t length = atoi(ptr);
7567 if(strlen(headerEnd + 4) >= length) { return 1; }
7571 return 0;
7574 static int32_t readRequest(FILE * f, IN_ADDR_T in, char **result, int8_t forcePlain)
7576 int32_t n, bufsize = 0, errcount = 0;
7577 char buf2[1024];
7578 struct pollfd pfd2[1];
7579 #ifdef WITH_SSL
7580 int8_t is_ssl = 0;
7581 if(ssl_active && !forcePlain)
7582 { is_ssl = 1; }
7583 #endif
7585 while(1)
7587 errno = 0;
7588 if(forcePlain)
7589 { n = read(fileno(f), buf2, sizeof(buf2)); }
7590 else
7591 { n = webif_read(buf2, sizeof(buf2), f); }
7592 if(n <= 0)
7594 if((errno == 0 || errno == EINTR))
7596 if(errcount++ < 10)
7598 cs_sleepms(5);
7599 continue;
7601 else { return -1; }
7603 #ifdef WITH_SSL
7604 if(is_ssl)
7606 if(errno != ECONNRESET)
7608 int32_t errcode = ERR_peek_error();
7609 char errstring[128];
7610 ERR_error_string_n(errcode, errstring, sizeof(errstring) - 1);
7611 cs_log_dbg(D_TRACE, "WebIf: read error ret=%d (%d%s%s)", n, SSL_get_error(cur_ssl(), n), errcode ? " " : "", errcode ? errstring : "");
7613 return -1;
7615 #else
7616 if(errno != ECONNRESET)
7617 { cs_log_dbg(D_TRACE, "WebIf: read error ret=%d (errno=%d %s)", n, errno, strerror(errno)); }
7618 #endif
7619 return -1;
7621 if(!cs_realloc(result, bufsize + n + 1))
7623 send_error500(f);
7624 NULLFREE(*result);
7625 return -1;
7628 memcpy(*result + bufsize, buf2, n);
7629 bufsize += n;
7631 //max request size 100kb
7632 if(bufsize > 102400)
7634 cs_log("error: too much data received from %s", cs_inet_ntoa(in));
7635 NULLFREE(*result);
7636 *result = NULL;
7637 return -1;
7640 #ifdef WITH_SSL
7641 if(ssl_active && !forcePlain)
7643 int32_t len = 0;
7644 len = SSL_pending((SSL *)f);
7646 if(len > 0)
7647 { continue; }
7649 pfd2[0].fd = SSL_get_fd((SSL *)f);
7652 else
7653 #endif
7654 pfd2[0].fd = fileno(f);
7656 pfd2[0].events = (POLLIN | POLLPRI);
7658 int32_t rc = poll(pfd2, 1, 100);
7659 if(rc > 0 || !check_request(*result, bufsize))
7660 { continue; }
7661 else
7662 { break; }
7664 return bufsize;
7666 static int32_t process_request(FILE * f, IN_ADDR_T in)
7668 int32_t ok = 0;
7669 int8_t *keepalive = (int8_t *)pthread_getspecific(getkeepalive);
7670 IN_ADDR_T addr = GET_IP();
7674 #ifdef WITH_SSL
7675 if(!ssl_active && *keepalive) { fflush(f); }
7676 #else
7677 if(*keepalive) { fflush(f); }
7678 #endif
7680 // at this point we do all checks related origin IP, ranges and dyndns stuff
7681 ok = check_valid_origin(addr);
7682 cs_log_dbg(D_TRACE, "WebIf: Origin checked. Result: access from %s => %s", cs_inet_ntoa(addr), (!ok) ? "forbidden" : "allowed");
7684 // based on the failed origin checks we send a 403 to calling browser
7685 if(!ok)
7687 send_error(f, 403, "Forbidden", NULL, "Access denied.", 0);
7688 cs_log("unauthorized access from %s", cs_inet_ntoa(addr));
7689 return 0;
7692 int32_t authok = 0;
7693 char expectednonce[(MD5_DIGEST_LENGTH * 2) + 1], opaque[(MD5_DIGEST_LENGTH * 2) + 1];
7694 char authheadertmp[sizeof(AUTHREALM) + sizeof(expectednonce) + sizeof(opaque) + 100];
7696 char *method, *path, *protocol, *str1, *saveptr1 = NULL, *authheader = NULL, *extraheader = NULL, *filebuf = NULL;
7697 char *pch, *tmp, *buf, *nameInUrl, subdir[32];
7698 /* List of possible pages */
7699 char *pages[] =
7701 "/config.html",
7702 "/readers.html",
7703 "/entitlements.html",
7704 "/status.html",
7705 "/userconfig.html",
7706 "/readerconfig.html",
7707 "/services.html",
7708 "/user_edit.html",
7709 "/site.css",
7710 "/services_edit.html",
7711 "/savetemplates.html",
7712 "/shutdown.html",
7713 "/script.html",
7714 "/scanusb.html",
7715 "/files.html",
7716 "/readerstats.html",
7717 "/failban.html",
7718 "/oscam.js",
7719 "/oscamapi.html",
7720 "/image",
7721 "/favicon.ico",
7722 "/graph.svg",
7723 "/oscamapi.xml",
7724 "/cacheex.html",
7725 "/oscamapi.json",
7726 "/emm.html",
7727 "/emm_running.html",
7728 "/robots.txt",
7729 "/ghttp.html",
7730 "/logpoll.html",
7731 "/jquery.js",
7734 int32_t pagescnt = sizeof(pages) / sizeof(char *); // Calculate the amount of items in array
7735 int32_t i, bufsize, len, pgidx = -1;
7736 uint32_t etagheader = 0;
7737 struct uriparams params;
7738 params.paramcount = 0;
7739 time_t modifiedheader = 0;
7741 bufsize = readRequest(f, in, &filebuf, 0);
7743 if(!filebuf || bufsize < 1)
7745 if(!*keepalive) { cs_log_dbg(D_CLIENT, "WebIf: No data received from client %s. Closing connection.", cs_inet_ntoa(addr)); }
7746 return -1;
7749 buf = filebuf;
7751 if((method = strtok_r(buf, " ", &saveptr1)) != NULL)
7753 if((path = strtok_r(NULL, " ", &saveptr1)) != NULL)
7755 if((protocol = strtok_r(NULL, "\r", &saveptr1)) == NULL)
7757 NULLFREE(filebuf);
7758 return -1;
7761 else
7763 NULLFREE(filebuf);
7764 return -1;
7767 else
7769 NULLFREE(filebuf);
7770 return -1;
7772 tmp = protocol + strlen(protocol) + 2;
7774 pch = path;
7775 /* advance pointer to beginning of query string */
7776 while(pch[0] != '?' && pch[0] != '\0') { ++pch; }
7777 if(pch[0] == '?')
7779 pch[0] = '\0';
7780 ++pch;
7783 nameInUrl = pch - 1;
7784 while(nameInUrl != path && nameInUrl[0] != '/') { --nameInUrl; }
7786 /* allow only alphanumeric sub-folders */
7787 int32_t subdirLen = nameInUrl - path;
7788 subdir[0] = '\0';
7789 if(subdirLen > 0 && subdirLen < 32)
7791 cs_strncpy(subdir, path + 1, subdirLen);
7793 int32_t invalidSubdir = 0;
7794 for(i = 0; i < subdirLen - 1; i++)
7796 if(!((subdir[i] >= '0' && subdir[i] <= '9')
7797 || (subdir[i] >= 'a' && subdir[i] <= 'z')
7798 || (subdir[i] >= 'A' && subdir[i] <= 'Z')))
7801 invalidSubdir = 1;
7802 subdir[0] = '\0';
7803 break;
7807 if(!invalidSubdir)
7809 subdir[subdirLen] = '\0';
7810 #ifdef WIN32
7811 subdir[subdirLen - 1] = '\\';
7812 #else
7813 subdir[subdirLen - 1] = '/';
7814 #endif
7818 /* Map page to our static page definitions */
7819 for(i = 0; i < pagescnt; i++)
7821 if(!strcmp(nameInUrl, pages[i])) { pgidx = i; }
7824 parseParams(&params, pch);
7826 if(!cfg.http_user || !cfg.http_pwd)
7827 { authok = 1; }
7829 for(str1 = strtok_r(tmp, "\n", &saveptr1); str1; str1 = strtok_r(NULL, "\n", &saveptr1))
7831 len = strlen(str1);
7832 if(str1[len - 1] == '\r')
7834 str1[len - 1] = '\0';
7835 --len;
7837 if(len == 0)
7839 if(strcmp(method, "POST") == 0)
7841 parseParams(&params, str1 + 2);
7843 break;
7845 if(!authok && len > 50 && strncasecmp(str1, "Authorization:", 14) == 0 && strstr(str1, "Digest") != NULL)
7847 if(cs_dblevel & D_CLIENT)
7849 if(cs_realloc(&authheader, len + 1))
7850 { cs_strncpy(authheader, str1, len); }
7852 authok = check_auth(str1, method, path, addr, expectednonce, opaque);
7854 else if(len > 40 && strncasecmp(str1, "If-Modified-Since:", 18) == 0)
7856 modifiedheader = parse_modifiedsince(str1);
7858 else if(len > 20 && strncasecmp(str1, "If-None-Match:", 14) == 0)
7860 for(pch = str1 + 14; pch[0] != '"' && pch[0] != '\0'; ++pch) { ; }
7861 if(strlen(pch) > 5) { etagheader = (uint32_t)strtoul(++pch, NULL, 10); }
7863 else if(len > 12 && strncasecmp(str1, "Connection: Keep-Alive", 22) == 0 && strcmp(method, "POST"))
7865 *keepalive = 1;
7869 if(cfg.http_user && cfg.http_pwd)
7871 if(!authok || strlen(opaque) != MD5_DIGEST_LENGTH * 2) { calculate_opaque(addr, opaque); }
7872 if(authok != 2)
7874 if(!authok)
7876 if(authheader)
7878 cs_log_dbg(D_CLIENT, "WebIf: Received wrong auth header from %s:", cs_inet_ntoa(addr));
7879 cs_log_dbg(D_CLIENT, "%s", authheader);
7881 else
7882 { cs_log_dbg(D_CLIENT, "WebIf: Received no auth header from %s.", cs_inet_ntoa(addr)); }
7884 calculate_nonce(NULL, expectednonce, opaque);
7886 if(authok != 1)
7888 snprintf(authheadertmp, sizeof(authheadertmp), "WWW-Authenticate: Digest algorithm=\"MD5\", realm=\"%s\", qop=\"auth\", opaque=\"%s\", nonce=\"%s\"", AUTHREALM, opaque, expectednonce);
7889 if(authok == 2) { strncat(authheadertmp, ", stale=true", sizeof(authheadertmp) - strlen(authheadertmp) - 1); }
7891 else
7892 { snprintf(authheadertmp, sizeof(authheadertmp), "Authentication-Info: nextnonce=\"%s\"", expectednonce); }
7893 extraheader = authheadertmp;
7894 if(authok != 1)
7896 char *msg = "Access denied.\n";
7897 send_headers(f, 401, "Unauthorized", extraheader, "text/html", 0, strlen(msg), msg, 0);
7898 webif_write(msg, f);
7899 NULLFREE(authheader);
7900 NULLFREE(filebuf);
7901 if(*keepalive) { continue; }
7902 else { return 0; }
7905 else { NULLFREE(authheader); }
7907 /*build page*/
7908 if(pgidx == 8)
7910 send_file(f, "CSS", subdir, modifiedheader, etagheader, extraheader);
7912 else if(pgidx == 17)
7914 send_file(f, "JS", subdir, modifiedheader, etagheader, extraheader);
7916 else if(pgidx == 30)
7918 send_file(f, "JQ", subdir, modifiedheader, etagheader, extraheader);
7920 else
7922 time_t t;
7923 struct templatevars *vars = tpl_create();
7924 if(vars == NULL)
7926 send_error500(f);
7927 NULLFREE(filebuf);
7928 return 0;
7931 tpl_addVar(vars, TPLADD, "SUBDIR", subdir);
7933 struct tm lt, st;
7934 time(&t);
7936 localtime_r(&t, &lt);
7938 tpl_addVar(vars, TPLADD, "CS_VERSION", CS_VERSION);
7939 tpl_addVar(vars, TPLADD, "CS_SVN_VERSION", CS_SVN_VERSION);
7940 tpl_addVar(vars, TPLADD, "CS_TARGET", CS_TARGET);
7941 tpl_addVar(vars, TPLADD, "HTTPOSCAMLABEL", xml_encode(vars,cfg.http_oscam_label));
7942 if (!boxtype_is("generic"))
7944 if (!boxname_is("generic"))
7945 tpl_printf(vars, TPLADD, "DETECTED_BOXTYPE", "%s (%s)", boxtype_get(), boxname_get());
7946 else
7947 tpl_addVar(vars, TPLADD, "DETECTED_BOXTYPE", boxtype_get());
7950 if(cfg.http_locale){
7951 float decimal_point = 0.0;
7952 setlocale(LC_ALL, cfg.http_locale);
7953 tpl_printf(vars, TPLADD, "TMP_DECPOINT", "%.1f", decimal_point);
7954 tpl_addVar(vars, TPLADD, "LOCALE_DECPOINT", strstr(tpl_getVar(vars, "TMP_DECPOINT"), ",") ? ",": ".");
7957 tpl_addVar(vars, TPLADD, "HTTP_CHARSET", cs_http_use_utf8 ? "UTF-8" : "ISO-8859-1");
7958 if(cfg.http_picon_size > 0)
7960 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);
7962 if(cfg.poll_refresh > 0)
7964 tpl_printf(vars, TPLADD, "POLLREFRESHTIME", "%d", cfg.poll_refresh);
7966 if ( cfg.http_refresh > 0 &&
7967 ((( pgidx == 1 || pgidx == 4 ) && !cfg.poll_refresh ) ||
7968 ( pgidx == 3 && ( cfg.http_status_log || !cfg.poll_refresh )) ||
7969 pgidx == 15 || pgidx == 23 || pgidx == -1 )) // wenn polling bei cachex.html eingeführt wird muss die 23 => 2 zeilen höher
7971 tpl_printf(vars, TPLADD, "REFRESHTIME", "%d", cfg.http_refresh);
7972 tpl_addVar(vars, TPLADD, "WITHQUERY", pgidx == 15 ? "1" : "0");
7973 tpl_addVar(vars, TPLADD, "REFRESH", tpl_getTpl(vars, "REFRESH"));
7975 #ifdef WEBIF_JQUERY
7976 tpl_printf(vars, TPLADD, "SRCJQUERY", "jquery.js?v=%s", CS_SVN_VERSION);
7977 #else
7978 tpl_addVar(vars, TPLADD, "SRCJQUERY", cfg.http_extern_jquery);
7979 #endif
7981 if(picon_exists("LOGO")||strlen(tpl_getTpl(vars, "IC_LOGO"))>3)
7983 tpl_addVar(vars, TPLADD, "LOGO_INS", tpl_getTpl(vars, "LOGOBITIMG"));
7985 else
7987 tpl_addVar(vars, TPLADD, "LOGO_INS", tpl_getTpl(vars, "LOGOBITSVG"));
7989 tpl_addVar(vars, TPLADD, "LOGO", tpl_getTpl(vars, "LOGOBIT"));
7990 tpl_printf(vars, TPLADD, "CURDATE", "%02d.%02d.%02d", lt.tm_mday, lt.tm_mon + 1, lt.tm_year % 100);
7991 tpl_printf(vars, TPLADD, "CURTIME", "%02d:%02d:%02d", lt.tm_hour, lt.tm_min, lt.tm_sec);
7992 localtime_r(&first_client->login, &st);
7993 tpl_printf(vars, TPLADD, "STARTDATE", "%02d.%02d.%02d", st.tm_mday, st.tm_mon + 1, st.tm_year % 100);
7994 tpl_printf(vars, TPLADD, "STARTTIME", "%02d:%02d:%02d", st.tm_hour, st.tm_min, st.tm_sec);
7995 tpl_printf(vars, TPLADD, "PROCESSID", "%d", getppid());
7996 tpl_addVar(vars, TPLADD, "RUNAS", urlencode(vars, username(first_client)));
7998 time_t now = time((time_t *)0);
7999 // XMLAPI
8000 if(pgidx == 18 || pgidx == 22 || pgidx == 24)
8002 char tbuffer [30];
8003 strftime(tbuffer, 30, "%Y-%m-%dT%H:%M:%S%z", &st);
8004 tpl_addVar(vars, TPLADD, "APISTARTTIME", tbuffer);
8005 tpl_printf(vars, TPLADD, "APIRUNTIME", "%ld", now - first_client->login);
8006 tpl_printf(vars, TPLADD, "APIREADONLY", "%d", cfg.http_readonly);
8007 if(strcmp(getParam(&params, "callback"), ""))
8009 tpl_printf(vars, TPLADD, "CALLBACK", "%s%s", getParam(&params, "callback"), "(");
8010 tpl_addVar(vars, TPLADD, "ENDBRACKET", ")");
8015 if (config_enabled(WITH_LB))
8016 tpl_addVar(vars, TPLADD, "LBISDEFINED", "1");
8018 // language code in helplink
8019 tpl_addVar(vars, TPLADD, "LANGUAGE", cfg.http_help_lang);
8020 tpl_addVar(vars, TPLADD, "RUNTIME", sec2timeformat(vars, (now - first_client->login)));
8021 time_t uptime = oscam_get_uptime();
8022 if(uptime > 0){
8023 tpl_printf(vars, TPLADD, "UPTIMETXT", "%s Up Time: ", strcmp(tpl_getVar(vars, "DETECTED_BOXTYPE"),"")==0 ? "System" : tpl_getVar(vars, "DETECTED_BOXTYPE"));
8024 tpl_addVar(vars, TPLADD, "UPTIME", sec2timeformat(vars, uptime));
8026 tpl_addVar(vars, TPLADD, "CURIP", cs_inet_ntoa(addr));
8027 if(cfg.http_readonly)
8028 { tpl_addVar(vars, TPLAPPEND, "BTNDISABLED", "DISABLED"); }
8030 i = ll_count(cfg.v_list);
8031 if(i > 0) { tpl_printf(vars, TPLADD, "FAILBANNOTIFIER", "<SPAN CLASS=\"span_notifier\">%d</SPAN>", i); }
8032 tpl_printf(vars, TPLADD, "FAILBANNOTIFIERPOLL", "%d", i);
8034 char *result = NULL;
8036 // WebIf allows modifying many things. Thus, all pages except images/css/static are expected to be non-threadsafe!
8037 if(pgidx != 19 && pgidx != 20 && pgidx != 21 && pgidx != 27) { cs_writelock(__func__, &http_lock); }
8038 switch(pgidx)
8040 case 0:
8041 tpl_addVar(vars, TPLADD, "CONFIG_CONTENT", send_oscam_config(vars, &params));
8042 result = tpl_getTpl(vars, "CONFIGCONTENT");
8043 break;
8044 case 1:
8045 result = send_oscam_reader(vars, &params, 0);
8046 break;
8047 case 2:
8048 result = send_oscam_entitlement(vars, &params, 0);
8049 break;
8050 case 3:
8051 result = send_oscam_status(vars, &params, 0);
8052 break;
8053 case 4:
8054 result = send_oscam_user_config(vars, &params, 0);
8055 break;
8056 case 5:
8057 result = send_oscam_reader_config(vars, &params);
8058 break;
8059 case 6:
8060 result = send_oscam_services(vars, &params);
8061 break;
8062 case 7:
8063 result = send_oscam_user_config_edit(vars, &params, 0);
8064 break;
8065 //case 8: css file
8066 case 9:
8067 result = send_oscam_services_edit(vars, &params);
8068 break;
8069 case 10:
8070 result = send_oscam_savetpls(vars);
8071 break;
8072 case 11:
8073 result = send_oscam_shutdown(vars, f, &params, 0, keepalive, extraheader);
8074 break;
8075 case 12:
8076 result = send_oscam_script(vars, &params);
8077 break;
8078 case 13:
8079 result = send_oscam_scanusb(vars);
8080 break;
8081 case 14:
8082 result = send_oscam_files(vars, &params, 0);
8083 break;
8084 case 15:
8085 result = send_oscam_reader_stats(vars, &params, 0);
8086 break;
8087 case 16:
8088 result = send_oscam_failban(vars, &params, 0);
8089 break;
8090 //case 17: js file
8091 case 18:
8092 result = send_oscam_api(vars, f, &params, keepalive, 1, extraheader);
8093 break; //oscamapi.html
8094 case 19:
8095 result = send_oscam_image(vars, f, &params, NULL, modifiedheader, etagheader, extraheader);
8096 break;
8097 case 20:
8098 result = send_oscam_image(vars, f, &params, "ICMAI", modifiedheader, etagheader, extraheader);
8099 break;
8100 case 21:
8101 result = send_oscam_graph(vars);
8102 break;
8103 case 22:
8104 result = send_oscam_api(vars, f, &params, keepalive, 1, extraheader);
8105 break; //oscamapi.xml
8106 #ifdef CS_CACHEEX
8107 case 23:
8108 result = send_oscam_cacheex(vars, &params, 0);
8109 break;
8110 #endif
8111 case 24:
8112 result = send_oscam_api(vars, f, &params, keepalive, 2, extraheader);
8113 break; //oscamapi.json
8114 case 25:
8115 result = send_oscam_EMM(vars, &params);
8116 break; //emm.html
8117 case 26:
8118 result = send_oscam_EMM_running(vars, &params);
8119 break; //emm_running.html
8120 case 27:
8121 result = send_oscam_robots_txt(f);
8122 break; //robots.txt
8123 #ifdef MODULE_GHTTP
8124 case 28:
8125 result = send_oscam_ghttp(vars, &params, 0);
8126 break;
8127 #endif
8128 #ifdef WEBIF_LIVELOG
8129 case 29:
8130 result = send_oscam_logpoll(vars, &params);
8131 break;
8132 #endif
8133 default:
8134 result = send_oscam_status(vars, &params, 0);
8135 break;
8137 if(pgidx != 19 && pgidx != 20 && pgidx != 21 && pgidx != 27) { cs_writeunlock(__func__, &http_lock); }
8139 if(result == NULL || !strcmp(result, "0") || strlen(result) == 0) { send_error500(f); }
8140 else if(strcmp(result, "1"))
8142 //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
8143 if(pgidx == 18)
8144 { send_headers(f, 200, "OK", extraheader, "text/xml", 0, strlen(result), NULL, 0); }
8145 else if(pgidx == 21)
8146 { send_headers(f, 200, "OK", extraheader, "image/svg+xml", 0, strlen(result), NULL, 0); }
8147 else if(pgidx == 24)
8148 { send_headers(f, 200, "OK", extraheader, "text/javascript", 0, strlen(result), NULL, 0); }
8149 else
8150 { send_headers(f, 200, "OK", extraheader, "text/html", 0, strlen(result), NULL, 0); }
8151 webif_write(result, f);
8153 tpl_clear(vars);
8155 NULLFREE(filebuf);
8157 while(*keepalive == 1 && !exit_oscam);
8158 return 0;
8161 static void *serve_process(void *conn)
8163 struct s_connection *myconn = (struct s_connection *)conn;
8164 int32_t s = myconn->socket;
8165 struct s_client *cl = myconn->cl;
8166 IN_ADDR_T in;
8167 IP_ASSIGN(in, myconn->remote);
8169 set_thread_name(__func__);
8171 #ifdef WITH_SSL
8172 SSL *ssl = myconn->ssl;
8173 SAFE_SETSPECIFIC(getssl, ssl);
8174 #endif
8175 NULLFREE(myconn);
8177 SAFE_SETSPECIFIC(getip, &in);
8178 SAFE_SETSPECIFIC(getclient, cl);
8180 int8_t keepalive = 0;
8181 SAFE_SETSPECIFIC(getkeepalive, &keepalive);
8183 #ifdef WITH_SSL
8184 if(ssl_active)
8186 if(SSL_set_fd(ssl, s))
8188 int32_t ok = (SSL_accept(ssl) != -1);
8189 if(!ok)
8191 int8_t tries = 100;
8192 while(!ok && tries--)
8194 int32_t err = SSL_get_error(ssl, -1);
8195 if(err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
8196 { break; }
8197 else
8199 struct pollfd pfd;
8200 pfd.fd = s;
8201 pfd.events = POLLIN | POLLPRI;
8202 int32_t rc = poll(&pfd, 1, -1);
8203 if(rc < 0)
8205 if(errno == EINTR || errno == EAGAIN) { continue; }
8206 break;
8208 if(rc == 1)
8209 { ok = (SSL_accept(ssl) != -1); }
8213 if(ok)
8215 process_request((FILE *)ssl, in);
8217 else
8219 FILE *f;
8220 f = fdopen(s, "r+");
8221 if(f != NULL)
8223 char *ptr, *filebuf = NULL, *host = NULL;
8224 int32_t bufsize = readRequest(f, in, &filebuf, 1);
8226 if(filebuf)
8228 filebuf[bufsize] = '\0';
8229 host = strstr(filebuf, "Host: ");
8230 if(host)
8232 host += 6;
8233 ptr = strchr(host, '\r');
8234 if(ptr) { ptr[0] = '\0'; }
8237 if(host)
8239 char extra[strlen(host) + 20];
8240 snprintf(extra, sizeof(extra), "Location: https://%s", host);
8241 send_error(f, 301, "Moved Permanently", extra, "This web server is running in SSL mode.", 1);
8243 else
8244 { send_error(f, 200, "Bad Request", NULL, "This web server is running in SSL mode.", 1); }
8245 fflush(f);
8246 fclose(f);
8247 NULLFREE(filebuf);
8249 else
8251 cs_log_dbg(D_TRACE, "WebIf: fdopen(%d) failed. (errno=%d %s)", s, errno, strerror(errno));
8255 else { cs_log("WebIf: Error calling SSL_set_fd()."); }
8256 SSL_shutdown(ssl);
8257 close(s);
8258 SSL_free(ssl);
8260 else
8261 #endif
8263 FILE *f;
8264 f = fdopen(s, "r+");
8265 if(f != NULL)
8267 process_request(f, in);
8268 fflush(f);
8269 fclose(f);
8271 else
8273 cs_log_dbg(D_TRACE, "WebIf: fdopen(%d) failed. (errno=%d %s)", s, errno, strerror(errno));
8275 shutdown(s, SHUT_WR);
8276 close(s);
8279 return NULL;
8282 /* Creates a random string with specified length. Note that dst must be one larger than size to hold the trailing \0*/
8283 static void create_rand_str(char *dst, int32_t size)
8285 int32_t i;
8286 for(i = 0; i < size; ++i)
8288 dst[i] = (rand() % 94) + 32;
8290 dst[i] = '\0';
8293 static void *http_server(void *UNUSED(d))
8295 struct s_client *cl = create_client(first_client->ip);
8296 if(cl == NULL) { return NULL; }
8297 SAFE_SETSPECIFIC(getclient, cl);
8298 cl->typ = 'h';
8299 int32_t s, reuse = 1;
8300 struct s_connection *conn;
8302 set_thread_name(__func__);
8304 /* Create random string for nonce value generation */
8305 create_rand_str(noncekey, 32);
8307 /* Prepare base64 decoding array */
8308 b64prepare();
8309 webif_tpls_prepare();
8311 tpl_checkDiskRevisions();
8313 cs_lock_create(__func__, &http_lock, "http_lock", 10000);
8314 init_noncelocks();
8316 memset(&p_stat_cur, 0x0, sizeof(p_stat_cur));
8318 if(pthread_key_create(&getip, NULL))
8320 cs_log("Could not create getip");
8321 return NULL;
8323 if(pthread_key_create(&getkeepalive, NULL))
8325 cs_log("Could not create getkeepalive");
8326 return NULL;
8329 struct SOCKADDR sin;
8330 socklen_t len = 0;
8331 memset(&sin, 0, sizeof(sin));
8333 bool do_ipv6 = config_enabled(IPV6SUPPORT);
8334 #ifdef IPV6SUPPORT
8335 if(do_ipv6)
8337 len = sizeof(struct sockaddr_in6);
8338 if((sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0)
8340 cs_log("HTTP Server: ERROR: Creating IPv6 socket failed! (errno=%d %s)", errno, strerror(errno));
8341 cs_log("HTTP Server: Falling back to IPv4.");
8342 do_ipv6 = false;
8344 else
8346 struct sockaddr_in6 *ia = (struct sockaddr_in6 *)&sin;
8347 ia->sin6_family = AF_INET6;
8348 ia->sin6_addr = in6addr_any;
8349 ia->sin6_port = htons(cfg.http_port);
8352 #endif
8353 if(!do_ipv6)
8355 len = sizeof(struct sockaddr_in);
8356 if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
8358 cs_log("HTTP Server: ERROR: Creating socket failed! (errno=%d %s)", errno, strerror(errno));
8359 return NULL;
8361 SIN_GET_FAMILY(sin) = AF_INET;
8362 if(IP_ISSET(cfg.http_srvip))
8363 { IP_ASSIGN(SIN_GET_ADDR(sin), cfg.http_srvip); }
8364 else if(IP_ISSET(cfg.srvip))
8365 { IP_ASSIGN(SIN_GET_ADDR(sin), cfg.srvip); }
8366 // The default is INADDR_ANY (0)
8367 SIN_GET_PORT(sin) = htons(cfg.http_port);
8370 if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
8372 cs_log("HTTP Server: Setting SO_REUSEADDR via setsockopt failed! (errno=%d %s)", errno, strerror(errno));
8375 if(bind(sock, (struct sockaddr *)&sin, len) < 0)
8377 cs_log("HTTP Server couldn't bind on port %d (errno=%d %s). Not starting HTTP!", cfg.http_port, errno, strerror(errno));
8378 close(sock);
8379 return NULL;
8382 if(listen(sock, SOMAXCONN) < 0)
8384 cs_log("HTTP Server: Call to listen() failed! (errno=%d %s)", errno, strerror(errno));
8385 close(sock);
8386 return NULL;
8389 #ifdef WITH_SSL
8390 if(pthread_key_create(&getssl, NULL))
8392 cs_log("Could not create getssl");
8395 SSL_CTX *ctx = NULL;
8396 if(cfg.http_use_ssl)
8398 ctx = SSL_Webif_Init();
8399 if(ctx == NULL)
8400 { cs_log("SSL could not be initialized. Starting WebIf in plain mode."); }
8401 else { ssl_active = 1; }
8403 else { ssl_active = 0; }
8404 cs_log("HTTP Server running. ip=%s port=%d%s", cs_inet_ntoa(SIN_GET_ADDR(sin)), cfg.http_port, ssl_active ? " (SSL)" : "");
8405 #else
8406 cs_log("HTTP Server running. ip=%s port=%d", cs_inet_ntoa(SIN_GET_ADDR(sin)), cfg.http_port);
8407 #endif
8409 struct SOCKADDR remote;
8410 memset(&remote, 0, sizeof(remote));
8412 while(!exit_oscam)
8414 if((s = accept(sock, (struct sockaddr *) &remote, &len)) < 0)
8416 if(exit_oscam)
8417 { break; }
8418 if(errno != EAGAIN && errno != EINTR)
8420 cs_log("HTTP Server: Error calling accept() (errno=%d %s)", errno, strerror(errno));
8421 cs_sleepms(100);
8423 else { cs_sleepms(5); }
8424 continue;
8426 else
8428 getpeername(s, (struct sockaddr *) &remote, &len);
8429 if(!cs_malloc(&conn, sizeof(struct s_connection)))
8431 close(s);
8432 continue;
8434 setTCPTimeouts(s);
8435 cur_client()->last = time((time_t *)0); //reset last busy time
8436 conn->cl = cur_client();
8437 #ifdef IPV6SUPPORT
8438 if(do_ipv6)
8440 struct sockaddr_in6 *ra = (struct sockaddr_in6 *)&remote;
8441 memcpy(&conn->remote, &ra->sin6_addr, sizeof(struct in6_addr));
8443 else
8445 struct sockaddr_in *fba = (struct sockaddr_in *)&remote;
8446 struct in6_addr taddr;
8447 memset(&taddr, 0, sizeof(taddr));
8448 taddr.s6_addr32[3] = fba->sin_addr.s_addr;
8449 memcpy(&conn->remote, &taddr, sizeof(struct in6_addr));
8451 #else
8452 memcpy(&conn->remote, &remote.sin_addr, sizeof(struct in_addr));
8453 #endif
8454 conn->socket = s;
8455 #ifdef WITH_SSL
8456 conn->ssl = NULL;
8457 if(ssl_active)
8459 conn->ssl = SSL_new(ctx);
8460 if(conn->ssl == NULL)
8462 close(s);
8463 cs_log("WebIf: Error calling SSL_new().");
8464 continue;
8467 #endif
8469 int32_t ret = start_thread("webif workthread", serve_process, (void *)conn, NULL, 1, 1);
8470 if(ret)
8472 NULLFREE(conn);
8476 // Wait a bit so that we don't close ressources while http threads are active
8477 cs_sleepms(300);
8478 #ifdef WITH_SSL
8479 SSL_CTX_free(ctx);
8480 CRYPTO_set_dynlock_create_callback(NULL);
8481 CRYPTO_set_dynlock_lock_callback(NULL);
8482 CRYPTO_set_dynlock_destroy_callback(NULL);
8483 CRYPTO_set_locking_callback(NULL);
8484 CRYPTO_set_id_callback(NULL);
8485 OPENSSL_free(lock_cs);
8486 lock_cs = NULL;
8487 #endif
8488 cs_log("HTTP Server stopped");
8489 free_client(cl);
8490 close(sock);
8491 return NULL;
8494 void webif_client_reset_lastresponsetime(struct s_client * cl)
8496 int32_t i;
8497 for(i = 0; i < CS_ECM_RINGBUFFER_MAX; i++)
8499 cl->cwlastresptimes[i].duration = 0;
8500 cl->cwlastresptimes[i].timestamp = time((time_t *)0);
8501 cl->cwlastresptimes[i].rc = 0;
8503 cl->cwlastresptimes_last = 0;
8506 void webif_client_add_lastresponsetime(struct s_client * cl, int32_t ltime, time_t timestamp, int32_t rc)
8508 int32_t last = cl->cwlastresptimes_last = (cl->cwlastresptimes_last + 1) & (CS_ECM_RINGBUFFER_MAX - 1);
8509 cl->cwlastresptimes[last].duration = ltime > 9999 ? 9999 : ltime;
8510 cl->cwlastresptimes[last].timestamp = timestamp;
8511 cl->cwlastresptimes[last].rc = rc;
8514 void webif_client_init_lastreader(struct s_client * client, ECM_REQUEST * er, struct s_reader * er_reader, const char *stxt[])
8516 if(er_reader)
8518 if(er->rc == E_FOUND)
8519 { cs_strncpy(client->lastreader, er_reader->label, sizeof(client->lastreader)); }
8520 else if(er->rc == E_CACHEEX)
8521 { cs_strncpy(client->lastreader, "cache3", sizeof(client->lastreader)); }
8522 else if(er->rc < E_NOTFOUND)
8523 { snprintf(client->lastreader, sizeof(client->lastreader) - 1, "%s (cache)", er_reader->label); }
8524 else
8525 { cs_strncpy(client->lastreader, stxt[er->rc], sizeof(client->lastreader)); }
8527 else
8529 cs_strncpy(client->lastreader, stxt[er->rc], sizeof(client->lastreader));
8533 void webif_init(void)
8535 char buf[8], fname[256];
8536 snprintf(buf, 8, "%'d", 7);
8537 if(strcmp(buf, "7"))
8539 useLocal = 0;
8542 if(cfg.http_port == 0)
8544 cs_log("http disabled");
8545 return;
8548 get_config_filename(fname, sizeof(fname), "oscam.srvid2");
8549 use_srvid2 = file_exists(fname);
8551 if(start_thread("http", http_server, NULL, &httpthread, 0, 1) == 0)
8553 httpthread_running = 1;
8557 void webif_close(void)
8559 if(!sock)
8560 { return; }
8562 shutdown(sock, 2);
8563 close(sock);
8565 if(httpthread_running)
8566 { SAFE_THREAD_JOIN(httpthread, NULL); }
8569 #endif