source: trunk/oscam.c@ 8467

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

ird-guess: Move everything related to irdeto guessing in the module.

  • Property svn:eol-style set to LF
File size: 41.6 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#ifdef CS_CACHEEX
797 time_to_check = add_ms_to_timeb(&tbc, (er->stage < 2 && er->cacheex_wait_time) ? 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#ifdef CS_CACHEEX
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)) {
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)) {
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)) {
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 free_readerdb();
1481 free_irdeto_guess_tab();
1482 config_free();
1483
1484 cs_log("cardserver down");
1485 log_free();
1486
1487 stop_garbage_collector();
1488
1489 // This prevents the compiler from removing config_mak from the final binary
1490 syslog_ident = config_mak;
1491
1492 return exit_oscam;
1493}
Note: See TracBrowser for help on using the repository browser.