source: trunk/oscam.c@ 2953

Last change on this file since 2953 was 2953, checked in by rorothetroll, 10 years ago

added Seagate FreeAgent DockStar support. thanks Robby

File size: 87.4 KB
Line 
1#define CS_CORE
2#include "globals.h"
3#ifdef AZBOX
4# include "openxcas/openxcas_api.h"
5#endif
6#ifdef CS_WITH_GBOX
7# include "csgbox/gbox.h"
8# define CS_VERSION_X CS_VERSION "-gbx-" GBXVERSION
9#else
10# define CS_VERSION_X CS_VERSION
11#endif
12/*****************************************************************************
13 Globals
14*****************************************************************************/
15int ridx=0;
16int pfd=0; // Primary FD, must be closed on exit
17int mfdr=0; // Master FD (read)
18int fd_c2m=0; // FD Client -> Master (for clients / write )
19int fd_c2l=0; // FD Client -> Logger (for clients / write )
20int cs_dblevel=0; // Debug Level (TODO !!)
21int cs_idx=0; // client index (0=master, ...)
22int cs_ptyp=0; // process-type
23struct s_module ph[CS_MAX_MOD]; // Protocols
24int is_server=0; // used in modules to specify function
25pid_t master_pid=0; // master pid OUTSIDE shm
26ushort len4caid[256]; // table for guessing caid (by len)
27char cs_confdir[128]=CS_CONFDIR;
28uchar mbuf[1024]; // global buffer
29pthread_mutex_t gethostbyname_lock;
30ECM_REQUEST *ecmtask;
31#ifdef CS_ANTICASC
32struct s_acasc ac_stat[CS_MAXPID];
33#endif
34
35/*****************************************************************************
36 Shared Memory
37*****************************************************************************/
38int *ecmidx; // Shared Memory
39int *logidx; // Shared Memory
40int *oscam_sem; // sem (multicam.o)
41int *c_start; // idx of 1st client
42int *log_fd; // log-process is running
43struct s_ecm *ecmcache; // Shared Memory
44struct s_client *client; // Shared Memory
45struct s_reader *reader; // Shared Memory
46
47struct card_struct *Cards; // Shared Memory
48struct idstore_struct *idstore; // Shared Memory
49unsigned long *IgnoreList; // Shared Memory
50
51struct s_config *cfg; // Shared Memory
52#ifdef CS_ANTICASC
53struct s_acasc_shm *acasc; // anti-cascading table indexed by account.ac_idx
54#endif
55#ifdef CS_LOGHISTORY
56int *loghistidx; // ptr to current entry
57char *loghist; // ptr of log-history
58#endif
59int *mcl=0; // Master close log?
60
61static int shmsize = CS_ECMCACHESIZE*(sizeof(struct s_ecm)) +
62 CS_MAXPID*(sizeof(struct s_client)) +
63 CS_MAXREADER*(sizeof(struct s_reader)) +
64#ifdef CS_WITH_GBOX
65 CS_MAXCARDS*(sizeof(struct card_struct))+
66 CS_MAXIGNORE*(sizeof(long))+
67 CS_MAXPID*(sizeof(struct idstore_struct))+
68#endif
69#ifdef CS_ANTICASC
70 CS_MAXPID*(sizeof(struct s_acasc_shm)) +
71#endif
72#ifdef CS_LOGHISTORY
73 CS_MAXLOGHIST*CS_LOGHISTSIZE + sizeof(int) +
74#endif
75 sizeof(struct s_config)+(6*sizeof(int));
76
77#ifdef CS_NOSHM
78char cs_memfile[128]=CS_MMAPFILE;
79#endif
80
81/*****************************************************************************
82 Statics
83*****************************************************************************/
84static char mloc[128]={0};
85static int shmid=0; // Shared Memory ID
86static int cs_last_idx=0; // client index of last fork (master only)
87static char *logo = " ___ ____ ___ \n / _ \\/ ___| / __|__ _ _ __ ___ \n| | | \\___ \\| | / _` | '_ ` _ \\ \n| |_| |___) | |_| (_| | | | | | |\n \\___/|____/ \\___\\__,_|_| |_| |_|\n";
88
89static void cs_set_mloc(int ato, char *txt)
90{
91 if (ato>=0)
92 alarm(ato);
93 if (txt)
94 strcpy(mloc, txt);
95}
96
97static void usage()
98{
99 fprintf(stderr, "%s\n\n", logo);
100 fprintf(stderr, "OSCam cardserver v%s, build #%s (%s) - (w) 2009-2010 streamboard SVN\n", CS_VERSION_X, CS_SVN_VERSION, CS_OSTYPE);
101 fprintf(stderr, "\tsee http://streamboard.gmc.to:8001/wiki/ for more details\n");
102 fprintf(stderr, "\tbased on streamboard mp-cardserver v0.9d - (w) 2004-2007 by dukat\n");
103 fprintf(stderr, "\tinbuilt modules: ");
104#ifdef HAVE_DVBAPI
105#ifdef WITH_STAPI
106 fprintf(stderr, "dvbapi with stapi");
107#else
108 fprintf(stderr, "dvbapi ");
109#endif
110#endif
111#ifdef WEBIF
112 fprintf(stderr, "webinterface ");
113#endif
114#ifdef CS_ANTICASC
115 fprintf(stderr, "anticascading ");
116#endif
117#ifdef LIBUSB
118 fprintf(stderr, "smartreader ");
119#endif
120#ifdef HAVE_PCSC
121 fprintf(stderr, "pcsc ");
122#endif
123#ifdef CS_WITH_GBOX
124 fprintf(stderr, "gbox ");
125#endif
126#ifdef IRDETO_GUESSING
127 fprintf(stderr, "irdeto-guessing ");
128#endif
129#ifdef CS_LED
130 fprintf(stderr, "led-trigger ");
131#endif
132 fprintf(stderr, "\n\n");
133 fprintf(stderr, "oscam [-b] [-c config-dir] [-d]");
134#ifdef CS_NOSHM
135 fprintf(stderr, " [-m memory-file]");
136#endif
137 fprintf(stderr, " [-h]");
138 fprintf(stderr, "\n\n\t-b : start in background\n");
139 fprintf(stderr, "\t-c <dir> : read configuration from <dir>\n");
140 fprintf(stderr, "\t default = %s\n", CS_CONFDIR);
141 fprintf(stderr, "\t-d <level> : debug level mask\n");
142 fprintf(stderr, "\t 0 = no debugging (default)\n");
143 fprintf(stderr, "\t 1 = detailed error messages\n");
144 fprintf(stderr, "\t 2 = ATR parsing info, ECM, EMM and CW dumps\n");
145 fprintf(stderr, "\t 4 = traffic from/to the reader\n");
146 fprintf(stderr, "\t 8 = traffic from/to the clients\n");
147 fprintf(stderr, "\t 16 = traffic to the reader-device on IFD layer\n");
148 fprintf(stderr, "\t 32 = traffic to the reader-device on I/O layer\n");
149 fprintf(stderr, "\t 64 = EMM logging\n");
150 fprintf(stderr, "\t 255 = debug all\n");
151#ifdef CS_NOSHM
152 fprintf(stderr, "\t-m <file> : use <file> as mmaped memory file\n");
153 fprintf(stderr, "\t default = %s\n", CS_MMAPFILE);
154#endif
155 fprintf(stderr, "\t-h : show this help\n");
156 fprintf(stderr, "\n");
157 exit(1);
158}
159
160#ifdef NEED_DAEMON
161#ifdef OS_MACOSX
162// this is done because daemon is being deprecated starting with 10.5 and -Werror will always trigger an error
163static int daemon_compat(int nochdir, int noclose)
164#else
165static int daemon(int nochdir, int noclose)
166#endif
167{
168 int fd;
169
170 switch (fork())
171 {
172 case -1: return (-1);
173 case 0: break;
174 default: _exit(0);
175 }
176
177 if (setsid()==(-1))
178 return(-1);
179
180 if (!nochdir)
181 (void)chdir("/");
182
183 if (!noclose && (fd=open("/dev/null", O_RDWR, 0)) != -1)
184 {
185 (void)dup2(fd, STDIN_FILENO);
186 (void)dup2(fd, STDOUT_FILENO);
187 (void)dup2(fd, STDERR_FILENO);
188 if (fd>2)
189 (void)close(fd);
190 }
191 return(0);
192}
193#endif
194
195int recv_from_udpipe(uchar *buf)
196{
197 unsigned short n;
198 if (!pfd) return(-9);
199 if (!read(pfd, buf, 3)) cs_exit(1);
200 if (buf[0]!='U')
201 {
202 cs_log("INTERNAL PIPE-ERROR");
203 cs_exit(1);
204 }
205 memcpy(&n, buf+1, 2);
206 return(read(pfd, buf, n));
207}
208
209char *username(int idx)
210{
211 if (client[idx].usr[0])
212 return(client[idx].usr);
213 else
214 return("anonymous");
215}
216
217static int idx_from_ip(in_addr_t ip, in_port_t port)
218{
219 int i, idx;
220 for (i=idx=0; (i<CS_MAXPID) && (!idx); i++)
221 if ((client[i].ip==ip) && (client[i].port==port) &&
222 ((client[i].typ=='c') || (client[i].typ=='m')))
223 idx=i;
224 return(idx);
225}
226
227int idx_from_pid(pid_t pid)
228{
229 int i, idx;
230 for (i=0, idx=(-1); (i<CS_MAXPID) && (idx<0); i++)
231 if (client[i].pid==pid)
232 idx=i;
233 return(idx);
234}
235
236static long chk_caid(ushort caid, CAIDTAB *ctab)
237{
238 int n;
239 long rc;
240 for (rc=(-1), n=0; (n<CS_MAXCAIDTAB) && (rc<0); n++)
241 if ((caid & ctab->mask[n]) == ctab->caid[n])
242 rc=ctab->cmap[n] ? ctab->cmap[n] : caid;
243 return(rc);
244}
245
246int chk_bcaid(ECM_REQUEST *er, CAIDTAB *ctab)
247{
248 long caid;
249 if ((caid=chk_caid(er->caid, ctab))<0)
250 return(0);
251 er->caid=caid;
252 return(1);
253}
254
255/*
256 * void set_signal_handler(int sig, int flags, void (*sighandler)(int))
257 * flags: 1 = restart, 2 = don't modify if SIG_IGN, may be combined
258 */
259void set_signal_handler(int sig, int flags, void (*sighandler)(int))
260{
261#ifdef CS_SIGBSD
262 if ((signal(sig, sighandler)==SIG_IGN) && (flags & 2))
263 {
264 signal(sig, SIG_IGN);
265 siginterrupt(sig, 0);
266 }
267 else
268 siginterrupt(sig, (flags & 1) ? 0 : 1);
269#else
270 struct sigaction sa;
271 sigaction(sig, (struct sigaction *) 0, &sa);
272 if (!((flags & 2) && (sa.sa_handler==SIG_IGN)))
273 {
274 sigemptyset(&sa.sa_mask);
275 sa.sa_flags=(flags & 1) ? SA_RESTART : 0;
276 sa.sa_handler=sighandler;
277 sigaction(sig, &sa, (struct sigaction *) 0);
278 }
279#endif
280}
281
282static void cs_alarm()
283{
284 cs_debug("Got alarm signal");
285 cs_log("disconnect from %s by watchdog", cs_inet_ntoa(client[cs_idx].ip));
286 cs_exit(0);
287}
288
289static void cs_master_alarm()
290{
291 cs_log("PANIC: master deadlock! last location: %s", mloc);
292 fprintf(stderr, "PANIC: master deadlock! last location: %s", mloc);
293 fflush(stderr);
294 cs_exit(0);
295}
296
297static void cs_sigpipe()
298{
299 if ((cs_idx) && (master_pid!=getppid()))
300 cs_exit(0);
301 cs_log("Got sigpipe signal -> captured");
302}
303
304void cs_exit(int sig)
305{
306
307//#ifdef ST_LINUX
308// Fortis_STSMART_Close();
309// Fortis_STPTI_Close();
310//#endif
311
312 set_signal_handler(SIGCHLD, 1, SIG_IGN);
313 set_signal_handler(SIGHUP , 1, SIG_IGN);
314 if (sig && (sig!=SIGQUIT))
315 cs_log("exit with signal %d", sig);
316 switch(client[cs_idx].typ)
317 {
318 case 'c':
319 cs_statistics(cs_idx);
320 client[cs_idx].last_caid = 0xFFFF;
321 client[cs_idx].last_srvid = 0xFFFF;
322 cs_statistics(cs_idx);
323 break;
324 case 'm': break;
325 case 'n': *log_fd=0;
326 break;
327 case 'r':
328 // free AES entries allocated memory
329 if(reader[ridx].aes_list) {
330 aes_clear_entries(&reader[ridx]);
331 }
332 // close the device
333 reader_device_close(&reader[ridx]);
334 break;
335 case 's': *log_fd=0;
336 int i;
337 for (i=1; i<CS_MAXPID; i++)
338 if (client[i].pid)
339 kill(client[i].pid, SIGQUIT);
340#ifdef CS_LED
341 cs_switch_led(LED1B, LED_OFF);
342 cs_switch_led(LED2, LED_OFF);
343 cs_switch_led(LED3, LED_OFF);
344 cs_switch_led(LED1A, LED_ON);
345#endif
346 if (cfg->pidfile != NULL) {
347 if (unlink(cfg->pidfile) < 0)
348 cs_log("cannot remove pid file %s errno=(%d)", cfg->pidfile, errno);
349 }
350#ifndef OS_CYGWIN32
351 if (unlink("/tmp/oscam.version") < 0)
352 cs_log("cannot remove /tmp/oscam.version errno=(%d)", errno);
353#endif
354 cs_log("cardserver down");
355#ifndef CS_NOSHM
356 if (ecmcache) shmdt((void *)ecmcache);
357#endif
358 break;
359 }
360 if (pfd) close(pfd);
361#ifdef CS_NOSHM
362 munmap((void *)ecmcache, (size_t)shmsize);
363 if (shmid) close(shmid);
364 unlink(CS_MMAPFILE); // ignore errors, last process must succeed
365#endif
366 exit(sig);
367}
368
369void cs_reinit_clients()
370{
371 int i;
372 struct s_auth *account;
373
374 for( i = 1; i < CS_MAXPID; i++ )
375 if( client[i].pid && client[i].typ == 'c' && client[i].usr[0] ) {
376 for (account = cfg->account; (account) ; account = account->next)
377 if (!strcmp(client[i].usr, account->usr))
378 break;
379
380 if (account && client[i].pcrc == crc32(0L, MD5((uchar *)account->pwd, strlen(account->pwd), NULL), 16)) {
381 client[i].grp = account->grp;
382 client[i].au = account->au;
383 client[i].autoau = account->autoau;
384 client[i].expirationdate = account->expirationdate;
385 client[i].allowedtimeframe[0] = account->allowedtimeframe[0];
386 client[i].allowedtimeframe[1] = account->allowedtimeframe[1];
387 client[i].ncd_keepalive = account->ncd_keepalive;
388 client[i].c35_suppresscmd08 = account->c35_suppresscmd08;
389 client[i].tosleep = (60*account->tosleep);
390 client[i].c35_sleepsend = account->c35_sleepsend;
391 client[i].monlvl = account->monlvl;
392 client[i].disabled = account->disabled;
393 client[i].fchid = account->fchid; // CHID filters
394 client[i].cltab = account->cltab; // Class
395
396 // newcamd module dosent like ident reloading
397 if(!client[i].ncd_server)
398 client[i].ftab = account->ftab; // Ident
399
400 client[i].sidtabok = account->sidtabok; // services
401 client[i].sidtabno = account->sidtabno; // services
402
403 memcpy(&client[i].ctab, &account->ctab, sizeof(client[i].ctab));
404 memcpy(&client[i].ttab, &account->ttab, sizeof(client[i].ttab));
405
406#ifdef CS_ANTICASC
407 client[i].ac_idx = account->ac_idx;
408 client[i].ac_penalty= account->ac_penalty;
409 client[i].ac_limit = (account->ac_users * 100 + 80) * cfg->ac_stime;
410#endif
411 } else {
412 if (ph[client[i].ctyp].type & MOD_CONN_NET) {
413 cs_debug("client '%s', pid=%d not found in db (or password changed)", client[i].usr, client[i].pid);
414 kill(client[i].pid, SIGQUIT);
415 }
416 }
417 }
418}
419
420static void cs_sighup()
421{
422 uchar dummy[1]={0x00};
423 write_to_pipe(fd_c2m, PIP_ID_HUP, dummy, 1);
424}
425
426static void cs_accounts_chk()
427{
428 init_userdb(&cfg->account);
429 cs_reinit_clients();
430#ifdef CS_ANTICASC
431 int i;
432 for (i=0; i<CS_MAXPID; i++)
433 if (client[i].typ=='a')
434 {
435 kill(client[i].pid, SIGHUP);
436 break;
437 }
438#endif
439}
440
441static void cs_debug_level()
442{
443 int i;
444
445 //switch debuglevel forward one step if not set from outside
446 if(cfg->debuglvl == cs_dblevel) {
447 switch (cs_dblevel) {
448 case 0:
449 cs_dblevel = 1;
450 break;
451 case 64:
452 cs_dblevel = 255;
453 break;
454 case 255:
455 cs_dblevel = 0;
456 break;
457 default:
458 cs_dblevel <<= 1;
459 }
460 } else {
461 cs_dblevel = cfg->debuglvl;
462 }
463
464 cfg->debuglvl = cs_dblevel;
465
466 if (master_pid == getpid())
467 for (i=0; i<CS_MAXPID && client[i].pid; i++)
468 client[i].dbglvl = cs_dblevel;
469 else
470 client[cs_idx].dbglvl = cs_dblevel;
471 cs_log("%sdebug_level=%d", (master_pid == getpid())?"all ":"", cs_dblevel);
472}
473
474static void cs_card_info(int i)
475{
476 uchar dummy[1]={0x00};
477
478 for( i=1; i<CS_MAXPID; i++ )
479 if( client[i].pid && client[i].typ=='r' && client[i].fd_m2c ){
480 write_to_pipe(client[i].fd_m2c, PIP_ID_CIN, dummy, 1);
481 }
482
483 //kill(client[i].pid, SIGUSR2);
484}
485
486static void prepare_reader_restart(int ridx, int cs_idx)
487{
488 reader[ridx].pid = 0;
489 reader[ridx].cc = NULL;
490 reader[ridx].tcp_connected = 0;
491 reader[ridx].fd=0;
492 reader[ridx].cs_idx=0;
493 reader[ridx].last_s = 0;
494 reader[ridx].last_g = 0;
495 cs_debug_mask(D_TRACE, "reader %s closed (index=%d)", reader[ridx].label, ridx);
496 if (client[cs_idx].ufd) close(client[cs_idx].ufd);
497 if (client[cs_idx].fd_m2c_c) close(client[cs_idx].fd_m2c_c);
498 memset(&client[cs_idx], 0, sizeof(struct s_client));
499 client[cs_idx].au=(-1);
500}
501
502//Schlocke: restart cardreader after 5 seconds:
503static void restart_cardreader(int pridx, int force_now) {
504 ridx = pridx;
505 if (reader[ridx].cs_idx) {
506 if (reader[ridx].pid==client[reader[ridx].cs_idx].pid) {
507 int pid = reader[ridx].pid;
508 prepare_reader_restart(ridx, reader[ridx].cs_idx);
509 kill(pid, SIGKILL);
510 }
511 }
512 reader[ridx].ridx = ridx; //FIXME
513 if ((reader[ridx].device[0]) && (reader[ridx].enable == 1) && (!reader[ridx].deleted)) {
514 switch (cs_fork(0, 99)) {
515 case -1:
516 cs_exit(1);
517 case 0:
518 break;
519 default:
520 if (!force_now)
521 cs_sleepms(cfg->reader_restart_seconds * 1000); // SS: wait
522 cs_log("restarting reader %s (index=%d)", reader[ridx].label, ridx);
523
524 wait4master();
525 start_cardreader(&reader[ridx]);
526 }
527 }
528}
529
530
531static void cs_child_chk(int i)
532{
533 while (waitpid(0, NULL, WNOHANG)>0);
534 for (i=1; i<CS_MAXPID; i++)
535 if (client[i].pid)
536 if (kill(client[i].pid, 0)) {
537 if ((client[i].typ!='c') && (client[i].typ!='m'))
538 {
539 char *txt="";
540 switch(client[i].typ)
541 {
542#ifdef CS_ANTICASC
543 case 'a': txt="anticascader"; break;
544#endif
545 case 'l': txt="logger"; break;
546 case 'p': txt="proxy"; break;
547 case 'r': txt="reader"; break;
548 case 'n': txt="resolver"; break;
549#ifdef WEBIF
550 case 'h': txt="http"; break;
551#endif
552 }
553 cs_log("PANIC: %s lost !! (pid=%d)", txt, client[i].pid);
554 if (cfg->reader_restart_seconds && (client[i].typ == 'r' || client[i].typ == 'p'))
555 {
556 int old_pid = client[i].pid;
557 client[i].pid = 0;
558 for (ridx = 0; ridx < CS_MAXREADER; ridx++)
559 {
560 if (reader[ridx].pid == old_pid)
561 {
562 prepare_reader_restart(ridx, i);
563 cs_log("restarting %s %s in %d seconds (index=%d)", reader[ridx].label, txt,
564 cfg->reader_restart_seconds, ridx);
565 send_restart_cardreader(ridx, 0);
566 break;
567 }
568 }
569 }
570 else {
571 *log_fd=0;
572 cs_exit(1);
573 }
574 }
575 else
576 {
577#ifdef CS_ANTICASC
578 char usr[32];
579 ushort ac_idx=0;
580 ushort ac_limit=0;
581 uchar ac_penalty=0;
582 if( cfg->ac_enabled )
583 {
584 cs_strncpy(usr, client[i].usr, sizeof(usr));
585 ac_idx = client[i].ac_idx;
586 ac_limit = client[i].ac_limit;
587 ac_penalty = client[i].ac_penalty;
588 }
589#endif
590 if (client[i].fd_m2c) close(client[i].fd_m2c);
591 if (client[i].ufd) close(client[i].ufd);
592 memset(&client[i], 0, sizeof(struct s_client));
593#ifdef CS_ANTICASC
594 if( cfg->ac_enabled )
595 {
596 client[i].ac_idx = ac_idx;
597 client[i].ac_limit = ac_limit;
598 client[i].ac_penalty = ac_penalty;
599 strcpy(client[i].usr, usr);
600 }
601#endif
602 client[i].au=(-1);
603
604#ifdef HAVE_DVBAPI
605 int phi = client[i].ctyp;
606 if (client[i].typ == 'c' && ph[phi].type & MOD_CONN_SERIAL) //Schlocke: dvbapi killed? restart
607 {
608 if (ph[phi].s_handler)
609 ph[phi].s_handler(phi);
610 }
611#endif
612 }
613 }
614 return;
615}
616
617int cs_fork(in_addr_t ip, in_port_t port)
618{
619 int i;
620 pid_t pid;
621 for (i=1; (i<CS_MAXPID) && (client[i].pid); i++); //find next available client index i
622 if (i<CS_MAXPID)
623 {
624 int fdp[2];
625 memset(&client[i], 0, sizeof(struct s_client));
626 client[i].au=(-1);
627 if (pipe(fdp))
628 {
629 cs_log("Cannot create pipe (errno=%d)", errno);
630 cs_exit(1);
631 }
632
633 make_non_blocking(fdp[0]);
634 make_non_blocking(fdp[1]);
635
636 if (reader[ridx].typ == R_SC8in1 && port == 99) { //SC8in1 reader gets threaded, not forked
637 if (reader[ridx].handle == 0)
638 reader_device_init(&reader[ridx]);
639 cs_log("creating thread for device %s slot %i with ridx %i=%i", reader[ridx].device, reader[ridx].slot, reader[ridx].ridx, ridx);
640 int rc;
641 pthread_t dummy;
642 rc = pthread_create(&dummy, NULL, start_cardreader, (void *)&reader[ridx]);
643 if (rc)
644 cs_log("ERROR; return code from pthread_create() is %d\n", rc);
645 //client part
646 is_server=((ip) || (port<90)) ? 1 : 0; //FIXME global should be local per thread
647 //cs_ptyp=D_CLIENT;
648 client[i].fd_m2c_c = fdp[0]; //store client read fd
649 cs_idx=i; //although thread runs in master process, reserve an cs_idx slot
650#ifndef CS_NOSHM
651 shmid=0;
652#endif
653 //master part
654 client[i].fd_m2c=fdp[1];
655 client[i].dbglvl=cs_dblevel;
656 client[i].stat=1;
657 client[i].typ='r'; // reader
658 client[i].sidtabok=reader[ridx].sidtabok;
659 client[i].sidtabno=reader[ridx].sidtabno;
660 reader[ridx].fd=client[i].fd_m2c;
661 reader[ridx].cs_idx=i; //although thread runs in master process, reserve an cs_idx slot
662 pid=getpid();
663 reader[ridx].pid=pid;
664 if (reader[ridx].r_port)
665 cs_log("proxy thread started (pid=%d, server=%s)",pid, reader[ridx].device);
666 else {
667 switch(reader[ridx].typ) {
668 case R_MOUSE:
669 case R_SMART:
670 cs_log("reader thread started (pid=%d, device=%s, detect=%s%s, mhz=%d, cardmhz=%d)",pid,
671 reader[ridx].device,reader[ridx].detect&0x80 ? "!" : "",RDR_CD_TXT[reader[ridx].detect&0x7f],
672 reader[ridx].mhz,reader[ridx].cardmhz);
673 break;
674 case R_SC8in1:
675 cs_log("reader thread started (pid=%d, device=%s:%i, detect=%s%s, mhz=%d, cardmhz=%d)",pid,
676 reader[ridx].device,reader[ridx].slot,reader[ridx].detect&0x80 ? "!" : "",
677 RDR_CD_TXT[reader[ridx].detect&0x7f],reader[ridx].mhz,reader[ridx].cardmhz);
678 break;
679 default:
680 cs_log("reader thread started (pid=%d, device=%s)",pid, reader[ridx].device);
681 }
682 client[i].ip=client[0].ip;
683 strcpy(client[i].usr, client[0].usr);
684 }
685 cdiff=i;
686 client[i].login=client[i].last=time((time_t *)0);
687 client[i].pid=pid; // MUST be last -> wait4master()
688 cs_last_idx=i;
689 i=0;
690 }
691 else {
692 pid=fork();
693 switch(pid)
694 {
695 case -1:
696 cs_log("PANIC: Cannot fork() (errno=%d)", errno);
697 cs_exit(1);
698 case 0: // HERE is client
699 alarm(0);
700 set_signal_handler(SIGALRM, 0, cs_alarm);
701 set_signal_handler(SIGCHLD, 1, SIG_IGN);
702 set_signal_handler(SIGHUP , 1, SIG_IGN);
703 set_signal_handler(SIGINT , 1, SIG_IGN);
704 set_signal_handler(SIGUSR1, 1, cs_debug_level);
705 is_server=((ip) || (port<90)) ? 1 : 0;
706 client[i].fd_m2c_c=fdp[0];
707 close(fdp[1]);
708 close(mfdr);
709 //cs_log("FORK-CLIENT: fd_m2c_c=%d", client[i].fd_m2c_c);
710 //SS:if( port!=97 ) cs_close_log();
711 mfdr=0;
712 cs_ptyp=D_CLIENT;
713 cs_idx=i;
714#ifndef CS_NOSHM
715 shmid=0;
716#endif
717 break;
718 default: // HERE is master
719 client[i].fd_m2c=fdp[1];
720 client[i].dbglvl=cs_dblevel;
721 close(fdp[0]);
722 //cs_log("FORK-MASTER: fd_m2c=%d", client[i].fd_m2c);
723 if (ip)
724 {
725 client[i].typ='c'; // dynamic client
726 client[i].ip=ip;
727 client[i].port=port;
728 cs_log("client(%d) connect from %s (pid=%d, pipfd=%d)",
729 i-cdiff, cs_inet_ntoa(ip), pid, client[i].fd_m2c);
730 }
731 else
732 {
733 client[i].stat=1;
734 switch(port)
735 {
736 case 99: client[i].typ='r'; // reader that is not Sc8in1 gets forked, not threaded
737 client[i].sidtabok=reader[ridx].sidtabok;
738 client[i].sidtabno=reader[ridx].sidtabno;
739 reader[ridx].fd=client[i].fd_m2c;
740 reader[ridx].cs_idx=i;
741 reader[ridx].pid=pid;
742 if (reader[ridx].r_port)
743 cs_log("proxy started (pid=%d, server=%s)",
744 pid, reader[ridx].device);
745 else
746 {
747 if (reader[ridx].typ==R_MOUSE || reader[ridx].typ==R_SMART)
748 cs_log("reader started (pid=%d, device=%s, detect=%s%s, mhz=%d, cardmhz=%d)",
749 pid, reader[ridx].device,
750 reader[ridx].detect&0x80 ? "!" : "",
751 RDR_CD_TXT[reader[ridx].detect&0x7f],
752 reader[ridx].mhz,
753 reader[ridx].cardmhz);
754 else
755 cs_log("reader started (pid=%d, device=%s)",
756 pid, reader[ridx].device);
757 client[i].ip=client[0].ip;
758 strcpy(client[i].usr, client[0].usr);
759 }
760 cdiff=i;
761 break;
762 case 97: client[i].typ='l'; // logger
763 client[i].ip=client[0].ip;
764 strcpy(client[i].usr, client[0].usr);
765 cs_log("logger started (pid=%d)", pid);
766 cdiff=i;
767 break;
768#ifdef CS_ANTICASC
769 case 96: client[i].typ='a';
770 client[i].ip=client[0].ip;
771 strcpy(client[i].usr, client[0].usr);
772 cs_log("anticascader started (pid=%d, delay=%d min)",
773 pid, cfg->ac_stime);
774 cdiff=i;
775 break;
776#endif
777
778#ifdef WEBIF
779 case 95: client[i].typ='h'; // http
780 client[i].ip=client[0].ip;
781 strcpy(client[i].usr, client[0].usr);
782 cs_log("http started (pid=%d)",pid);
783 cdiff=i;
784 break;
785#endif
786
787 default: client[i].typ='c'; // static client
788 client[i].ip=client[0].ip;
789 client[i].ctyp=port;
790 cs_log("%s: initialized (pid=%d%s)", ph[port].desc,
791 pid, ph[port].logtxt ? ph[port].logtxt : "");
792 break;
793 }
794 }
795 client[i].login=client[i].last=time((time_t *)0);
796 client[i].pid=pid; // MUST be last -> wait4master()
797 cs_last_idx=i;
798 i=0;
799 }//switch
800 }//else
801 }
802 else
803 {
804 cs_log("max connections reached -> reject client %s", cs_inet_ntoa(ip));
805 i=(-1);
806 }
807 return(i);
808}
809
810static void init_signal()
811{
812 int i;
813 for (i=1; i<NSIG; i++)
814 set_signal_handler(i, 3, cs_exit);
815 set_signal_handler(SIGWINCH, 1, SIG_IGN);
816 // set_signal_handler(SIGPIPE , 0, SIG_IGN);
817 set_signal_handler(SIGPIPE , 0, cs_sigpipe);
818 // set_signal_handler(SIGALRM , 0, cs_alarm);
819 set_signal_handler(SIGALRM , 0, cs_master_alarm);
820 set_signal_handler(SIGCHLD , 1, cs_child_chk);
821 // set_signal_handler(SIGHUP , 1, cs_accounts_chk);
822 set_signal_handler(SIGHUP , 1, cs_sighup);
823 set_signal_handler(SIGUSR1, 1, cs_debug_level);
824 set_signal_handler(SIGUSR2, 1, cs_card_info);
825 set_signal_handler(SIGCONT, 1, SIG_IGN);
826 cs_log("signal handling initialized (type=%s)",
827#ifdef CS_SIGBSD
828 "bsd"
829#else
830 "sysv"
831#endif
832 );
833 return;
834}
835
836static void init_shm()
837{
838#ifdef CS_NOSHM
839 //int i, fd;
840 char *buf;
841 if ((shmid=open(cs_memfile, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR))<0)
842 {
843 fprintf(stderr, "Cannot create mmaped file (errno=%d)", errno);
844 cs_exit(1);
845 }
846
847 buf=(char *)malloc(shmsize);
848 memset(buf, 0, shmsize);
849 if (!write(shmid, buf, shmsize)) cs_exit(1);
850 free(buf);
851
852 ecmcache=(struct s_ecm *)mmap((void *)0, (size_t) shmsize,
853 PROT_READ|PROT_WRITE, MAP_SHARED, shmid, 0);
854#else
855 struct shmid_ds sd;
856 char *shmerr_txt="Cannot %s shared memory (errno=%d)\n";
857 if ((shmid=shmget(IPC_PRIVATE, shmsize, IPC_CREAT | 0600))<0)
858 {
859 fprintf(stderr, shmerr_txt, "create", errno);
860 shmid=0;
861 cs_exit(1);
862 }
863 if ((ecmcache=(struct s_ecm *)shmat(shmid, 0, 0))==(void *)(-1))
864 {
865 fprintf(stderr, shmerr_txt, "attach", errno);
866 cs_exit(1);
867 }
868 memset(ecmcache, 0, shmsize);
869 shmctl(shmid, IPC_RMID, &sd);
870#endif
871#ifdef CS_ANTICASC
872 acasc=(struct s_acasc_shm *)&ecmcache[CS_ECMCACHESIZE];
873 ecmidx=(int *)&acasc[CS_MAXPID];
874#else
875 ecmidx=(int *)&ecmcache[CS_ECMCACHESIZE];
876#endif
877 mcl=(int *)((void *)ecmidx+sizeof(int));
878 logidx=(int *)((void *)mcl+sizeof(int));
879 c_start=(int *)((void *)logidx+sizeof(int));
880 log_fd=(int *)((void *)c_start+sizeof(int));
881 oscam_sem=(int *)((void *)log_fd+sizeof(int));
882 client=(struct s_client *)((void *)oscam_sem+sizeof(int));
883 reader=(struct s_reader *)&client[CS_MAXPID];
884#ifdef CS_WITH_GBOX
885 Cards=(struct card_struct*)&reader[CS_MAXREADER];
886 IgnoreList=(unsigned long*)&Cards[CS_MAXCARDS];
887 idstore=(struct idstore_struct*)&IgnoreList[CS_MAXIGNORE];
888 cfg=(struct s_config *)&idstore[CS_MAXPID];
889#else
890 cfg=(struct s_config *)&reader[CS_MAXREADER];
891#endif
892#ifdef CS_LOGHISTORY
893 loghistidx=(int *)((void *)cfg+sizeof(struct s_config));
894 loghist=(char *)((void *)loghistidx+sizeof(int));
895#endif
896
897#ifdef DEBUG_SHM_POINTER
898 printf("SHM ALLOC: %x\n", shmsize);
899 printf("SHM START: %p\n", (void *) ecmcache);
900 printf("SHM ST1: %p %x (%x)\n", (void *) ecmidx, ((void *) ecmidx) - ((void *) ecmcache), CS_ECMCACHESIZE*(sizeof(struct s_ecm)));
901 printf("SHM ST2: %p %x (%x)\n", (void *) oscam_sem, ((void *) oscam_sem) - ((void *) ecmidx), sizeof(int));
902 printf("SHM ST3: %p %x (%x)\n", (void *) client, ((void *) client) - ((void *) oscam_sem), sizeof(int));
903 printf("SHM ST4: %p %x (%x)\n", (void *) reader, ((void *) reader) - ((void *) client), CS_MAXPID*(sizeof(struct s_client)));
904 printf("SHM ST5: %p %x (%x)\n", (void *) cfg, ((void *) cfg) - ((void *) reader), CS_MAXREADER*(sizeof(struct s_reader)));
905 printf("SHM ST6: %p %x (%x)\n", ((void *) cfg)+sizeof(struct s_config), sizeof(struct s_config), sizeof(struct s_config));
906 printf("SHM ENDE: %p\n", ((void *) cfg)+sizeof(struct s_config));
907 printf("SHM SIZE: %x\n", ((void *) cfg)-((void *) ecmcache) + sizeof(struct s_config));
908 fflush(stdout);
909#endif
910
911 *ecmidx=0;
912 *logidx=0;
913 *oscam_sem=0;
914 client[0].pid=getpid();
915 client[0].login=time((time_t *)0);
916 client[0].ip=cs_inet_addr("127.0.0.1");
917 client[0].typ='s';
918 client[0].au=(-1);
919 client[0].dbglvl=cs_dblevel;
920
921 // get username master running under
922 struct passwd *pwd;
923 if ((pwd = getpwuid(getuid())) != NULL)
924 strcpy(client[0].usr, pwd->pw_name);
925 else
926 strcpy(client[0].usr, "root");
927
928 pthread_mutex_init(&gethostbyname_lock, NULL);
929 init_stat();
930
931#ifdef CS_LOGHISTORY
932 *loghistidx=0;
933 memset(loghist, 0, CS_MAXLOGHIST*CS_LOGHISTSIZE);
934#endif
935}
936
937static int start_listener(struct s_module *ph, int port_idx)
938{
939 int ov=1, timeout, is_udp, i;
940 char ptxt[2][32];
941 //struct hostent *ptrh; /* pointer to a host table entry */
942 struct protoent *ptrp; /* pointer to a protocol table entry */
943 struct sockaddr_in sad; /* structure to hold server's address */
944
945 ptxt[0][0]=ptxt[1][0]='\0';
946 if (!ph->ptab->ports[port_idx].s_port)
947 {
948 cs_log("%s: disabled", ph->desc);
949 return(0);
950 }
951 is_udp=(ph->type==MOD_CONN_UDP);
952
953 memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
954 sad.sin_family = AF_INET; /* set family to Internet */
955 if (!ph->s_ip)
956 ph->s_ip=cfg->srvip;
957 if (ph->s_ip)
958 {
959 sad.sin_addr.s_addr=ph->s_ip;
960 sprintf(ptxt[0], ", ip=%s", inet_ntoa(sad.sin_addr));
961 }
962 else
963 sad.sin_addr.s_addr=INADDR_ANY;
964 timeout=cfg->bindwait;
965 //ph->fd=0;
966 ph->ptab->ports[port_idx].fd = 0;
967
968 if (ph->ptab->ports[port_idx].s_port > 0) /* test for illegal value */
969 sad.sin_port = htons((u_short)ph->ptab->ports[port_idx].s_port);
970 else
971 {
972 cs_log("%s: Bad port %d", ph->desc, ph->ptab->ports[port_idx].s_port);
973 return(0);
974 }
975
976 /* Map transport protocol name to protocol number */
977
978 if( (ptrp=getprotobyname(is_udp ? "udp" : "tcp")) )
979 ov=ptrp->p_proto;
980 else
981 ov=(is_udp) ? 17 : 6; // use defaults on error
982
983 if ((ph->ptab->ports[port_idx].fd=socket(PF_INET,is_udp ? SOCK_DGRAM : SOCK_STREAM, ov))<0)
984 {
985 cs_log("%s: Cannot create socket (errno=%d)", ph->desc, errno);
986 return(0);
987 }
988
989 ov=1;
990 if (setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_REUSEADDR, (void *)&ov, sizeof(ov))<0)
991 {
992 cs_log("%s: setsockopt failed (errno=%d)", ph->desc, errno);
993 close(ph->ptab->ports[port_idx].fd);
994 return(ph->ptab->ports[port_idx].fd=0);
995 }
996
997#ifdef SO_REUSEPORT
998 setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_REUSEPORT, (void *)&ov, sizeof(ov));
999#endif
1000
1001#ifdef SO_PRIORITY
1002 if (cfg->netprio)
1003 if (!setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_PRIORITY, (void *)&cfg->netprio, sizeof(ulong)))
1004 sprintf(ptxt[1], ", prio=%ld", cfg->netprio);
1005#endif
1006
1007 if( !is_udp )
1008 {
1009 ulong keep_alive = 1;
1010 setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_KEEPALIVE,
1011 (void *)&keep_alive, sizeof(ulong));
1012 }
1013
1014 while (timeout--)
1015 {
1016 if (bind(ph->ptab->ports[port_idx].fd, (struct sockaddr *)&sad, sizeof (sad))<0)
1017 {
1018 if (timeout)
1019 {
1020 cs_log("%s: Bind request failed, waiting another %d seconds",
1021 ph->desc, timeout);
1022 cs_sleepms(1000);
1023 }
1024 else
1025 {
1026 cs_log("%s: Bind request failed, giving up", ph->desc);
1027 close(ph->ptab->ports[port_idx].fd);
1028 return(ph->ptab->ports[port_idx].fd=0);
1029 }
1030 }
1031 else timeout=0;
1032 }
1033
1034 if (!is_udp)
1035 if (listen(ph->ptab->ports[port_idx].fd, CS_QLEN)<0)
1036 {
1037 cs_log("%s: Cannot start listen mode (errno=%d)", ph->desc, errno);
1038 close(ph->ptab->ports[port_idx].fd);
1039 return(ph->ptab->ports[port_idx].fd=0);
1040 }
1041
1042 cs_log("%s: initialized (fd=%d, port=%d%s%s%s)",
1043 ph->desc, ph->ptab->ports[port_idx].fd,
1044 ph->ptab->ports[port_idx].s_port,
1045 ptxt[0], ptxt[1], ph->logtxt ? ph->logtxt : "");
1046
1047 for( i=0; i<ph->ptab->ports[port_idx].ftab.nfilts; i++ ) {
1048 int j;
1049 cs_log("CAID: %04X", ph->ptab->ports[port_idx].ftab.filts[i].caid );
1050 for( j=0; j<ph->ptab->ports[port_idx].ftab.filts[i].nprids; j++ )
1051 cs_log("provid #%d: %06X", j, ph->ptab->ports[port_idx].ftab.filts[i].prids[j]);
1052 }
1053 return(ph->ptab->ports[port_idx].fd);
1054}
1055
1056static void cs_client_resolve()
1057{
1058 while (1)
1059 {
1060 struct addrinfo hints, *res = NULL;
1061 struct s_auth *account;
1062
1063 for (account=cfg->account; account; account=account->next)
1064 if (account->dyndns[0])
1065 {
1066 pthread_mutex_lock(&gethostbyname_lock);
1067 memset(&hints, 0, sizeof(hints));
1068 hints.ai_socktype = SOCK_STREAM;
1069 hints.ai_family = AF_INET;
1070 hints.ai_protocol = IPPROTO_TCP;
1071
1072 int err = getaddrinfo((const char*)account->dyndns, NULL, &hints, &res);
1073 if (err != 0 || !res || !res->ai_addr) {
1074 cs_log("can't resolve %s, error: %s", account->dyndns, err ? gai_strerror(err) : "unknown");
1075 }
1076 else {
1077 account->dynip=cs_inet_order(((struct sockaddr_in *)(res->ai_addr))->sin_addr.s_addr);
1078 }
1079 if (res) freeaddrinfo(res);
1080 pthread_mutex_unlock(&gethostbyname_lock);
1081 }
1082 sleep(cfg->resolvedelay);
1083 }
1084}
1085
1086static void start_thread(void * startroutine, char * nameroutine)
1087{
1088 int i;
1089 pthread_t tid;
1090
1091 i=pthread_create(&tid, (pthread_attr_t *)0, startroutine, (void *) 0);
1092 if (i)
1093 cs_log("ERROR: can't create %s thread (err=%d)", i, nameroutine);
1094 else
1095 {
1096 cs_log("%s thread started", nameroutine);
1097 pthread_detach(tid);
1098 }
1099}
1100
1101static void cs_logger(void)
1102{
1103 *log_fd=client[cs_idx].fd_m2c;
1104 while(1)
1105 {
1106 uchar *ptr;
1107 //struct timeval tv;
1108 fd_set fds;
1109
1110 FD_ZERO(&fds);
1111 FD_SET(client[cs_idx].fd_m2c_c, &fds);
1112 select(client[cs_idx].fd_m2c_c+1, &fds, 0, 0, 0);
1113
1114 if (master_pid!=getppid())
1115 cs_exit(0);
1116
1117 if (FD_ISSET(client[cs_idx].fd_m2c_c, &fds))
1118 {
1119 int n;
1120// switch(n=read_from_pipe(client[cs_idx].fd_m2c_c, &ptr, 1))
1121 n=read_from_pipe(client[cs_idx].fd_m2c_c, &ptr, 1);
1122//if (n!=PIP_ID_NUL) printf("received %d bytes\n", n); fflush(stdout);
1123 switch(n)
1124 {
1125 case PIP_ID_LOG:
1126 cs_write_log((char *)ptr);
1127 break;
1128 }
1129 }
1130 }
1131}
1132
1133#ifdef CS_ANTICASC
1134static void start_anticascader()
1135{
1136 int i;
1137
1138 use_ac_log=1;
1139 set_signal_handler(SIGHUP, 1, ac_init_stat);
1140
1141 ac_init_stat();
1142 while(1)
1143 {
1144 for( i=0; i<cfg->ac_stime*60; i++ )
1145 if( master_pid!=getppid() )
1146 cs_exit(0);
1147 else
1148 cs_sleepms(1000);
1149
1150 if (master_pid!=getppid())
1151 cs_exit(0);
1152
1153 ac_do_stat();
1154 }
1155}
1156#endif
1157
1158#ifdef WEBIF
1159static void cs_http()
1160{
1161 http_srv();
1162}
1163#endif
1164
1165
1166static void init_cardreader()
1167{
1168 for (ridx=0; ridx<CS_MAXREADER; ridx++) {
1169 reader[ridx].ridx = ridx; //FIXME
1170 if ((reader[ridx].device[0]) && (reader[ridx].enable == 1)) {
1171 switch(cs_fork(0, 99)) {
1172 case -1:
1173 cs_exit(1);
1174 case 0:
1175 break;
1176 default:
1177 wait4master();
1178 start_cardreader(&reader[ridx]);
1179 }
1180 }
1181 }
1182}
1183
1184static void init_service(int srv)
1185{
1186 switch(cs_fork(0, srv))
1187 {
1188 case -1:
1189 cs_exit(1);
1190 case 0:
1191 break;
1192 default:
1193 wait4master();
1194 switch(srv)
1195 {
1196#ifdef CS_ANTICASC
1197 case 96: start_anticascader();
1198#endif
1199 case 97: cs_logger();
1200#ifdef WEBIF
1201 case 95: cs_http();
1202#endif
1203 }
1204 }
1205}
1206
1207void wait4master()
1208{
1209 int i;
1210 for (i=0; (i<1000) && (client[cs_idx].pid!=getpid()); i++)
1211 cs_sleepms(1);
1212 if (client[cs_idx].pid!=getpid())
1213 {
1214 cs_log("PANIC: client not found in shared memory");
1215 cs_exit(1);
1216 }
1217 cs_debug("starting client %d with ip %s",
1218 cs_idx-cdiff, cs_inet_ntoa(client[cs_idx].ip));
1219}
1220
1221static void cs_fake_client(char *usr, int uniq, in_addr_t ip)
1222{
1223 /* Uniq = 1: only one connection per user
1224 *
1225 * Uniq = 2: set (new connected) user only to fake if source
1226 * ip is different (e.g. for newcamd clients with
1227 * different CAID's -> Ports)
1228 *
1229 * Uniq = 3: only one connection per user, but only the last
1230 * login will survive (old mpcs behavior)
1231 *
1232 * Uniq = 4: set user only to fake if source ip is
1233 * different, but only the last login will survive
1234 */
1235
1236 int i;
1237 for (i=cdiff+1; i<CS_MAXPID; i++)
1238 {
1239 if (client[i].pid && (client[i].typ == 'c') && !client[i].dup && !strcmp(client[i].usr, usr)
1240 && (uniq < 5) && ((uniq % 2) || (client[i].ip != ip)))
1241 {
1242 if (uniq == 3 || uniq == 4)
1243 {
1244 client[i].dup = 1;
1245 client[i].au = -1;
1246 cs_log("client(%d) duplicate user '%s' from %s set to fake (uniq=%d)", i-cdiff, usr, cs_inet_ntoa(ip), uniq);
1247 }
1248 else
1249 {
1250 client[cs_idx].dup = 1;
1251 client[cs_idx].au = -1;
1252 cs_log("client(%d) duplicate user '%s' from %s set to fake (uniq=%d)", cs_idx-cdiff, usr, cs_inet_ntoa(ip), uniq);
1253 break;
1254 }
1255
1256 }
1257 }
1258
1259}
1260
1261int cs_auth_client(struct s_auth *account, char *e_txt)
1262{
1263 int rc=0;
1264 char buf[32];
1265 char *t_crypt="encrypted";
1266 char *t_plain="plain";
1267 char *t_grant=" granted";
1268 char *t_reject=" rejected";
1269 char *t_msg[]= { buf, "invalid access", "invalid ip", "unknown reason" };
1270 client[cs_idx].grp=0xffffffff;
1271 client[cs_idx].au=(-1);
1272 switch((long)account)
1273 {
1274#ifdef CS_WITH_GBOX
1275 case -2: // gbx-dummy
1276 client[cs_idx].dup=0;
1277 break;
1278#endif
1279 case 0: // reject access
1280 rc=1;
1281 cs_log("%s %s-client %s%s (%s)",
1282 client[cs_idx].crypted ? t_crypt : t_plain,
1283 ph[client[cs_idx].ctyp].desc,
1284 client[cs_idx].ip ? cs_inet_ntoa(client[cs_idx].ip) : "",
1285 client[cs_idx].ip ? t_reject : t_reject+1,
1286 e_txt ? e_txt : t_msg[rc]);
1287 break;
1288 default: // grant/check access
1289 if (client[cs_idx].ip && account->dyndns[0]) {
1290 if (cfg->clientdyndns) {
1291 if (client[cs_idx].ip != account->dynip)
1292 rc=2;
1293 }
1294 else
1295 cs_log("Warning: clientdyndns disabled in config. Enable clientdyndns to use hostname restrictions");
1296 }
1297
1298 if (!rc)
1299 {
1300 client[cs_idx].dup=0;
1301 if (client[cs_idx].typ=='c')
1302 {
1303 client[cs_idx].last_caid = 0xFFFE;
1304 client[cs_idx].last_srvid = 0xFFFE;
1305 client[cs_idx].expirationdate=account->expirationdate;
1306 client[cs_idx].disabled=account->disabled;
1307 client[cs_idx].c35_suppresscmd08 = account->c35_suppresscmd08;
1308 client[cs_idx].ncd_keepalive = account->ncd_keepalive;
1309 client[cs_idx].grp=account->grp;
1310 client[cs_idx].au=account->au;
1311 client[cs_idx].autoau=account->autoau;
1312 client[cs_idx].tosleep=(60*account->tosleep);
1313 client[cs_idx].c35_sleepsend = account->c35_sleepsend;
1314 memcpy(&client[cs_idx].ctab, &account->ctab, sizeof(client[cs_idx].ctab));
1315 if (account->uniq)
1316 cs_fake_client(account->usr, account->uniq, client[cs_idx].ip);
1317 client[cs_idx].ftab = account->ftab; // IDENT filter
1318 client[cs_idx].cltab = account->cltab; // CLASS filter
1319 client[cs_idx].fchid = account->fchid; // CHID filter
1320 client[cs_idx].sidtabok= account->sidtabok; // services
1321 client[cs_idx].sidtabno= account->sidtabno; // services
1322 client[cs_idx].pcrc = crc32(0L, MD5((uchar *)account->pwd, strlen(account->pwd), NULL), 16);
1323 memcpy(&client[cs_idx].ttab, &account->ttab, sizeof(client[cs_idx].ttab));
1324#ifdef CS_ANTICASC
1325 ac_init_client(account);
1326#endif
1327 }
1328 }
1329 client[cs_idx].monlvl=account->monlvl;
1330 strcpy(client[cs_idx].usr, account->usr);
1331 case -1: // anonymous grant access
1332 if (rc)
1333 t_grant=t_reject;
1334 else
1335 {
1336 if (client[cs_idx].typ=='m')
1337 sprintf(t_msg[0], "lvl=%d", client[cs_idx].monlvl);
1338 else
1339 {
1340 if(client[cs_idx].autoau)
1341 {
1342 if(client[cs_idx].ncd_server)
1343 {
1344 int r=0;
1345 for(r=0;r<CS_MAXREADER;r++)
1346 {
1347 if(reader[r].caid[0]==cfg->ncd_ptab.ports[client[cs_idx].port_idx].ftab.filts[0].caid)
1348 {
1349 client[cs_idx].au=r;
1350 break;
1351 }
1352 }
1353 if(client[cs_idx].au<0) sprintf(t_msg[0], "au(auto)=%d", client[cs_idx].au+1);
1354 else sprintf(t_msg[0], "au(auto)=%s", reader[client[cs_idx].au].label);
1355 }
1356 else
1357 {
1358 sprintf(t_msg[0], "au=auto");
1359 }
1360 }
1361 else
1362 {
1363 if(client[cs_idx].au<0) sprintf(t_msg[0], "au=%d", client[cs_idx].au+1);
1364 else sprintf(t_msg[0], "au=%s", reader[client[cs_idx].au].label);
1365 }
1366 }
1367 }
1368 if(client[cs_idx].ncd_server)
1369 {
1370 cs_log("%s %s:%d-client %s%s (%s, %s)",
1371 client[cs_idx].crypted ? t_crypt : t_plain,
1372 e_txt ? e_txt : ph[client[cs_idx].ctyp].desc,
1373 cfg->ncd_ptab.ports[client[cs_idx].port_idx].s_port,
1374 client[cs_idx].ip ? cs_inet_ntoa(client[cs_idx].ip) : "",
1375 client[cs_idx].ip ? t_grant : t_grant+1,
1376 username(cs_idx), t_msg[rc]);
1377 }
1378 else
1379 {
1380 cs_log("%s %s-client %s%s (%s, %s)",
1381 client[cs_idx].crypted ? t_crypt : t_plain,
1382 e_txt ? e_txt : ph[client[cs_idx].ctyp].desc,
1383 client[cs_idx].ip ? cs_inet_ntoa(client[cs_idx].ip) : "",
1384 client[cs_idx].ip ? t_grant : t_grant+1,
1385 username(cs_idx), t_msg[rc]);
1386 }
1387
1388 break;
1389 }
1390 return(rc);
1391}
1392
1393void cs_disconnect_client(void)
1394{
1395 char buf[32]={0};
1396 if (client[cs_idx].ip)
1397 sprintf(buf, " from %s", cs_inet_ntoa(client[cs_idx].ip));
1398 cs_log("%s disconnected %s", username(cs_idx), buf);
1399 cs_exit(0);
1400}
1401
1402/**
1403 * cache 1: client-invoked
1404 * returns found ecm task index
1405 **/
1406int check_ecmcache1(ECM_REQUEST *er, ulong grp)
1407{
1408 int i;
1409 //cs_ddump(ecmd5, CS_ECMSTORESIZE, "ECM search");
1410 //cs_log("cache1 CHECK: grp=%lX", grp);
1411 for(i=0; i<CS_ECMCACHESIZE; i++) {
1412 if ((grp & ecmcache[i].grp) &&
1413 ecmcache[i].caid==er->caid &&
1414 (!memcmp(ecmcache[i].ecmd5, er->ecmd5, CS_ECMSTORESIZE)))
1415 {
1416 //cs_log("cache1 found: grp=%lX cgrp=%lX", grp, ecmcache[i].grp);
1417 memcpy(er->cw, ecmcache[i].cw, 16);
1418 er->reader[0] = ecmcache[i].reader;
1419 return(1);
1420 }
1421 }
1422 return(0);
1423}
1424
1425/**
1426 * cache 2: reader-invoked
1427 * returns 1 if found in cache. cw is copied to er
1428 **/
1429int check_ecmcache2(ECM_REQUEST *er, ulong grp)
1430{
1431 // disable cache2
1432 if (!reader[ridx].cachecm) return(0);
1433
1434 int i;
1435 //cs_ddump(ecmd5, CS_ECMSTORESIZE, "ECM search");
1436 //cs_log("cache2 CHECK: grp=%lX", grp);
1437 for(i=0; i<CS_ECMCACHESIZE; i++) {
1438 if ((grp & ecmcache[i].grp) &&
1439 ecmcache[i].caid==er->caid &&
1440 (!memcmp(ecmcache[i].ecmd5, er->ecmd5, CS_ECMSTORESIZE)))
1441 {
1442 //cs_log("cache2 found: grp=%lX cgrp=%lX", grp, ecmcache[i].grp);
1443 memcpy(er->cw, ecmcache[i].cw, 16);
1444 return(1);
1445 }
1446 }
1447 return(0);
1448}
1449
1450
1451static void store_ecm(ECM_REQUEST *er)
1452{
1453 int rc;
1454 rc=*ecmidx;
1455 *ecmidx=(*ecmidx+1) % CS_ECMCACHESIZE;
1456 //cs_log("store ecm from reader %d", er->reader[0]);
1457 memcpy(ecmcache[rc].ecmd5, er->ecmd5, CS_ECMSTORESIZE);
1458 memcpy(ecmcache[rc].cw, er->cw, 16);
1459 ecmcache[rc].caid = er->caid;
1460 ecmcache[rc].grp = reader[er->reader[0]].grp;
1461 ecmcache[rc].reader = er->reader[0];
1462 //cs_ddump(ecmcache[*ecmidx].ecmd5, CS_ECMSTORESIZE, "ECM stored (idx=%d)", *ecmidx);
1463}
1464
1465void store_logentry(char *txt)
1466{
1467#ifdef CS_LOGHISTORY
1468 char *ptr;
1469 ptr=(char *)(loghist+(*loghistidx*CS_LOGHISTSIZE));
1470 ptr[0]='\1'; // make username unusable
1471 ptr[1]='\0';
1472 if ((client[cs_idx].typ=='c') || (client[cs_idx].typ=='m'))
1473 cs_strncpy(ptr, client[cs_idx].usr, 31);
1474 cs_strncpy(ptr+32, txt, CS_LOGHISTSIZE-33);
1475 *loghistidx=(*loghistidx+1) % CS_MAXLOGHIST;
1476#endif
1477}
1478
1479/*
1480 * write_to_pipe():
1481 * write all kind of data to pipe specified by fd
1482 */
1483int write_to_pipe(int fd, int id, uchar *data, int n)
1484{
1485 if( !fd ) {
1486 cs_log("write_to_pipe: fd==0 id: %d", id);
1487 return -1;
1488 }
1489
1490//printf("WRITE_START pid=%d", getpid()); fflush(stdout);
1491
1492 uchar buf[1024+3+sizeof(int)];
1493
1494 if ((id<0) || (id>PIP_ID_MAX))
1495 return(PIP_ID_ERR);
1496 memcpy(buf, PIP_ID_TXT[id], 3);
1497 memcpy(buf+3, &n, sizeof(int));
1498 memcpy(buf+3+sizeof(int), data, n);
1499 n+=3+sizeof(int);
1500
1501//n=write(fd, buf, n);
1502//printf("WRITE_END pid=%d", getpid()); fflush(stdout);
1503//return(n);
1504
1505 return(write(fd, buf, n));
1506}
1507
1508/*
1509 * read_from_pipe():
1510 * read all kind of data from pipe specified by fd
1511 * special-flag redir: if set AND data is ECM: this will redirected to appr. client
1512 */
1513int read_from_pipe(int fd, uchar **data, int redir)
1514{
1515 int rc;
1516 static int hdr=0;
1517 static uchar buf[1024+1+3+sizeof(int)];
1518
1519 *data=(uchar *)0;
1520 rc=PIP_ID_NUL;
1521
1522 if (!hdr)
1523 {
1524 if (bytes_available(fd))
1525 {
1526 if (read(fd, buf, 3+sizeof(int))==3+sizeof(int))
1527 memcpy(&hdr, buf+3, sizeof(int));
1528 else
1529 cs_log("WARNING: pipe header to small !");
1530 }
1531 }
1532 if (hdr)
1533 {
1534 int l;
1535 for (l=0; (rc<0) && (PIP_ID_TXT[l]); l++)
1536 if (!memcmp(buf, PIP_ID_TXT[l], 3))
1537 rc=l;
1538
1539 if (rc<0)
1540 {
1541 fprintf(stderr, "WARNING: pipe garbage from pipe %i", fd);
1542 fflush(stderr);
1543 cs_log("WARNING: pipe garbage from pipe %i", fd);
1544 rc=PIP_ID_ERR;
1545 }
1546 else
1547 {
1548 l=hdr;
1549 if ((l+3-1+sizeof(int))>sizeof(buf))
1550 {
1551 cs_log("WARNING: packet size (%d) to large", l);
1552 l=sizeof(buf)+3-1+sizeof(int);
1553 }
1554 if (!bytes_available(fd))
1555 return(PIP_ID_NUL);
1556 hdr=0;
1557 if (read(fd, buf+3+sizeof(int), l)==l)
1558 *data=buf+3+sizeof(int);
1559 else
1560 {
1561 cs_log("WARNING: pipe data to small !");
1562 return(PIP_ID_ERR);
1563 }
1564 buf[l+3+sizeof(int)]=0;
1565 if ((redir) && (rc==PIP_ID_ECM))
1566 {
1567 //int idx;
1568 ECM_REQUEST *er;
1569 er=(ECM_REQUEST *)(buf+3+sizeof(int));
1570 if( er->cidx && client[er->cidx].fd_m2c )
1571 if (!write(client[er->cidx].fd_m2c, buf, l+3+sizeof(int))) cs_exit(1);
1572 rc=PIP_ID_DIR;
1573 }
1574 }
1575 }
1576 return(rc);
1577}
1578
1579/*
1580 * write_ecm_request():
1581 */
1582int write_ecm_request(int fd, ECM_REQUEST *er)
1583{
1584 return(write_to_pipe(fd, PIP_ID_ECM, (uchar *) er, sizeof(ECM_REQUEST)));
1585}
1586
1587int write_ecm_DCW(int fd, ECM_REQUEST *er)
1588{
1589 return(write_to_pipe(fd, PIP_ID_DCW, (uchar *) er, sizeof(ECM_REQUEST)));
1590}
1591
1592/*
1593 * This function writes the current CW from ECM struct to a cwl file.
1594 * The filename is re-calculated and file re-opened every time.
1595 * This will consume a bit cpu time, but nothing has to be stored between
1596 * each call. If not file exists, a header is prepended
1597 */
1598void logCWtoFile(ECM_REQUEST *er)
1599{
1600 FILE *pfCWL;
1601 char srvname[128];
1602 /* %s / %s _I %04X _ %s .cwl */
1603 char buf[256 + sizeof(srvname)];
1604 char date[7];
1605 unsigned char i, parity, writeheader = 0;
1606 time_t t;
1607 struct tm *timeinfo;
1608 struct s_srvid *this;
1609
1610 /*
1611 * search service name for that id and change characters
1612 * causing problems in file name
1613 */
1614 srvname[0] = 0;
1615 for (this=cfg->srvid; this; this = this->next) {
1616 if (this->srvid == er->srvid) {
1617 cs_strncpy(srvname, this->name, sizeof(srvname));
1618 srvname[sizeof(srvname)-1] = 0;
1619 for (i = 0; srvname[i]; i++)
1620 if (srvname[i] == ' ') srvname[i] = '_';
1621 break;
1622 }
1623 }
1624
1625 /* calc log file name */
1626 time(&t);
1627 timeinfo = localtime(&t);
1628 strftime(date, sizeof(date), "%Y%m%d", timeinfo);
1629 sprintf(buf, "%s/%s_I%04X_%s.cwl", cfg->cwlogdir, date, er->srvid, srvname);
1630
1631 /* open failed, assuming file does not exist, yet */
1632 if((pfCWL = fopen(buf, "r")) == NULL) {
1633 writeheader = 1;
1634 } else {
1635 /* we need to close the file if it was opened correctly */
1636 fclose(pfCWL);
1637 }
1638
1639 if ((pfCWL = fopen(buf, "a+")) == NULL) {
1640 /* maybe this fails because the subdir does not exist. Is there a common function to create it?
1641 for the moment do not print to log on every ecm
1642 cs_log(""error opening cw logfile for writing: %s (errno %d)", buf, errno); */
1643 return;
1644 }
1645 if (writeheader) {
1646 /* no global macro for cardserver name :( */
1647 fprintf(pfCWL, "# OSCam cardserver v%s - http://streamboard.gmc.to:8001/oscam/wiki\n", CS_VERSION_X);
1648 fprintf(pfCWL, "# control word log file for use with tsdec offline decrypter\n");
1649 strftime(buf, sizeof(buf),"DATE %Y-%m-%d, TIME %H:%M:%S, TZ %Z\n", timeinfo);
1650 fprintf(pfCWL, "# %s", buf);
1651 fprintf(pfCWL, "# CAID 0x%04X, SID 0x%04X, SERVICE \"%s\"\n", er->caid, er->srvid, srvname);
1652 }
1653
1654 parity = er->ecm[0]&1;
1655 fprintf(pfCWL, "%d ", parity);
1656 for (i = parity * 8; i < 8 + parity * 8; i++)
1657 fprintf(pfCWL, "%02X ", er->cw[i]);
1658 /* better use incoming time er->tps rather than current time? */
1659 strftime(buf,sizeof(buf),"%H:%M:%S\n", timeinfo);
1660 fprintf(pfCWL, "# %s", buf);
1661 fflush(pfCWL);
1662 fclose(pfCWL);
1663}
1664
1665int write_ecm_answer(struct s_reader * reader, int fd, ECM_REQUEST *er)
1666{
1667 int i;
1668 uchar c;
1669 for (i=0; i<16; i+=4)
1670 {
1671 c=((er->cw[i]+er->cw[i+1]+er->cw[i+2]) & 0xff);
1672 if (er->cw[i+3]!=c)
1673 {
1674 cs_debug("notice: changed dcw checksum byte cw[%i] from %02x to %02x", i+3, er->cw[i+3],c);
1675 er->cw[i+3]=c;
1676 }
1677 }
1678
1679 er->reader[0]=reader->ridx;
1680//cs_log("answer from reader %d (rc=%d)", er->reader[0], er->rc);
1681 er->caid=er->ocaid;
1682
1683#ifdef CS_WITH_GBOX
1684 if (er->rc==1||(er->gbxRidx&&er->rc==0)) {
1685#else
1686 if (er->rc==1) {
1687#endif
1688 store_ecm(er);
1689
1690 /* CWL logging only if cwlogdir is set in config */
1691 if (cfg->cwlogdir != NULL)
1692 logCWtoFile(er);
1693 }
1694
1695 return(write_ecm_request(fd, er));
1696}
1697
1698 /*
1699static int cs_read_timer(int fd, uchar *buf, int l, int msec)
1700{
1701 struct timeval tv;
1702 fd_set fds;
1703 int rc;
1704
1705 if (!fd) return(-1);
1706 tv.tv_sec = msec / 1000;
1707 tv.tv_usec = (msec % 1000) * 1000;
1708 FD_ZERO(&fds);
1709 FD_SET(pfd, &fds);
1710
1711 select(fd+1, &fds, 0, 0, &tv);
1712
1713 rc=0;
1714 if (FD_ISSET(pfd, &fds))
1715 if (!(rc=read(fd, buf, l)))
1716 rc=-1;
1717
1718 return(rc);
1719}*/
1720
1721ECM_REQUEST *get_ecmtask()
1722{
1723 int i, n;
1724 ECM_REQUEST *er=0;
1725
1726 if (!ecmtask)
1727 {
1728 n=(ph[client[cs_idx].ctyp].multi)?CS_MAXPENDING:1;
1729 if( (ecmtask=(ECM_REQUEST *)malloc(n*sizeof(ECM_REQUEST))) )
1730 memset(ecmtask, 0, n*sizeof(ECM_REQUEST));
1731 }
1732
1733 n=(-1);
1734 if (!ecmtask)
1735 {
1736 cs_log("Cannot allocate memory (errno=%d)", errno);
1737 n=(-2);
1738 }
1739 else
1740 if (ph[client[cs_idx].ctyp].multi)
1741 {
1742 for (i=0; (n<0) && (i<CS_MAXPENDING); i++)
1743 if (ecmtask[i].rc<100)
1744 er=&ecmtask[n=i];
1745 }
1746 else
1747 er=&ecmtask[n=0];
1748
1749 if (n<0)
1750 cs_log("WARNING: ecm pending table overflow !");
1751 else
1752 {
1753 memset(er, 0, sizeof(ECM_REQUEST));
1754 er->rc=100;
1755 er->cpti=n;
1756 er->cidx=cs_idx;
1757 cs_ftime(&er->tps);
1758 }
1759 return(er);
1760}
1761
1762void send_reader_stat(int ridx, ECM_REQUEST *er, int rc)
1763{
1764 if (!cfg->reader_auto_loadbalance || rc == 100)
1765 return;
1766 struct timeb tpe;
1767 cs_ftime(&tpe);
1768 int time = 1000*(tpe.time-er->tps.time)+tpe.millitm-er->tps.millitm;
1769
1770 ADD_READER_STAT add_stat;
1771 memset(&add_stat, 0, sizeof(ADD_READER_STAT));
1772 add_stat.ridx = ridx;
1773 add_stat.time = time;
1774 add_stat.rc = rc;
1775 add_stat.caid = er->caid;
1776 add_stat.prid = er->prid;
1777 add_stat.srvid = er->srvid;
1778 write_to_pipe(fd_c2m, PIP_ID_STA, (uchar*)&add_stat, sizeof(ADD_READER_STAT));
1779}
1780
1781int hexserialset(int ridx)
1782{
1783 int i;
1784 for (i = 0; i < 8; i++)
1785 if (reader[ridx].hexserial[i])
1786 return 1;
1787 return 0;
1788}
1789
1790int send_dcw(ECM_REQUEST *er)
1791{
1792 static char *stxt[]={"found", "cache1", "cache2", "emu",
1793 "not found", "timeout", "sleeping",
1794 "fake", "invalid", "corrupt", "no card", "expdate", "disabled", "stopped"};
1795 static char *stxtEx[]={"", "group", "caid", "ident", "class", "chid", "queue", "peer"};
1796 static char *stxtWh[]={"", "user ", "reader ", "server ", "lserver "};
1797 char sby[32]="";
1798 char erEx[32]="";
1799 char uname[38]="";
1800 struct timeb tpe;
1801 ushort lc, *lp;
1802 for (lp=(ushort *)er->ecm+(er->l>>2), lc=0; lp>=(ushort *)er->ecm; lp--)
1803 lc^=*lp;
1804 cs_ftime(&tpe);
1805
1806#ifdef CS_WITH_GBOX
1807 if(er->gbxFrom)
1808 snprintf(uname,sizeof(uname)-1, "%s(%04X)", username(cs_idx), er->gbxFrom);
1809 else
1810#endif
1811 snprintf(uname,sizeof(uname)-1, "%s", username(cs_idx));
1812 if (er->rc==0)
1813 {
1814#ifdef CS_WITH_GBOX
1815 if(reader[er->reader[0]].typ==R_GBOX)
1816 snprintf(sby, sizeof(sby)-1, " by %s(%04X)", reader[er->reader[0]].label,er->gbxCWFrom);
1817 else
1818#endif
1819 // add marker to reader if ECM_REQUEST was betatunneled
1820 if(er->btun)
1821 snprintf(sby, sizeof(sby)-1, " by %s(btun)", reader[er->reader[0]].label);
1822 else
1823 snprintf(sby, sizeof(sby)-1, " by %s", reader[er->reader[0]].label);
1824 }
1825 if (er->rc<4) er->rcEx=0;
1826 if (er->rcEx)
1827 snprintf(erEx, sizeof(erEx)-1, "rejected %s%s", stxtWh[er->rcEx>>4],
1828 stxtEx[er->rcEx&0xf]);
1829
1830 client[cs_idx].cwlastresptime = 1000*(tpe.time-er->tps.time)+tpe.millitm-er->tps.millitm;
1831
1832#ifdef CS_LED
1833 if(!er->rc) cs_switch_led(LED2, LED_BLINK_OFF);
1834#endif
1835
1836 send_reader_stat(er->reader[0], er, er->rc);
1837
1838 if(cfg->mon_appendchaninfo)
1839 cs_log("%s (%04X&%06X/%04X/%02X:%04X): %s (%d ms)%s - %s",
1840 uname, er->caid, er->prid, er->srvid, er->l, lc,
1841 er->rcEx?erEx:stxt[er->rc], client[cs_idx].cwlastresptime, sby, get_servicename(er->srvid, er->caid));
1842 else
1843 cs_log("%s (%04X&%06X/%04X/%02X:%04X): %s (%d ms)%s",
1844 uname, er->caid, er->prid, er->srvid, er->l, lc,
1845 er->rcEx?erEx:stxt[er->rc], client[cs_idx].cwlastresptime, sby);
1846#ifdef WEBIF
1847 if(er->rc == 0)
1848 snprintf(client[cs_idx].lastreader, sizeof(client[cs_idx].lastreader)-1, "%s", sby);
1849 else if ((er->rc == 1) || (er->rc == 2))
1850 snprintf(client[cs_idx].lastreader, sizeof(client[cs_idx].lastreader)-1, "by %s (cache)", reader[er->reader[0]].label);
1851 else
1852 snprintf(client[cs_idx].lastreader, sizeof(client[cs_idx].lastreader)-1, "%s", stxt[er->rc]);
1853#endif
1854
1855 if(!client[cs_idx].ncd_server && client[cs_idx].autoau && er->rcEx==0)
1856 {
1857 if(client[cs_idx].au>=0 && er->caid!=reader[client[cs_idx].au].caid[0])
1858 {
1859 client[cs_idx].au=(-1);
1860 }
1861 //martin
1862 //client[cs_idx].au=er->reader[0];
1863 //if(client[cs_idx].au<0)
1864 //{
1865 struct s_reader *cur = &reader[er->reader[0]];
1866
1867 if (cur->typ == R_CCCAM && !cur->caid[0] && !cur->audisabled &&
1868 cur->card_system == get_cardsystem(er->caid) && hexserialset(er->reader[0]))
1869 client[cs_idx].au = er->reader[0];
1870 else if((er->caid == cur->caid[0]) && (!cur->audisabled)) {
1871 client[cs_idx].au = er->reader[0]; // First chance - check whether actual reader can AU
1872 } else {
1873 int r=0;
1874 for(r=0;r<CS_MAXREADER;r++) //second chance loop through all readers to find an AU reader
1875 {
1876 cur = &reader[r];
1877 if (matching_reader(er, cur)) {
1878 if (cur->typ == R_CCCAM && !cur->caid[0] && !cur->audisabled &&
1879 cur->card_system == get_cardsystem(er->caid) && hexserialset(r))
1880 {
1881 client[cs_idx].au = r;
1882 break;
1883 }
1884 else if((er->caid == cur->caid[0]) && (er->prid == cur->auprovid) && (!cur->audisabled))
1885 {
1886 client[cs_idx].au=r;
1887 break;
1888 }
1889 }
1890 }
1891 if(r==CS_MAXREADER)
1892 {
1893 client[cs_idx].au=(-1);
1894 }
1895 }
1896 //}
1897 }
1898
1899 er->caid = er->ocaid;
1900 switch(er->rc) {
1901 case 0:
1902 case 3:
1903 // 0 - found
1904 // 3 - emu FIXME: obsolete ?
1905 client[cs_idx].cwfound++;
1906 break;
1907
1908 case 1:
1909 case 2:
1910 // 1 - cache1
1911 // 2 - cache2
1912 client[cs_idx].cwcache++;
1913 break;
1914
1915 case 4:
1916 case 9:
1917 case 10:
1918 // 4 - not found
1919 // 9 - corrupt
1920 // 10 - no card
1921 if (er->rcEx)
1922 client[cs_idx].cwignored++;
1923 else
1924 client[cs_idx].cwnot++;
1925 break;
1926
1927 case 5:
1928 // 5 - timeout
1929 client[cs_idx].cwtout++;
1930 break;
1931
1932 default:
1933 client[cs_idx].cwignored++;
1934 }
1935
1936#ifdef CS_ANTICASC
1937 ac_chk(er, 1);
1938#endif
1939
1940 cs_ddump_mask (D_ATR, er->cw, 16, "cw:");
1941 if (er->rc==7) er->rc=0;
1942 ph[client[cs_idx].ctyp].send_dcw(er);
1943 return 0;
1944}
1945
1946void chk_dcw(int fd)
1947{
1948 ECM_REQUEST *er, *ert;
1949 if (read_from_pipe(fd, (uchar **)(void *)&er, 0) != PIP_ID_ECM)
1950 return;
1951 //cs_log("dcw check from reader %d for idx %d (rc=%d)", er->reader[0], er->cpti, er->rc);
1952 ert=&ecmtask[er->cpti];
1953 if (ert->rc<100) {
1954 send_reader_stat(er->reader[0], er, (er->rc==0)?4:((er->rc==1)?0:er->rc));
1955 return; // already done
1956 }
1957 if( (er->caid!=ert->caid) || memcmp(er->ecm , ert->ecm , sizeof(er->ecm)) )
1958 return; // obsolete
1959 ert->rcEx=er->rcEx;
1960 if (er->rc>0) // found
1961 {
1962 switch(er->rc)
1963 {
1964 case 2:
1965 ert->rc=2;
1966 break;
1967 case 3:
1968 ert->rc=3;
1969 break;
1970 default:
1971 ert->rc=0;
1972 }
1973 ert->rcEx=0;
1974 ert->reader[0]=er->reader[0];
1975 memcpy(ert->cw , er->cw , sizeof(er->cw));
1976#ifdef CS_WITH_GBOX
1977 ert->gbxCWFrom=er->gbxCWFrom;
1978#endif
1979 }
1980 else // not found (from ONE of the readers !)
1981 {
1982 //save reader informations for loadbalance-statistics:
1983 ECM_REQUEST *save_ert = ert;
1984 int save_ridx = er->reader[0];
1985
1986 //
1987 int i;
1988 ert->reader[er->reader[0]]=0;
1989 for (i=0; (ert) && (i<CS_MAXREADER); i++)
1990 if (ert->reader[i]) {// we have still another chance
1991 ert=(ECM_REQUEST *)0;
1992 }
1993 if (ert) ert->rc=4;
1994 else send_reader_stat(save_ridx, save_ert, 4);
1995 }
1996 if (ert) send_dcw(ert);
1997 return;
1998}
1999
2000ulong chk_provid(uchar *ecm, ushort caid) {
2001 int i, len, descriptor_length = 0;
2002 ulong provid = 0;
2003
2004 switch(caid >> 8) {
2005 case 0x01:
2006 // seca
2007 provid = b2i(2, ecm+3);
2008 break;
2009
2010 case 0x05:
2011 // viaccess
2012 i = (ecm[4] == 0xD2) ? ecm[5]+2 : 0; // skip d2 nano
2013 if((ecm[5+i] == 3) && ((ecm[4+i] == 0x90) || (ecm[4+i] == 0x40)))
2014 provid = (b2i(3, ecm+6+i) & 0xFFFFF0);
2015
2016 i = (ecm[6] == 0xD2) ? ecm[7]+2 : 0; // skip d2 nano long ecm
2017 if((ecm[7+i] == 7) && ((ecm[6+i] == 0x90) || (ecm[6+i] == 0x40)))
2018 provid = (b2i(3, ecm+8+i) & 0xFFFFF0);
2019
2020 break;
2021
2022 case 0x0D:
2023 // cryptoworks
2024 len = (((ecm[1] & 0xf) << 8) | ecm[2])+3;
2025 for(i=8; i<len; i+=descriptor_length+2) {
2026 descriptor_length = ecm[i+1];
2027 if (ecm[i] == 0x83) {
2028 provid = (ulong)ecm[i+2] & 0xFE;
2029 break;
2030 }
2031 }
2032 break;
2033 }
2034 return(provid);
2035}
2036
2037#ifdef IRDETO_GUESSING
2038void guess_irdeto(ECM_REQUEST *er)
2039{
2040 uchar b3;
2041 int b47;
2042 //ushort chid;
2043 struct s_irdeto_quess *ptr;
2044
2045 b3 = er->ecm[3];
2046 ptr = cfg->itab[b3];
2047 if( !ptr ) {
2048 cs_debug("unknown irdeto byte 3: %02X", b3);
2049 return;
2050 }
2051 b47 = b2i(4, er->ecm+4);
2052 //chid = b2i(2, er->ecm+6);
2053 //cs_debug("ecm: b47=%08X, ptr->b47=%08X, ptr->caid=%04X", b47, ptr->b47, ptr->caid);
2054 while( ptr )
2055 {
2056 if( b47==ptr->b47 )
2057 {
2058 if( er->srvid && (er->srvid!=ptr->sid) )
2059 {
2060 cs_debug("sid mismatched (ecm: %04X, guess: %04X), wrong oscam.ird file?",
2061 er->srvid, ptr->sid);
2062 return;
2063 }
2064 er->caid=ptr->caid;
2065 er->srvid=ptr->sid;
2066 er->chid=(ushort)ptr->b47;
2067// cs_debug("quess_irdeto() found caid=%04X, sid=%04X, chid=%04X",
2068// er->caid, er->srvid, er->chid);
2069 return;
2070 }
2071 ptr=ptr->next;
2072 }
2073}
2074#endif
2075
2076void cs_betatunnel(ECM_REQUEST *er)
2077{
2078 int n;
2079 ulong mask_all = 0xFFFF;
2080 TUNTAB *ttab;
2081 ttab = &client[cs_idx].ttab;
2082 for (n = 0; (n < CS_MAXTUNTAB); n++) {
2083 if ((er->caid==ttab->bt_caidfrom[n]) && ((er->srvid==ttab->bt_srvid[n]) || (ttab->bt_srvid[n])==mask_all)) {
2084 uchar hack_n3[13] = {0x70, 0x51, 0xc7, 0x00, 0x00, 0x00, 0x01, 0x10, 0x10, 0x00, 0x87, 0x12, 0x07};
2085 uchar hack_n2[13] = {0x70, 0x51, 0xc9, 0x00, 0x00, 0x00, 0x01, 0x10, 0x10, 0x00, 0x48, 0x12, 0x07};
2086 er->caid = ttab->bt_caidto[n];
2087 er->prid = 0;
2088 er->l = (er->ecm[2]+3);
2089 memmove(er->ecm+14, er->ecm+4, er->l-1);
2090 if (er->l > 0x88) {
2091 memcpy(er->ecm+1, hack_n3, 13);
2092 if (er->ecm[0] == 0x81)
2093 er->ecm[12] += 1;
2094 }
2095 else {
2096 memcpy(er->ecm+1, hack_n2, 13);
2097 }
2098 er->l += 10;
2099 er->ecm[2] = er->l-3;
2100 er->btun = 1;
2101 client[cs_idx].cwtun++;
2102 cs_debug("ECM converted from: 0x%X to BetaCrypt: 0x%X for service id:0x%X",
2103 ttab->bt_caidfrom[n], ttab->bt_caidto[n], ttab->bt_srvid[n]);
2104 }
2105 }
2106}
2107
2108void guess_cardsystem(ECM_REQUEST *er)
2109{
2110 ushort last_hope=0;
2111
2112 // viaccess - check by provid-search
2113 if( (er->prid=chk_provid(er->ecm, 0x500)) )
2114 er->caid=0x500;
2115
2116 // nagra
2117 // is ecm[1] always 0x30 ?
2118 // is ecm[3] always 0x07 ?
2119 if ((er->ecm[6]==1) && (er->ecm[4]==er->ecm[2]-2))
2120 er->caid=0x1801;
2121
2122 // seca2 - very poor
2123 if ((er->ecm[8]==0x10) && ((er->ecm[9]&0xF1)==1))
2124 last_hope=0x100;
2125
2126 // is cryptoworks, but which caid ?
2127 if ((er->ecm[3]==0x81) && (er->ecm[4]==0xFF) &&
2128 (!er->ecm[5]) && (!er->ecm[6]) && (er->ecm[7]==er->ecm[2]-5))
2129 last_hope=0xd00;
2130
2131#ifdef IRDETO_GUESSING
2132 if (!er->caid && er->ecm[2]==0x31 && er->ecm[0x0b]==0x28)
2133 guess_irdeto(er);
2134#endif
2135
2136 if (!er->caid) // guess by len ..
2137 er->caid=len4caid[er->ecm[2]+3];
2138
2139 if (!er->caid)
2140 er->caid=last_hope;
2141}
2142
2143void request_cw(ECM_REQUEST *er, int flag, int reader_types)
2144{
2145 int i;
2146 if ((reader_types == 0) || (reader_types == 2))
2147 er->level=flag;
2148 flag=(flag)?3:1; // flag specifies with/without fallback-readers
2149 for (i=0; i<CS_MAXREADER; i++)
2150 {
2151 //if (reader[i].pid)
2152 // cs_log("active reader: %d pid %d fd %d", i, reader[i].pid, reader[i].fd);
2153 int status = 0;
2154 switch (reader_types)
2155 {
2156 // network and local cards
2157 default:
2158 case 0:
2159 if (er->reader[i]&flag){
2160 //cs_debug_mask(D_TRACE, "request_cw1 to reader %s ridx=%d fd=%d", reader[i].label, i, reader[i].fd);
2161 status = write_ecm_request(reader[i].fd, er);
2162 }
2163 break;
2164 // only local cards
2165 case 1:
2166 if (!(reader[i].typ & R_IS_NETWORK))
2167 if (er->reader[i]&flag) {
2168 //cs_debug_mask(D_TRACE, "request_cw2 to reader %s ridx=%d fd=%d", reader[i].label, i, reader[i].fd);
2169 status = write_ecm_request(reader[i].fd, er);
2170 }
2171 break;
2172 // only network
2173 case 2:
2174 //cs_log("request_cw3 ridx=%d fd=%d", i, reader[i].fd);
2175 if ((reader[i].typ & R_IS_NETWORK))
2176 if (er->reader[i]&flag) {
2177 //cs_debug_mask(D_TRACE, "request_cw3 to reader %s ridx=%d fd=%d", reader[i].label, i, reader[i].fd);
2178 status = write_ecm_request(reader[i].fd, er);
2179 }
2180 break;
2181 }
2182 if (status == -1) {
2183 cs_log("request_cw() failed on reader %s (%d) errno=%d, %s", reader[i].label, i, errno, strerror(errno));
2184 if (reader[i].fd && reader[i].pid) {
2185 reader[i].fd_error++;
2186 if (reader[i].fd_error > 5) {
2187 reader[i].fd_error = 0;
2188 kill(client[reader[i].cs_idx].pid, 1); //Schlocke: This should restart the reader!
2189 }
2190 }
2191 }
2192 else
2193 reader[i].fd_error = 0;
2194 }
2195}
2196
2197//receive best reader from master process. Call this function from client!
2198void recv_best_reader(ECM_REQUEST *er, int *reader_avail)
2199{
2200 GET_READER_STAT grs;
2201 memset(&grs, 0, sizeof(grs));
2202 grs.caid = er->caid;
2203 grs.prid = er->prid;
2204 grs.srvid = er->srvid;
2205 grs.cidx = cs_idx;
2206 memcpy(grs.ecmd5, er->ecmd5, sizeof(er->ecmd5));
2207 memcpy(grs.reader_avail, reader_avail, sizeof(int)*CS_MAXREADER);
2208 cs_debug_mask(D_TRACE, "requesting client %s best reader for %04X/%06X/%04X", username(cs_idx), grs.caid, grs.prid, grs.srvid);
2209
2210 int res_write = write_to_pipe(fd_c2m, PIP_ID_BES, (uchar*)&grs, sizeof(GET_READER_STAT));
2211 if (res_write <= 0) {
2212 cs_debug_mask(D_TRACE, "get best reader: write error!");
2213 return;
2214 }
2215
2216 uchar *ptr;
2217 fd_set fds;
2218 do
2219 {
2220 struct timeval timeout;
2221 timeout.tv_sec = 1;
2222 timeout.tv_usec = 500;
2223 FD_ZERO(&fds);
2224 FD_SET(client[cs_idx].fd_m2c_c, &fds);
2225 int res = select(client[cs_idx].fd_m2c_c+1, &fds, 0, 0, &timeout);
2226 if (res == 0) {
2227 cs_debug_mask(D_TRACE, "get best reader: timeout!");
2228 return; //timeout
2229 }
2230 else if (res < 0) {
2231 cs_debug_mask(D_TRACE, "get best reader: failed!");
2232 return; //failed
2233 }
2234
2235 if (master_pid!=getppid())
2236 cs_exit(0);
2237 if (FD_ISSET(client[cs_idx].fd_m2c_c, &fds))
2238 {
2239 int n = read_from_pipe(client[cs_idx].fd_m2c_c, &ptr, 1);
2240 if (n == PIP_ID_BES) {
2241 int *best_readers = (int*)ptr;
2242 memcpy(reader_avail, best_readers, sizeof(int)*CS_MAXREADER);
2243 return;
2244 }
2245 else if (n == PIP_ID_DIR)
2246 continue;
2247 else //should neven happen
2248 cs_debug_mask(D_TRACE, "get best reader: illegal paket? n=%d", n);
2249 }
2250 } while (1);
2251}
2252
2253void get_cw(ECM_REQUEST *er)
2254{
2255 int i, j, m;
2256 time_t now = time((time_t)0);
2257
2258 client[cs_idx].lastecm = now;
2259
2260 if (!er->caid)
2261 guess_cardsystem(er);
2262
2263 /* Quickfix Area */
2264
2265 if( (er->caid & 0xFF00) == 0x600 && !er->chid )
2266 er->chid = (er->ecm[6]<<8)|er->ecm[7];
2267
2268 // quickfix for 0100:000065
2269 if (er->caid == 0x100 && er->prid == 0x65 && er->srvid == 0)
2270 er->srvid = 0x0642;
2271
2272 // Quickfixes for Opticum/Globo HD9500
2273 // Quickfix for 0500:030300
2274 if (er->caid == 0x500 && er->prid == 0x030300)
2275 er->prid = 0x030600;
2276
2277 // Quickfix for 0500:D20200
2278 if (er->caid == 0x500 && er->prid == 0xD20200)
2279 er->prid = 0x030600;
2280
2281 /* END quickfixes */
2282
2283 if (!er->prid)
2284 er->prid = chk_provid(er->ecm, er->caid);
2285
2286 // Set providerid for newcamd clients if none is given
2287 if( (!er->prid) && client[cs_idx].ncd_server ) {
2288 int pi = client[cs_idx].port_idx;
2289 if( pi >= 0 && cfg->ncd_ptab.nports && cfg->ncd_ptab.nports >= pi )
2290 er->prid = cfg->ncd_ptab.ports[pi].ftab.filts[0].prids[0];
2291 }
2292
2293 // CAID not supported or found
2294 if (!er->caid) {
2295 er->rc = 8;
2296 er->rcEx = E2_CAID;
2297 }
2298
2299 // user expired
2300 if(client[cs_idx].expirationdate && client[cs_idx].expirationdate < client[cs_idx].lastecm)
2301 er->rc = 11;
2302
2303 // out of timeframe
2304 if(client[cs_idx].allowedtimeframe[0] && client[cs_idx].allowedtimeframe[1]) {
2305 struct tm *acttm;
2306 acttm = localtime(&now);
2307 int curtime = (acttm->tm_hour * 60) + acttm->tm_min;
2308 int mintime = client[cs_idx].allowedtimeframe[0];
2309 int maxtime = client[cs_idx].allowedtimeframe[1];
2310 if(!((mintime <= maxtime && curtime > mintime && curtime < maxtime) || (mintime > maxtime && (curtime > mintime || curtime < maxtime))))
2311 er->rc = 11;
2312 }
2313
2314 // user disabled
2315 if(client[cs_idx].disabled != 0)
2316 er->rc = 12;
2317
2318 // rc<100 -> ecm error
2319 if (er->rc > 99) {
2320
2321 m = er->caid;
2322 er->ocaid = er->caid;
2323 i = er->srvid;
2324
2325 if ((i != client[cs_idx].last_srvid) || (!client[cs_idx].lastswitch)) {
2326 if(cfg->usrfileflag)
2327 cs_statistics(cs_idx);
2328 client[cs_idx].lastswitch = now;
2329 }
2330
2331 // user sleeping
2332 if ((client[cs_idx].tosleep) && (now - client[cs_idx].lastswitch > client[cs_idx].tosleep)) {
2333 if (client[cs_idx].c35_sleepsend != 0) {
2334 er->rc = 13; // send stop command CMD08 {00 xx}
2335 } else {
2336 er->rc = 6;
2337 }
2338 }
2339
2340 client[cs_idx].last_srvid = i;
2341 client[cs_idx].last_caid = m;
2342
2343 for (j = 0; (j < 6) && (er->rc > 99); j++)
2344 {
2345 switch(j) {
2346
2347 case 0:
2348 // fake (uniq)
2349 if (client[cs_idx].dup)
2350 er->rc = 7;
2351 break;
2352
2353 case 1:
2354 // invalid (caid)
2355 if (!chk_bcaid(er, &client[cs_idx].ctab)) {
2356 er->rc = 8;
2357 er->rcEx = E2_CAID;
2358 }
2359 break;
2360
2361 case 2:
2362 // invalid (srvid)
2363 if (!chk_srvid(er, cs_idx))
2364 er->rc = 8;
2365 break;
2366
2367 case 3:
2368 // invalid (ufilters)
2369 if (!chk_ufilters(er))
2370 er->rc = 8;
2371 break;
2372
2373 case 4:
2374 // invalid (sfilter)
2375 if (!chk_sfilter(er, ph[client[cs_idx].ctyp].ptab))
2376 er->rc = 8;
2377 break;
2378
2379 case 5:
2380 // corrupt
2381 if( (i = er->l - (er->ecm[2] + 3)) ) {
2382 if (i > 0) {
2383 cs_debug("warning: ecm size adjusted from 0x%X to 0x%X",
2384 er->l, er->ecm[2] + 3);
2385 er->l = (er->ecm[2] + 3);
2386 }
2387 else
2388 er->rc = 9;
2389 }
2390 break;
2391 }
2392 }
2393 }
2394
2395 //Schlocke: above checks could change er->rc so
2396 if (er->rc > 99) {
2397 /*BetaCrypt tunneling
2398 *moved behind the check routines,
2399 *because newcamd ECM will fail
2400 *if ECM is converted before
2401 */
2402 if (&client[cs_idx].ttab)
2403 cs_betatunnel(er);
2404
2405 // store ECM in cache
2406 memcpy(er->ecmd5, MD5(er->ecm, er->l, NULL), CS_ECMSTORESIZE);
2407
2408 // cache1
2409 if (check_ecmcache1(er, client[cs_idx].grp))
2410 er->rc = 1;
2411
2412#ifdef CS_ANTICASC
2413 ac_chk(er, 0);
2414#endif
2415 }
2416
2417 if(er->rc > 99) {
2418
2419 if (cfg->reader_auto_loadbalance) {
2420 int reader_avail[CS_MAXREADER];
2421 for (i =0; i < CS_MAXREADER; i++)
2422 reader_avail[i] = matching_reader(er, &reader[i]);
2423
2424 recv_best_reader(er, reader_avail);
2425
2426 for (i = m = 0; i < CS_MAXREADER; i++) {
2427 if (reader_avail[i]) {
2428 m|=er->reader[i] = reader_avail[i];
2429 }
2430 }
2431 }
2432 else
2433 {
2434 for (i = m = 0; i < CS_MAXREADER; i++)
2435 if (matching_reader(er, &reader[i]))
2436 m|=er->reader[i] = (reader[i].fallback)? 2: 1;
2437 }
2438
2439 switch(m) {
2440 // no reader -> not found
2441 case 0:
2442 er->rc = 4;
2443 if (!er->rcEx)
2444 er->rcEx = E2_GROUP;
2445 break;
2446
2447 // fallbacks only, switch them
2448 case 2:
2449 for (i = 0; i < CS_MAXREADER; i++)
2450 er->reader[i]>>=1;
2451 }
2452 }
2453
2454 if (er->rc < 100) {
2455 if (cfg->delay)
2456 cs_sleepms(cfg->delay);
2457
2458 send_dcw(er);
2459 return;
2460 }
2461
2462 er->rcEx = 0;
2463 request_cw(er, 0, cfg->preferlocalcards ? 1 : 0);
2464}
2465
2466void log_emm_request(int auidx)
2467{
2468// cs_log("%s send emm-request (reader=%s, caid=%04X)",
2469// cs_inet_ntoa(client[cs_idx].ip), reader[auidx].label, reader[auidx].caid[0]);
2470 cs_log("%s emm-request sent (reader=%s, caid=%04X)",
2471 username(cs_idx), reader[auidx].label, reader[auidx].caid[0]);
2472}
2473
2474void do_emm(EMM_PACKET *ep)
2475{
2476 int au;
2477 char *typtext[]={"UNKNOWN", "UNIQUE", "SHARED", "GLOBAL"};
2478
2479 au = client[cs_idx].au;
2480 cs_ddump_mask(D_ATR, ep->emm, ep->l, "emm:");
2481
2482 //Unique Id matching for pay-per-view channels:
2483 if (client[cs_idx].autoau) {
2484 int i;
2485 for (i=0;i<CS_MAXREADER;i++) {
2486 if (reader[i].card_system>0 && !reader[i].audisabled) {
2487 if (reader_get_emm_type(ep, &reader[i])) { //decodes ep->type and ep->hexserial from the EMM
2488 if (memcmp(ep->hexserial, reader[i].hexserial, sizeof(ep->hexserial))==0) {
2489 au = i;
2490 break; //
2491 }
2492 }
2493 }
2494 }
2495 }
2496
2497 if ((au < 0) || (au >= CS_MAXREADER)) {
2498 cs_debug_mask(D_EMM, "emm disabled, client has no au-reader!");
2499 return;
2500 }
2501
2502 if (reader[au].card_system>0) {
2503 if (!reader_get_emm_type(ep, &reader[au])) { //decodes ep->type and ep->hexserial from the EMM
2504 cs_debug_mask(D_EMM, "emm skipped");
2505 return;
2506 }
2507 }
2508 else {
2509 cs_debug_mask(D_EMM, "emm skipped, reader %s (%d) has no cardsystem defined!", reader[au].label, au);
2510 return;
2511 }
2512
2513 cs_debug_mask(D_EMM, "emmtype %s. Reader %s has serial %s.", typtext[ep->type], reader[au].label, cs_hexdump(0, reader[au].hexserial, 8));
2514 cs_ddump_mask(D_EMM, ep->hexserial, 8, "emm UA/SA:");
2515 cs_ddump_mask(D_EMM, ep->emm, ep->l, "emm:");
2516
2517 switch (ep->type) {
2518 case UNKNOWN:
2519 if (reader[au].blockemm_unknown) {
2520#ifdef WEBIF
2521 reader[au].emmblocked[UNKNOWN]++;
2522#endif
2523 return;
2524 }
2525 break;
2526
2527 case UNIQUE:
2528 if (reader[au].blockemm_u) {
2529#ifdef WEBIF
2530 reader[au].emmblocked[UNIQUE]++;
2531#endif
2532 return;
2533 }
2534 break;
2535
2536 case SHARED:
2537 if (reader[au].blockemm_s) {
2538#ifdef WEBIF
2539 reader[au].emmblocked[SHARED]++;
2540#endif
2541 return;
2542 }
2543 break;
2544
2545 // FIXME only camd33 delivers hexserial from the net, newcamd, camd35 copy
2546 // cardreader hexserial in; reader_get_emm_type overwrites this with real SA value if known!
2547 case GLOBAL:
2548 if (reader[au].blockemm_g) {
2549#ifdef WEBIF
2550 reader[au].emmblocked[GLOBAL]++;
2551#endif
2552 return;
2553 }
2554 break;
2555 }
2556
2557 client[cs_idx].lastemm = time((time_t)0);
2558
2559 if (reader[au].card_system > 0) {
2560 if (!check_emm_cardsystem(&reader[au], ep)) { // wrong caid
2561 client[cs_idx].emmnok++;
2562 return;
2563 }
2564 client[cs_idx].emmok++;
2565 }
2566 ep->cidx = cs_idx;
2567 cs_debug_mask(D_EMM, "emm is being sent to reader %s.", reader[au].label);
2568 write_to_pipe(reader[au].fd, PIP_ID_EMM, (uchar *) ep, sizeof(EMM_PACKET));
2569}
2570
2571static int comp_timeb(struct timeb *tpa, struct timeb *tpb)
2572{
2573 if (tpa->time>tpb->time) return(1);
2574 if (tpa->time<tpb->time) return(-1);
2575 if (tpa->millitm>tpb->millitm) return(1);
2576 if (tpa->millitm<tpb->millitm) return(-1);
2577 return(0);
2578}
2579
2580struct timeval *chk_pending(struct timeb tp_ctimeout)
2581{
2582 int i;
2583 ulong td;
2584 struct timeb tpn, tpe, tpc; // <n>ow, <e>nd, <c>heck
2585 static struct timeval tv;
2586
2587 ECM_REQUEST *er;
2588 cs_ftime(&tpn);
2589 tpe=tp_ctimeout; // latest delay -> disconnect
2590
2591 if (ecmtask)
2592 i=(ph[client[cs_idx].ctyp].multi)?CS_MAXPENDING:1;
2593 else
2594 i=0;
2595
2596 //cs_log("num pend=%d", i);
2597
2598 for (--i; i>=0; i--) {
2599 if (ecmtask[i].rc>=100) { // check all pending ecm-requests
2600 er=&ecmtask[i];
2601 if (check_ecmcache1(er, client[cs_idx].grp)) { //Schlocke: caching dupplicate requests from different clients
2602 er->rc = 1;
2603 send_dcw(er);
2604 }
2605 }
2606 if (ecmtask[i].rc>=100) { // check all pending ecm-requests
2607 int act, j;
2608 er=&ecmtask[i];
2609 tpc=er->tps;
2610 tpc.millitm += (er->stage) ? cfg->ctimeout : cfg->ftimeout;
2611 tpc.time += tpc.millitm / 1000;
2612 tpc.millitm = tpc.millitm % 1000;
2613 if (!er->stage) {
2614 for (j=0, act=1; (act) && (j<CS_MAXREADER); j++) {
2615 if (cfg->preferlocalcards && !er->locals_done) {
2616 if ((er->reader[j]&1) && !(reader[j].typ & R_IS_NETWORK))
2617 act=0;
2618 } else if (cfg->preferlocalcards && er->locals_done) {
2619 if ((er->reader[j]&1) && (reader[j].typ & R_IS_NETWORK))
2620 act=0;
2621 } else {
2622 if (er->reader[j]&1)
2623 act=0;
2624 }
2625 }
2626
2627 //cs_log("stage 0, act=%d r0=%d, r1=%d, r2=%d, r3=%d, r4=%d r5=%d", act,
2628 // er->reader[0], er->reader[1], er->reader[2],
2629 // er->reader[3], er->reader[4], er->reader[5]);
2630
2631 if (act) {
2632 int inc_stage = 1;
2633 if (cfg->preferlocalcards && !er->locals_done) {
2634 er->locals_done = 1;
2635 for (j = 0; j < CS_MAXREADER; j++) {
2636 if (reader[j].typ & R_IS_NETWORK)
2637 inc_stage = 0;
2638 }
2639 }
2640 if (!inc_stage) {
2641 request_cw(er, er->stage, 2);
2642 tpc.millitm += 1000 * (tpn.time - er->tps.time) + tpn.millitm - er->tps.millitm;
2643 tpc.time += tpc.millitm / 1000;
2644 tpc.millitm = tpc.millitm % 1000;
2645 } else {
2646 er->locals_done = 0;
2647 er->stage++;
2648 request_cw(er, er->stage, cfg->preferlocalcards ? 1 : 0);
2649
2650 tpc.millitm += (cfg->ctimeout-cfg->ftimeout);
2651 tpc.time += tpc.millitm / 1000;
2652 tpc.millitm = tpc.millitm % 1000;
2653 }
2654 }
2655 }
2656 if (comp_timeb(&tpn, &tpc)>0) { // action needed
2657 //cs_log("Action now %d.%03d", tpn.time, tpn.millitm);
2658 //cs_log(" %d.%03d", tpc.time, tpc.millitm);
2659 if (er->stage) {
2660 er->rc=5; // timeout
2661 if (cfg->reader_auto_loadbalance) {
2662 int r;
2663 for (r=0; r<CS_MAXREADER; r++)
2664 if (er->reader[r])
2665 send_reader_stat(r, er, 5);
2666 }
2667 send_dcw(er);
2668 continue;
2669 } else {
2670 er->stage++;
2671 request_cw(er, er->stage, 0);
2672 tpc.millitm += (cfg->ctimeout-cfg->ftimeout);
2673 tpc.time += tpc.millitm / 1000;
2674 tpc.millitm = tpc.millitm % 1000;
2675 }
2676 }
2677 //build_delay(&tpe, &tpc);
2678 if (comp_timeb(&tpe, &tpc)>0) {
2679 tpe.time=tpc.time;
2680 tpe.millitm=tpc.millitm;
2681 }
2682 }
2683 }
2684
2685 td=(tpe.time-tpn.time)*1000+(tpe.millitm-tpn.millitm)+5;
2686 tv.tv_sec = td/1000;
2687 tv.tv_usec = (td%1000)*1000;
2688 //cs_log("delay %d.%06d", tv.tv_sec, tv.tv_usec);
2689 return(&tv);
2690}
2691
2692int process_input(uchar *buf, int l, int timeout)
2693{
2694 int rc;
2695 fd_set fds;
2696 struct timeb tp;
2697
2698 if (master_pid!=getppid()) cs_exit(0);
2699 if (!pfd) return(-1);
2700 cs_ftime(&tp);
2701 tp.time+=timeout;
2702 if (ph[client[cs_idx].ctyp].watchdog)
2703 alarm(cfg->cmaxidle + (cfg->ctimeout + 500) / 1000 + 1);
2704 while (1)
2705 {
2706 FD_ZERO(&fds);
2707 FD_SET(pfd, &fds);
2708 FD_SET(client[cs_idx].fd_m2c_c, &fds);
2709
2710 rc=select(((pfd>client[cs_idx].fd_m2c_c)?pfd:client[cs_idx].fd_m2c_c)+1, &fds, 0, 0, chk_pending(tp));
2711 if (master_pid!=getppid()) cs_exit(0);
2712 if (rc<0)
2713 {
2714 if (errno==EINTR) continue;
2715 else return(0);
2716 }
2717
2718 if (FD_ISSET(client[cs_idx].fd_m2c_c, &fds)) // read from pipe
2719 chk_dcw(client[cs_idx].fd_m2c_c);
2720
2721 if (FD_ISSET(pfd, &fds)) // read from client
2722 {
2723 rc=ph[client[cs_idx].ctyp].recv(buf, l);
2724 break;
2725 }
2726 if (tp.time<=time((time_t *)0)) // client maxidle reached
2727 {
2728 rc=(-9);
2729 break;
2730 }
2731 }
2732 if (ph[client[cs_idx].ctyp].watchdog)
2733 alarm(cfg->cmaxidle + (cfg->ctimeout + 500) / 1000 + 1);
2734 return(rc);
2735}
2736
2737static void restart_clients()
2738{
2739 int i;
2740 cs_log("restarting clients");
2741 for (i=0; i<CS_MAXPID; i++) {
2742 if (client[i].pid && client[i].typ=='c' && ph[client[i].ctyp].type & MOD_CONN_NET) {
2743 kill(client[i].pid, SIGKILL);
2744 cs_log("killing client c%02d pid %d", i, client[i].pid);
2745 }
2746 }
2747}
2748
2749
2750// gets and send the best reader to the client. Called from master-process
2751void send_best_reader(GET_READER_STAT *grs)
2752{
2753 //cs_debug_mask(D_TRACE, "got request for best reader for %04X/%04X/%04X", grs->caid, grs->prid, grs->srvid);
2754 int best_reader[CS_MAXREADER];
2755 get_best_reader(grs, best_reader);
2756 //cs_debug_mask(D_TRACE, "sending best reader %d", ridx);
2757 write_to_pipe(client[grs->cidx].fd_m2c, PIP_ID_BES, (uchar*)&best_reader, sizeof(best_reader));
2758}
2759
2760void send_clear_reader_stat(int ridx)
2761{
2762 write_to_pipe(fd_c2m, PIP_ID_RES, (uchar*)&ridx, sizeof(ridx));
2763}
2764
2765void send_restart_cardreader(int ridx, int force_now)
2766{
2767 int restart_info[2];
2768 restart_info[0] = ridx;
2769 restart_info[1] = force_now;
2770 write_to_pipe(fd_c2m, PIP_ID_RST, (uchar*)&restart_info, sizeof(restart_info));
2771}
2772
2773static void process_master_pipe()
2774{
2775 int n;
2776 uchar *ptr;
2777
2778 switch(n=read_from_pipe(mfdr, &ptr, 1))
2779 {
2780 case PIP_ID_LOG:
2781 cs_write_log((char *)ptr);
2782 break;
2783 case PIP_ID_HUP:
2784 cs_accounts_chk();
2785 break;
2786 case PIP_ID_RST:{ //Restart Cardreader with ridx=prt[0]
2787 int *restart_info = (int *)ptr;
2788 restart_cardreader(restart_info[0], restart_info[1]);
2789 break; }
2790 case PIP_ID_KCL: //Kill all clients
2791 restart_clients();
2792 break;
2793 case PIP_ID_STA: //Add reader statistics
2794 add_reader_stat((ADD_READER_STAT *)ptr);
2795 break;
2796 case PIP_ID_BES: //Get best reader
2797 send_best_reader((GET_READER_STAT *)ptr);
2798 break;
2799 case PIP_ID_RES: //Reset reader statistics
2800 clear_reader_stat(*(int*)ptr);
2801 break;
2802 }
2803}
2804
2805void cs_log_config()
2806{
2807 uchar buf[20];
2808
2809 if (cfg->nice!=99)
2810 sprintf((char *)buf, ", nice=%d", cfg->nice);
2811 else
2812 buf[0]='\0';
2813 cs_log("version=%s, build #%s, system=%s-%s-%s%s", CS_VERSION_X, CS_SVN_VERSION, CS_OS_CPU, CS_OS_HW, CS_OS_SYS, buf);
2814 cs_log("max. clients=%d, client max. idle=%d sec",
2815#ifdef CS_ANTICASC
2816 CS_MAXPID-3, cfg->cmaxidle);
2817#else
2818 CS_MAXPID-2, cfg->cmaxidle);
2819#endif
2820 if( cfg->max_log_size )
2821 sprintf((char *)buf, "%d Kb", cfg->max_log_size);
2822 else
2823 strcpy((char *)buf, "unlimited");
2824 cs_log("max. logsize=%s", buf);
2825 cs_log("client timeout=%lu ms, fallback timeout=%lu ms, cache delay=%d ms",
2826 cfg->ctimeout, cfg->ftimeout, cfg->delay);
2827#ifdef CS_NOSHM
2828 cs_log("shared memory initialized (size=%d, fd=%d)", shmsize, shmid);
2829#else
2830 cs_log("shared memory initialized (size=%d, id=%d)", shmsize, shmid);
2831#endif
2832}
2833
2834void cs_waitforcardinit()
2835{
2836 if (cfg->waitforcards)
2837 {
2838 cs_log("waiting for local card init");
2839 int card_init_done, i;
2840 cs_sleepms(3000); // short sleep for card detect to work proberly
2841 do {
2842 card_init_done = 1;
2843 for (i = 0; i < CS_MAXREADER; i++) {
2844 if (reader[i].card_status == CARD_NEED_INIT) {
2845 card_init_done = 0;
2846 break;
2847 }
2848 }
2849 cs_sleepms(300); // wait a little bit
2850 alarm(cfg->cmaxidle + cfg->ctimeout / 1000 + 1);
2851 } while (!card_init_done);
2852 cs_log("init for all local cards done");
2853 }
2854}
2855
2856void cs_resolve()
2857{
2858 int i;
2859 for (i=0; i<CS_MAXREADER; i++)
2860 if (reader[i].enable && !reader[i].deleted && (reader[i].cs_idx) && (reader[i].typ & R_IS_NETWORK) && (reader[i].typ!=R_CONSTCW))
2861 hostResolve(i);
2862}
2863
2864static void loop_resolver()
2865{
2866 cs_sleepms(1000); // wait for reader
2867 while(cfg->resolvedelay > 0)
2868 {
2869 cs_resolve();
2870 cs_sleepms(1000*cfg->resolvedelay);
2871 }
2872}
2873
2874int main (int argc, char *argv[])
2875{
2876
2877#ifdef CS_LED
2878 cs_switch_led(LED1A, LED_DEFAULT);
2879 cs_switch_led(LED1A, LED_ON);
2880#endif
2881
2882 struct sockaddr_in cad; /* structure to hold client's address */
2883 int scad; /* length of address */
2884 //int fd; /* socket descriptors */
2885 int i, j, n;
2886 int bg=0;
2887 int gfd; //nph,
2888 int fdp[2];
2889 uchar buf[2048];
2890 void (*mod_def[])(struct s_module *)=
2891 {
2892 module_monitor,
2893 module_camd33,
2894 module_camd35,
2895 module_camd35_tcp,
2896 module_newcamd,
2897 module_cccam,
2898 module_constcw,
2899#ifdef CS_WITH_GBOX
2900 module_gbox,
2901#endif
2902 module_radegast,
2903 module_oscam_ser,
2904#ifdef HAVE_DVBAPI
2905 module_dvbapi,
2906#endif
2907 0
2908 };
2909
2910 while ((i=getopt(argc, argv, "bc:d:hm:"))!=EOF)
2911 {
2912 switch(i)
2913 {
2914 case 'b': bg=1;
2915 break;
2916 case 'c': cs_strncpy(cs_confdir, optarg, sizeof(cs_confdir));
2917 break;
2918 case 'd': cs_dblevel=atoi(optarg);
2919 break;
2920 case 'm':
2921#ifdef CS_NOSHM
2922 cs_strncpy(cs_memfile, optarg, sizeof(cs_memfile));
2923 break;
2924#endif
2925 case 'h':
2926 default : usage();
2927 }
2928 }
2929 if (cs_confdir[strlen(cs_confdir)]!='/') strcat(cs_confdir, "/");
2930 init_shm();
2931 init_config();
2932 cfg->debuglvl = cs_dblevel; // give static debuglevel to outer world
2933 for (i=0; mod_def[i]; i++) // must be later BEFORE init_config()
2934 {
2935 memset(&ph[i], 0, sizeof(struct s_module));
2936 mod_def[i](&ph[i]);
2937 }
2938
2939 cs_log("auth size=%d", sizeof(struct s_auth));
2940
2941 init_sidtab();
2942 init_readerdb();
2943 init_userdb(&cfg->account);
2944 init_signal();
2945 cs_set_mloc(30, "init");
2946 init_srvid();
2947 //Todo #ifdef CCCAM
2948 init_provid();
2949
2950 init_len4caid();
2951#ifdef IRDETO_GUESSING
2952 init_irdeto_guess_tab();
2953#endif
2954
2955
2956 if (pipe(fdp))
2957 {
2958 cs_log("Cannot create pipe (errno=%d)", errno);
2959 cs_exit(1);
2960 }
2961 mfdr=fdp[0];
2962 fd_c2m=fdp[1];
2963 gfd=mfdr+1;
2964
2965#ifdef OS_MACOSX
2966 if (bg && daemon_compat(1,0))
2967#else
2968 if (bg && daemon(1,0))
2969#endif
2970 {
2971 cs_log("Error starting in background (errno=%d)", errno);
2972 cs_exit(1);
2973 }
2974 master_pid=client[0].pid=getpid();
2975 if (cfg->pidfile != NULL)
2976 {
2977 FILE *fp;
2978 if (!(fp=fopen(cfg->pidfile, "w")))
2979 {
2980 cs_log("Cannot open pid-file (errno=%d)", errno);
2981 cs_exit(1);
2982 }
2983 fprintf(fp, "%d\n", getpid());
2984 fclose(fp);
2985 }
2986
2987#ifndef OS_CYGWIN32
2988 // /tmp/oscam.version file (Uptime + Version)
2989 FILE *fp;
2990 if (!(fp=fopen("/tmp/oscam.version", "w"))) {
2991 cs_log("Cannot open oscam.version (errno=%d)", errno);
2992 } else {
2993 time_t now = time((time_t)0);
2994 struct tm *st;
2995 st = localtime(&now);
2996 fprintf(fp, "uxstarttime: %d\n", (int)now);
2997 fprintf(fp, "starttime: %02d.%02d.%02d", st->tm_mday, st->tm_mon+1, st->tm_year%100);
2998 fprintf(fp, " %02d:%02d:%02d\n", st->tm_hour, st->tm_min, st->tm_sec);
2999 fprintf(fp, "version: %s#%s\n", CS_VERSION, CS_SVN_VERSION);
3000 fprintf(fp, "maxpid: %d\n", CS_MAXPID);
3001#ifdef WEBIF
3002 fprintf(fp, "webifsupport: yes\n");
3003#else
3004 fprintf(fp, "webifsupport: no\n");
3005#endif
3006#ifdef HAVE_DVBAPI
3007 fprintf(fp, "dvbapisupport: yes\n");
3008#else
3009 fprintf(fp, "dvbapisupport: no\n");
3010#endif
3011#ifdef CS_WITH_GBOX
3012 fprintf(fp, "gboxsupport: yes\n");
3013#else
3014 fprintf(fp, "gboxsupport: no\n");
3015#endif
3016#ifdef CS_ANTICASC
3017 fprintf(fp, "anticascsupport: yes\n");
3018#else
3019 fprintf(fp, "anticascsupport: no\n");
3020#endif
3021 fclose(fp);
3022 }
3023#endif
3024
3025
3026#ifdef AZBOX
3027 openxcas_debug_message_onoff(1); // debug
3028
3029 if (openxcas_open_with_smartcard("oscamCAS") < 0) {
3030 cs_log("openxcas: could not init");
3031 }
3032#endif
3033
3034 for (i=0; i<CS_MAX_MOD; i++)
3035 if( (ph[i].type & MOD_CONN_NET) && ph[i].ptab )
3036 for(j=0; j<ph[i].ptab->nports; j++)
3037 {
3038 start_listener(&ph[i], j);
3039 if( ph[i].ptab->ports[j].fd+1>gfd )
3040 gfd=ph[i].ptab->ports[j].fd+1;
3041 }
3042
3043 //set time for server to now to avoid 0 in monitor/webif
3044 client[0].last=time((time_t *)0);
3045
3046 if(cfg->clientdyndns)
3047 start_thread((void *) &cs_client_resolve, "client resolver");
3048
3049 init_service(97); // logger
3050
3051 if (cfg->resolvedelay > 0)
3052 start_thread(&loop_resolver, "Resolver");
3053#ifdef WEBIF
3054 if(cfg->http_port == 0)
3055 cs_log("http disabled");
3056 else
3057 init_service(95); // http
3058#endif
3059 init_cardreader();
3060
3061 cs_waitforcardinit();
3062#ifdef CS_LED
3063 cs_switch_led(LED1A, LED_OFF);
3064 cs_switch_led(LED1B, LED_ON);
3065#endif
3066
3067#ifdef CS_ANTICASC
3068 if( !cfg->ac_enabled )
3069 cs_log("anti cascading disabled");
3070 else
3071 {
3072 init_ac();
3073 init_service(96);
3074 }
3075#endif
3076
3077 for (i=0; i<CS_MAX_MOD; i++)
3078 if (ph[i].type & MOD_CONN_SERIAL) // for now: oscam_ser only
3079 if (ph[i].s_handler)
3080 ph[i].s_handler(i);
3081
3082 //cs_close_log();
3083 *mcl=1;
3084 while (1)
3085 {
3086 fd_set fds;
3087
3088 do
3089 {
3090 FD_ZERO(&fds);
3091 FD_SET(mfdr, &fds);
3092 for (i=0; i<CS_MAX_MOD; i++)
3093 if ( (ph[i].type & MOD_CONN_NET) && ph[i].ptab )
3094 for (j=0; j<ph[i].ptab->nports; j++)
3095 if (ph[i].ptab->ports[j].fd)
3096 FD_SET(ph[i].ptab->ports[j].fd, &fds);
3097 errno=0;
3098 cs_set_mloc(0, "before select");
3099 select(gfd, &fds, 0, 0, 0);
3100 cs_set_mloc(60, "after select");
3101 } while (errno==EINTR);
3102 cs_set_mloc(-1, "event (global)");
3103
3104 client[0].last=time((time_t *)0);
3105 scad = sizeof(cad);
3106 if (FD_ISSET(mfdr, &fds))
3107 {
3108 cs_set_mloc(-1, "event: master-pipe");
3109 process_master_pipe();
3110 }
3111 for (i=0; i<CS_MAX_MOD; i++)
3112 {
3113 if( (ph[i].type & MOD_CONN_NET) && ph[i].ptab )
3114 {
3115 for( j=0; j<ph[i].ptab->nports; j++ )
3116 {
3117 if( ph[i].ptab->ports[j].fd && FD_ISSET(ph[i].ptab->ports[j].fd, &fds) )
3118 {
3119 if (ph[i].type==MOD_CONN_UDP)
3120 {
3121 cs_set_mloc(-1, "event: udp-socket");
3122 if ((n=recvfrom(ph[i].ptab->ports[j].fd, buf+3, sizeof(buf)-3, 0, (struct sockaddr *)&cad, (socklen_t *)&scad))>0)
3123 {
3124 int idx;
3125 idx=idx_from_ip(cs_inet_order(cad.sin_addr.s_addr), ntohs(cad.sin_port));
3126 if (!idx)
3127 {
3128 if (pipe(fdp))
3129 {
3130 cs_log("Cannot create pipe (errno=%d)", errno);
3131 cs_exit(1);
3132 }
3133 switch(cs_fork(cs_inet_order(cad.sin_addr.s_addr), ntohs(cad.sin_port)))
3134 {
3135 case -1:
3136 close(fdp[0]);
3137 close(fdp[1]);
3138 break;
3139 case 0:
3140 client[idx=cs_last_idx].ufd=fdp[1];
3141 close(fdp[0]);
3142 break;
3143 default:
3144// close(fdp[1]); // now used to simulate event
3145 pfd=fdp[0];
3146 wait4master();
3147 client[cs_idx].ctyp=i;
3148 client[cs_idx].port_idx=j;
3149 client[cs_idx].udp_fd=ph[i].ptab->ports[j].fd;
3150 client[cs_idx].udp_sa=cad;
3151 if (ph[client[cs_idx].ctyp].watchdog)
3152 alarm(cfg->cmaxidle + cfg->ctimeout / 1000 + 1);
3153 ph[i].s_handler(cad); // never return
3154 }
3155 }
3156 if (idx)
3157 {
3158 unsigned short rl;
3159 rl=n;
3160 buf[0]='U';
3161 memcpy(buf+1, &rl, 2);
3162 if (!write(client[idx].ufd, buf, n+3)) cs_exit(1);
3163 }
3164 }
3165 }
3166 else
3167 {
3168 cs_set_mloc(-1, "event: tcp-socket");
3169 if ((pfd=accept(ph[i].ptab->ports[j].fd, (struct sockaddr *)&cad, (socklen_t *)&scad))>0)
3170 {
3171 switch(cs_fork(cs_inet_order(cad.sin_addr.s_addr), ntohs(cad.sin_port)))
3172 {
3173 case -1:
3174 case 0:
3175 close(pfd);
3176 break;
3177 default:
3178 wait4master();
3179 client[cs_idx].ctyp=i;
3180 client[cs_idx].udp_fd=pfd;
3181 client[cs_idx].port_idx=j;
3182 if (ph[client[cs_idx].ctyp].watchdog)
3183 alarm(cfg->cmaxidle + cfg->ctimeout / 1000 + 1);
3184 ph[i].s_handler();
3185 }
3186 }
3187 }
3188 }
3189 }
3190 } // if (ph[i].type & MOD_CONN_NET)
3191 }
3192 }
3193
3194
3195#ifdef AZBOX
3196 if (openxcas_close() < 0) {
3197 cs_log("openxcas: could not close");
3198 }
3199#endif
3200
3201 cs_exit(1);
3202}
3203
3204#ifdef CS_LED
3205void cs_switch_led(int led, int action) {
3206
3207 if(action < 2) { // only LED_ON and LED_OFF
3208 char ledfile[256];
3209 FILE *f;
3210
3211 #ifdef DOCKSTAR
3212 switch(led){
3213 case LED1A:snprintf(ledfile, 255, "/sys/class/leds/dockstar:orange:misc/brightness");
3214 break;
3215 case LED1B:snprintf(ledfile, 255, "/sys/class/leds/dockstar:green:health/brightness");
3216 break;
3217 case LED2:snprintf(ledfile, 255, "/sys/class/leds/dockstar:green:health/brightness");
3218 break;
3219 case LED3:snprintf(ledfile, 255, "/sys/class/leds/dockstar:orange:misc/brightness");
3220 break;
3221 }
3222 #else
3223 switch(led){
3224 case LED1A:snprintf(ledfile, 255, "/sys/class/leds/nslu2:red:status/brightness");
3225 break;
3226 case LED1B:snprintf(ledfile, 255, "/sys/class/leds/nslu2:green:ready/brightness");
3227 break;
3228 case LED2:snprintf(ledfile, 255, "/sys/class/leds/nslu2:green:disk-1/brightness");
3229 break;
3230 case LED3:snprintf(ledfile, 255, "/sys/class/leds/nslu2:green:disk-2/brightness");
3231 break;
3232 }
3233 #endif
3234
3235 if (!(f=fopen(ledfile, "w"))){
3236 // FIXME: sometimes cs_log was not available when calling cs_switch_led -> signal 11
3237 //cs_log("Cannot open file \"%s\" (errno=%d)", ledfile, errno);
3238 return;
3239 }
3240 fprintf(f,"%d", action);
3241 fclose(f);
3242 } else { // LED Macros
3243 switch(action){
3244 case LED_DEFAULT:
3245 cs_switch_led(LED1A, LED_OFF);
3246 cs_switch_led(LED1B, LED_OFF);
3247 cs_switch_led(LED2, LED_ON);
3248 cs_switch_led(LED3, LED_OFF);
3249 break;
3250 case LED_BLINK_OFF:
3251 cs_switch_led(led, LED_OFF);
3252 cs_sleepms(100);
3253 cs_switch_led(led, LED_ON);
3254 break;
3255 case LED_BLINK_ON:
3256 cs_switch_led(led, LED_ON);
3257 cs_sleepms(300);
3258 cs_switch_led(led, LED_OFF);
3259 break;
3260 }
3261 }
3262}
3263#endif
Note: See TracBrowser for help on using the repository browser.