1 #define MODULE_LOG_PREFIX "main"
6 #include "csctapi/cardreaders.h"
10 #include "extapi/coolapi.h"
11 #include "module-anticasc.h"
12 #include "module-cacheex.h"
13 #include "module-cccam.h"
14 #include "module-dvbapi.h"
15 #include "module-dvbapi-azbox.h"
16 #include "module-dvbapi-mca.h"
17 #include "module-dvbapi-chancache.h"
18 #include "module-gbox-sms.h"
19 #include "module-lcd.h"
20 #include "module-led.h"
21 #include "module-stat.h"
22 #include "module-webif.h"
23 #include "module-webif-tpl.h"
24 #include "module-cw-cycle-check.h"
25 #include "module-streamrelay.h"
26 #include "oscam-chk.h"
27 #include "oscam-cache.h"
28 #include "oscam-client.h"
29 #include "oscam-config.h"
30 #include "oscam-ecm.h"
31 #include "oscam-emm.h"
32 #include "oscam-emm-cache.h"
33 #include "oscam-files.h"
34 #include "oscam-garbage.h"
35 #include "oscam-lock.h"
36 #include "oscam-net.h"
37 #include "oscam-reader.h"
38 #include "oscam-string.h"
39 #include "oscam-time.h"
40 #include "oscam-work.h"
41 #include "reader-common.h"
42 #include "module-gbox.h"
45 #include <openssl/crypto.h>
46 #include <openssl/ssl.h>
47 #include <openssl/err.h>
49 static void ssl_init(void)
51 SSL_load_error_strings();
52 ERR_load_BIO_strings();
53 ERR_load_SSL_strings();
57 static void ssl_done(void)
59 #if OPENSSL_VERSION_NUMBER < 0x1010005fL
64 CRYPTO_cleanup_all_ex_data();
68 static void ssl_init(void) { }
69 static void ssl_done(void) { }
72 extern char *config_mak
;
74 /*****************************************************************************
76 *****************************************************************************/
77 const char *syslog_ident
= "oscam";
78 static char *oscam_pidfile
;
79 static char default_pidfile
[64];
81 int32_t exit_oscam
= 0;
82 static struct s_module modules
[CS_MAX_MOD
];
84 struct s_client
*first_client
= NULL
; // Pointer to clients list, first client is master
85 struct s_reader
*first_active_reader
= NULL
; // list of active readers (enable=1 deleted = 0)
86 LLIST
*configured_readers
= NULL
; // list of all (configured) readers
89 uint16_t cs_dblevel
= 0; // Debug Level
90 int32_t thread_pipe
[2] = {0, 0};
91 static int8_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
93 uint8_t cs_http_use_utf8
= 1;
95 uint8_t cs_http_use_utf8
= 0;
97 static int8_t cs_capture_SEGV
;
98 static int8_t cs_dump_stack
;
99 static uint16_t cs_waittime
= 60;
101 CS_MUTEX_LOCK system_lock
;
102 CS_MUTEX_LOCK config_lock
;
103 CS_MUTEX_LOCK gethostbyname_lock
;
104 CS_MUTEX_LOCK clientlist_lock
;
105 CS_MUTEX_LOCK readerlist_lock
;
106 CS_MUTEX_LOCK fakeuser_lock
;
107 CS_MUTEX_LOCK readdir_lock
;
108 CS_MUTEX_LOCK cwcycle_lock
;
109 pthread_key_t getclient
;
112 static int32_t max_pending
= 32;
115 CS_MUTEX_LOCK ecmcache_lock
;
116 struct ecm_request_t
*ecmcwcache
= NULL
;
117 uint32_t ecmcwcache_size
= 0;
119 // pushout deleted list
120 CS_MUTEX_LOCK ecm_pushed_deleted_lock
;
121 struct ecm_request_t
*ecm_pushed_deleted
= NULL
;
125 int log_remove_sensitive
= 1;
127 static char *prog_name
;
128 static char *stb_boxtype
;
129 static char *stb_boxname
;
131 static int32_t oscam_stacksize
= 0;
133 /*****************************************************************************
135 *****************************************************************************/
136 /* Prints usage information and information about the built-in modules. */
137 static void show_usage(void)
141 " / _ \\/ ___| / __|__ _ _ __ ___\n"
142 "| | | \\___ \\| | / _` | '_ ` _ \\\n"
143 "| |_| |___) | |_| (_| | | | | | |\n"
144 " \\___/|____/ \\___\\__,_|_| |_| |_|\n\n");
145 printf("OSCam Cardserver v%s, build r%s (%s)\n", CS_VERSION
, CS_SVN_VERSION
, CS_TARGET
);
146 printf("Copyright (C) 2009-2024 OSCam developers.\n");
147 printf("This program is distributed under GPLv3.\n");
148 printf("OSCam is based on Streamboard mp-cardserver v0.9d written by dukat\n");
149 printf("Visit https://board.streamboard.tv/ for more details.\n\n");
151 printf(" ConfigDir : %s\n", CS_CONFDIR
);
153 printf(" Usage: oscam [parameters]\n");
154 printf("\n Directories:\n");
155 printf(" -c, --config-dir <dir> | Read configuration files from <dir>.\n");
156 printf(" . Default: %s\n", CS_CONFDIR
);
157 printf(" -t, --temp-dir <dir> | Set temporary directory to <dir>.\n");
158 #if defined(__CYGWIN__)
159 printf(" . Default: (OS-TMP)\n");
161 printf(" . Default: /tmp/.oscam\n");
163 printf("\n Startup:\n");
164 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
165 printf(" -f, --foreground | Start in the foreground mode.\n");
167 printf(" -b, --daemon | Start in the background as daemon.\n");
169 printf(" -B, --pidfile <pidfile> | Create pidfile when starting.\n");
170 if(config_enabled(WEBIF
))
172 printf(" -r, --restart <level> | Set restart level:\n");
173 printf(" . 0 - Restart disabled (exit on restart request).\n");
174 printf(" . 1 - WebIf restart is active (default).\n");
175 printf(" . 2 - Like 1, but also restart on segfaults.\n");
177 printf(" -w, --wait <secs> | Set how much seconds to wait at startup for the\n");
178 printf(" . system clock to be set correctly. Default: 60\n");
179 printf("\n Logging:\n");
180 printf(" -I, --syslog-ident <ident> | Set syslog ident. Default: oscam\n");
181 printf(" -S, --show-sensitive | Do not filter sensitive info (card serials, boxids)\n");
182 printf(" . from the logs.\n");
183 printf(" -d, --debug <level> | Set debug level mask used for logging:\n");
184 printf(" . 0 - No extra debugging (default).\n");
185 printf(" . 1 - Detailed error messages.\n");
186 printf(" . 2 - ATR parsing info, ECM, EMM and CW dumps.\n");
187 printf(" . 4 - Traffic from/to the reader.\n");
188 printf(" . 8 - Traffic from/to the clients.\n");
189 printf(" . 16 - Traffic to the reader-device on IFD layer.\n");
190 printf(" . 32 - Traffic to the reader-device on I/O layer.\n");
191 printf(" . 64 - EMM logging.\n");
192 printf(" . 128 - DVBAPI logging.\n");
193 printf(" . 256 - Loadbalancer logging.\n");
194 printf(" . 512 - CACHEEX logging.\n");
195 printf(" . 1024 - Client ECM logging.\n");
196 printf(" . 2048 - CSP logging.\n");
197 printf(" . 4096 - CWC logging.\n");
198 #ifdef CS_CACHEEX_AIO
199 printf(" . 8192 - CW Cache logging.\n");
201 printf(" . 65535 - Debug all.\n");
202 printf("\n Settings:\n");
203 printf(" -p, --pending-ecm <num> | Set the maximum number of pending ECM packets.\n");
204 printf(" . Default: 32 Max: 4096\n");
205 if(config_enabled(WEBIF
))
207 printf(" -u, --utf8 | Enable WebIf support for UTF-8 charset.\n");
209 printf("\n Debug parameters:\n");
210 printf(" -a, --crash-dump | Write oscam.crash file on segfault. This option\n");
211 printf(" . needs GDB to be installed and OSCam executable to\n");
212 printf(" . contain the debug information (run oscam-XXXX.debug)\n");
213 printf(" -s, --capture-segfaults | Capture segmentation faults.\n");
214 printf(" -g, --gcollect <mode> | Garbage collector debug mode:\n");
215 printf(" . 1 - Immediate free.\n");
216 printf(" . 2 - Check for double frees.\n");
217 printf("\n Information:\n");
218 printf(" -h, --help | Show command line help text.\n");
219 printf(" -V, --build-info | Show OSCam binary configuration and version.\n");
222 /* Keep the options sorted */
223 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
224 static const char short_options
[] = "aB:fc:d:g:hI:p:r:Sst:uVw:";
226 static const char short_options
[] = "aB:bc:d:g:hI:p:r:Sst:uVw:";
229 /* Keep the options sorted by short option */
230 static const struct option long_options
[] =
232 { "crash-dump", no_argument
, NULL
, 'a' },
233 { "pidfile", required_argument
, NULL
, 'B' },
234 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
235 { "foreground", no_argument
, NULL
, 'f' },
237 { "daemon", no_argument
, NULL
, 'b' },
239 { "config-dir", required_argument
, NULL
, 'c' },
240 { "debug", required_argument
, NULL
, 'd' },
241 { "gcollect", required_argument
, NULL
, 'g' },
242 { "help", no_argument
, NULL
, 'h' },
243 { "syslog-ident", required_argument
, NULL
, 'I' },
244 { "pending-ecm", required_argument
, NULL
, 'p' },
245 { "restart", required_argument
, NULL
, 'r' },
246 { "show-sensitive", no_argument
, NULL
, 'S' },
247 { "capture-segfaults", no_argument
, NULL
, 's' },
248 { "temp-dir", required_argument
, NULL
, 't' },
249 { "utf8", no_argument
, NULL
, 'u' },
250 { "build-info", no_argument
, NULL
, 'V' },
251 { "wait", required_argument
, NULL
, 'w' },
255 static void set_default_dirs_first(void)
257 snprintf(cs_confdir
, sizeof(cs_confdir
), "%s", CS_CONFDIR
);
258 memset(cs_tmpdir
, 0, sizeof(cs_tmpdir
)); // will get further procesed trought oscam_files.c !!
261 static void write_versionfile(bool use_stdout
);
263 static void parse_cmdline_params(int argc
, char **argv
)
265 #if defined(WITH_STAPI) || defined(WITH_STAPI5)
270 while((i
= getopt_long(argc
, argv
, short_options
, long_options
, NULL
)) != EOF
)
273 { fprintf(stderr
, "ERROR: Unknown command line parameter: %s\n", argv
[optind
- 1]); }
276 case 'a': // --crash-dump
279 case 'B': // --pidfile
280 oscam_pidfile
= optarg
;
282 case 'f': // --foreground
285 case 'b': // --daemon
288 case 'c': // --config-dir
289 cs_strncpy(cs_confdir
, optarg
, sizeof(cs_confdir
));
292 cs_dblevel
= atoi(optarg
);
294 case 'g': // --gcollect
301 case 'I': // --syslog-ident
302 syslog_ident
= optarg
;
304 case 'p': // --pending-ecm
305 max_pending
= atoi(optarg
) <= 0 ? 32 : MIN(atoi(optarg
), 4096);
307 case 'r': // --restart
308 if(config_enabled(WEBIF
))
310 cs_restart_mode
= atoi(optarg
);
313 case 'S': // --show-sensitive
314 log_remove_sensitive
= !log_remove_sensitive
;
316 case 's': // --capture-segfaults
319 case 't': // --temp-dir
321 mkdir(optarg
, S_IRWXU
);
322 int j
= open(optarg
, O_RDONLY
);
326 cs_strncpy(cs_tmpdir
, optarg
, sizeof(cs_tmpdir
));
330 printf("WARNING: Temp dir does not exist. Using default value.\n");
335 if(config_enabled(WEBIF
))
337 cs_http_use_utf8
= 1;
338 printf("WARNING: Web interface UTF-8 mode enabled. Carefully read documentation as bugs may arise.\n");
341 case 'V': // --build-info
342 write_versionfile(true);
346 cs_waittime
= strtoul(optarg
, NULL
, 10);
352 #define write_conf(CONFIG_VAR, text) \
353 fprintf(fp, "%-40s %s\n", text ":", config_enabled(CONFIG_VAR) ? "yes" : "no")
355 #define write_readerconf(CONFIG_VAR, text) \
356 fprintf(fp, "%-40s %s\n", text ":", config_enabled(CONFIG_VAR) ? "yes" : "no - no EMM support!")
358 #define write_cardreaderconf(CONFIG_VAR, text) \
359 fprintf(fp, "%s%-29s %s\n", "cardreader_", text ":", config_enabled(CONFIG_VAR) ? "yes" : "no")
361 static void write_versionfile(bool use_stdout
)
366 char targetfile
[256];
367 fp
= fopen(get_tmp_dir_filename(targetfile
, sizeof(targetfile
), "oscam.version"), "w");
370 cs_log("Cannot open %s (errno=%d %s)", targetfile
, errno
, strerror(errno
));
374 time_t walltime
= cs_time();
375 localtime_r(&walltime
, &st
);
376 fprintf(fp
, "Unix starttime: %ld\n", walltime
);
377 fprintf(fp
, "Starttime: %02d.%02d.%04d %02d:%02d:%02d\n",
378 st
.tm_mday
, st
.tm_mon
+ 1, st
.tm_year
+ 1900,
379 st
.tm_hour
, st
.tm_min
, st
.tm_sec
);
382 fprintf(fp
, "Version: oscam-%s-r%s\n", CS_VERSION
, CS_SVN_VERSION
);
383 fprintf(fp
, "Compiler: %s\n", CS_TARGET
);
384 fprintf(fp
, "Box type: %s (%s)\n", boxtype_get(), boxname_get());
385 fprintf(fp
, "PID: %d\n", getppid());
386 fprintf(fp
, "TempDir: %s\n", cs_tmpdir
);
388 if(cfg
.gbox_tmp_dir
== NULL
)
390 fprintf(fp
, "GBox tmp_dir: not defined using: %s\n", cs_tmpdir
);
394 fprintf(fp
, "GBox tmp_dir: %s\n", cfg
.gbox_tmp_dir
);
398 fprintf(fp
, "ConfigDir: %s\n", cs_confdir
);
401 fprintf(fp
, "WebifPort: %d\n", cfg
.http_port
);
405 write_conf(WEBIF
, "Web interface support");
406 write_conf(WEBIF_LIVELOG
, "LiveLog support");
407 write_conf(WEBIF_JQUERY
, "jQuery support intern");
408 write_conf(TOUCH
, "Touch interface support");
409 write_conf(WITH_SSL
, "SSL support");
410 write_conf(HAVE_DVBAPI
, "DVB API support");
411 if(config_enabled(HAVE_DVBAPI
))
413 if(config_enabled(MODULE_STREAMRELAY
))
415 write_conf(true, "DVB API with Stream Relay support");
417 write_conf(WITH_AZBOX
, "DVB API with AZBOX support");
418 write_conf(WITH_MCA
, "DVB API with MCA support");
419 write_conf(WITH_COOLAPI
, "DVB API with COOLAPI support");
420 write_conf(WITH_COOLAPI2
, "DVB API with COOLAPI2 support");
421 write_conf(WITH_STAPI
, "DVB API with STAPI support");
422 write_conf(WITH_STAPI5
, "DVB API with STAPI5 support");
423 write_conf(WITH_NEUTRINO
, "DVB API with NEUTRINO support");
424 write_conf(READ_SDT_CHARSETS
, "DVB API read-sdt charsets");
426 write_conf(CS_ANTICASC
, "Anti-cascading support");
427 write_conf(WITH_DEBUG
, "Debug mode");
428 write_conf(MODULE_MONITOR
, "Monitor");
429 write_conf(WITH_LB
, "Loadbalancing support");
430 write_conf(CS_CACHEEX
, "Cache exchange support");
431 #ifdef CS_CACHEEX_AIO
432 write_conf(CS_CACHEEX_AIO
, "Cache exchange AIO support");
434 write_conf(CW_CYCLE_CHECK
, "CW Cycle Check support");
435 write_conf(LCDSUPPORT
, "LCD support");
436 write_conf(LEDSUPPORT
, "LED support");
437 switch (cs_getclocktype())
439 case CLOCK_TYPE_UNKNOWN
: write_conf(CLOCKFIX
, "Clockfix with UNKNOWN clock"); break;
440 case CLOCK_TYPE_REALTIME
: write_conf(CLOCKFIX
, "Clockfix with realtime clock"); break;
441 case CLOCK_TYPE_MONOTONIC
: write_conf(CLOCKFIX
, "Clockfix with monotonic clock"); break;
443 write_conf(IPV6SUPPORT
, "IPv6 support");
444 #if defined(__arm__) || defined(__aarch64__)
445 write_conf(WITH_ARM_NEON
, "ARM NEON (SIMD/MPE) support");
449 write_conf(MODULE_CAMD33
, "camd 3.3x");
450 write_conf(MODULE_CAMD35
, "camd 3.5 UDP");
451 write_conf(MODULE_CAMD35_TCP
, "camd 3.5 TCP");
452 write_conf(MODULE_NEWCAMD
, "newcamd");
453 write_conf(MODULE_CCCAM
, "CCcam");
454 write_conf(MODULE_CCCSHARE
, "CCcam share");
455 write_conf(MODULE_GBOX
, "gbox");
456 write_conf(MODULE_RADEGAST
, "radegast");
457 write_conf(MODULE_SCAM
, "scam");
458 write_conf(MODULE_SERIAL
, "serial");
459 write_conf(MODULE_CONSTCW
, "constant CW");
460 write_conf(MODULE_PANDORA
, "Pandora");
461 write_conf(MODULE_GHTTP
, "ghttp");
462 write_conf(MODULE_STREAMRELAY
, "Streamrelay");
465 write_conf(WITH_CARDREADER
, "Reader support");
466 if(config_enabled(WITH_CARDREADER
))
469 write_readerconf(READER_NAGRA
, "Nagra");
470 write_readerconf(READER_NAGRA_MERLIN
, "Nagra Merlin");
471 write_readerconf(READER_IRDETO
, "Irdeto");
472 write_readerconf(READER_CONAX
, "Conax");
473 write_readerconf(READER_CRYPTOWORKS
, "Cryptoworks");
474 write_readerconf(READER_SECA
, "Seca");
475 write_readerconf(READER_VIACCESS
, "Viaccess");
476 write_readerconf(READER_VIDEOGUARD
, "NDS Videoguard");
477 write_readerconf(READER_DRE
, "DRE Crypt");
478 write_readerconf(READER_TONGFANG
, "TONGFANG");
479 write_readerconf(READER_BULCRYPT
, "Bulcrypt");
480 write_readerconf(READER_GRIFFIN
, "Griffin");
481 write_readerconf(READER_DGCRYPT
, "DGCrypt");
483 write_cardreaderconf(CARDREADER_PHOENIX
, "phoenix");
484 write_cardreaderconf(CARDREADER_DRECAS
, "drecas");
485 write_cardreaderconf(CARDREADER_INTERNAL_AZBOX
, "internal_azbox");
486 write_cardreaderconf(CARDREADER_INTERNAL_COOLAPI
, "internal_coolapi");
487 write_cardreaderconf(CARDREADER_INTERNAL_COOLAPI2
, "internal_coolapi2");
488 write_cardreaderconf(CARDREADER_INTERNAL_SCI
, "internal_sci");
489 write_cardreaderconf(CARDREADER_SC8IN1
, "sc8in1");
490 write_cardreaderconf(CARDREADER_MP35
, "mp35");
491 write_cardreaderconf(CARDREADER_SMARGO
, "smargo");
492 write_cardreaderconf(CARDREADER_PCSC
, "pcsc");
493 write_cardreaderconf(CARDREADER_SMART
, "smartreader");
494 write_cardreaderconf(CARDREADER_DB2COM
, "db2com");
495 write_cardreaderconf(CARDREADER_STAPI
, "stapi");
496 write_cardreaderconf(CARDREADER_STAPI5
, "stapi5");
497 write_cardreaderconf(CARDREADER_STINGER
, "stinger");
501 write_readerconf(WITH_CARDREADER
, "Reader Support");
507 #undef write_readerconf
508 #undef write_cardreaderconf
510 static void remove_versionfile(void)
512 char targetfile
[256];
513 unlink(get_tmp_dir_filename(targetfile
, sizeof(targetfile
), "oscam.version"));
516 #define report_emm_support(CONFIG_VAR, text) \
518 if (!config_enabled(CONFIG_VAR)) \
519 cs_log_dbg(D_TRACE, "Binary without %s module - no EMM processing for %s possible!", text, text); \
522 static void do_report_emm_support(void)
524 if(!config_enabled(WITH_CARDREADER
))
526 cs_log("Binary without Cardreader Support! No EMM processing possible!");
530 report_emm_support(READER_NAGRA
, "Nagra");
531 report_emm_support(READER_NAGRA_MERLIN
, "Nagra Merlin");
532 report_emm_support(READER_IRDETO
, "Irdeto");
533 report_emm_support(READER_CONAX
, "Conax");
534 report_emm_support(READER_CRYPTOWORKS
, "Cryptoworks");
535 report_emm_support(READER_SECA
, "Seca");
536 report_emm_support(READER_VIACCESS
, "Viaccess");
537 report_emm_support(READER_VIDEOGUARD
, "NDS Videoguard");
538 report_emm_support(READER_DRE
, "DRE Crypt");
539 report_emm_support(READER_TONGFANG
, "TONGFANG");
540 report_emm_support(READER_BULCRYPT
, "Bulcrypt");
541 report_emm_support(READER_GRIFFIN
, "Griffin");
542 report_emm_support(READER_DGCRYPT
, "DGCrypt");
545 #undef report_emm_support
548 // The compat function is not called daemon() because this may cause problems.
549 static int32_t do_daemon(int32_t nochdir
, int32_t noclose
)
567 { (void)chdir("/"); }
569 if(!noclose
&& (fd
= open("/dev/null", O_RDWR
, 0)) != -1)
571 (void)dup2(fd
, STDIN_FILENO
);
572 (void)dup2(fd
, STDOUT_FILENO
);
573 (void)dup2(fd
, STDERR_FILENO
);
580 #define do_daemon daemon
584 * flags: 1 = restart, 2 = don't modify if SIG_IGN, may be combined
586 static void set_signal_handler(int32_t sig
, int32_t flags
, void (*sighandler
))
589 sigaction(sig
, (struct sigaction
*) 0, &sa
);
590 if(!((flags
& 2) && (sa
.sa_handler
== SIG_IGN
)))
592 sigemptyset(&sa
.sa_mask
);
593 sa
.sa_flags
= (flags
& 1) ? SA_RESTART
: 0;
594 sa
.sa_handler
= sighandler
;
595 sigaction(sig
, &sa
, (struct sigaction
*) 0);
599 static void cs_master_alarm(void)
601 cs_log("PANIC: master deadlock!");
602 fprintf(stderr
, "PANIC: master deadlock!");
606 static void cs_sigpipe(void)
608 if(cs_dblevel
& D_ALL_DUMP
)
609 { cs_log("Got sigpipe signal -> captured"); }
612 static void cs_dummy(void)
617 /* Switch debuglevel forward one step (called when receiving SIGUSR1). */
618 static void cs_debug_level(void)
635 cs_log("debug_level=%d", cs_dblevel
);
639 * write stacktrace to oscam.crash. file is always appended
641 * 1. compile oscam with debug parameters (Makefile: DS_OPTS="-ggdb")
642 * 2. you need gdb installed and working on the local machine
643 * 3. start oscam with parameter: -a
645 static void cs_dumpstack(int32_t sig
)
647 FILE *fp
= fopen("oscam.crash", "a+");
653 cs_ctime_r(&timep
, buf
);
655 fprintf(stderr
, "crashed with signal %d on %swriting oscam.crash\n", sig
, buf
);
657 fprintf(fp
, "%sOSCam cardserver v%s, build r%s (%s)\n", buf
, CS_VERSION
, CS_SVN_VERSION
, CS_TARGET
);
658 fprintf(fp
, "FATAL: Signal %d: %s Fault. Logged StackTrace:\n\n", sig
, (sig
== SIGSEGV
) ? "Segmentation" : ((sig
== SIGBUS
) ? "Bus" : "Unknown"));
661 FILE *cmd
= fopen("/tmp/gdbcmd", "w");
663 fputs("thread apply all bt\n", cmd
);
666 snprintf(buf
, sizeof(buf
) - 1, "gdb %s %d -batch -x /tmp/gdbcmd >> oscam.crash", prog_name
, getpid());
667 if(system(buf
) == -1)
668 { fprintf(stderr
, "Fatal error on trying to start gdb process."); }
675 * called by signal SIGHUP
678 * - useraccounts (oscam.user)
679 * - readers (oscam.server)
680 * - services ids (oscam.srvid)
681 * - tier ids (oscam.tiers)
682 * Also clears anticascading stats.
684 static void cs_reload_config(void)
686 static pthread_mutex_t mutex
;
687 static int8_t mutex_init
= 0;
691 SAFE_MUTEX_INIT(&mutex
, NULL
);
695 if(pthread_mutex_trylock(&mutex
))
700 if(cfg
.reload_useraccounts
)
705 if(cfg
.reload_readers
)
710 if(cfg
.reload_provid
)
715 if(cfg
.reload_services_ids
)
720 if(cfg
.reload_tier_ids
)
725 if(cfg
.reload_fakecws
)
730 if(cfg
.reload_ac_stat
)
737 cs_reopen_log(); // FIXME: aclog.log, emm logs, cw logs (?)
740 SAFE_MUTEX_UNLOCK(&mutex
);
743 /* Sets signal handlers to ignore for early startup of OSCam because for example log
744 could cause SIGPIPE errors and the normal signal handlers can't be used at this point. */
745 static void init_signal_pre(void)
747 set_signal_handler(SIGPIPE
, 1, SIG_IGN
);
748 set_signal_handler(SIGWINCH
, 1, SIG_IGN
);
749 set_signal_handler(SIGALRM
, 1, SIG_IGN
);
750 set_signal_handler(SIGHUP
, 1, SIG_IGN
);
753 /* Sets the signal handlers.*/
754 static void init_signal(void)
756 set_signal_handler(SIGINT
, 3, cs_exit
);
757 #if defined(__APPLE__)
758 set_signal_handler(SIGEMT
, 3, cs_exit
);
760 set_signal_handler(SIGTERM
, 3, cs_exit
);
762 set_signal_handler(SIGWINCH
, 1, SIG_IGN
);
763 set_signal_handler(SIGPIPE
, 0, cs_sigpipe
);
764 set_signal_handler(SIGALRM
, 0, cs_master_alarm
);
765 set_signal_handler(SIGHUP
, 1, cs_reload_config
);
766 set_signal_handler(SIGUSR1
, 1, cs_debug_level
);
767 set_signal_handler(SIGUSR2
, 1, cs_card_info
);
768 set_signal_handler(OSCAM_SIGNAL_WAKEUP
, 0, cs_dummy
);
772 set_signal_handler(SIGSEGV
, 1, cs_exit
);
773 set_signal_handler(SIGBUS
, 1, cs_exit
);
775 else if(cs_dump_stack
)
777 set_signal_handler(SIGSEGV
, 1, cs_dumpstack
);
778 set_signal_handler(SIGBUS
, 1, cs_dumpstack
);
781 cs_log("signal handling initialized");
785 void cs_exit(int32_t sig
)
787 if(cs_dump_stack
&& (sig
== SIGSEGV
|| sig
== SIGBUS
|| sig
== SIGQUIT
))
788 { cs_dumpstack(sig
); }
790 set_signal_handler(SIGHUP
, 1, SIG_IGN
);
791 set_signal_handler(SIGPIPE
, 1, SIG_IGN
);
793 struct s_client
*cl
= cur_client();
797 // this is very important - do not remove
800 cs_log_dbg(D_TRACE
, "thread %8lX ended!", (unsigned long)pthread_self());
804 // Restore signals before exiting thread
805 set_signal_handler(SIGPIPE
, 0, cs_sigpipe
);
806 set_signal_handler(SIGHUP
, 1, cs_reload_config
);
813 { exit_oscam
= sig
? sig
: 1; }
816 static char *read_line_from_file(char *fname
, char *buf
, int bufsz
)
818 memset(buf
, 0, bufsz
);
819 FILE *f
= fopen(fname
, "r");
822 while (fgets(buf
, bufsz
, f
))
824 if (strstr(buf
,"\n")) // we need only the first line
826 buf
[cs_strlen(buf
)-1] = '\0';
836 static void init_machine_info(void)
838 struct utsname buffer
;
839 if (uname(&buffer
) == 0)
841 cs_log("System name = %s", buffer
.sysname
);
842 cs_log("Host name = %s", buffer
.nodename
);
843 cs_log("Release = %s", buffer
.release
);
844 cs_log("Version = %s", buffer
.version
);
845 cs_log("Machine = %s", buffer
.machine
);
847 cs_log("ERROR: uname call failed: %s", strerror(errno
));
850 #if !defined(__linux__)
854 // Linux only functionality
864 if ((f
= fopen("/proc/stb/info/azmodel", "r"))){ azmodel
= 1; fclose(f
);}
865 read_line_from_file("/proc/stb/info/model", model
, sizeof(model
));
866 read_line_from_file("/proc/stb/info/boxtype", boxtype
, sizeof(boxtype
));
867 read_line_from_file("/proc/stb/info/vumodel", vumodel
, sizeof(vumodel
));
868 if (vumodel
[0] && !boxtype
[0] && !azmodel
)
870 snprintf(boxtype
, sizeof(boxtype
), "vu%s", vumodel
);
872 if (!boxtype
[0] && azmodel
)
873 snprintf(boxtype
, sizeof(boxtype
), "Azbox-%s", model
);
875 // Detect dreambox type
876 if (strcasecmp(buffer
.machine
, "ppc") == 0 && !model
[0] && !boxtype
[0])
879 int have_dreambox
= 0;
880 if ((f
= fopen("/proc/cpuinfo", "r")))
882 while (fgets(line
, sizeof(line
), f
))
884 if (strstr(line
, "STBx25xx")) have_dreambox
++;
885 if (strstr(line
, "pvr" )) have_dreambox
++;
886 if (strstr(line
, "Dreambox")) have_dreambox
++;
887 if (strstr(line
, "9.80" )) have_dreambox
++;
888 if (strstr(line
, "63MHz" )) have_dreambox
++;
891 have_dreambox
= have_dreambox
== 5 ? 1 : 0; // Need to find all 5 strings
895 if (read_line_from_file("/proc/meminfo", line
, sizeof(line
)) && (p
= strchr(line
, ' ')))
897 unsigned long memtotal
= strtoul(p
, NULL
, 10);
898 if (memtotal
> 40000)
899 snprintf(boxtype
, sizeof(boxtype
), "%s", "dm600pvr");
901 snprintf(boxtype
, sizeof(boxtype
), "%s", "dm500");
906 if (!boxtype
[0] && !strcasecmp(model
, "dm800") && !strcasecmp(buffer
.machine
, "armv7l"))
907 snprintf(boxtype
, sizeof(boxtype
), "%s", "su980");
912 pos
= (uint8_t *)memchr(buffer
.release
, 'd', sizeof(buffer
.release
));
915 if((!memcmp(pos
, "dbox2", sizeof("dbox2"))) && !strcasecmp(buffer
.machine
, "ppc"))
917 snprintf(boxtype
, sizeof(boxtype
), "%s", "dbox2");
923 cs_log("Stb model = %s", model
);
926 cs_log("Stb vumodel = vu%s", vumodel
);
931 if(!strcasecmp(boxtype
,"ini-8000am")){snprintf(boxname
, sizeof(boxname
), "%s", "Atemio Nemesis");}
932 else if(!strcasecmp(boxtype
,"ini-9000ru")){snprintf(boxname
, sizeof(boxname
), "%s", "Sezam Marvel");}
933 else if(!strcasecmp(boxtype
,"ini-8000sv")){snprintf(boxname
, sizeof(boxname
), "%s", "Miraclebox Ultra");}
934 else if(!strcasecmp(boxtype
,"ini-9000de")){snprintf(boxname
, sizeof(boxname
), "%s", "Xpeed LX3");}
936 if(boxname
[0]){cs_log("Stb boxname = %s", boxname
); stb_boxname
= cs_strdup(boxname
);}
937 cs_log("Stb boxtype = %s", boxtype
);
941 stb_boxtype
= cs_strdup(boxtype
);
943 stb_boxtype
= cs_strdup(model
);
946 const char *boxtype_get(void)
948 return stb_boxtype
? stb_boxtype
: "generic";
951 const char *boxname_get(void)
953 return stb_boxname
? stb_boxname
: "generic";
956 bool boxtype_is(const char *boxtype
)
958 return strcasecmp(boxtype_get(), boxtype
) == 0;
961 bool boxname_is(const char *boxname
)
963 return strcasecmp(boxname_get(), boxname
) == 0;
966 /* Checks if the date of the system is correct and waits if necessary. */
967 static void init_check(void)
969 char *ptr
= __DATE__
;
970 int32_t month
, year
= atoi(ptr
+ cs_strlen(ptr
) - 4), day
= atoi(ptr
+ 4);
971 if(day
> 0 && day
< 32 && year
> 2010 && year
< 9999)
974 char months
[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
975 for(month
= 0; month
< 12; ++month
)
977 if(!strncmp(ptr
, months
[month
], 3)) { break; }
979 if(month
> 11) { month
= 0; }
980 memset(&timeinfo
, 0, sizeof(timeinfo
));
981 timeinfo
.tm_mday
= day
;
982 timeinfo
.tm_mon
= month
;
983 timeinfo
.tm_year
= year
- 1900;
984 time_t builddate
= mktime(&timeinfo
) - 86400;
986 while(time((time_t *)0) < builddate
)
988 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
); }
993 cs_log("Waiting was not successful. OSCam will be started but is UNSUPPORTED this way. Do not report any errors with this version.");
997 // adjust login time of first client
998 if(i
> 0) { first_client
->login
= time((time_t *)0); }
1003 #include <sys/prctl.h>
1004 // PR_SET_NAME is introduced in 2.6.9 (which is ancient, released 18 Oct 2004)
1005 // but apparantly we can't count on having at least that version :(
1007 #define PR_SET_NAME 15
1009 // Set the thread name (comm) under linux (the limit is 16 chars)
1010 void set_thread_name(const char *thread_name
)
1012 prctl(PR_SET_NAME
, thread_name
, NULL
, NULL
, NULL
);
1015 void set_thread_name(const char *UNUSED(thread_name
)) { }
1019 static void fix_stacksize(void)
1021 // Changing the default stack size is generally a bad idea.
1022 // We are doing it anyway at the moment, because we are using several threads,
1023 // and are running on machnies with little RAM.
1024 // HOWEVER, as we do not know which minimal stack size is needed to run
1025 // oscam without SEQFAULT (stack overflow), this is risky business.
1026 // If after a code change SEQFAULTs related to stack overflow appear,
1027 // increase OSCAM_STACK_MIN or remove the calls to SAFE_ATTR_SETSTACKSIZE.
1029 #ifndef PTHREAD_STACK_MIN
1030 #define PTHREAD_STACK_MIN 64000
1032 #define OSCAM_STACK_MIN PTHREAD_STACK_MIN + 32768
1034 if(oscam_stacksize
< OSCAM_STACK_MIN
)
1036 long pagesize
= sysconf(_SC_PAGESIZE
);
1039 oscam_stacksize
= OSCAM_STACK_MIN
;
1043 oscam_stacksize
= ((OSCAM_STACK_MIN
) / pagesize
+ 1) * pagesize
;
1047 /* Starts a thread named nameroutine with the start function startroutine. */
1048 int32_t start_thread(char *nameroutine
, void *startroutine
, void *arg
, pthread_t
*pthread
, int8_t detach
, int8_t modify_stacksize
)
1051 pthread_attr_t attr
;
1053 cs_log_dbg(D_TRACE
, "starting thread %s", nameroutine
);
1055 SAFE_ATTR_INIT(&attr
);
1057 if(modify_stacksize
)
1058 { SAFE_ATTR_SETSTACKSIZE(&attr
, oscam_stacksize
); }
1060 int32_t ret
= pthread_create(pthread
== NULL
? &temp
: pthread
, &attr
, startroutine
, arg
);
1062 { cs_log("ERROR: can't create %s thread (errno=%d %s)", nameroutine
, ret
, strerror(ret
)); }
1065 cs_log_dbg(D_TRACE
, "%s thread started", nameroutine
);
1068 { pthread_detach(pthread
== NULL
? temp
: *pthread
); }
1071 pthread_attr_destroy(&attr
);
1076 int32_t start_thread_nolog(char *nameroutine
, void *startroutine
, void *arg
, pthread_t
*pthread
, int8_t detach
, int8_t modify_stacksize
)
1079 pthread_attr_t attr
;
1081 SAFE_ATTR_INIT(&attr
);
1083 if(modify_stacksize
)
1084 { SAFE_ATTR_SETSTACKSIZE(&attr
, oscam_stacksize
); }
1086 int32_t ret
= pthread_create(pthread
== NULL
? &temp
: pthread
, &attr
, startroutine
, arg
);
1088 { fprintf(stderr
, "ERROR: can't create %s thread (errno=%d %s)", nameroutine
, ret
, strerror(ret
)); }
1092 { pthread_detach(pthread
== NULL
? temp
: *pthread
); }
1095 pthread_attr_destroy(&attr
);
1100 /* Allows to kill another thread specified through the client cl with locking.
1101 If the own thread has to be cancelled, cs_exit or cs_disconnect_client has to be used. */
1102 void kill_thread(struct s_client
*cl
)
1104 if(!cl
|| cl
->kill
) { return; }
1105 if(cl
== cur_client())
1107 cs_log("Trying to kill myself, exiting.");
1110 add_job(cl
, ACTION_CLIENT_KILL
, NULL
, 0); //add kill job, ...
1111 cl
->kill
= 1; //then set kill flag!
1114 struct s_module
*get_module(struct s_client
*cl
)
1116 return &modules
[cl
->module_idx
];
1119 void module_reader_set(struct s_reader
*rdr
)
1122 if(!is_cascading_reader(rdr
))
1124 for(i
= 0; i
< CS_MAX_MOD
; i
++)
1126 struct s_module
*module
= &modules
[i
];
1127 if(module
->num
&& module
->num
== rdr
->typ
)
1132 static void cs_waitforcardinit(void)
1134 if(cfg
.waitforcards
)
1136 cs_log("waiting for local card init");
1137 int32_t card_init_done
;
1141 struct s_reader
*rdr
;
1142 LL_ITER itr
= ll_iter_create(configured_readers
);
1143 while((rdr
= ll_iter_next(&itr
)))
1145 if(rdr
->enable
&& !is_cascading_reader(rdr
) && (rdr
->card_status
== CARD_NEED_INIT
|| rdr
->card_status
== UNKNOWN
))
1153 { cs_sleepms(300); } // wait a little bit
1154 //alarm(cfg.cmaxidle + cfg.ctimeout / 1000 + 1);
1156 while(!card_init_done
&& !exit_oscam
);
1158 if(cfg
.waitforcards_extra_delay
> 0 && !exit_oscam
)
1159 { cs_sleepms(cfg
.waitforcards_extra_delay
); }
1160 cs_log("init for all local cards done");
1164 static uint32_t resize_pfd_cllist(struct pollfd
**pfd
, struct s_client
***cl_list
, uint32_t old_size
, uint32_t new_size
)
1166 if(old_size
!= new_size
)
1168 struct pollfd
*pfd_new
;
1169 if(!cs_malloc(&pfd_new
, new_size
* sizeof(struct pollfd
)))
1173 struct s_client
**cl_list_new
;
1174 if(!cs_malloc(&cl_list_new
, new_size
* sizeof(cl_list
)))
1181 memcpy(pfd_new
, *pfd
, old_size
* sizeof(struct pollfd
));
1182 memcpy(cl_list_new
, *cl_list
, old_size
* sizeof(cl_list
));
1187 *cl_list
= cl_list_new
;
1192 static uint32_t chk_resize_cllist(struct pollfd
**pfd
, struct s_client
***cl_list
, uint32_t cur_size
, uint32_t chk_size
)
1195 if(chk_size
> cur_size
)
1197 uint32_t new_size
= ((chk_size
% 100) + 1) * 100; //increase 100 step
1198 cur_size
= resize_pfd_cllist(pfd
, cl_list
, cur_size
, new_size
);
1203 static void process_clients(void)
1205 int32_t i
, k
, j
, rc
, pfdcount
= 0;
1206 struct s_client
*cl
;
1207 struct s_reader
*rdr
;
1209 struct s_client
**cl_list
;
1210 struct timeb start
, end
; // start time poll, end time poll
1211 uint32_t cl_size
= 0;
1215 if(pipe(thread_pipe
) == -1)
1217 printf("cannot create pipe, errno=%d\n", errno
);
1221 cl_size
= chk_resize_cllist(&pfd
, &cl_list
, 0, 100);
1223 pfd
[pfdcount
].fd
= thread_pipe
[0];
1224 pfd
[pfdcount
].events
= POLLIN
| POLLPRI
;
1225 cl_list
[pfdcount
] = NULL
;
1231 // connected tcp clients
1232 for(cl
= first_client
->next
; cl
; cl
= cl
->next
)
1234 if(cl
->init_done
&& !cl
->kill
&& cl
->pfd
&& cl
->typ
== 'c' && !cl
->is_udp
)
1236 if(cl
->pfd
&& !cl
->thread_active
)
1238 cl_size
= chk_resize_cllist(&pfd
, &cl_list
, cl_size
, pfdcount
);
1239 cl_list
[pfdcount
] = cl
;
1240 pfd
[pfdcount
].fd
= cl
->pfd
;
1241 pfd
[pfdcount
++].events
= POLLIN
| POLLPRI
;
1246 // - TCP socket must be connected
1247 // - no active init thread
1249 // - connection status ignored
1250 // - no active init thread
1252 if(rdr
&& cl
->typ
== 'p' && cl
->init_done
)
1254 if(cl
->pfd
&& !cl
->thread_active
&& ((rdr
->tcp_connected
&& rdr
->ph
.type
== MOD_CONN_TCP
) || (rdr
->ph
.type
== MOD_CONN_UDP
)))
1256 cl_size
= chk_resize_cllist(&pfd
, &cl_list
, cl_size
, pfdcount
);
1257 cl_list
[pfdcount
] = cl
;
1258 pfd
[pfdcount
].fd
= cl
->pfd
;
1259 pfd
[pfdcount
++].events
= (POLLIN
| POLLPRI
);
1264 //server (new tcp connections or udp messages)
1265 for(k
= 0; k
< CS_MAX_MOD
; k
++)
1267 struct s_module
*module
= &modules
[k
];
1268 if((module
->type
& MOD_CONN_NET
))
1270 for(j
= 0; j
< module
->ptab
.nports
; j
++)
1272 if(module
->ptab
.ports
[j
].fd
)
1274 cl_size
= chk_resize_cllist(&pfd
, &cl_list
, cl_size
, pfdcount
);
1275 cl_list
[pfdcount
] = NULL
;
1276 pfd
[pfdcount
].fd
= module
->ptab
.ports
[j
].fd
;
1277 pfd
[pfdcount
++].events
= (POLLIN
| POLLPRI
);
1283 if(pfdcount
>= 1024)
1284 { cs_log("WARNING: too many users!"); }
1285 cs_ftime(&start
); // register start time
1286 rc
= poll(pfd
, pfdcount
, 5000);
1287 if(rc
< 1) { continue; }
1288 cs_ftime(&end
); // register end time
1290 for(i
= 0; i
< pfdcount
&& rc
> 0; i
++)
1292 if(pfd
[i
].revents
== 0) { continue; } // skip sockets with no changes
1293 rc
--; //event handled!
1294 cs_log_dbg(D_TRACE
, "[OSCAM] new event %d occurred on fd %d after %"PRId64
" ms inactivity", pfd
[i
].revents
,
1295 pfd
[i
].fd
, comp_timeb(&end
, &start
));
1298 if(cl
&& !is_valid_client(cl
))
1301 if(pfd
[i
].fd
== thread_pipe
[0] && (pfd
[i
].revents
& (POLLIN
| POLLPRI
)))
1303 // a thread ended and cl->pfd should be added to pollfd list again (thread_active==0)
1304 int32_t len
= read(thread_pipe
[0], buf
, sizeof(buf
));
1307 cs_log_dbg(D_TRACE
, "[OSCAM] Reading from pipe failed (errno=%d %s)", errno
, strerror(errno
));
1309 cs_log_dump_dbg(D_TRACE
, buf
, len
, "[OSCAM] Readed:");
1314 // message on an open tcp connection
1315 if(cl
&& cl
->init_done
&& cl
->pfd
&& (cl
->typ
== 'c' || cl
->typ
== 'm'))
1317 if(pfd
[i
].fd
== cl
->pfd
&& (pfd
[i
].revents
& (POLLHUP
| POLLNVAL
| POLLERR
)))
1319 //client disconnects
1323 if(pfd
[i
].fd
== cl
->pfd
&& (pfd
[i
].revents
& (POLLIN
| POLLPRI
)))
1325 add_job(cl
, ACTION_CLIENT_TCP
, NULL
, 0);
1330 // either an ecm answer, a keepalive or connection closed from a proxy
1331 // physical reader ('r') should never send data without request
1333 struct s_client
*cl2
= NULL
;
1334 if(cl
&& cl
->typ
== 'p')
1338 { cl2
= rdr
->client
; }
1341 if(rdr
&& cl2
&& cl2
->init_done
)
1343 if(cl2
->pfd
&& pfd
[i
].fd
== cl2
->pfd
&& (pfd
[i
].revents
& (POLLHUP
| POLLNVAL
| POLLERR
)))
1345 //connection to remote proxy was closed
1346 //oscam should check for rdr->tcp_connected and reconnect on next ecm request sent to the proxy
1347 network_tcp_connection_close(rdr
, "closed");
1348 rdr_log_dbg(rdr
, D_READER
, "connection closed");
1350 if(cl2
->pfd
&& pfd
[i
].fd
== cl2
->pfd
&& (pfd
[i
].revents
& (POLLIN
| POLLPRI
)))
1352 add_job(cl2
, ACTION_READER_REMOTE
, NULL
, 0);
1357 // new connection on a tcp listen socket or new message on udp listen socket
1358 if(!cl
&& (pfd
[i
].revents
& (POLLIN
| POLLPRI
)))
1360 for(k
= 0; k
< CS_MAX_MOD
; k
++)
1362 struct s_module
*module
= &modules
[k
];
1363 if((module
->type
& MOD_CONN_NET
))
1365 for(j
= 0; j
< module
->ptab
.nports
; j
++)
1367 if(module
->ptab
.ports
[j
].fd
&& module
->ptab
.ports
[j
].fd
== pfd
[i
].fd
)
1369 accept_connection(module
, k
, j
);
1376 cs_ftime(&start
); // register start time for new poll next run
1377 first_client
->last
= time((time_t *)0);
1384 static pthread_cond_t reader_check_sleep_cond
;
1385 static pthread_mutex_t reader_check_sleep_cond_mutex
;
1387 static void *reader_check(void)
1389 struct s_client
*cl
;
1390 struct s_reader
*rdr
;
1391 set_thread_name(__func__
);
1392 cs_pthread_cond_init(__func__
, &reader_check_sleep_cond_mutex
, &reader_check_sleep_cond
);
1395 for(cl
= first_client
->next
; cl
; cl
= cl
->next
)
1397 if(!cl
->thread_active
)
1398 { client_check_status(cl
); }
1400 cs_readlock(__func__
, &readerlist_lock
);
1401 for(rdr
= first_active_reader
; rdr
; rdr
= rdr
->next
)
1407 { restart_cardreader(rdr
, 0); }
1408 else if(!cl
->thread_active
)
1409 { client_check_status(cl
); }
1412 cs_readunlock(__func__
, &readerlist_lock
);
1413 sleepms_on_cond(__func__
, &reader_check_sleep_cond_mutex
, &reader_check_sleep_cond
, 1000);
1418 static pthread_cond_t card_poll_sleep_cond
;
1420 static void * card_poll(void) {
1421 struct s_client
*cl
;
1422 struct s_reader
*rdr
;
1423 pthread_mutex_t card_poll_sleep_cond_mutex
;
1424 SAFE_MUTEX_INIT(&card_poll_sleep_cond_mutex
, NULL
);
1425 SAFE_COND_INIT(&card_poll_sleep_cond
, NULL
);
1426 set_thread_name(__func__
);
1427 while (!exit_oscam
) {
1428 cs_readlock(__func__
, &readerlist_lock
);
1429 for (rdr
=first_active_reader
; rdr
; rdr
=rdr
->next
) {
1430 if (rdr
->enable
&& rdr
->card_status
== CARD_INSERTED
) {
1432 if (cl
&& !cl
->kill
)
1433 { add_job(cl
, ACTION_READER_POLL_STATUS
, 0, 0); }
1436 cs_readunlock(__func__
, &readerlist_lock
);
1439 gettimeofday(&tv
, NULL
);
1440 ts
.tv_sec
= tv
.tv_sec
;
1441 ts
.tv_nsec
= tv
.tv_usec
* 1000;
1443 SAFE_MUTEX_LOCK(&card_poll_sleep_cond_mutex
);
1444 SAFE_COND_TIMEDWAIT(&card_poll_sleep_cond
, &card_poll_sleep_cond_mutex
, &ts
); // sleep on card_poll_sleep_cond
1445 SAFE_MUTEX_UNLOCK(&card_poll_sleep_cond_mutex
);
1453 static void fwd_sig(int32_t sig
)
1458 static void restart_daemon(void)
1462 // start client process:
1465 { return; } // client process=oscam process
1469 // set signal handler for the restart daemon:
1470 set_signal_handler(SIGINT
, 3, fwd_sig
);
1471 #if defined(__APPLE__)
1472 set_signal_handler(SIGEMT
, 3, fwd_sig
);
1474 set_signal_handler(SIGTERM
, 3, fwd_sig
);
1475 set_signal_handler(SIGQUIT
, 0, fwd_sig
);
1476 set_signal_handler(SIGHUP
, 0, fwd_sig
);
1477 set_signal_handler(SIGUSR1
, 0, fwd_sig
);
1478 set_signal_handler(SIGUSR2
, 0, fwd_sig
);
1479 set_signal_handler(SIGALRM
, 0, fwd_sig
);
1480 set_signal_handler(SIGWINCH
, 1, SIG_IGN
);
1481 set_signal_handler(SIGPIPE
, 0, SIG_IGN
);
1482 set_signal_handler(OSCAM_SIGNAL_WAKEUP
, 0, SIG_IGN
);
1484 // restart control process:
1489 res
= waitpid(pid
, &status
, 0);
1498 if(cs_restart_mode
== 2 && WIFSIGNALED(status
) && WTERMSIG(status
) == SIGSEGV
)
1499 { status
= 99; } // restart on segfault!
1501 { status
= WEXITSTATUS(status
); }
1503 // status=99 restart oscam, all other->terminate
1511 void cs_restart_oscam(void)
1514 cs_log("restart oscam requested");
1517 int32_t cs_get_restartmode(void)
1519 return cs_restart_mode
;
1523 void cs_exit_oscam(void)
1526 cs_log("exit oscam requested");
1529 static void pidfile_create(char *pidfile
)
1531 FILE *f
= fopen(pidfile
, "w");
1534 pid_t my_pid
= getpid();
1535 cs_log("creating pidfile %s with pid %d", pidfile
, my_pid
);
1536 fprintf(f
, "%d\n", my_pid
);
1541 static bool running_under_valgrind
;
1543 static void detect_valgrind(void)
1547 snprintf(fname
, sizeof(fname
), "/proc/%d/maps", getpid());
1548 FILE *f
= fopen(fname
, "r");
1551 while (fgets(line
, sizeof(line
), f
)) {
1552 if (strstr(line
, "/valgrind/")) {
1553 running_under_valgrind
= true;
1563 extern void run_all_tests(void);
1564 __attribute__ ((noreturn
)) static void run_tests(void)
1570 static void run_tests(void) { }
1573 const struct s_cardsystem
*cardsystems
[] =
1578 #ifdef READER_NAGRA_MERLIN
1581 #ifdef READER_IRDETO
1587 #ifdef READER_CRYPTOWORKS
1588 &reader_cryptoworks
,
1593 #ifdef READER_VIACCESS
1596 #ifdef READER_VIDEOGUARD
1597 &reader_videoguard1
,
1598 &reader_videoguard2
,
1599 &reader_videoguard12
,
1604 #ifdef READER_DRECAS
1607 #ifdef READER_TONGFANG
1610 #ifdef READER_BULCRYPT
1613 #ifdef READER_GRIFFIN
1616 #ifdef READER_DGCRYPT
1622 const struct s_cardreader
*cardreaders
[] =
1624 #ifdef CARDREADER_DB2COM
1627 #if defined(CARDREADER_INTERNAL_AZBOX)
1628 &cardreader_internal_azbox
,
1629 #elif defined(CARDREADER_INTERNAL_COOLAPI)
1630 &cardreader_internal_cool
,
1631 #elif defined(CARDREADER_INTERNAL_COOLAPI2)
1632 &cardreader_internal_cool
,
1633 #elif defined(CARDREADER_INTERNAL_SCI)
1634 &cardreader_internal_sci
,
1636 #ifdef CARDREADER_PHOENIX
1639 #ifdef CARDREADER_DRECAS
1642 #ifdef CARDREADER_MP35
1645 #ifdef CARDREADER_PCSC
1648 #ifdef CARDREADER_SC8IN1
1651 #ifdef CARDREADER_SMARGO
1654 #ifdef CARDREADER_SMART
1655 &cardreader_smartreader
,
1657 #if defined(CARDREADER_STAPI) || defined(CARDREADER_STAPI5)
1660 #ifdef CARDREADER_STINGER
1661 &cardreader_stinger
,
1670 static void find_conf_dir(void)
1672 static const char* confdirs
[] =
1674 "/etc/tuxbox/config/",
1675 "/etc/tuxbox/config/oscam/",
1676 "/var/tuxbox/config/",
1686 char conf_file
[128+16];
1689 if(cs_confdir
[cs_strlen(cs_confdir
) - 1] != '/')
1690 { cs_strncat(cs_confdir
, "/", sizeof(cs_confdir
)); }
1692 if(snprintf(conf_file
, sizeof(conf_file
), "%soscam.conf", cs_confdir
) < 0)
1695 if(!access(conf_file
, F_OK
))
1698 for(i
=0; confdirs
[i
] != NULL
; i
++)
1700 if(snprintf(conf_file
, sizeof(conf_file
), "%soscam.conf", confdirs
[i
]) < 0)
1703 if (!access(conf_file
, F_OK
))
1705 cs_strncpy(cs_confdir
, confdirs
[i
], sizeof(cs_confdir
));
1711 int32_t main(int32_t argc
, char *argv
[])
1717 prog_name
= argv
[0];
1718 struct timespec start_ts
;
1719 cs_gettime(&start_ts
); // Initialize clock_type
1721 if(pthread_key_create(&getclient
, NULL
))
1723 fprintf(stderr
, "Could not create getclient, exiting...");
1727 void (*mod_def
[])(struct s_module
*) =
1729 #ifdef MODULE_MONITOR
1732 #ifdef MODULE_CAMD33
1735 #ifdef MODULE_CAMD35
1738 #ifdef MODULE_CAMD35_TCP
1741 #ifdef MODULE_NEWCAMD
1747 #ifdef MODULE_PANDORA
1759 #ifdef MODULE_CONSTCW
1762 #ifdef MODULE_RADEGAST
1768 #ifdef MODULE_SERIAL
1777 set_default_dirs_first();
1781 parse_cmdline_params(argc
, argv
);
1783 if(bg
&& do_daemon(1, 0))
1785 printf("Error starting in background (errno=%d: %s)", errno
, strerror(errno
));
1789 get_random_bytes_init();
1793 { restart_daemon(); }
1796 memset(&cfg
, 0, sizeof(struct s_config
));
1797 cfg
.max_pending
= max_pending
;
1799 if(cs_confdir
[cs_strlen(cs_confdir
) - 1] != '/') { cs_strncat(cs_confdir
, "/", sizeof(cs_confdir
)); }
1800 init_signal_pre(); // because log could cause SIGPIPE errors, init a signal handler first
1801 init_first_client();
1802 cs_lock_create(__func__
, &system_lock
, "system_lock", 5000);
1803 cs_lock_create(__func__
, &config_lock
, "config_lock", 10000);
1804 cs_lock_create(__func__
, &gethostbyname_lock
, "gethostbyname_lock", 10000);
1805 cs_lock_create(__func__
, &clientlist_lock
, "clientlist_lock", 5000);
1806 cs_lock_create(__func__
, &readerlist_lock
, "readerlist_lock", 5000);
1807 cs_lock_create(__func__
, &fakeuser_lock
, "fakeuser_lock", 5000);
1808 cs_lock_create(__func__
, &ecmcache_lock
, "ecmcache_lock", 5000);
1809 cs_lock_create(__func__
, &ecm_pushed_deleted_lock
, "ecm_pushed_deleted_lock", 5000);
1810 cs_lock_create(__func__
, &readdir_lock
, "readdir_lock", 5000);
1811 cs_lock_create(__func__
, &cwcycle_lock
, "cwcycle_lock", 5000);
1813 cacheex_init_hitcache();
1815 #ifdef CS_CACHEEX_AIO
1820 init_machine_info();
1822 if(!oscam_pidfile
&& cfg
.pidfile
)
1823 { oscam_pidfile
= cfg
.pidfile
; }
1826 oscam_pidfile
= get_tmp_dir_filename(default_pidfile
, sizeof(default_pidfile
), "oscam.pid");
1829 { pidfile_create(oscam_pidfile
); }
1830 cs_init_statistics();
1835 // These initializations *MUST* be called after init_config()
1836 // because modules depend on config values.
1837 for(i
= 0; mod_def
[i
]; i
++)
1839 struct s_module
*module
= &modules
[i
];
1845 #ifdef MODULE_STREAMRELAY
1846 init_stream_server();
1848 cfg
.account
= init_userdb();
1855 start_garbage_collector(gbdb
);
1859 write_versionfile(false);
1862 led_status_default();
1868 global_whitelist_read();
1871 #ifdef MODULE_SERIAL
1875 for(i
= 0; i
< CS_MAX_MOD
; i
++)
1877 struct s_module
*module
= &modules
[i
];
1878 if((module
->type
& MOD_CONN_NET
))
1880 for(j
= 0; j
< module
->ptab
.nports
; j
++)
1882 start_listener(module
, &module
->ptab
.ports
[j
]);
1887 // set time for server to now to avoid 0 in monitor/webif
1888 first_client
->last
= time((time_t *)0);
1892 start_thread("reader check", (void *) &reader_check
, NULL
, NULL
, 1, 1);
1893 cw_process_thread_start();
1894 checkcache_process_thread_start();
1898 do_report_emm_support();
1902 cs_waitforcardinit();
1905 load_emmstat_from_file();
1907 led_status_starting();
1911 gbox_send_init_hello();
1913 start_thread("card poll", (void *) &card_poll
, NULL
, NULL
, 1, 1);
1915 for(i
= 0; i
< CS_MAX_MOD
; i
++)
1917 struct s_module
*module
= &modules
[i
];
1918 if((module
->type
& MOD_CONN_SERIAL
) && module
->s_handler
)
1919 { module
->s_handler(NULL
, NULL
, i
); }
1922 // main loop function
1925 SAFE_COND_SIGNAL(&card_poll_sleep_cond
); // Stop card_poll thread
1926 cw_process_thread_wakeup(); // Stop cw_process thread
1927 SAFE_COND_SIGNAL(&reader_check_sleep_cond
); // Stop reader_check thread
1933 #ifdef MODULE_STREAMRELAY
1934 stop_stream_server();
1938 coolapi_close_all();
1941 led_status_stopping();
1945 remove_versionfile();
1948 dvbapi_stop_all_descrambling(0);
1949 dvbapi_save_channel_cache();
1951 save_emmstat_to_file();
1954 gbox_send_good_night();
1958 for(i
= 0; i
< CS_MAX_MOD
; i
++)
1960 struct s_module
*module
= &modules
[i
];
1961 if((module
->type
& MOD_CONN_NET
))
1963 for(j
= 0; j
< module
->ptab
.nports
; j
++)
1965 struct s_port
*port
= &module
->ptab
.ports
[j
];
1968 shutdown(port
->fd
, SHUT_RDWR
);
1977 { unlink(oscam_pidfile
); }
1979 // sleep a bit, so hopefully all threads are stopped when we continue
1983 #ifdef CS_CACHEEX_AIO
1986 cacheex_free_hitcache();
1988 init_free_userdb(cfg
.account
);
1996 if (!running_under_valgrind
)
1997 cs_log("cardserver down");
1999 cs_log("running under valgrind, waiting 5 seconds before stopping cardserver");
2002 if (running_under_valgrind
) sleep(5); // HACK: Wait a bit for things to settle
2004 stop_garbage_collector();
2006 NULLFREE(first_client
->account
);
2007 NULLFREE(first_client
);
2011 // This prevents the compiler from removing config_mak from the final binary
2012 syslog_ident
= config_mak
;