source: trunk/oscam.c@ 8395

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

config: Do not write info config_mak variable.

For some reason writing into config_mak crashes OSCam when restart
from WebIf is requested.

Reported by today in streamboard forum.

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