source: trunk/oscam.c@ 8434

Last change on this file since 8434 was 8434, checked in by gf, 9 years ago

webif: Create and use private templates array.

This allows storing of additional information along with templates
data (which is const).

For now we store name hash but in the future the data that comes from
struct templates (in webif/pages.c) may need to be preprocessed
(uncompressed for example) and the abstraction in this commit makes
it easier to do such changes.

  • Property svn:eol-style set to LF
File size: 41.7 KB
Line 
1#include "globals.h"
2#include <getopt.h>
3
4#include "csctapi/cardreaders.h"
5#include "modules.h"
6#include "readers.h"
7
8#include "extapi/coolapi.h"
9#include "module-anticasc.h"
10#include "module-cacheex.h"
11#include "module-cccam.h"
12#include "module-dvbapi-azbox.h"
13#include "module-dvbapi-mca.h"
14#include "module-ird-guess.h"
15#include "module-lcd.h"
16#include "module-led.h"
17#include "module-stat.h"
18#include "module-webif.h"
19#include "module-webif-tpl.h"
20#include "module-cw-cycle-check.h"
21#include "oscam-chk.h"
22#include "oscam-client.h"
23#include "oscam-config.h"
24#include "oscam-ecm.h"
25#include "oscam-emm.h"
26#include "oscam-files.h"
27#include "oscam-garbage.h"
28#include "oscam-lock.h"
29#include "oscam-net.h"
30#include "oscam-reader.h"
31#include "oscam-string.h"
32#include "oscam-time.h"
33#include "oscam-work.h"
34#include "reader-common.h"
35
36extern char *config_mak;
37
38/*****************************************************************************
39 Globals
40*****************************************************************************/
41const char *syslog_ident = "oscam";
42char *oscam_pidfile = NULL;
43char default_pidfile[64];
44
45int32_t exit_oscam=0;
46static struct s_module modules[CS_MAX_MOD];
47struct s_cardsystem cardsystems[CS_MAX_MOD];
48struct s_cardreader cardreaders[CS_MAX_MOD];
49
50struct s_client * first_client = NULL; //Pointer to clients list, first client is master
51struct s_reader * first_active_reader = NULL; //list of active readers (enable=1 deleted = 0)
52LLIST * configured_readers = NULL; //list of all (configured) readers
53
54uint16_t len4caid[256]; // table for guessing caid (by len)
55char cs_confdir[128]=CS_CONFDIR;
56uint16_t cs_dblevel=0; // Debug Level
57int32_t thread_pipe[2] = {0, 0};
58int8_t cs_restart_mode=1; //Restartmode: 0=off, no restart fork, 1=(default)restart fork, restart by webif, 2=like=1, but also restart on segfaults
59uint8_t cs_http_use_utf8 = 0;
60int8_t cs_capture_SEGV=0;
61int8_t cs_dump_stack=0;
62uint16_t cs_waittime = 60;
63char cs_tmpdir[200]={0x00};
64CS_MUTEX_LOCK system_lock;
65CS_MUTEX_LOCK config_lock;
66CS_MUTEX_LOCK gethostbyname_lock;
67CS_MUTEX_LOCK clientlist_lock;
68CS_MUTEX_LOCK readerlist_lock;
69CS_MUTEX_LOCK fakeuser_lock;
70CS_MUTEX_LOCK ecmcache_lock;
71CS_MUTEX_LOCK readdir_lock;
72CS_MUTEX_LOCK cwcycle_lock;
73CS_MUTEX_LOCK hitcache_lock;
74pthread_key_t getclient;
75static int32_t bg;
76static int32_t gbdb;
77static int32_t max_pending = 32;
78
79struct s_client *timecheck_client;
80
81//Cache for ecms, cws and rcs:
82struct ecm_request_t *ecmcwcache = NULL;
83uint32_t ecmcwcache_size = 0;
84
85struct s_config cfg;
86
87int log_remove_sensitive = 1;
88
89char *prog_name = NULL;
90char *processUsername = NULL;
91
92/*****************************************************************************
93 Statics
94*****************************************************************************/
95/* Prints usage information and information about the built-in modules. */
96static void show_usage(void)
97{
98 printf("%s",
99" ___ ____ ___\n"
100" / _ \\/ ___| / __|__ _ _ __ ___\n"
101"| | | \\___ \\| | / _` | '_ ` _ \\\n"
102"| |_| |___) | |_| (_| | | | | | |\n"
103" \\___/|____/ \\___\\__,_|_| |_| |_|\n\n");
104 printf("OSCam cardserver v%s, build r%s (%s)\n", CS_VERSION, CS_SVN_VERSION, CS_TARGET);
105 printf("Copyright (C) 2009-2013 OSCam developers.\n");
106 printf("This program is distributed under GPLv3.\n");
107 printf("OSCam is based on Streamboard mp-cardserver v0.9d written by dukat\n");
108 printf("Visit http://www.streamboard.tv/oscam/ for more details.\n\n");
109
110 printf(" ConfigDir : %s\n", CS_CONFDIR);
111 printf("\n");
112 printf(" Usage: oscam [parameters]\n");
113 printf("\n Directories:\n");
114 printf(" -c, --config-dir <dir> | Read configuration files from <dir>.\n");
115 printf(" . Default: %s\n", CS_CONFDIR);
116 printf(" -t, --temp-dir <dir> | Set temporary directory to <dir>.\n");
117#if defined(__CYGWIN__)
118 printf(" . Default: (OS-TMP)\n");
119#else
120 printf(" . Default: /tmp/.oscam\n");
121#endif
122 printf("\n Startup:\n");
123 printf(" -b, --daemon | Start in the background as daemon.\n");
124 printf(" -B, --pidfile <pidfile> | Create pidfile when starting.\n");
125 if (config_enabled(WEBIF)) {
126 printf(" -r, --restart <level> | Set restart level:\n");
127 printf(" . 0 - Restart disabled (exit on restart request).\n");
128 printf(" . 1 - WebIf restart is active (default).\n");
129 printf(" . 2 - Like 1, but also restart on segfaults.\n");
130 }
131 printf(" -w, --wait <secs> | Set how much seconds to wait at startup for the\n");
132 printf(" . system clock to be set correctly. Default: 60\n");
133 printf("\n Logging:\n");
134 printf(" -I, --syslog-ident <ident> | Set syslog ident. Default: oscam\n");
135 printf(" -S, --show-sensitive | Do not filter sensitive info (card serials, boxids)\n");
136 printf(" . from the logs.\n");
137 printf(" -d, --debug <level> | Set debug level mask used for logging:\n");
138 printf(" . 0 - No extra debugging (default).\n");
139 printf(" . 1 - Detailed error messages.\n");
140 printf(" . 2 - ATR parsing info, ECM, EMM and CW dumps.\n");
141 printf(" . 4 - Traffic from/to the reader.\n");
142 printf(" . 8 - Traffic from/to the clients.\n");
143 printf(" . 16 - Traffic to the reader-device on IFD layer.\n");
144 printf(" . 32 - Traffic to the reader-device on I/O layer.\n");
145 printf(" . 64 - EMM logging.\n");
146 printf(" . 128 - DVBAPI logging.\n");
147 printf(" . 256 - Loadbalancer logging.\n");
148 printf(" . 512 - CACHEEX logging.\n");
149 printf(" . 1024 - Client ECM logging.\n");
150 printf(" . 65535 - Debug all.\n");
151 printf("\n Settings:\n");
152 printf(" -p, --pending-ecm <num> | Set the maximum number of pending ECM packets.\n");
153 printf(" . Default: 32 Max: 255\n");
154 if (config_enabled(WEBIF)) {
155 printf(" -u, --utf8 | Enable WebIf support for UTF-8 charset.\n");
156 }
157 printf("\n Debug parameters:\n");
158 printf(" -a, --crash-dump | Write oscam.crash file on segfault. This option\n");
159 printf(" . needs GDB to be installed and OSCam executable to\n");
160 printf(" . contain the debug information (run oscam-XXXX.debug)\n");
161 printf(" -s, --capture-segfaults | Capture segmentation faults.\n");
162 printf(" -g, --gcollect <mode> | Garbage collector debug mode:\n");
163 printf(" . 1 - Immediate free.\n");
164 printf(" . 2 - Check for double frees.\n");
165 printf("\n Information:\n");
166 printf(" -h, --help | Show command line help text.\n");
167 printf(" -V, --build-info | Show OSCam binary configuration and version.\n");
168}
169
170/* Keep the options sorted */
171static const char short_options[] = "aB:bc:d:g:hI:p:r:Sst:uVw:";
172
173/* Keep the options sorted by short option */
174static const struct option long_options[] = {
175 { "crash-dump", no_argument, NULL, 'a' },
176 { "pidfile", required_argument, NULL, 'B' },
177 { "daemon", no_argument, NULL, 'b' },
178 { "config-dir", required_argument, NULL, 'c' },
179 { "debug", required_argument, NULL, 'd' },
180 { "gcollect", required_argument, NULL, 'g' },
181 { "help", no_argument, NULL, 'h' },
182 { "syslog-ident", required_argument, NULL, 'I' },
183 { "pending-ecm", required_argument, NULL, 'p' },
184 { "restart", required_argument, NULL, 'r' },
185 { "show-sensitive", no_argument, NULL, 'S' },
186 { "capture-segfaults", no_argument, NULL, 's' },
187 { "temp-dir", required_argument, NULL, 't' },
188 { "utf8", no_argument, NULL, 'u' },
189 { "build-info", no_argument, NULL, 'V' },
190 { "wait", required_argument, NULL, 'w' },
191 { 0, 0, 0, 0 }
192};
193
194static void write_versionfile(bool use_stdout);
195
196static void parse_cmdline_params(int argc, char **argv) {
197 int i;
198 while ((i = getopt_long(argc, argv, short_options, long_options, NULL)) != EOF) {
199 if (i == '?')
200 fprintf(stderr, "ERROR: Unknown command line parameter: %s\n", argv[optind - 1]);
201 switch(i) {
202 case 'a': // --crash-dump
203 cs_dump_stack = 1;
204 break;
205 case 'B': // --pidfile
206 oscam_pidfile = optarg;
207 break;
208 case 'b': // --daemon
209 bg = 1;
210 break;
211 case 'c': // --config-dir
212 cs_strncpy(cs_confdir, optarg, sizeof(cs_confdir));
213 break;
214 case 'd': // --debug
215 cs_dblevel = atoi(optarg);
216 break;
217 case 'g': // --gcollect
218 gbdb = atoi(optarg);
219 break;
220 case 'h': // --help
221 show_usage();
222 exit(EXIT_SUCCESS);
223 break;
224 case 'I': // --syslog-ident
225 syslog_ident = optarg;
226 break;
227 case 'p': // --pending-ecm
228 max_pending = atoi(optarg) <= 0 ? 32 : MIN(atoi(optarg), 255);
229 break;
230 case 'r': // --restart
231 if (config_enabled(WEBIF)) {
232 cs_restart_mode = atoi(optarg);
233 }
234 break;
235 case 'S': // --show-sensitive
236 log_remove_sensitive = !log_remove_sensitive;
237 break;
238 case 's': // --capture-segfaults
239 cs_capture_SEGV = 1;
240 break;
241 case 't': { // --temp-dir
242 mkdir(optarg, S_IRWXU);
243 int j = open(optarg, O_RDONLY);
244 if (j >= 0) {
245 close(j);
246 cs_strncpy(cs_tmpdir, optarg, sizeof(cs_tmpdir));
247 } else {
248 printf("WARNING: Temp dir does not exist. Using default value.\n");
249 }
250 break;
251 }
252 case 'u': // --utf8
253 if (config_enabled(WEBIF)) {
254 cs_http_use_utf8 = 1;
255 printf("WARNING: Web interface UTF-8 mode enabled. Carefully read documentation as bugs may arise.\n");
256 }
257 break;
258 case 'V': // --build-info
259 write_versionfile(true);
260 exit(EXIT_SUCCESS);
261 break;
262 case 'w': // --wait
263 cs_waittime = strtoul(optarg, NULL, 10);
264 break;
265 }
266 }
267}
268
269#define write_conf(CONFIG_VAR, text) \
270 fprintf(fp, "%-30s %s\n", text ":", config_enabled(CONFIG_VAR) ? "yes" : "no")
271
272#define write_readerconf(CONFIG_VAR, text) \
273 fprintf(fp, "%-30s %s\n", text ":", config_enabled(CONFIG_VAR) ? "yes" : "no - no EMM support!")
274
275#define write_cardreaderconf(CONFIG_VAR, text) \
276 fprintf(fp, "%s%-19s %s\n", "cardreader_", text ":", config_enabled(CONFIG_VAR) ? "yes" : "no")
277
278static void write_versionfile(bool use_stdout) {
279 FILE *fp = stdout;
280 if (!use_stdout) {
281 char targetfile[256];
282 fp = fopen(get_tmp_dir_filename(targetfile, sizeof(targetfile), "oscam.version"), "w");
283 if (!fp) {
284 cs_log("Cannot open %s (errno=%d %s)", targetfile, errno, strerror(errno));
285 return;
286 }
287 struct tm st;
288 time_t now = time(NULL);
289 localtime_r(&now, &st);
290
291 fprintf(fp, "Unix starttime: %ld\n", (long)now);
292 fprintf(fp, "Starttime: %02d.%02d.%04d %02d:%02d:%02d\n",
293 st.tm_mday, st.tm_mon + 1, st.tm_year + 1900,
294 st.tm_hour, st.tm_min, st.tm_sec);
295 }
296
297 fprintf(fp, "Version: oscam-%s-r%s\n", CS_VERSION, CS_SVN_VERSION);
298
299 fprintf(fp, "\n");
300 write_conf(WEBIF, "Web interface support");
301 write_conf(TOUCH, "Touch interface support");
302 write_conf(WITH_SSL, "SSL support");
303 write_conf(HAVE_DVBAPI, "DVB API support");
304 if (config_enabled(HAVE_DVBAPI)) {
305 write_conf(WITH_AZBOX, "DVB API with AZBOX support");
306 write_conf(WITH_MCA, "DVB API with MCA support");
307 write_conf(WITH_COOLAPI, "DVB API with COOLAPI support");
308 write_conf(WITH_STAPI, "DVB API with STAPI support");
309 }
310 write_conf(CS_ANTICASC, "Anti-cascading support");
311 write_conf(IRDETO_GUESSING, "Irdeto guessing");
312 write_conf(WITH_DEBUG, "Debug mode");
313 write_conf(MODULE_MONITOR, "Monitor");
314 write_conf(WITH_LB, "Loadbalancing support");
315 write_conf(CW_CYCLE_CHECK, "CW Cycle Check support");
316 write_conf(LCDSUPPORT, "LCD support");
317 write_conf(LEDSUPPORT, "LED support");
318 write_conf(IPV6SUPPORT, "IPv6 support");
319 write_conf(CS_CACHEEX, "Cache exchange support");
320
321 fprintf(fp, "\n");
322 write_conf(MODULE_CAMD33, "camd 3.3x");
323 write_conf(MODULE_CAMD35, "camd 3.5 UDP");
324 write_conf(MODULE_CAMD35_TCP, "camd 3.5 TCP");
325 write_conf(MODULE_NEWCAMD, "newcamd");
326 write_conf(MODULE_CCCAM, "CCcam");
327 write_conf(MODULE_CCCSHARE, "CCcam share");
328 write_conf(MODULE_PANDORA, "Pandora");
329 write_conf(MODULE_GHTTP, "ghttp");
330 write_conf(MODULE_GBOX, "gbox");
331 write_conf(MODULE_RADEGAST, "radegast");
332 write_conf(MODULE_SERIAL, "serial");
333 write_conf(MODULE_CONSTCW, "constant CW");
334
335 fprintf(fp, "\n");
336 write_conf(WITH_CARDREADER, "Reader support");
337 if (config_enabled(WITH_CARDREADER)) {
338 fprintf(fp, "\n");
339 write_readerconf(READER_NAGRA, "Nagra");
340 write_readerconf(READER_IRDETO, "Irdeto");
341 write_readerconf(READER_CONAX, "Conax");
342 write_readerconf(READER_CRYPTOWORKS, "Cryptoworks");
343 write_readerconf(READER_SECA, "Seca");
344 write_readerconf(READER_VIACCESS, "Viaccess");
345 write_readerconf(READER_VIDEOGUARD, "NDS Videoguard");
346 write_readerconf(READER_DRE, "DRE Crypt");
347 write_readerconf(READER_TONGFANG, "TONGFANG");
348 write_readerconf(READER_BULCRYPT, "Bulcrypt");
349 write_readerconf(READER_GRIFFIN, "Griffin");
350 write_readerconf(READER_DGCRYPT, "DGCrypt");
351 fprintf(fp, "\n");
352 write_cardreaderconf(CARDREADER_PHOENIX, "phoenix");
353 write_cardreaderconf(CARDREADER_INTERNAL_AZBOX, "internal_azbox");
354 write_cardreaderconf(CARDREADER_INTERNAL_COOLAPI, "internal_coolapi");
355 write_cardreaderconf(CARDREADER_INTERNAL_SCI, "internal_sci");
356 write_cardreaderconf(CARDREADER_SC8IN1, "sc8in1");
357 write_cardreaderconf(CARDREADER_MP35, "mp35");
358 write_cardreaderconf(CARDREADER_SMARGO, "smargo");
359 write_cardreaderconf(CARDREADER_PCSC, "pcsc");
360 write_cardreaderconf(CARDREADER_SMART, "smartreader");
361 write_cardreaderconf(CARDREADER_DB2COM, "db2com");
362 write_cardreaderconf(CARDREADER_STAPI, "stapi");
363 } else {
364 write_readerconf(WITH_CARDREADER, "Reader Support");
365 }
366 if (!use_stdout)
367 fclose(fp);
368}
369#undef write_conf
370#undef write_readerconf
371#undef write_cardreaderconf
372
373static void remove_versionfile(void) {
374 char targetfile[256];
375 unlink(get_tmp_dir_filename(targetfile, sizeof(targetfile), "oscam.version"));
376}
377
378#define report_emm_support(CONFIG_VAR, text) \
379 do { \
380 if (!config_enabled(CONFIG_VAR)) \
381 cs_log("Binary without %s module - no EMM processing for %s possible!", text, text); \
382 } while(0)
383
384static void do_report_emm_support(void) {
385 if (!config_enabled(WITH_CARDREADER)) {
386 cs_log("Binary without Cardreader Support! No EMM processing possible!");
387 } else {
388 report_emm_support(READER_NAGRA, "Nagra");
389 report_emm_support(READER_IRDETO, "Irdeto");
390 report_emm_support(READER_CONAX, "Conax");
391 report_emm_support(READER_CRYPTOWORKS, "Cryptoworks");
392 report_emm_support(READER_SECA, "Seca");
393 report_emm_support(READER_VIACCESS, "Viaccess");
394 report_emm_support(READER_VIDEOGUARD, "NDS Videoguard");
395 report_emm_support(READER_DRE, "DRE Crypt");
396 report_emm_support(READER_TONGFANG, "TONGFANG");
397 report_emm_support(READER_BULCRYPT, "Bulcrypt");
398 report_emm_support(READER_GRIFFIN, "Griffin");
399 report_emm_support(READER_DGCRYPT, "DGCrypt");
400 }
401}
402#undef report_emm_support
403
404#ifdef NEED_DAEMON
405// The compat function is not called daemon() because this may cause problems.
406static int32_t do_daemon(int32_t nochdir, int32_t noclose)
407{
408 int32_t fd;
409
410 switch (fork())
411 {
412 case -1: return (-1);
413 case 0: break;
414 default: _exit(0);
415 }
416
417 if (setsid()==(-1))
418 return(-1);
419
420 if (!nochdir)
421 (void)chdir("/");
422
423 if (!noclose && (fd=open("/dev/null", O_RDWR, 0)) != -1)
424 {
425 (void)dup2(fd, STDIN_FILENO);
426 (void)dup2(fd, STDOUT_FILENO);
427 (void)dup2(fd, STDERR_FILENO);
428 if (fd>2)
429 (void)close(fd);
430 }
431 return(0);
432}
433#else
434#define do_daemon daemon
435#endif
436
437/*
438 * flags: 1 = restart, 2 = don't modify if SIG_IGN, may be combined
439 */
440static void set_signal_handler(int32_t sig, int32_t flags, void (*sighandler))
441{
442 struct sigaction sa;
443 sigaction(sig, (struct sigaction *) 0, &sa);
444 if (!((flags & 2) && (sa.sa_handler==SIG_IGN)))
445 {
446 sigemptyset(&sa.sa_mask);
447 sa.sa_flags=(flags & 1) ? SA_RESTART : 0;
448 sa.sa_handler=sighandler;
449 sigaction(sig, &sa, (struct sigaction *) 0);
450 }
451}
452
453static void cs_master_alarm(void)
454{
455 cs_log("PANIC: master deadlock!");
456 fprintf(stderr, "PANIC: master deadlock!");
457 fflush(stderr);
458}
459
460static void cs_sigpipe(void)
461{
462 if (cs_dblevel & D_ALL_DUMP)
463 cs_log("Got sigpipe signal -> captured");
464}
465
466static void cs_dummy(void) {
467 return;
468}
469
470/* Switch debuglevel forward one step (called when receiving SIGUSR1). */
471static void cs_debug_level(void) {
472 switch (cs_dblevel) {
473 case 0:
474 cs_dblevel = 1;
475 break;
476 case 128:
477 cs_dblevel = 255;
478 break;
479 case 255:
480 cs_dblevel = 0;
481 break;
482 default:
483 cs_dblevel <<= 1;
484 }
485
486 cs_log("debug_level=%d", cs_dblevel);
487}
488
489/**
490 * write stacktrace to oscam.crash. file is always appended
491 * Usage:
492 * 1. compile oscam with debug parameters (Makefile: DS_OPTS="-ggdb")
493 * 2. you need gdb installed and working on the local machine
494 * 3. start oscam with parameter: -a
495 */
496static void cs_dumpstack(int32_t sig)
497{
498 FILE *fp = fopen("oscam.crash", "a+");
499
500 time_t timep;
501 char buf[200];
502
503 time(&timep);
504 cs_ctime_r(&timep, buf);
505
506 fprintf(stderr, "crashed with signal %d on %swriting oscam.crash\n", sig, buf);
507
508 fprintf(fp, "%sOSCam cardserver v%s, build r%s (%s)\n", buf, CS_VERSION, CS_SVN_VERSION, CS_TARGET);
509 fprintf(fp, "FATAL: Signal %d: %s Fault. Logged StackTrace:\n\n", sig, (sig == SIGSEGV) ? "Segmentation" : ((sig == SIGBUS) ? "Bus" : "Unknown"));
510 fclose(fp);
511
512 FILE *cmd = fopen("/tmp/gdbcmd", "w");
513 fputs("bt\n", cmd);
514 fputs("thread apply all bt\n", cmd);
515 fclose(cmd);
516
517 snprintf(buf, sizeof(buf)-1, "gdb %s %d -batch -x /tmp/gdbcmd >> oscam.crash", prog_name, getpid());
518 if(system(buf) == -1)
519 fprintf(stderr, "Fatal error on trying to start gdb process.");
520
521 exit(-1);
522}
523
524
525/**
526 * called by signal SIGHUP
527 *
528 * reloads configs:
529 * - useraccounts (oscam.user)
530 * - services ids (oscam.srvid)
531 * - tier ids (oscam.tiers)
532 * Also clears anticascading stats.
533 **/
534static void cs_reload_config(void)
535{
536 cs_accounts_chk();
537 init_srvid();
538 init_tierid();
539 ac_init_stat();
540}
541
542/* Sets signal handlers to ignore for early startup of OSCam because for example log
543 could cause SIGPIPE errors and the normal signal handlers can't be used at this point. */
544static void init_signal_pre(void)
545{
546 set_signal_handler(SIGPIPE , 1, SIG_IGN);
547 set_signal_handler(SIGWINCH, 1, SIG_IGN);
548 set_signal_handler(SIGALRM , 1, SIG_IGN);
549 set_signal_handler(SIGHUP , 1, SIG_IGN);
550}
551
552/* Sets the signal handlers.*/
553static void init_signal(void)
554{
555 set_signal_handler(SIGINT, 3, cs_exit);
556#if defined(__APPLE__)
557 set_signal_handler(SIGEMT, 3, cs_exit);
558#endif
559 set_signal_handler(SIGTERM, 3, cs_exit);
560
561 set_signal_handler(SIGWINCH, 1, SIG_IGN);
562 set_signal_handler(SIGPIPE , 0, cs_sigpipe);
563 set_signal_handler(SIGALRM , 0, cs_master_alarm);
564 set_signal_handler(SIGHUP , 1, cs_reload_config);
565 set_signal_handler(SIGUSR1, 1, cs_debug_level);
566 set_signal_handler(SIGUSR2, 1, cs_card_info);
567 set_signal_handler(OSCAM_SIGNAL_WAKEUP, 0, cs_dummy);
568
569 if (cs_capture_SEGV) {
570 set_signal_handler(SIGSEGV, 1, cs_exit);
571 set_signal_handler(SIGBUS, 1, cs_exit);
572 }
573 else if (cs_dump_stack) {
574 set_signal_handler(SIGSEGV, 1, cs_dumpstack);
575 set_signal_handler(SIGBUS, 1, cs_dumpstack);
576 }
577
578 cs_log("signal handling initialized");
579 return;
580}
581
582void cs_exit(int32_t sig)
583{
584 if (cs_dump_stack && (sig == SIGSEGV || sig == SIGBUS || sig == SIGQUIT))
585 cs_dumpstack(sig);
586
587 set_signal_handler(SIGHUP , 1, SIG_IGN);
588 set_signal_handler(SIGPIPE, 1, SIG_IGN);
589
590 struct s_client *cl = cur_client();
591 if (!cl)
592 return;
593
594 // this is very important - do not remove
595 if (cl->typ != 's') {
596 cs_debug_mask(D_TRACE, "thread %8lX ended!", (unsigned long)pthread_self());
597
598 free_client(cl);
599
600 //Restore signals before exiting thread
601 set_signal_handler(SIGPIPE , 0, cs_sigpipe);
602 set_signal_handler(SIGHUP , 1, cs_reload_config);
603
604 pthread_exit(NULL);
605 return;
606 }
607
608 if (!exit_oscam)
609 exit_oscam = sig?sig:1;
610}
611
612/* Checks if the date of the system is correct and waits if necessary. */
613static void init_check(void){
614 char *ptr = __DATE__;
615 int32_t month, year = atoi(ptr + strlen(ptr) - 4), day = atoi(ptr + 4);
616 if(day > 0 && day < 32 && year > 2010 && year < 9999){
617 struct tm timeinfo;
618 char months[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
619 for(month = 0; month < 12; ++month){
620 if(!strncmp(ptr, months[month], 3)) break;
621 }
622 if(month > 11) month = 0;
623 memset(&timeinfo, 0, sizeof(timeinfo));
624 timeinfo.tm_mday = day;
625 timeinfo.tm_mon = month;
626 timeinfo.tm_year = year - 1900;
627 time_t builddate = mktime(&timeinfo) - 86400;
628 int32_t i = 0;
629 while(time((time_t*)0) < builddate){
630 if(i == 0) cs_log("The current system time is smaller than the build date (%s). Waiting up to %d seconds for time to correct", ptr, cs_waittime);
631 cs_sleepms(1000);
632 ++i;
633 if(i > cs_waittime){
634 cs_log("Waiting was not successful. OSCam will be started but is UNSUPPORTED this way. Do not report any errors with this version.");
635 break;
636 }
637 }
638 // adjust login time of first client
639 if(i > 0) first_client->login=time((time_t *)0);
640 }
641}
642
643#ifdef __linux__
644#include <sys/prctl.h>
645// PR_SET_NAME is introduced in 2.6.9 (which is ancient, released 18 Oct 2004)
646// but apparantly we can't count on having at least that version :(
647#ifndef PR_SET_NAME
648#define PR_SET_NAME 15
649#endif
650// Set the thread name (comm) under linux (the limit is 16 chars)
651void set_thread_name(const char *thread_name) {
652 prctl(PR_SET_NAME, thread_name, NULL, NULL, NULL);
653}
654#else
655void set_thread_name(const char *UNUSED(thread_name)) { }
656#endif
657
658/* Starts a thread named nameroutine with the start function startroutine. */
659void start_thread(void * startroutine, char * nameroutine) {
660 pthread_t temp;
661 pthread_attr_t attr;
662 pthread_attr_init(&attr);
663 cs_debug_mask(D_TRACE, "starting thread %s", nameroutine);
664 pthread_attr_setstacksize(&attr, PTHREAD_STACK_SIZE);
665 cs_writelock(&system_lock);
666 int32_t ret = pthread_create(&temp, &attr, startroutine, NULL);
667 if (ret)
668 cs_log("ERROR: can't create %s thread (errno=%d %s)", nameroutine, ret, strerror(ret));
669 else {
670 cs_debug_mask(D_TRACE, "%s thread started", nameroutine);
671 pthread_detach(temp);
672 }
673 pthread_attr_destroy(&attr);
674 cs_writeunlock(&system_lock);
675}
676
677/* Allows to kill another thread specified through the client cl with locking.
678 If the own thread has to be cancelled, cs_exit or cs_disconnect_client has to be used. */
679void kill_thread(struct s_client *cl) {
680 if (!cl || cl->kill) return;
681 if (cl == cur_client()) {
682 cs_log("Trying to kill myself, exiting.");
683 cs_exit(0);
684 }
685 add_job(cl, ACTION_CLIENT_KILL, NULL, 0); //add kill job, ...
686 cl->kill=1; //then set kill flag!
687}
688
689struct s_module *get_module(struct s_client *cl) {
690 return &modules[cl->module_idx];
691}
692
693void module_reader_set(struct s_reader *rdr) {
694 int i;
695 if (!is_cascading_reader(rdr))
696 return;
697 for (i = 0; i < CS_MAX_MOD; i++) {
698 struct s_module *module = &modules[i];
699 if (module->num && module->num == rdr->typ) {
700 rdr->ph = *module;
701 if (rdr->device[0])
702 rdr->ph.active = 1;
703 }
704 }
705}
706
707static void cs_waitforcardinit(void)
708{
709 if (cfg.waitforcards)
710 {
711 cs_log("waiting for local card init");
712 int32_t card_init_done;
713 do {
714 card_init_done = 1;
715 struct s_reader *rdr;
716 LL_ITER itr = ll_iter_create(configured_readers);
717 while((rdr = ll_iter_next(&itr))) {
718 if (rdr->enable && !is_cascading_reader(rdr) && (rdr->card_status == CARD_NEED_INIT || rdr->card_status == UNKNOWN)) {
719 card_init_done = 0;
720 break;
721 }
722 }
723
724 if (!card_init_done)
725 cs_sleepms(300); // wait a little bit
726 //alarm(cfg.cmaxidle + cfg.ctimeout / 1000 + 1);
727 } while (!card_init_done && !exit_oscam);
728 if (cfg.waitforcards_extra_delay>0 && !exit_oscam)
729 cs_sleepms(cfg.waitforcards_extra_delay);
730 cs_log("init for all local cards done");
731 }
732}
733
734static uint32_t auto_timeout(ECM_REQUEST *er, uint32_t timeout) {
735 (void)er; // Prevent warning about unused er, when WITH_LB is disabled
736#ifdef WITH_LB
737 if (cfg.lb_auto_timeout)
738 return lb_auto_timeout(er, timeout);
739#endif
740 return timeout;
741}
742
743
744static void * check_thread(void) {
745 int32_t time_to_check, next_check, ecmc_next, msec_wait = 3000;
746 struct timeb t_now, tbc, ecmc_time;
747 ECM_REQUEST *er = NULL;
748 time_t ecm_timeout;
749 time_t ecm_mintimeout;
750 struct timespec ts;
751 struct s_client *cl = create_client(first_client->ip);
752 cl->typ = 's';
753#ifdef WEBIF
754 cl->wihidden = 1;
755#endif
756 cl->thread = pthread_self();
757
758 timecheck_client = cl;
759
760#ifdef CS_ANTICASC
761 int32_t ac_next;
762 struct timeb ac_time;
763 cs_ftime(&ac_time);
764 add_ms_to_timeb(&ac_time, cfg.ac_stime*60*1000);
765#endif
766
767 cs_ftime(&ecmc_time);
768 add_ms_to_timeb(&ecmc_time, 1000);
769
770 while(1) {
771 ts.tv_sec = msec_wait/1000;
772 ts.tv_nsec = (msec_wait % 1000) * 1000000L;
773 pthread_mutex_lock(&cl->thread_lock);
774 cl->thread_active = 2;
775 pthread_mutex_unlock(&cl->thread_lock);
776 nanosleep(&ts, NULL);
777 pthread_mutex_lock(&cl->thread_lock);
778 cl->thread_active = 1;
779 pthread_mutex_unlock(&cl->thread_lock);
780
781 next_check = 0;
782#ifdef CS_ANTICASC
783 ac_next = 0;
784#endif
785 ecmc_next = 0;
786 msec_wait = 0;
787
788 cs_ftime(&t_now);
789 cs_readlock(&ecmcache_lock);
790
791 for (er = ecmcwcache; er; er = er->next) {
792 if (er->rc < E_99 || !er->ecmlen || !er->matching_rdr) //ignore CACHEEX pending ECMs
793 continue;
794
795 tbc = er->tps;
796#if defined CS_CACHEEX && defined CW_CYCLE_CHECK
797 time_to_check = add_ms_to_timeb(&tbc, (er->stage < 2) ? er->cacheex_wait_time:((er->stage < 4) ? auto_timeout(er, cfg.ftimeout) : auto_timeout(er, cfg.ctimeout)));
798#else
799 time_to_check = add_ms_to_timeb(&tbc, ((er->stage < 4) ? auto_timeout(er, cfg.ftimeout) : auto_timeout(er, cfg.ctimeout)));
800#endif
801 if (comp_timeb(&t_now, &tbc) >= 0) {
802 if (er->stage < 4) {
803#if defined CS_CACHEEX && defined CW_CYCLE_CHECK
804 if (er->stage < 2 && er->cacheex_wait_time)
805 debug_ecm(D_TRACE, "request for %s %s", username(er->client), buf);
806 else
807#endif
808 debug_ecm(D_TRACE, "fallback for %s %s", username(er->client), buf);
809
810 if (er->rc >= E_UNHANDLED) //do not request rc=99
811 request_cw_from_readers(er);
812
813 tbc = er->tps;
814 time_to_check = add_ms_to_timeb(&tbc, auto_timeout(er, cfg.ctimeout));
815 } else {
816 if (er->client) {
817 er->selected_reader = NULL;
818 debug_ecm(D_TRACE, "timeout for %s %s", username(er->client), buf);
819 write_ecm_answer(NULL, er, E_TIMEOUT, 0, NULL, NULL);
820 }
821#ifdef WITH_LB
822 if (!er->ecmcacheptr) { //do not add stat for cache entries:
823 //because of lb, send E_TIMEOUT for all readers:
824 struct s_ecm_answer *ea_list;
825
826 for(ea_list = er->matching_rdr; ea_list; ea_list = ea_list->next) {
827 if ((ea_list->status & (REQUEST_SENT|REQUEST_ANSWERED)) == REQUEST_SENT) //Request send, but no answer!
828 send_reader_stat(ea_list->reader, er, NULL, E_TIMEOUT);
829 }
830 }
831#endif
832
833 time_to_check = 0;
834 }
835 }
836 if (!next_check || (time_to_check > 0 && time_to_check < next_check))
837 next_check = time_to_check;
838 }
839 cs_readunlock(&ecmcache_lock);
840
841#ifdef CS_ANTICASC
842 if ((ac_next = comp_timeb(&ac_time, &t_now)) <= 10) {
843 if (cfg.ac_enabled)
844 ac_do_stat();
845 cs_ftime(&ac_time);
846 ac_next = add_ms_to_timeb(&ac_time, cfg.ac_stime*60*1000);
847 }
848#endif
849
850 if ((ecmc_next = comp_timeb(&ecmc_time, &t_now)) <= 10) {
851 ecm_timeout = t_now.time-cfg.max_cache_time;
852 ecm_mintimeout = t_now.time-(cfg.ctimeout/1000+2);
853 uint32_t count = 0;
854
855 struct ecm_request_t *ecm, *ecmt=NULL, *prv;
856 cs_readlock(&ecmcache_lock);
857 for (ecm = ecmcwcache, prv = NULL; ecm; prv = ecm, ecm = ecm->next, count++) {
858 if (ecm->tps.time < ecm_timeout || (ecm->tps.time<ecm_mintimeout && count>cfg.max_cache_count)) {
859 cs_readunlock(&ecmcache_lock);
860 cs_writelock(&ecmcache_lock);
861 ecmt = ecm;
862 if (prv)
863 prv->next = NULL;
864 else
865 ecmcwcache = NULL;
866 cs_writeunlock(&ecmcache_lock);
867 break;
868 }
869 }
870 if (!ecmt)
871 cs_readunlock(&ecmcache_lock);
872 ecmcwcache_size = count;
873
874 while (ecmt) {
875 ecm = ecmt->next;
876 free_ecm(ecmt);
877 ecmt = ecm;
878 }
879
880 cs_ftime(&ecmc_time);
881 ecmc_next = add_ms_to_timeb(&ecmc_time, 1000);
882 }
883
884 msec_wait = next_check;
885
886#ifdef CS_ANTICASC
887 if (!msec_wait || (ac_next > 0 && ac_next < msec_wait))
888 msec_wait = ac_next;
889#endif
890
891 if (!msec_wait || (ecmc_next > 0 && ecmc_next < msec_wait))
892 msec_wait = ecmc_next;
893
894 if (!msec_wait)
895 msec_wait = 3000;
896 cleanupcwcycle();
897 cleanup_hitcache();
898 }
899 add_garbage(cl);
900 timecheck_client = NULL;
901 return NULL;
902}
903
904static uint32_t resize_pfd_cllist(struct pollfd **pfd, struct s_client ***cl_list, uint32_t old_size, uint32_t new_size) {
905 if (old_size != new_size) {
906 struct pollfd *pfd_new;
907 if (!cs_malloc(&pfd_new, new_size * sizeof(struct pollfd))) {
908 return old_size;
909 }
910 struct s_client **cl_list_new;
911 if (!cs_malloc(&cl_list_new, new_size * sizeof(cl_list))) {
912 free(pfd_new);
913 return old_size;
914 }
915 if (old_size > 0) {
916 memcpy(pfd_new, *pfd, old_size*sizeof(struct pollfd));
917 memcpy(cl_list_new, *cl_list, old_size*sizeof(cl_list));
918 free(*pfd);
919 free(*cl_list);
920 }
921 *pfd = pfd_new;
922 *cl_list = cl_list_new;
923 }
924 return new_size;
925}
926
927static uint32_t chk_resize_cllist(struct pollfd **pfd, struct s_client ***cl_list, uint32_t cur_size, uint32_t chk_size) {
928 chk_size++;
929 if (chk_size > cur_size) {
930 uint32_t new_size = ((chk_size % 100)+1) * 100; //increase 100 step
931 cur_size = resize_pfd_cllist(pfd, cl_list, cur_size, new_size);
932 }
933 return cur_size;
934}
935
936static void process_clients(void) {
937 int32_t i, k, j, rc, pfdcount = 0;
938 struct s_client *cl;
939 struct s_reader *rdr;
940 struct pollfd *pfd;
941 struct s_client **cl_list;
942 uint32_t cl_size = 0;
943
944 char buf[10];
945
946 if (pipe(thread_pipe) == -1) {
947 printf("cannot create pipe, errno=%d\n", errno);
948 exit(1);
949 }
950
951 cl_size = chk_resize_cllist(&pfd, &cl_list, 0, 100);
952
953 pfd[pfdcount].fd = thread_pipe[0];
954 pfd[pfdcount].events = POLLIN | POLLPRI | POLLHUP;
955 cl_list[pfdcount] = NULL;
956
957 while (!exit_oscam) {
958 pfdcount = 1;
959
960 //connected tcp clients
961 for (cl=first_client->next; cl; cl=cl->next) {
962 if (cl->init_done && !cl->kill && cl->pfd && cl->typ=='c' && !cl->is_udp) {
963 if (cl->pfd && !cl->thread_active) {
964 cl_size = chk_resize_cllist(&pfd, &cl_list, cl_size, pfdcount);
965 cl_list[pfdcount] = cl;
966 pfd[pfdcount].fd = cl->pfd;
967 pfd[pfdcount++].events = POLLIN | POLLPRI | POLLHUP;
968 }
969 }
970 //reader:
971 //TCP:
972 // - TCP socket must be connected
973 // - no active init thread
974 //UDP:
975 // - connection status ignored
976 // - no active init thread
977 rdr = cl->reader;
978 if (rdr && cl->typ=='p' && cl->init_done) {
979 if (cl->pfd && !cl->thread_active && ((rdr->tcp_connected && rdr->ph.type==MOD_CONN_TCP)||(rdr->ph.type==MOD_CONN_UDP))) {
980 cl_size = chk_resize_cllist(&pfd, &cl_list, cl_size, pfdcount);
981 cl_list[pfdcount] = cl;
982 pfd[pfdcount].fd = cl->pfd;
983 pfd[pfdcount++].events = POLLIN | POLLPRI | POLLHUP;
984 }
985 }
986 }
987
988 //server (new tcp connections or udp messages)
989 for (k = 0; k < CS_MAX_MOD; k++) {
990 struct s_module *module = &modules[k];
991 if ((module->type & MOD_CONN_NET) && module->ptab) {
992 for (j = 0; j < module->ptab->nports; j++) {
993 if (module->ptab->ports[j].fd) {
994 cl_size = chk_resize_cllist(&pfd, &cl_list, cl_size, pfdcount);
995 cl_list[pfdcount] = NULL;
996 pfd[pfdcount].fd = module->ptab->ports[j].fd;
997 pfd[pfdcount++].events = POLLIN | POLLPRI | POLLHUP;
998 }
999 }
1000 }
1001 }
1002
1003 if (pfdcount >= 1024)
1004 cs_log("WARNING: too many users!");
1005
1006 rc = poll(pfd, pfdcount, 5000);
1007
1008 if (rc<1)
1009 continue;
1010
1011 for (i=0; i<pfdcount; i++) {
1012 //clients
1013 cl = cl_list[i];
1014 if (cl && !is_valid_client(cl))
1015 continue;
1016
1017 if (pfd[i].fd == thread_pipe[0] && (pfd[i].revents & (POLLIN | POLLPRI))) {
1018 // a thread ended and cl->pfd should be added to pollfd list again (thread_active==0)
1019 if(read(thread_pipe[0], buf, sizeof(buf)) == -1){
1020 cs_debug_mask(D_TRACE, "Reading from pipe failed (errno=%d %s)", errno, strerror(errno));
1021 }
1022 continue;
1023 }
1024
1025 //clients
1026 // message on an open tcp connection
1027 if (cl && cl->init_done && cl->pfd && (cl->typ == 'c' || cl->typ == 'm')) {
1028 if (pfd[i].fd == cl->pfd && (pfd[i].revents & (POLLHUP | POLLNVAL))) {
1029 //client disconnects
1030 kill_thread(cl);
1031 continue;
1032 }
1033 if (pfd[i].fd == cl->pfd && (pfd[i].revents & (POLLIN | POLLPRI))) {
1034 add_job(cl, ACTION_CLIENT_TCP, NULL, 0);
1035 }
1036 }
1037
1038
1039 //reader
1040 // either an ecm answer, a keepalive or connection closed from a proxy
1041 // physical reader ('r') should never send data without request
1042 rdr = NULL;
1043 struct s_client *cl2 = NULL;
1044 if (cl && cl->typ == 'p'){
1045 rdr = cl->reader;
1046 if(rdr)
1047 cl2 = rdr->client;
1048 }
1049
1050 if (rdr && cl2 && cl2->init_done) {
1051 if (cl2->pfd && pfd[i].fd == cl2->pfd && (pfd[i].revents & (POLLHUP | POLLNVAL))) {
1052 //connection to remote proxy was closed
1053 //oscam should check for rdr->tcp_connected and reconnect on next ecm request sent to the proxy
1054 network_tcp_connection_close(rdr, "closed");
1055 rdr_debug_mask(rdr, D_READER, "connection closed");
1056 }
1057 if (cl2->pfd && pfd[i].fd == cl2->pfd && (pfd[i].revents & (POLLIN | POLLPRI))) {
1058 add_job(cl2, ACTION_READER_REMOTE, NULL, 0);
1059 }
1060 }
1061
1062
1063 //server sockets
1064 // new connection on a tcp listen socket or new message on udp listen socket
1065 if (!cl && (pfd[i].revents & (POLLIN | POLLPRI))) {
1066 for (k = 0; k < CS_MAX_MOD; k++) {
1067 struct s_module *module = &modules[k];
1068 if ((module->type & MOD_CONN_NET) && module->ptab) {
1069 for (j = 0; j < module->ptab->nports; j++) {
1070 if (module->ptab->ports[j].fd && module->ptab->ports[j].fd == pfd[i].fd) {
1071 accept_connection(module, k, j);
1072 }
1073 }
1074 }
1075 }
1076 }
1077 }
1078 first_client->last=time((time_t *)0);
1079 }
1080 free(pfd);
1081 free(cl_list);
1082 return;
1083}
1084
1085static void * reader_check(void) {
1086 struct s_client *cl;
1087 struct s_reader *rdr;
1088 set_thread_name(__func__);
1089 while (1) {
1090 for (cl=first_client->next; cl ; cl=cl->next) {
1091 if (!cl->thread_active)
1092 client_check_status(cl);
1093 }
1094 cs_readlock(&readerlist_lock);
1095 for (rdr=first_active_reader; rdr; rdr=rdr->next) {
1096 if (rdr->enable) {
1097 cl = rdr->client;
1098 if (!cl || cl->kill)
1099 restart_cardreader(rdr, 0);
1100 else if (!cl->thread_active)
1101 client_check_status(cl);
1102 }
1103 }
1104 cs_readunlock(&readerlist_lock);
1105 cs_sleepms(1000);
1106 }
1107 return NULL;
1108}
1109
1110#ifdef WEBIF
1111pid_t pid;
1112
1113
1114static void fwd_sig(int32_t sig)
1115{
1116 kill(pid, sig);
1117}
1118
1119static void restart_daemon(void)
1120{
1121 while (1) {
1122
1123 //start client process:
1124 pid = fork();
1125 if (!pid)
1126 return; //client process=oscam process
1127 if (pid < 0)
1128 exit(1);
1129
1130 //set signal handler for the restart daemon:
1131 set_signal_handler(SIGINT, 3, fwd_sig);
1132#if defined(__APPLE__)
1133 set_signal_handler(SIGEMT, 3, fwd_sig);
1134#endif
1135 set_signal_handler(SIGTERM, 3, fwd_sig);
1136 set_signal_handler(SIGQUIT, 0, fwd_sig);
1137 set_signal_handler(SIGHUP , 0, fwd_sig);
1138 set_signal_handler(SIGUSR1, 0, fwd_sig);
1139 set_signal_handler(SIGUSR2, 0, fwd_sig);
1140 set_signal_handler(SIGALRM , 0, fwd_sig);
1141 set_signal_handler(SIGWINCH, 1, SIG_IGN);
1142 set_signal_handler(SIGPIPE , 0, SIG_IGN);
1143 set_signal_handler(OSCAM_SIGNAL_WAKEUP, 0, SIG_IGN);
1144
1145 //restart control process:
1146 int32_t res=0;
1147 int32_t status=0;
1148 do {
1149 res = waitpid(pid, &status, 0);
1150 if (res==-1) {
1151 if (errno!=EINTR)
1152 exit(1);
1153 }
1154 } while (res!=pid);
1155
1156 if (cs_restart_mode==2 && WIFSIGNALED(status) && WTERMSIG(status)==SIGSEGV)
1157 status=99; //restart on segfault!
1158 else
1159 status = WEXITSTATUS(status);
1160
1161 //status=99 restart oscam, all other->terminate
1162 if (status!=99) {
1163 exit(status);
1164 }
1165 }
1166}
1167
1168void cs_restart_oscam(void) {
1169 exit_oscam=99;
1170 cs_log("restart oscam requested");
1171}
1172
1173int32_t cs_get_restartmode(void) {
1174 return cs_restart_mode;
1175}
1176#endif
1177
1178void cs_exit_oscam(void) {
1179 exit_oscam = 1;
1180 cs_log("exit oscam requested");
1181}
1182
1183static void pidfile_create(char *pidfile) {
1184 FILE *f = fopen(pidfile, "w");
1185 if (f) {
1186 pid_t my_pid = getpid();
1187 cs_log("creating pidfile %s with pid %d", pidfile, my_pid);
1188 fprintf(f, "%d\n", my_pid);
1189 fclose(f);
1190 }
1191}
1192
1193int32_t main (int32_t argc, char *argv[])
1194{
1195 int32_t i, j;
1196 prog_name = argv[0];
1197 if (pthread_key_create(&getclient, NULL)) {
1198 fprintf(stderr, "Could not create getclient, exiting...");
1199 exit(1);
1200 }
1201
1202 void (*mod_def[])(struct s_module *)=
1203 {
1204#ifdef MODULE_MONITOR
1205 module_monitor,
1206#endif
1207#ifdef MODULE_CAMD33
1208 module_camd33,
1209#endif
1210#ifdef MODULE_CAMD35
1211 module_camd35,
1212#endif
1213#ifdef MODULE_CAMD35_TCP
1214 module_camd35_tcp,
1215#endif
1216#ifdef MODULE_NEWCAMD
1217 module_newcamd,
1218#endif
1219#ifdef MODULE_CCCAM
1220 module_cccam,
1221#endif
1222#ifdef MODULE_PANDORA
1223 module_pandora,
1224#endif
1225#ifdef MODULE_GHTTP
1226 module_ghttp,
1227#endif
1228#ifdef CS_CACHEEX
1229 module_csp,
1230#endif
1231#ifdef MODULE_GBOX
1232 module_gbox,
1233#endif
1234#ifdef MODULE_CONSTCW
1235 module_constcw,
1236#endif
1237#ifdef MODULE_RADEGAST
1238 module_radegast,
1239#endif
1240#ifdef MODULE_SERIAL
1241 module_serial,
1242#endif
1243#ifdef HAVE_DVBAPI
1244 module_dvbapi,
1245#endif
1246 0
1247 };
1248
1249 void (*cardsystem_def[])(struct s_cardsystem *)=
1250 {
1251#ifdef READER_NAGRA
1252 reader_nagra,
1253#endif
1254#ifdef READER_IRDETO
1255 reader_irdeto,
1256#endif
1257#ifdef READER_CONAX
1258 reader_conax,
1259#endif
1260#ifdef READER_CRYPTOWORKS
1261 reader_cryptoworks,
1262#endif
1263#ifdef READER_SECA
1264 reader_seca,
1265#endif
1266#ifdef READER_VIACCESS
1267 reader_viaccess,
1268#endif
1269#ifdef READER_VIDEOGUARD
1270 reader_videoguard1,
1271 reader_videoguard2,
1272 reader_videoguard12,
1273#endif
1274#ifdef READER_DRE
1275 reader_dre,
1276#endif
1277#ifdef READER_TONGFANG
1278 reader_tongfang,
1279#endif
1280#ifdef READER_BULCRYPT
1281 reader_bulcrypt,
1282#endif
1283#ifdef READER_GRIFFIN
1284 reader_griffin,
1285#endif
1286#ifdef READER_DGCRYPT
1287 reader_dgcrypt,
1288#endif
1289 0
1290 };
1291
1292 void (*cardreader_def[])(struct s_cardreader *)=
1293 {
1294#ifdef CARDREADER_DB2COM
1295 cardreader_db2com,
1296#endif
1297#if defined(CARDREADER_INTERNAL_AZBOX)
1298 cardreader_internal_azbox,
1299#elif defined(CARDREADER_INTERNAL_COOLAPI)
1300 cardreader_internal_cool,
1301#elif defined(CARDREADER_INTERNAL_SCI)
1302 cardreader_internal_sci,
1303#endif
1304#ifdef CARDREADER_PHOENIX
1305 cardreader_mouse,
1306#endif
1307#ifdef CARDREADER_MP35
1308 cardreader_mp35,
1309#endif
1310#ifdef CARDREADER_PCSC
1311 cardreader_pcsc,
1312#endif
1313#ifdef CARDREADER_SC8IN1
1314 cardreader_sc8in1,
1315#endif
1316#ifdef CARDREADER_SMARGO
1317 cardreader_smargo,
1318#endif
1319#ifdef CARDREADER_SMART
1320 cardreader_smartreader,
1321#endif
1322#ifdef CARDREADER_STAPI
1323 cardreader_stapi,
1324#endif
1325 0
1326 };
1327
1328 parse_cmdline_params(argc, argv);
1329
1330 if (bg && do_daemon(1,0))
1331 {
1332 printf("Error starting in background (errno=%d: %s)", errno, strerror(errno));
1333 cs_exit(1);
1334 }
1335
1336 get_random_bytes_init();
1337
1338#ifdef WEBIF
1339 if (cs_restart_mode)
1340 restart_daemon();
1341#endif
1342
1343 memset(&cfg, 0, sizeof(struct s_config));
1344 cfg.max_pending = max_pending;
1345
1346 if (cs_confdir[strlen(cs_confdir) - 1] != '/') strcat(cs_confdir, "/");
1347 init_signal_pre(); // because log could cause SIGPIPE errors, init a signal handler first
1348 init_first_client();
1349 cs_lock_create(&system_lock, 5, "system_lock");
1350 cs_lock_create(&config_lock, 10, "config_lock");
1351 cs_lock_create(&gethostbyname_lock, 10, "gethostbyname_lock");
1352 cs_lock_create(&clientlist_lock, 5, "clientlist_lock");
1353 cs_lock_create(&readerlist_lock, 5, "readerlist_lock");
1354 cs_lock_create(&fakeuser_lock, 5, "fakeuser_lock");
1355 cs_lock_create(&ecmcache_lock, 5, "ecmcache_lock");
1356 cs_lock_create(&readdir_lock, 5, "readdir_lock");
1357 cs_lock_create(&cwcycle_lock, 5, "cwcycle_lock");
1358 cs_lock_create(&hitcache_lock, 5, "hitcache_lock");
1359 coolapi_open_all();
1360 init_config();
1361 cs_init_log();
1362 if (!oscam_pidfile && cfg.pidfile)
1363 oscam_pidfile = cfg.pidfile;
1364 if (!oscam_pidfile) {
1365 oscam_pidfile = get_tmp_dir_filename(default_pidfile, sizeof(default_pidfile), "oscam.pid");
1366 }
1367 if (oscam_pidfile)
1368 pidfile_create(oscam_pidfile);
1369 cs_init_statistics();
1370 init_check();
1371 init_stat();
1372
1373 // These initializations *MUST* be called after init_config()
1374 // because modules depend on config values.
1375 for (i=0; mod_def[i]; i++)
1376 {
1377 struct s_module *module = &modules[i];
1378 mod_def[i](module);
1379 }
1380 for (i=0; cardsystem_def[i]; i++)
1381 {
1382 memset(&cardsystems[i], 0, sizeof(struct s_cardsystem));
1383 cardsystem_def[i](&cardsystems[i]);
1384 }
1385 for (i=0; cardreader_def[i]; i++)
1386 {
1387 memset(&cardreaders[i], 0, sizeof(struct s_cardreader));
1388 cardreader_def[i](&cardreaders[i]);
1389 }
1390
1391 init_sidtab();
1392 init_readerdb();
1393 cfg.account = init_userdb();
1394 init_signal();
1395 init_srvid();
1396 init_tierid();
1397 init_provid();
1398
1399 start_garbage_collector(gbdb);
1400
1401 cacheex_init();
1402
1403 init_len4caid();
1404 init_irdeto_guess_tab();
1405
1406 write_versionfile(false);
1407
1408 led_init();
1409 led_status_default();
1410
1411 azbox_init();
1412
1413 mca_init();
1414
1415 global_whitelist_read();
1416 cacheex_load_config_file();
1417
1418 for (i = 0; i < CS_MAX_MOD; i++) {
1419 struct s_module *module = &modules[i];
1420 if ((module->type & MOD_CONN_NET) && module->ptab) {
1421 for (j = 0; j < module->ptab->nports; j++) {
1422 start_listener(module, &module->ptab->ports[j]);
1423 }
1424 }
1425 }
1426
1427 //set time for server to now to avoid 0 in monitor/webif
1428 first_client->last=time((time_t *)0);
1429
1430 webif_init();
1431
1432 start_thread((void *) &reader_check, "reader check");
1433 start_thread((void *) &check_thread, "check");
1434
1435 lcd_thread_start();
1436
1437 do_report_emm_support();
1438
1439 init_cardreader();
1440
1441 cs_waitforcardinit();
1442
1443 led_status_starting();
1444
1445 ac_init();
1446
1447 for (i = 0; i < CS_MAX_MOD; i++) {
1448 struct s_module *module = &modules[i];
1449 if ((module->type & MOD_CONN_SERIAL) && module->s_handler)
1450 module->s_handler(NULL, NULL, i);
1451 }
1452
1453 // main loop function
1454 process_clients();
1455
1456 // Cleanup
1457 azbox_close();
1458 coolapi_close_all();
1459 mca_close();
1460
1461 led_status_stopping();
1462 led_stop();
1463 lcd_thread_stop();
1464
1465 remove_versionfile();
1466
1467 stat_finish();
1468 cccam_done_share();
1469
1470 kill_all_clients();
1471 kill_all_readers();
1472
1473 if (oscam_pidfile)
1474 unlink(oscam_pidfile);
1475
1476 webif_tpls_free();
1477 init_free_userdb(cfg.account);
1478 cfg.account = NULL;
1479 init_free_sidtab();
1480 config_free();
1481
1482 cs_log("cardserver down");
1483 cs_close_log();
1484
1485 stop_garbage_collector();
1486
1487 // This prevents the compiler from removing config_mak from the final binary
1488 syslog_ident = config_mak;
1489
1490 return exit_oscam;
1491}
Note: See TracBrowser for help on using the repository browser.